The 'inotify' driver currently keeps all its state in a global static variables. Not so great since we access this from all sorts of places and its hard to guarentee thread safety. Also, we're using per-connection FD watches to update this state, so if multiple Xen connections were active, they'd all be updating the same globl state. So we move the state into the virConnect object. This will increase memory usage if a single process has multiple Xen connections open though, but not by very much xen_inotify.c | 105 +++++++++++++++++++++++++++++++--------------------------- xen_unified.h | 7 +++ xs_internal.c | 33 ++++++++---------- 3 files changed, 79 insertions(+), 66 deletions(-) Daniel diff --git a/src/xen_inotify.c b/src/xen_inotify.c --- a/src/xen_inotify.c +++ b/src/xen_inotify.c @@ -48,9 +48,6 @@ __FUNCTION__, __LINE__, fmt) #define LIBVIRTD_DOMAINS_DIR "/var/lib/xend/domains" -static const char *configDir = NULL; -static int useXenConfigCache = 0; -static xenUnifiedDomainInfoListPtr configInfoList = NULL; struct xenUnifiedDriver xenInotifyDriver = { xenInotifyOpen, /* open */ @@ -121,6 +118,7 @@ xenInotifyXendDomainsDirLookup(virConnec virDomainPtr dom; const char *uuid_str; unsigned char rawuuid[VIR_UUID_BUFLEN]; + xenUnifiedPrivatePtr priv = conn->privateData; /* xend is managing domains. we will get * a filename in the manner: @@ -142,15 +140,15 @@ xenInotifyXendDomainsDirLookup(virConnec /* If we are here, the domain has gone away. search for, and create a domain from the stored list info */ - for (i=0; i<configInfoList->count; i++) { - if (!memcmp(uuid, configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN)) { - *name = strdup(configInfoList->doms[i]->name); + for (i = 0 ; i < priv->configInfoList->count ; i++) { + if (!memcmp(uuid, priv->configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN)) { + *name = strdup(priv->configInfoList->doms[i]->name); if (!*name) { virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, _("finding dom for %s"), uuid_str); return -1; } - memcpy(uuid, configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN); + memcpy(uuid, priv->configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN); DEBUG0("Found dom on list"); return 0; } @@ -172,7 +170,8 @@ xenInotifyDomainLookup(virConnectPtr con xenInotifyDomainLookup(virConnectPtr conn, const char *filename, char **name, unsigned char *uuid) { - if (useXenConfigCache) + xenUnifiedPrivatePtr priv = conn->privateData; + if (priv->useXenConfigCache) return xenInotifyXenCacheLookup(filename, name, uuid); else return xenInotifyXendDomainsDirLookup(conn, filename, name, uuid); @@ -195,8 +194,9 @@ xenInotifyDomainEventFromFile(virConnect } static int -xenInotifyXendDomainsDirRemoveEntry(virConnectPtr conn ATTRIBUTE_UNUSED, +xenInotifyXendDomainsDirRemoveEntry(virConnectPtr conn, const char *fname) { + xenUnifiedPrivatePtr priv = conn->privateData; const char *uuidstr = fname + strlen(LIBVIRTD_DOMAINS_DIR) + 1; unsigned char uuid[VIR_UUID_BUFLEN]; int i; @@ -208,22 +208,22 @@ xenInotifyXendDomainsDirRemoveEntry(virC } /* match and remove on uuid */ - for (i=0; i<configInfoList->count; i++) { - if (!memcmp(uuid, configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN)) { - VIR_FREE(configInfoList->doms[i]->name); - VIR_FREE(configInfoList->doms[i]); + for (i = 0 ; i < priv->configInfoList->count ; i++) { + if (!memcmp(uuid, priv->configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN)) { + VIR_FREE(priv->configInfoList->doms[i]->name); + VIR_FREE(priv->configInfoList->doms[i]); - if (i < (configInfoList->count - 1)) - memmove(configInfoList->doms + i, - configInfoList->doms + i + 1, - sizeof(*(configInfoList->doms)) * - (configInfoList->count - (i + 1))); + if (i < (priv->configInfoList->count - 1)) + memmove(priv->configInfoList->doms + i, + priv->configInfoList->doms + i + 1, + sizeof(*(priv->configInfoList->doms)) * + (priv->configInfoList->count - (i + 1))); - if (VIR_REALLOC_N(configInfoList->doms, - configInfoList->count - 1) < 0) { + if (VIR_REALLOC_N(priv->configInfoList->doms, + priv->configInfoList->count - 1) < 0) { ; /* Failure to reduce memory allocation isn't fatal */ } - configInfoList->count--; + priv->configInfoList->count--; return 0; } } @@ -235,13 +235,15 @@ xenInotifyXendDomainsDirAddEntry(virConn const char *fname) { char *name = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; + xenUnifiedPrivatePtr priv = conn->privateData; + if (xenInotifyDomainLookup(conn, fname, &name, uuid) < 0) { virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("Error looking up domain")); return -1; } - if( xenUnifiedAddDomainInfo(configInfoList, + if (xenUnifiedAddDomainInfo(priv->configInfoList, -1, name, uuid) < 0) { virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("Error adding file to config cache")); @@ -255,15 +257,19 @@ static int static int xenInotifyRemoveDomainConfigInfo(virConnectPtr conn, const char *fname) { - return useXenConfigCache ? xenXMConfigCacheRemoveFile(conn, fname) : - xenInotifyXendDomainsDirRemoveEntry(conn, fname); + xenUnifiedPrivatePtr priv = conn->privateData; + return priv->useXenConfigCache ? + xenXMConfigCacheRemoveFile(conn, fname) : + xenInotifyXendDomainsDirRemoveEntry(conn, fname); } static int xenInotifyAddDomainConfigInfo(virConnectPtr conn, const char *fname) { - return useXenConfigCache ? xenXMConfigCacheAddFile(conn, fname) : - xenInotifyXendDomainsDirAddEntry(conn, fname); + xenUnifiedPrivatePtr priv = conn->privateData; + return priv->useXenConfigCache ? + xenXMConfigCacheAddFile(conn, fname) : + xenInotifyXendDomainsDirAddEntry(conn, fname); } static void @@ -277,7 +283,7 @@ xenInotifyEvent(int watch ATTRIBUTE_UNUS struct inotify_event *e; int got; char *tmp, *name; - virConnectPtr conn = (virConnectPtr) data; + virConnectPtr conn = data; xenUnifiedPrivatePtr priv = NULL; DEBUG0("got inotify event"); @@ -315,7 +321,8 @@ reread: name = (char *)&(e->name); - snprintf(fname, 1024, "%s/%s", configDir, name); + snprintf(fname, 1024, "%s/%s", + priv->configDir, name); if (e->mask & (IN_DELETE | IN_MOVED_FROM)) { virDomainEventPtr event = @@ -378,24 +385,24 @@ xenInotifyOpen(virConnectPtr conn ATTRIB if(priv->xendConfigVersion <= 2) { /* /etc/xen */ - configDir = xenXMGetConfigDir(); - useXenConfigCache = 1; + priv->configDir = xenXMGetConfigDir(); + priv->useXenConfigCache = 1; } else { /* /var/lib/xend/domains/<uuid>/config.sxp */ - configDir = LIBVIRTD_DOMAINS_DIR; - useXenConfigCache = 0; + priv->configDir = LIBVIRTD_DOMAINS_DIR; + priv->useXenConfigCache = 0; - if ( VIR_ALLOC(configInfoList ) < 0) { + if (VIR_ALLOC(priv->configInfoList) < 0) { virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("failed to allocate configInfoList")); + "%s", _("failed to allocate configInfoList")); return -1; } /* populate initial list */ - if (!(dh = opendir(configDir))) { + if (!(dh = opendir(priv->configDir))) { virReportSystemError(NULL, errno, _("cannot open directory: %s"), - configDir); + priv->configDir); return -1; } while ((ent = readdir(dh))) { @@ -403,9 +410,10 @@ xenInotifyOpen(virConnectPtr conn ATTRIB continue; /* Build the full file path */ - if ((strlen(configDir) + 1 + strlen(ent->d_name) + 1) > PATH_MAX) + if ((strlen(priv->configDir) + 1 + + strlen(ent->d_name) + 1) > PATH_MAX) continue; - strcpy(path, configDir); + strcpy(path, priv->configDir); strcat(path, "/"); strcat(path, ent->d_name); @@ -419,24 +427,25 @@ xenInotifyOpen(virConnectPtr conn ATTRIB } if ((priv->inotifyFD = inotify_init()) < 0) { - virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("initializing inotify")); + virReportSystemError(NULL, errno, + "%s", _("initializing inotify")); return -1; } - DEBUG("Adding a watch on %s", configDir); + DEBUG("Adding a watch on %s", priv->configDir); if (inotify_add_watch(priv->inotifyFD, - configDir, + priv->configDir, IN_CREATE | IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM) < 0) { - virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR, - _("adding watch on %s"), _(configDir)); + virReportSystemError(NULL, errno, + _("adding watch on %s"), + priv->configDir); return -1; } DEBUG0("Building initial config cache"); - if (useXenConfigCache && + if (priv->useXenConfigCache && xenXMConfigCacheRefresh (conn) < 0) { DEBUG("Failed to enable XM config cache %s", conn->err.message); return -1; @@ -464,10 +473,10 @@ int int xenInotifyClose(virConnectPtr conn) { - xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; - if(configInfoList) - xenUnifiedDomainInfoListFree(configInfoList); + if (priv->configInfoList) + xenUnifiedDomainInfoListFree(priv->configInfoList); if (priv->inotifyWatch != -1) virEventRemoveHandle(priv->inotifyWatch); diff --git a/src/xen_unified.h b/src/xen_unified.h --- a/src/xen_unified.h +++ b/src/xen_unified.h @@ -156,6 +156,9 @@ struct _xenUnifiedPrivate { /* A list of xenstore watches */ xenStoreWatchListPtr xsWatchList; int xsWatch; + /* A list of active domain name/uuids */ + xenUnifiedDomainInfoListPtr activeDomainList; + /* An list of callbacks */ virDomainEventCallbackListPtr domainEventCallbacks; @@ -164,6 +167,10 @@ struct _xenUnifiedPrivate { /* The inotify fd */ int inotifyFD; int inotifyWatch; + + const char *configDir; + int useXenConfigCache ; + xenUnifiedDomainInfoListPtr configInfoList; #endif }; diff --git a/src/xs_internal.c b/src/xs_internal.c --- a/src/xs_internal.c +++ b/src/xs_internal.c @@ -46,9 +46,6 @@ #endif #ifndef PROXY -/* A list of active domain name/uuids */ -static xenUnifiedDomainInfoListPtr activeDomainList = NULL; - static char *xenStoreDomainGetOSType(virDomainPtr domain); struct xenUnifiedDriver xenStoreDriver = { @@ -312,7 +309,7 @@ xenStoreOpen(virConnectPtr conn, #ifndef PROXY /* Init activeDomainList */ - if ( VIR_ALLOC(activeDomainList) < 0) { + if (VIR_ALLOC(priv->activeDomainList) < 0) { virXenStoreError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("failed to allocate activeDomainList")); return -1; @@ -389,7 +386,7 @@ xenStoreClose(virConnectPtr conn) xenStoreWatchListFree(priv->xsWatchList); #ifndef PROXY - xenUnifiedDomainInfoListFree(activeDomainList); + xenUnifiedDomainInfoListFree(priv->activeDomainList); #endif if (priv->xshandle == NULL) return(-1); @@ -1188,7 +1185,7 @@ int xenStoreDomainIntroduced(virConnectP int *new_domids; int nread; - xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) opaque; + xenUnifiedPrivatePtr priv = opaque; retry: new_domain_cnt = xenStoreNumOfDomains(conn); @@ -1207,8 +1204,8 @@ retry: missing = 0; for (i=0 ; i < new_domain_cnt ; i++) { found = 0; - for (j = 0 ; j < activeDomainList->count ; j++) { - if (activeDomainList->doms[j]->id == new_domids[i]) { + for (j = 0 ; j < priv->activeDomainList->count ; j++) { + if (priv->activeDomainList->doms[j]->id == new_domids[i]) { found = 1; break; } @@ -1236,7 +1233,7 @@ retry: xenUnifiedDomainEventDispatch(priv, event); /* Add to the list */ - xenUnifiedAddDomainInfo(activeDomainList, + xenUnifiedAddDomainInfo(priv->activeDomainList, new_domids[i], name, uuid); VIR_FREE(name); @@ -1265,7 +1262,7 @@ int xenStoreDomainReleased(virConnectPtr xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) opaque; - if(!activeDomainList->count) return 0; + if(!priv->activeDomainList->count) return 0; retry: new_domain_cnt = xenStoreNumOfDomains(conn); @@ -1283,10 +1280,10 @@ retry: } removed = 0; - for (j=0 ; j < activeDomainList->count ; j++) { + for (j=0 ; j < priv->activeDomainList->count ; j++) { found = 0; for (i=0 ; i < new_domain_cnt ; i++) { - if (activeDomainList->doms[j]->id == new_domids[i]) { + if (priv->activeDomainList->doms[j]->id == new_domids[i]) { found = 1; break; } @@ -1295,18 +1292,18 @@ retry: if (!found) { virDomainEventPtr event = virDomainEventNew(-1, - activeDomainList->doms[j]->name, - activeDomainList->doms[j]->uuid, + priv->activeDomainList->doms[j]->name, + priv->activeDomainList->doms[j]->uuid, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); if (event) xenUnifiedDomainEventDispatch(priv, event); /* Remove from the list */ - xenUnifiedRemoveDomainInfo(activeDomainList, - activeDomainList->doms[j]->id, - activeDomainList->doms[j]->name, - activeDomainList->doms[j]->uuid); + xenUnifiedRemoveDomainInfo(priv->activeDomainList, + priv->activeDomainList->doms[j]->id, + priv->activeDomainList->doms[j]->name, + priv->activeDomainList->doms[j]->uuid); removed = 1; } -- |: 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