[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] [patch 4/7] Add autostart QEMU implementation



Actually implement the autostart API in qemud by saving
autostart configs to a specific directory.

Signed-off-by: Mark McLoughlin <markmc redhat com>

Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1147,7 +1147,7 @@ static int qemudSaveConfig(struct qemud_
         return -1;
     }
 
-    if ((err = qemudEnsureDir(server->configDir))) {
+    if ((err = qemudEnsureDir(!vm->autostart ? server->configDir : server->autostartConfigDir))) {
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
                          "cannot create config directory %s: %s",
                          server->configDir, strerror(err));
@@ -1195,7 +1195,8 @@ static int qemudSaveConfig(struct qemud_
 struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
                                     const char *file,
                                     const char *doc,
-                                    int save) {
+                                    int save,
+                                    int isAutostart) {
     struct qemud_vm_def *def = NULL;
     struct qemud_vm *vm = NULL;
     xmlDocPtr xml;
@@ -1239,12 +1240,15 @@ struct qemud_vm *qemudLoadConfigXML(stru
         newVM = 1;
     }
 
+    vm->autostart = (isAutostart != 0);
+
     if (file) {
         strncpy(vm->configFile, file, PATH_MAX);
         vm->configFile[PATH_MAX-1] = '\0';
     } else {
         if (save) {
-            if (qemudMakeConfigPath(server->configDir, vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
+            if (qemudMakeConfigPath(!vm->autostart ? server->configDir : server->autostartConfigDir,
+                                    vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
                 qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
                                  "cannot construct config file path");
                 if (newVM)
@@ -1283,7 +1287,7 @@ static int qemudSaveNetworkConfig(struct
         return -1;
     }
 
-    if ((err = qemudEnsureDir(server->networkConfigDir))) {
+    if ((err = qemudEnsureDir(!network->autostart ? server->networkConfigDir : server->autostartNetworkConfigDir))) {
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
                          "cannot create config directory %s: %s",
                          server->networkConfigDir, strerror(err));
@@ -1550,7 +1554,8 @@ static struct qemud_network_def *qemudPa
 struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
                                                 const char *file,
                                                 const char *doc,
-                                                int save) {
+                                                int save,
+                                                int isAutostart) {
     struct qemud_network_def *def = NULL;
     struct qemud_network *network = NULL;
     xmlDocPtr xml;
@@ -1588,12 +1593,15 @@ struct qemud_network *qemudLoadNetworkCo
         newNetwork = 1;
     }
 
+    network->autostart = (isAutostart != 0);
+
     if (file) {
         strncpy(network->configFile, file, PATH_MAX);
         network->configFile[PATH_MAX-1] = '\0';
     } else {
         if (save) {
-            if (qemudMakeConfigPath(server->networkConfigDir, network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
+            if (qemudMakeConfigPath(!network->autostart ? server->networkConfigDir : server->autostartNetworkConfigDir,
+                                    network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
                 qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
                 if (newNetwork)
                     qemudFreeNetwork(network);
@@ -1623,7 +1631,8 @@ struct qemud_network *qemudLoadNetworkCo
 /* Load a guest from its persistent config file */
 static void qemudLoadConfig(struct qemud_server *server,
                             const char *file,
-                            int isGuest) {
+                            int isGuest,
+                            int isAutostart) {
     FILE *fh;
     struct stat st;
     char xml[QEMUD_MAX_XML_LEN];
@@ -1651,9 +1660,9 @@ static void qemudLoadConfig(struct qemud
     xml[st.st_size] = '\0';
 
     if (isGuest) {
-        qemudLoadConfigXML(server, file, xml, 1);
+        qemudLoadConfigXML(server, file, xml, 1, isAutostart);
     } else {
-        qemudLoadNetworkConfigXML(server, file, xml, 1);
+        qemudLoadNetworkConfigXML(server, file, xml, 1, isAutostart);
     }
  cleanup:
     fclose(fh);
@@ -1663,7 +1672,8 @@ static void qemudLoadConfig(struct qemud
 static
 int qemudScanConfigDir(struct qemud_server *server,
                        const char *configDir,
-                       int isGuest) {
+                       int isGuest,
+                       int isAutostart) {
     DIR *dir;
     struct dirent *entry;
 
@@ -1683,7 +1693,7 @@ int qemudScanConfigDir(struct qemud_serv
         if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) < 0)
             continue;
 
-        qemudLoadConfig(server, file, isGuest);
+        qemudLoadConfig(server, file, isGuest, isAutostart);
     }
 
     closedir(dir);
@@ -1693,9 +1703,13 @@ int qemudScanConfigDir(struct qemud_serv
 
 /* Scan for all guest and network config files */
 int qemudScanConfigs(struct qemud_server *server) {
-    if (qemudScanConfigDir(server, server->configDir, 1) < 0)
+    if (qemudScanConfigDir(server, server->configDir, 1, 0) < 0 ||
+        qemudScanConfigDir(server, server->autostartConfigDir, 1, 1) < 0)
         return -1;
-    return qemudScanConfigDir(server, server->networkConfigDir, 0);
+    if (qemudScanConfigDir(server, server->networkConfigDir, 0, 0) < 0 ||
+        qemudScanConfigDir(server, server->autostartNetworkConfigDir, 0, 1) < 0)
+        return -1;
+    return 0;
 }
 
 /* Simple grow-on-demand string buffer */
Index: libvirt/qemud/conf.h
===================================================================
--- libvirt.orig/qemud/conf.h
+++ libvirt/qemud/conf.h
@@ -40,7 +40,8 @@ void qemudFreeVM(struct qemud_vm *vm);
 struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
                                     const char *file,
                                     const char *doc,
-                                    int persist);
+                                    int persist,
+                                    int isAutostart);
 char *qemudGenerateXML(struct qemud_server *server,
                        struct qemud_vm *vm, int live);
 
@@ -49,7 +50,8 @@ void qemudFreeNetwork(struct qemud_netwo
 struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
                                                 const char *file,
                                                 const char *doc,
-                                                int persist);
+                                                int persist,
+                                                int isAutostart);
 char *qemudGenerateNetworkXML(struct qemud_server *server,
                               struct qemud_network *network,
                               int live);
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -294,6 +294,8 @@ struct qemud_server {
     iptablesContext *iptables;
     char configDir[PATH_MAX];
     char networkConfigDir[PATH_MAX];
+    char autostartConfigDir[PATH_MAX];
+    char autostartNetworkConfigDir[PATH_MAX];
     char errorMessage[QEMUD_MAX_ERROR_LEN];
     int errorCode;
     unsigned int shutdown : 1;
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -357,6 +357,8 @@ static int qemudListenUnix(struct qemud_
 static int qemudInitPaths(int sys,
                           char *configDir,
                           char *networkConfigDir,
+                          char *autostartConfigDir,
+                          char *autostartNetworkConfigDir,
                           char *sockname,
                           char *roSockname,
                           int maxlen) {
@@ -376,6 +378,12 @@ static int qemudInitPaths(int sys,
         if (snprintf(networkConfigDir, maxlen, "%s/libvirt/qemu/networks", SYSCONF_DIR) >= maxlen)
             goto snprintf_error;
 
+        if (snprintf(autostartConfigDir, maxlen, "%s/libvirt/qemu/autostart", SYSCONF_DIR) >= maxlen)
+            goto snprintf_error;
+
+        if (snprintf(autostartNetworkConfigDir, maxlen, "%s/libvirt/qemu/networks/autostart", SYSCONF_DIR) >= maxlen)
+            goto snprintf_error;
+
         if (snprintf(sockname, maxlen, "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= maxlen)
             goto snprintf_error;
 
@@ -400,6 +408,12 @@ static int qemudInitPaths(int sys,
         if (snprintf(networkConfigDir, maxlen, "%s/.libvirt/qemu/networks", pw->pw_dir) >= maxlen)
             goto snprintf_error;
 
+        if (snprintf(autostartConfigDir, maxlen, "%s/.libvirt/qemu/autostart", pw->pw_dir) >= maxlen)
+            goto snprintf_error;
+
+        if (snprintf(autostartNetworkConfigDir, maxlen, "%s/.libvirt/qemu/networks/autostart", pw->pw_dir) >= maxlen)
+            goto snprintf_error;
+
         if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen)
             goto snprintf_error;
     }
@@ -430,6 +444,7 @@ static struct qemud_server *qemudInitial
     roSockname[0] = '\0';
 
     if (qemudInitPaths(sys, server->configDir, server->networkConfigDir,
+                       server->autostartConfigDir, server->autostartNetworkConfigDir,
                        sockname, roSockname, PATH_MAX) < 0)
         goto cleanup;
 
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -281,7 +281,7 @@ int qemudNumDomains(struct qemud_server 
 struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
     struct qemud_vm *vm;
 
-    if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0))) {
+    if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0, 0))) {
         return NULL;
     }
 
@@ -464,7 +464,7 @@ int qemudDomainStart(struct qemud_server
 
 
 struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
-    return qemudLoadConfigXML(server, NULL, xml, 1);
+    return qemudLoadConfigXML(server, NULL, xml, 1, 0);
 }
 
 int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
@@ -525,6 +525,9 @@ int qemudDomainSetAutostart(struct qemud
                              const unsigned char *uuid,
                              int autostart) {
     struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+    char oldConfig[PATH_MAX];
+    char *xml;
+    int ret = -1;
 
     if (!vm) {
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
@@ -536,9 +539,35 @@ int qemudDomainSetAutostart(struct qemud
     if (vm->autostart == autostart)
         return 0;
 
+    if (!(xml = qemudGenerateXML(server, vm, 0)))
+        goto error;
+
+    strncpy(oldConfig, vm->configFile, PATH_MAX);
+    oldConfig[PATH_MAX-1] = '\0';
+
+    if (!qemudLoadConfigXML(server, NULL, xml, 1, autostart))
+        goto error;
+
+    if (oldConfig[0] && qemudDeleteConfig(server, oldConfig, vm->def->name) < 0) {
+        if (unlink(vm->configFile) < 0)
+            qemudLog(QEMUD_ERR, "Failed to unlink '%s' in order to roll "
+                     "back in qemudDomainSetAutostart(): %s", strerror(errno));
+
+        strncpy(vm->configFile, oldConfig, PATH_MAX);
+        vm->configFile[PATH_MAX-1] = '\0';
+
+        goto error;
+    }
+
     vm->autostart = autostart;
 
-    return 0;
+    ret = 0;
+
+ error:
+    if (xml)
+        free(xml);
+
+    return ret;
 }
 
 struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
@@ -606,7 +635,7 @@ int qemudListDefinedNetworks(struct qemu
 struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
     struct qemud_network *network;
 
-    if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0))) {
+    if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0, 0))) {
         return NULL;
     }
 
@@ -619,7 +648,7 @@ struct qemud_network *qemudNetworkCreate
 }
 
 struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
-    return qemudLoadNetworkConfigXML(server, NULL, xml, 1);
+    return qemudLoadNetworkConfigXML(server, NULL, xml, 1, 0);
 }
 
 int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
@@ -730,6 +759,9 @@ int qemudNetworkSetAutostart(struct qemu
                              const unsigned char *uuid,
                              int autostart) {
     struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+    char oldConfig[PATH_MAX];
+    char *xml;
+    int ret = -1;
 
     if (!network) {
         qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
@@ -741,9 +773,35 @@ int qemudNetworkSetAutostart(struct qemu
     if (network->autostart == autostart)
         return 0;
 
+    if (!(xml = qemudGenerateNetworkXML(server, network, 0)))
+        goto error;
+
+    strncpy(oldConfig, network->configFile, PATH_MAX);
+    oldConfig[PATH_MAX-1] = '\0';
+
+    if (!qemudLoadNetworkConfigXML(server, NULL, xml, 1, autostart))
+        goto error;
+
+    if (oldConfig[0] && qemudDeleteConfig(server, oldConfig, network->def->name) < 0) {
+        if (unlink(network->configFile) < 0)
+            qemudLog(QEMUD_ERR, "Failed to unlink '%s' in order to roll "
+                     "back in qemudNetworkSetAutostart(): %s", strerror(errno));
+
+        strncpy(network->configFile, oldConfig, PATH_MAX);
+        network->configFile[PATH_MAX-1] = '\0';
+
+        goto error;
+    }
+
     network->autostart = autostart;
 
-    return 0;
+    ret = 0;
+
+ error:
+    if (xml)
+        free(xml);
+
+    return ret;
 }
 
 /*

-- 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]