This patch removes the configDir and autostartLink paths from the internal
virDomainObjPtr struct. Instead they can calculated at time of use. This
is to facilitate a following patch, where we want to write a config to an
alternative location at some points. This also makes the LXC & QEMU drivers
correctly set/use the 'persistent' property.
domain_conf.c | 99 +++++++++++++++++++++++++++++-----------------------------
domain_conf.h | 8 +---
lxc_driver.c | 40 ++++++++++++++++++-----
qemu_driver.c | 71 ++++++++++++++++++++++++++++++-----------
4 files changed, 138 insertions(+), 80 deletions(-)
Daniel
diff -r a204a9425afd src/domain_conf.c
--- a/src/domain_conf.c Tue Aug 05 16:50:49 2008 +0100
+++ b/src/domain_conf.c Tue Aug 05 16:50:51 2008 +0100
@@ -399,8 +399,6 @@
virDomainDefFree(dom->newDef);
VIR_FREE(dom->vcpupids);
- VIR_FREE(dom->configFile);
- VIR_FREE(dom->autostartLink);
VIR_FREE(dom);
}
@@ -2952,31 +2950,23 @@
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);
- goto cleanup;
- }
- if (!dom->autostartLink &&
- asprintf(&dom->autostartLink, "%s/%s.xml",
- autostartDir, dom->def->name) < 0) {
- dom->autostartLink = NULL;
+ if (asprintf(&configFile, "%s/%s.xml",
+ configDir, def->name) < 0) {
+ configFile = 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;
@@ -2987,34 +2977,27 @@
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;
}
@@ -3072,8 +3055,6 @@
goto error;
dom->state = VIR_DOMAIN_SHUTOFF;
- dom->configFile = configFile;
- dom->autostartLink = autostartLink;
dom->autostart = autostart;
return dom;
@@ -3104,6 +3085,8 @@
}
while ((entry = readdir(dir))) {
+ virDomainObjPtr dom;
+
if (entry->d_name[0] == '.')
continue;
@@ -3112,12 +3095,14 @@
/* 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);
@@ -3126,25 +3111,43 @@
}
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 (asprintf(&configFile, "%s/%s",
+ configDir, dom->def->name) < 0) {
+ configFile = NULL;
+ virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
+ }
+ if (asprintf(&autostartLink, "%s/%s",
+ autostartDir, dom->def->name) < 0) {
+ autostartLink = NULL;
+ virDomainReportError(conn, VIR_ERR_NO_MEMORY, 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;
}
#endif /* ! PROXY */
diff -r a204a9425afd src/domain_conf.h
--- a/src/domain_conf.h Tue Aug 05 16:50:49 2008 +0100
+++ b/src/domain_conf.h Tue Aug 05 16:50:51 2008 +0100
@@ -409,9 +409,6 @@
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 */
@@ -482,8 +479,7 @@
int virDomainSaveConfig(virConnectPtr conn,
const char *configDir,
- const char *autostartDir,
- virDomainObjPtr dom);
+ virDomainDefPtr def);
virDomainObjPtr virDomainLoadConfig(virConnectPtr conn,
virCapsPtr caps,
@@ -499,6 +495,8 @@
const char *autostartDir);
int virDomainDeleteConfig(virConnectPtr conn,
+ const char *configDir,
+ const char *autostartDir,
virDomainObjPtr dom);
virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn,
diff -r a204a9425afd src/lxc_driver.c
--- a/src/lxc_driver.c Tue Aug 05 16:50:49 2008 +0100
+++ b/src/lxc_driver.c Tue Aug 05 16:50:51 2008 +0100
@@ -250,11 +250,11 @@
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 @@
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);
@@ -639,8 +646,13 @@
return;
}
- if (lxcVmTerminate(NULL, vm, SIGINT) < 0)
- virEventRemoveHandle(fd);
+ lxcVmTerminate(NULL, vm, SIGINT);
+
+ virEventRemoveHandle(fd);
+
+ if (!vm->persistent)
+ virDomainRemoveInactive(&driver->domains,
+ vm);
}
@@ -846,6 +858,7 @@
{
lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
+ int ret;
if (!vm) {
lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -853,7 +866,12 @@
return -1;
}
- return lxcVmTerminate(dom->conn, vm, 0);
+ ret = lxcVmTerminate(dom->conn, vm, 0);
+ if (!vm->persistent)
+ virDomainRemoveInactive(&driver->domains,
+ vm);
+
+ return ret;
}
@@ -869,6 +887,7 @@
{
lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
+ int ret;
if (!vm) {
lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -876,7 +895,12 @@
return -1;
}
- return lxcVmTerminate(dom->conn, vm, SIGKILL);
+ ret = lxcVmTerminate(dom->conn, vm, SIGKILL);
+ if (!vm->persistent)
+ virDomainRemoveInactive(&driver->domains,
+ vm);
+
+ return ret;
}
static int lxcCheckNetNsSupport(void)
diff -r a204a9425afd src/qemu_driver.c
--- a/src/qemu_driver.c Tue Aug 05 16:50:49 2008 +0100
+++ b/src/qemu_driver.c Tue Aug 05 16:50:51 2008 +0100
@@ -351,7 +351,7 @@
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;
@@ -1068,7 +1068,7 @@
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);
}
@@ -1078,7 +1078,7 @@
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;
@@ -2138,7 +2138,7 @@
}
qemudShutdownVMDaemon(dom->conn, driver, vm);
- if (!vm->configFile)
+ if (!vm->persistent)
virDomainRemoveInactive(&driver->domains,
vm);
@@ -2469,7 +2469,7 @@
/* Shut it down */
qemudShutdownVMDaemon(dom->conn, driver, vm);
- if (!vm->configFile)
+ if (!vm->persistent)
virDomainRemoveInactive(&driver->domains,
vm);
@@ -2761,7 +2761,7 @@
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;
@@ -2867,11 +2867,11 @@
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;
@@ -2898,7 +2898,13 @@
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,
@@ -3024,13 +3030,21 @@
}
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,
"%s", _("no domain with matching uuid"));
+ return -1;
+ }
+
+ if (!vm->persistent) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot set autostart for transient
domain"));
return -1;
}
@@ -3039,6 +3053,20 @@
if (vm->autostart == autostart)
return 0;
+ if (asprintf(&configFile, "%s/%s.xml",
+ driver->configDir, vm->def->name) < 0) {
+ configFile = NULL;
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
+ }
+
+ if (asprintf(&autostartLink, "%s/%s.xml",
+ driver->autostartDir, vm->def->name) < 0) {
+ autostartLink = NULL;
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
+ }
+
if (autostart) {
int err;
@@ -3046,27 +3074,32 @@
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
--
|: 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 :|