From 6334cd16dfc61dbfde5241bbd3a144d314b809d2 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 20 Aug 2008 19:42:36 +0000 Subject: [PATCH] Remove configFile/autostartLink vars from virDomainObj struct --- ChangeLog | 9 ++++ src/domain_conf.c | 133 +++++++++++++++++++++------------------------- src/domain_conf.h | 14 ++--- src/lxc_driver.c | 15 ++++-- src/qemu_driver.c | 62 ++++++++++++++------- src/util.c | 17 ++++++ src/util.h | 3 ++ 7 files changed, 153 insertions(+), 100 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83011f3b26..555a206ecb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Wed Aug 20 42:42:09 BST 2008 Daniel P. Berrange + + * src/util.c, src/util.h: Add convenience APIs for stripping + a file extension + * src/domain_conf.c, src/domain_conf.h, src/lxc_driver.c, + src/qemu_driver.c: Remove fixed configfile/autostartlink + fields in virDomainObjPtr. Generate paths on-demand at time + of use + Wed Aug 20 15:42:09 CEST 2008 Daniel Veillard * src/openvz_conf.c src/openvz_driver.c: patch from Evgeniy Sokolov diff --git a/src/domain_conf.c b/src/domain_conf.c index 4b095984fd..fc2bcf3132 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -421,8 +421,6 @@ void virDomainObjFree(virDomainObjPtr dom) virDomainDefFree(dom->newDef); VIR_FREE(dom->vcpupids); - VIR_FREE(dom->configFile); - VIR_FREE(dom->autostartLink); VIR_FREE(dom); } @@ -3220,31 +3218,19 @@ char *virDomainDefFormat(virConnectPtr conn, int virDomainSaveConfig(virConnectPtr conn, const char *configDir, - const char *autostartDir, - virDomainObjPtr dom) + virDomainDefPtr def) { char *xml; + char *configFile = NULL; int fd = -1, ret = -1; size_t towrite; int err; - if (!dom->configFile && - asprintf(&dom->configFile, "%s/%s.xml", - configDir, dom->def->name) < 0) { - dom->configFile = NULL; - virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL); + if ((configFile = virDomainConfigFile(conn, configDir, def->name)) == NULL) goto cleanup; - } - if (!dom->autostartLink && - asprintf(&dom->autostartLink, "%s/%s.xml", - autostartDir, dom->def->name) < 0) { - dom->autostartLink = NULL; - virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL); - goto cleanup; - } if (!(xml = virDomainDefFormat(conn, - dom->newDef ? dom->newDef : dom->def, + def, VIR_DOMAIN_XML_SECURE))) goto cleanup; @@ -3255,34 +3241,27 @@ int virDomainSaveConfig(virConnectPtr conn, goto cleanup; } - if ((err = virFileMakePath(autostartDir))) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot create autostart directory %s: %s"), - autostartDir, strerror(err)); - goto cleanup; - } - - if ((fd = open(dom->configFile, + if ((fd = open(configFile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR )) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot create config file %s: %s"), - dom->configFile, strerror(errno)); + _("cannot create config file %s: %s"), + configFile, strerror(errno)); goto cleanup; } towrite = strlen(xml); if (safewrite(fd, xml, towrite) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot write config file %s: %s"), - dom->configFile, strerror(errno)); + _("cannot write config file %s: %s"), + configFile, strerror(errno)); goto cleanup; } if (close(fd) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot save config file %s: %s"), - dom->configFile, strerror(errno)); + _("cannot save config file %s: %s"), + configFile, strerror(errno)); goto cleanup; } @@ -3302,25 +3281,18 @@ virDomainObjPtr virDomainLoadConfig(virConnectPtr conn, virDomainObjPtr *doms, const char *configDir, const char *autostartDir, - const char *file) + const char *name) { char *configFile = NULL, *autostartLink = NULL; virDomainDefPtr def = NULL; virDomainObjPtr dom; int autostart; - if (asprintf(&configFile, "%s/%s", - configDir, file) < 0) { - configFile = NULL; - virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL); + if ((configFile = virDomainConfigFile(conn, configDir, name)) == NULL) goto error; - } - if (asprintf(&autostartLink, "%s/%s", - autostartDir, file) < 0) { - autostartLink = NULL; - virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL); + if ((autostartLink = virDomainConfigFile(conn, autostartDir, name)) == NULL) goto error; - } + if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0) goto error; @@ -3328,20 +3300,10 @@ virDomainObjPtr virDomainLoadConfig(virConnectPtr conn, if (!(def = virDomainDefParseFile(conn, caps, configFile))) goto error; - if (!virFileMatchesNameSuffix(file, def->name, ".xml")) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("Domain config filename '%s'" - " does not match domain name '%s'"), - configFile, def->name); - goto error; - } - if (!(dom = virDomainAssignDef(conn, doms, def))) goto error; dom->state = VIR_DOMAIN_SHUTOFF; - dom->configFile = configFile; - dom->autostartLink = autostartLink; dom->autostart = autostart; return dom; @@ -3372,20 +3334,24 @@ int virDomainLoadAllConfigs(virConnectPtr conn, } while ((entry = readdir(dir))) { + virDomainObjPtr dom; + if (entry->d_name[0] == '.') continue; - if (!virFileHasSuffix(entry->d_name, ".xml")) + if (!virFileStripSuffix(entry->d_name, ".xml")) continue; /* NB: ignoring errors, so one malformed config doesn't kill the whole process */ - virDomainLoadConfig(conn, - caps, - doms, - configDir, - autostartDir, - entry->d_name); + dom = virDomainLoadConfig(conn, + caps, + doms, + configDir, + autostartDir, + entry->d_name); + if (dom) + dom->persistent = 1; } closedir(dir); @@ -3394,25 +3360,50 @@ int virDomainLoadAllConfigs(virConnectPtr conn, } int virDomainDeleteConfig(virConnectPtr conn, - virDomainObjPtr dom) + const char *configDir, + const char *autostartDir, + virDomainObjPtr dom) { - if (!dom->configFile || !dom->autostartLink) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("no config file for %s"), dom->def->name); - return -1; - } + char *configFile = NULL, *autostartLink = NULL; + int ret = -1; + + if ((configFile = virDomainConfigFile(conn, configDir, dom->def->name)) == NULL) + goto cleanup; + if ((autostartLink = virDomainConfigFile(conn, autostartDir, dom->def->name)) == NULL) + goto cleanup; /* Not fatal if this doesn't work */ - unlink(dom->autostartLink); + unlink(autostartLink); - if (unlink(dom->configFile) < 0) { + if (unlink(configFile) < 0 && + errno != ENOENT) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot remove config for %s: %s"), + _("cannot remove config for %s: %s"), dom->def->name, strerror(errno)); - return -1; + goto cleanup; } - return 0; + ret = 0; + +cleanup: + VIR_FREE(configFile); + VIR_FREE(autostartLink); + return ret; } +char *virDomainConfigFile(virConnectPtr conn, + const char *dir, + const char *name) +{ + char *ret = NULL; + + if (asprintf(&ret, "%s/%s.xml", dir, name) < 0) { + virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL); + return NULL; + } + + return ret; +} + + #endif /* ! PROXY */ diff --git a/src/domain_conf.h b/src/domain_conf.h index 01959b721b..b98f7f34aa 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -458,9 +458,6 @@ struct _virDomainObj { unsigned int autostart : 1; unsigned int persistent : 1; - char *configFile; - char *autostartLink; - virDomainDefPtr def; /* The current definition */ virDomainDefPtr newDef; /* New definition to activate at shutdown */ @@ -532,15 +529,14 @@ char *virDomainCpuSetFormat(virConnectPtr conn, int virDomainSaveConfig(virConnectPtr conn, const char *configDir, - const char *autostartDir, - virDomainObjPtr dom); + virDomainDefPtr def); virDomainObjPtr virDomainLoadConfig(virConnectPtr conn, virCapsPtr caps, virDomainObjPtr *doms, const char *configDir, const char *autostartDir, - const char *file); + const char *name); int virDomainLoadAllConfigs(virConnectPtr conn, virCapsPtr caps, @@ -549,8 +545,14 @@ int virDomainLoadAllConfigs(virConnectPtr conn, const char *autostartDir); int virDomainDeleteConfig(virConnectPtr conn, + const char *configDir, + const char *autostartDir, virDomainObjPtr dom); +char *virDomainConfigFile(virConnectPtr conn, + const char *dir, + const char *name); + virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn, xmlNodePtr node); diff --git a/src/lxc_driver.c b/src/lxc_driver.c index 629f51bcb5..da0fe41d48 100644 --- a/src/lxc_driver.c +++ b/src/lxc_driver.c @@ -250,11 +250,11 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml) virDomainDefFree(def); return NULL; } + vm->persistent = 1; if (virDomainSaveConfig(conn, driver->configDir, - driver->autostartDir, - vm) < 0) { + vm->newDef ? vm->newDef : vm->def) < 0) { virDomainRemoveInactive(&driver->domains, vm); return NULL; } @@ -284,10 +284,17 @@ static int lxcDomainUndefine(virDomainPtr dom) return -1; } - if (virDomainDeleteConfig(dom->conn, vm) <0) + if (!vm->persistent) { + lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot undefine transient domain")); return -1; + } - vm->configFile[0] = '\0'; + if (virDomainDeleteConfig(dom->conn, + driver->configDir, + driver->autostartDir, + vm) <0) + return -1; virDomainRemoveInactive(&driver->domains, vm); diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 01c30e80fd..2cef549368 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -351,7 +351,7 @@ qemudShutdown(void) { virDomainObjPtr next = vm->next; if (virDomainIsActive(vm)) qemudShutdownVMDaemon(NULL, qemu_driver, vm); - if (!vm->configFile) + if (!vm->persistent) virDomainRemoveInactive(&qemu_driver->domains, vm); vm = next; @@ -1072,7 +1072,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, int fd) { if (qemudVMData(driver, vm, fd) < 0) { qemudShutdownVMDaemon(NULL, driver, vm); - if (!vm->configFile) + if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); } @@ -1082,7 +1082,7 @@ static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, i static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr vm, int fd ATTRIBUTE_UNUSED) { qemudShutdownVMDaemon(NULL, driver, vm); - if (!vm->configFile) + if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); return 0; @@ -2162,7 +2162,7 @@ static int qemudDomainDestroy(virDomainPtr dom) { } qemudShutdownVMDaemon(dom->conn, driver, vm); - if (!vm->configFile) + if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -2493,7 +2493,7 @@ static int qemudDomainSave(virDomainPtr dom, /* Shut it down */ qemudShutdownVMDaemon(dom->conn, driver, vm); - if (!vm->configFile) + if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -2785,7 +2785,7 @@ static int qemudDomainRestore(virConnectPtr conn, if (ret < 0) { qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", _("failed to start VM")); - if (!vm->configFile) + if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); return -1; @@ -2891,11 +2891,11 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { virDomainDefFree(def); return NULL; } + vm->persistent = 1; if (virDomainSaveConfig(conn, driver->configDir, - driver->autostartDir, - vm) < 0) { + vm->newDef ? vm->newDef : vm->def) < 0) { virDomainRemoveInactive(&driver->domains, vm); return NULL; @@ -2922,7 +2922,13 @@ static int qemudDomainUndefine(virDomainPtr dom) { return -1; } - if (virDomainDeleteConfig(dom->conn, vm) < 0) + if (!vm->persistent) { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot undefine transient domain")); + return -1; + } + + if (virDomainDeleteConfig(dom->conn, driver->configDir, driver->autostartDir, vm) < 0) return -1; virDomainRemoveInactive(&driver->domains, @@ -3162,9 +3168,11 @@ static int qemudDomainGetAutostart(virDomainPtr dom, } static int qemudDomainSetAutostart(virDomainPtr dom, - int autostart) { + int autostart) { struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + char *configFile = NULL, *autostartLink = NULL; + int ret = -1; if (!vm) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, @@ -3172,11 +3180,22 @@ static int qemudDomainSetAutostart(virDomainPtr dom, return -1; } + if (!vm->persistent) { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot set autostart for transient domain")); + return -1; + } + autostart = (autostart != 0); if (vm->autostart == autostart) return 0; + if ((configFile = virDomainConfigFile(dom->conn, driver->configDir, vm->def->name)) == NULL) + goto cleanup; + if ((autostartLink = virDomainConfigFile(dom->conn, driver->autostartDir, vm->def->name)) == NULL) + goto cleanup; + if (autostart) { int err; @@ -3184,27 +3203,32 @@ static int qemudDomainSetAutostart(virDomainPtr dom, qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, _("cannot create autostart directory %s: %s"), driver->autostartDir, strerror(err)); - return -1; + goto cleanup; } - if (symlink(vm->configFile, vm->autostartLink) < 0) { + if (symlink(configFile, autostartLink) < 0) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, - _("Failed to create symlink '%s' to '%s': %s"), - vm->autostartLink, vm->configFile, strerror(errno)); - return -1; + _("Failed to create symlink '%s to '%s': %s"), + autostartLink, configFile, strerror(errno)); + goto cleanup; } } else { - if (unlink(vm->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) { + if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, _("Failed to delete symlink '%s': %s"), - vm->autostartLink, strerror(errno)); - return -1; + autostartLink, strerror(errno)); + goto cleanup; } } vm->autostart = autostart; + ret = 0; - return 0; +cleanup: + VIR_FREE(configFile); + VIR_FREE(autostartLink); + + return ret; } /* This uses the 'info blockstats' monitor command which was diff --git a/src/util.c b/src/util.c index 25a9f0555e..8cf18d3d4c 100644 --- a/src/util.c +++ b/src/util.c @@ -89,6 +89,23 @@ ReportError(virConnectPtr conn, NULL, NULL, NULL, -1, -1, "%s", errorMessage); } +int virFileStripSuffix(char *str, + const char *suffix) +{ + int len = strlen(str); + int suffixlen = strlen(suffix); + + if (len < suffixlen) + return 0; + + if (!STREQ(str + len - suffixlen, suffix)) + return 0; + + str[len-suffixlen] = '\0'; + + return 1; +} + #ifndef __MINGW32__ static int virSetCloseExec(int fd) { diff --git a/src/util.h b/src/util.h index 123d08aa3d..e7dde8ecc1 100644 --- a/src/util.h +++ b/src/util.h @@ -55,6 +55,9 @@ int virFileMatchesNameSuffix(const char *file, int virFileHasSuffix(const char *str, const char *suffix); +int virFileStripSuffix(char *str, + const char *suffix); + int virFileLinkPointsTo(const char *checkLink, const char *checkDest);