On Tue, Nov 11, 2008 at 01:34:29PM -0500, Ben Guthro wrote: > This version of the Xen-Events patch goes a step further > than the last version, and now emits the following domain events: > > STARTED > STOPPED > ADDED > REMOVED > > This is accomplished by monitoring /etc/xen, and taking advantage > of what seemed to be dormant code in the XM driver. By re-enabling > the "config cache", we can properly track domains when files come, > and go into this directory. This isn't quite correct. The /etc/xen directory & thus xm_internal.c driver is only used for Xen < 3.0.4, where there was no XenD management of inactive domains. For Xen >= 3.0.4, we let XenD itself manage all inactive domains, so /etc/xen should not be used. XenD keeps its persistent configs in /var/lib/xen/xend/domains. So for this inotify magic, we shouldn't be looking at /etc/xen, and instead watch /var/lib/xen/xend/domains. THis is actually nice & easy because the files in the directry are named according to the UUID, so we don't even need to read the file contents in that scenario. > +static void > +xenInotifyEvent(int fd, > + int events ATTRIBUTE_UNUSED, > + void *data) > +{ > + char buf[1024]; > + char fname[1024]; > + struct inotify_event *e; > + int got; > + char *tmp, *name; > + virConnectPtr conn = (virConnectPtr) data; > + xenUnifiedPrivatePtr priv = NULL; > + virDomainPtr dom = NULL; > + > + DEBUG0("got inotify event"); > + > + if( conn && conn->privateData ) { > + priv = conn->privateData; > + } else { > + virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, > + "%s", _("conn, or private data is NULL")); > + return; > + } > + > +reread: > + got = read(fd, buf, sizeof(buf)); > + if (got == -1) { > + if (errno == EINTR) > + goto reread; > + return; > + } > + > + tmp = buf; > + while (got) { > + if (got < sizeof(struct inotify_event)) > + return; /* bad */ > + > + e = (struct inotify_event *)tmp; > + tmp += sizeof(struct inotify_event); > + got -= sizeof(struct inotify_event); > + > + if (got < e->len) > + return; > + > + tmp += e->len; > + got -= e->len; > + > + name = (char *)&(e->name); > + > + snprintf(fname, 1024, "%s/%s", xenXMGetConfigDir(), name); > + > + if (e->mask & IN_DELETE) { > + if (!(dom = xenInotifyConfigLookupCache(conn, fname))) { > + virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, > + "%s", _("looking up dom")); > + continue; > + } > + > + xenUnifiedDomainEventDispatch(conn->privateData, > + dom, VIR_DOMAIN_EVENT_REMOVED); > + > + if (xenXMConfigCacheRefresh (conn) < 0) { > + virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, > + "%s", _("Error refreshing config cache")); > + return; > + } > + } else if (e->mask & IN_MODIFY) { > + /* if we track IN_CREATED we get 2 added events */ > + if (xenXMConfigCacheRefresh (conn) < 0) { > + virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, > + "%s", _("Error refreshing config cache")); > + return; > + } If we've activated inotify, then we should not call xenXMConfigCacheRefresh() since that iterates over every file in the directory. Since we know the new or old filenames, we can just populate / remove the individual file. This will require re-factoring xenXMConfigCacheRefresh() slightly. It currently has all its useful logic inside its while() loop. We should break the body of xenXMConfigCacheRefresh() out into a separate method which just able to process a single new file, eg xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename); And also add a new xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename); to just remove the old file from the cache. When activating inotify we can call xenXMConfigCacheRefresh() once to get the initial list of domains, and then disable various calls to it in all the public APIs in xm_internal.h, and rely on the inotify code to keep it up2date. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list