Devel
  Threads by month 
                
            - ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
February 2007
- 17 participants
- 81 discussions
                    
                        Add virDomainGetAutostart(), virDomainSetAutostart(),
virNetworkGetAutostart() and virNetworkSetAutostart().
Add the methods to the drivers' vtables, but don't
actually implement it anywhere.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/include/libvirt/libvirt.h.in
===================================================================
--- libvirt.orig/include/libvirt/libvirt.h.in
+++ libvirt/include/libvirt/libvirt.h.in
@@ -328,6 +328,11 @@ int			virConnectListDefinedDomains (virC
 						 int maxnames);
 int			virDomainCreate		(virDomainPtr domain);
 
+int			virDomainGetAutostart	(virDomainPtr domain,
+						 int *autostart);
+int			virDomainSetAutostart	(virDomainPtr domain,
+						 int autostart);
+
 /**
  * virVcpuInfo: structure for information about a virtual CPU in a domain.
  */
@@ -528,6 +533,11 @@ char *			virNetworkGetXMLDesc	(virNetwor
 						 int flags);
 char *			virNetworkGetBridgeName (virNetworkPtr network);
 
+int			virNetworkGetAutostart	(virNetworkPtr network,
+						 int *autostart);
+int			virNetworkSetAutostart	(virNetworkPtr network,
+						 int autostart);
+
 #ifdef __cplusplus
 }
 #endif
Index: libvirt/src/libvirt.c
===================================================================
--- libvirt.orig/src/libvirt.c
+++ libvirt/src/libvirt.c
@@ -1862,6 +1862,69 @@ virDomainCreate(virDomainPtr domain) {
 }
 
 /**
+ * virDomainGetAutostart:
+ * @domain: a domain object
+ *
+ * Return a boolean value indicating whether the domain
+ * configured to be automatically started when the host
+ * machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainGetAutostart(virDomainPtr domain,
+                      int *autostart) {
+    int i;
+
+    if (!VIR_IS_DOMAIN(domain)) {
+        virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+    if (!autostart) {
+        virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    for (i = 0;i < domain->conn->nb_drivers;i++) {
+	if ((domain->conn->drivers[i] != NULL) &&
+	    (domain->conn->drivers[i]->domainGetAutostart != NULL) &&
+            (domain->conn->drivers[i]->domainGetAutostart(domain, autostart) == 0))
+            return (0);
+    }
+    virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return (-1);
+}
+
+/**
+ * virDomainSetAutostart:
+ * @domain: a domain object
+ *
+ * Configure the domain to be automatically started
+ * when the host machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainSetAutostart(virDomainPtr domain,
+                      int autostart) {
+    int i;
+
+    if (!VIR_IS_DOMAIN(domain)) {
+        virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+
+    for (i = 0;i < domain->conn->nb_drivers;i++) {
+	if ((domain->conn->drivers[i] != NULL) &&
+	    (domain->conn->drivers[i]->domainSetAutostart != NULL) &&
+            (domain->conn->drivers[i]->domainSetAutostart(domain, autostart) == 0))
+            return (0);
+    }
+    virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return (-1);
+}
+
+/**
  * virDomainSetVcpus:
  * @domain: pointer to domain object, or NULL for Domain0
  * @nvcpus: the new number of virtual CPUs for this domain
@@ -2766,3 +2829,66 @@ virNetworkGetBridgeName(virNetworkPtr ne
     }
     return(ret);
 }
+
+/**
+ * virNetworkGetAutostart:
+ * @network: a network object
+ *
+ * Return a boolean value indicating whether the network
+ * configured to be automatically started when the host
+ * machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virNetworkGetAutostart(virNetworkPtr network,
+                       int *autostart) {
+    int i;
+
+    if (!VIR_IS_NETWORK(network)) {
+        virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
+        return (-1);
+    }
+    if (!autostart) {
+        virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    for (i = 0;i < network->conn->nb_network_drivers;i++) {
+	if ((network->conn->networkDrivers[i] != NULL) &&
+	    (network->conn->networkDrivers[i]->networkGetAutostart != NULL) &&
+            (network->conn->networkDrivers[i]->networkGetAutostart(network, autostart) == 0))
+            return (0);
+    }
+    virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return (-1);
+}
+
+/**
+ * virNetworkSetAutostart:
+ * @network: a network object
+ *
+ * Configure the network to be automatically started
+ * when the host machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virNetworkSetAutostart(virNetworkPtr network,
+                       int autostart) {
+    int i;
+
+    if (!VIR_IS_NETWORK(network)) {
+        virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
+        return (-1);
+    }
+
+    for (i = 0;i < network->conn->nb_network_drivers;i++) {
+	if ((network->conn->networkDrivers[i] != NULL) &&
+	    (network->conn->networkDrivers[i]->networkSetAutostart != NULL) &&
+            (network->conn->networkDrivers[i]->networkSetAutostart(network, autostart) == 0))
+            return (0);
+    }
+    virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return (-1);
+}
Index: libvirt/src/driver.h
===================================================================
--- libvirt.orig/src/driver.h
+++ libvirt/src/driver.h
@@ -134,6 +134,12 @@ typedef int
 typedef int
 	(*virDrvDomainDetachDevice)	(virDomainPtr domain,
 					 char *xml);
+typedef int
+	(*virDrvDomainGetAutostart)	(virDomainPtr domain,
+					 int *autostart);
+typedef int
+	(*virDrvDomainSetAutostart)	(virDomainPtr domain,
+					 int autostart);
 
 typedef struct _virDriver virDriver;
 typedef virDriver *virDriverPtr;
@@ -183,6 +189,8 @@ struct _virDriver {
 	virDrvDomainUndefine            domainUndefine;
 	virDrvDomainAttachDevice	domainAttachDevice;
 	virDrvDomainDetachDevice	domainDetachDevice;
+	virDrvDomainGetAutostart	domainGetAutostart;
+	virDrvDomainSetAutostart	domainSetAutostart;
 };
 
 typedef int
@@ -219,6 +227,13 @@ typedef char *
 					 int flags);
 typedef char *
 	(*virDrvNetworkGetBridgeName)	(virNetworkPtr network);
+typedef int
+	(*virDrvNetworkGetAutostart)	(virNetworkPtr network,
+					 int *autostart);
+typedef int
+	(*virDrvNetworkSetAutostart)	(virNetworkPtr network,
+					 int autostart);
+
 
 typedef struct _virNetworkDriver virNetworkDriver;
 typedef virNetworkDriver *virNetworkDriverPtr;
@@ -245,6 +260,8 @@ struct _virNetworkDriver {
 	virDrvNetworkDestroy		networkDestroy;
 	virDrvNetworkDumpXML		networkDumpXML;
 	virDrvNetworkGetBridgeName	networkGetBridgeName;
+	virDrvNetworkGetAutostart	networkGetAutostart;
+	virDrvNetworkSetAutostart	networkSetAutostart;
 };
 
 
Index: libvirt/src/proxy_internal.c
===================================================================
--- libvirt.orig/src/proxy_internal.c
+++ libvirt/src/proxy_internal.c
@@ -81,6 +81,8 @@ static virDriver xenProxyDriver = {
     NULL, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 
 /**
Index: libvirt/src/qemu_internal.c
===================================================================
--- libvirt.orig/src/qemu_internal.c
+++ libvirt/src/qemu_internal.c
@@ -1132,6 +1132,8 @@ static virDriver qemuDriver = {
     qemuUndefine, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 
 static virNetworkDriver qemuNetworkDriver = {
@@ -1150,6 +1152,8 @@ static virNetworkDriver qemuNetworkDrive
     qemuNetworkDestroy, /* networkDestroy */
     qemuNetworkDumpXML, /* networkDumpXML */
     qemuNetworkGetBridgeName, /* networkGetBridgeName */
+    NULL, /* networkGetAutostart */
+    NULL, /* networkSetAutostart */
 };
 
 void qemuRegister(void) {
Index: libvirt/src/test.c
===================================================================
--- libvirt.orig/src/test.c
+++ libvirt/src/test.c
@@ -125,6 +125,8 @@ static virDriver testDriver = {
     testDomainUndefine, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 
 typedef struct _testDev {
Index: libvirt/src/xen_internal.c
===================================================================
--- libvirt.orig/src/xen_internal.c
+++ libvirt/src/xen_internal.c
@@ -454,6 +454,8 @@ static virDriver xenHypervisorDriver = {
     NULL, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 #endif /* !PROXY */
 
Index: libvirt/src/xend_internal.c
===================================================================
--- libvirt.orig/src/xend_internal.c
+++ libvirt/src/xend_internal.c
@@ -96,7 +96,9 @@ static virDriver xenDaemonDriver = {
     xenDaemonDomainDefineXML, /* domainDefineXML */
     xenDaemonDomainUndefine, /* domainUndefine */
     xenDaemonAttachDevice, /* domainAttachDevice */
-    xenDaemonDetachDevice /* domainDetachDevice */
+    xenDaemonDetachDevice, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 
 /**
Index: libvirt/src/xm_internal.c
===================================================================
--- libvirt.orig/src/xm_internal.c
+++ libvirt/src/xm_internal.c
@@ -104,6 +104,8 @@ static virDriver xenXMDriver = {
     xenXMDomainUndefine, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 
 static void
Index: libvirt/src/xs_internal.c
===================================================================
--- libvirt.orig/src/xs_internal.c
+++ libvirt/src/xs_internal.c
@@ -75,6 +75,8 @@ static virDriver xenStoreDriver = {
     NULL, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
+    NULL, /* domainGetAutostart */
+    NULL, /* domainSetAutostart */
 };
 
 /**
Index: libvirt/src/libvirt_sym.version
===================================================================
--- libvirt.orig/src/libvirt_sym.version
+++ libvirt/src/libvirt_sym.version
@@ -37,6 +37,8 @@
 	virConnectListDefinedDomains;
 	virConnectNumOfDefinedDomains;
 	virDomainUndefine;
+	virDomainGetAutostart;
+	virDomainSetAutostart;
 	virGetVersion;
 	virCopyLastError;
 	virConnSetErrorFunc;
@@ -76,6 +78,8 @@
 	virNetworkGetUUIDString;
 	virNetworkGetXMLDesc;
 	virNetworkGetBridgeName;
+	virNetworkGetAutostart;
+	virNetworkSetAutostart;
 
     local: *;
 };
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    22 Feb '07
                    
                        The easiest way to explain where I'm coming from with
this patch is to look at the current qemudLoadConfigXML().
It carries out three distinct operations - (a) parse the
supplied XML, (b) assign the def to a VM (creating one
if needed) and (c) save the XML.
It's used in three places:
  1) Loading at startup - you want (a) and (b), but you
     want to check whether the name matches the filename
     before doing (b)
  2) Create() - you want (a) and (b)
  3) Define() - you want (a), (b) and (c)
So, mostly I'm just splitting the function into three
and making the logic above much more obvious. It should
also make some of the autostart code much more
straightforward.
There are a number of misc. improvements lurking in
here too:
  - The couple of places where we remove a VM or network
    from the list is co-alesced into qemudRemoveInactiveVM()
    and qemudRemoveInactiveNetwork()
  - In qemudDomainCreate() and qemudNetworkCreate(), if
    starting the VM/network failed, we were leaving it
    on the list
  - The compareFileToNameSuffix() stuff
  - When loading config files at startup, we were failing
    to log any errors
    
Signed-off-by: Mark McLoughlin <markmc(a)redhat.c>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1140,22 +1140,14 @@ int qemudBuildCommandLine(struct qemud_s
 
 /* Save a guest's config data into a persistent file */
 static int qemudSaveConfig(struct qemud_server *server,
-                           struct qemud_vm *vm) {
+                           struct qemud_vm *vm,
+                           struct qemud_vm_def *def) {
     char *xml;
     int fd = -1, ret = -1;
     int towrite;
-    int err;
 
-    if (!(xml = qemudGenerateXML(server, vm, 0))) {
+    if (!(xml = qemudGenerateXML(server, vm, def, 0)))
         return -1;
-    }
-
-    if ((err = qemudEnsureDir(server->configDir))) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
-                         "cannot create config directory %s: %s",
-                         server->configDir, strerror(err));
-        goto cleanup;
-    }
 
     if ((fd = open(vm->configFile,
                    O_WRONLY | O_CREAT | O_TRUNC,
@@ -1192,31 +1184,33 @@ static int qemudSaveConfig(struct qemud_
     return ret;
 }
 
-
-/* Create a qemud_vm instance, populating it based on the data
- * in a libvirt XML document describing the guest */
-struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
-                                    const char *file,
-                                    const char *doc,
-                                    int save) {
-    struct qemud_vm_def *def = NULL;
-    struct qemud_vm *vm = NULL;
+struct qemud_vm_def *
+qemudParseVMDef(struct qemud_server *server,
+                const char *xmlStr,
+                const char *displayName) {
     xmlDocPtr xml;
-    int newVM = 0;
+    struct qemud_vm_def *def = NULL;
 
-    if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "domain.xml", NULL,
+    if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "domain.xml", NULL,
                            XML_PARSE_NOENT | XML_PARSE_NONET |
                            XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
         qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
         return NULL;
     }
 
-    if (!(def = qemudParseXML(server, xml))) {
-        xmlFreeDoc(xml);
-        return NULL;
-    }
+    def = qemudParseXML(server, xml);
+
     xmlFreeDoc(xml);
 
+    return def;
+}
+
+struct qemud_vm *
+qemudAssignVMDef(struct qemud_server *server,
+                 struct qemud_vm_def *def)
+{
+    struct qemud_vm *vm = NULL;
+
     if ((vm = qemudFindVMByName(server, def->name))) {
         if (!qemudIsActiveVM(vm)) {
             qemudFreeVMDef(vm->def);
@@ -1226,63 +1220,87 @@ struct qemud_vm *qemudLoadConfigXML(stru
                 qemudFreeVMDef(vm->newDef);
             vm->newDef = def;
         }
-    } else {
-        if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
-            qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
-            qemudFreeVMDef(def);
-            return NULL;
-        }
-
-        vm->stdout = -1;
-        vm->stderr = -1;
-        vm->monitor = -1;
-        vm->pid = -1;
-        vm->id = -1;
-        vm->def = def;
-        newVM = 1;
-    }
-
-    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) {
-                qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
-                                 "cannot construct config file path");
-                if (newVM)
-                    qemudFreeVM(vm);
-                return NULL;
-            }
 
-            if (qemudSaveConfig(server, vm) < 0) {
-                if (newVM)
-                    qemudFreeVM(vm);
-                return NULL;
-            }
-        } else {
-            vm->configFile[0] = '\0';
-        }
+        return vm;
     }
 
-    if (newVM) {
-        vm->next = server->vms;
-        server->vms = vm;
-        server->ninactivevms++;
+    if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
+        qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
+        return NULL;
     }
 
+    vm->stdout = -1;
+    vm->stderr = -1;
+    vm->monitor = -1;
+    vm->pid = -1;
+    vm->id = -1;
+    vm->def = def;
+    vm->next = server->vms;
+
+    server->vms = vm;
+    server->ninactivevms++;
+
     return vm;
 }
 
+void
+qemudRemoveInactiveVM(struct qemud_server *server,
+                      struct qemud_vm *vm)
+{
+    struct qemud_vm *prev = NULL, *curr;
+
+    curr = server->vms;
+    while (curr != vm) {
+        prev = curr;
+        curr = curr->next;
+    }
+
+    if (curr) {
+        if (prev)
+            prev->next = curr->next;
+        else
+            server->vms = curr->next;
+
+        server->ninactivevms--;
+    }
+
+    qemudFreeVM(vm);
+}
+
+int
+qemudSaveVMDef(struct qemud_server *server,
+               struct qemud_vm *vm,
+               struct qemud_vm_def *def) {
+    if (vm->configFile[0] == '\0') {
+        int err;
+
+        if ((err = qemudEnsureDir(server->configDir))) {
+            qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+                             "cannot create config directory %s: %s",
+                             server->configDir, strerror(err));
+            return -1;
+        }
+
+        if (qemudMakeConfigPath(server->configDir, def->name, ".xml",
+                                vm->configFile, PATH_MAX) < 0) {
+            qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+                             "cannot construct config file path");
+            return -1;
+        }
+    }
+
+    return qemudSaveConfig(server, vm, def);
+}
 
 static int qemudSaveNetworkConfig(struct qemud_server *server,
-                                  struct qemud_network *network) {
+                                  struct qemud_network *network,
+                                  struct qemud_network_def *def) {
     char *xml;
     int fd, ret = -1;
     int towrite;
     int err;
 
-    if (!(xml = qemudGenerateNetworkXML(server, network, 0))) {
+    if (!(xml = qemudGenerateNetworkXML(server, network, def))) {
         return -1;
     }
 
@@ -1550,28 +1568,32 @@ static struct qemud_network_def *qemudPa
     return NULL;
 }
 
-struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
-                                                const char *file,
-                                                const char *doc,
-                                                int save) {
-    struct qemud_network_def *def = NULL;
-    struct qemud_network *network = NULL;
+struct qemud_network_def *
+qemudParseNetworkDef(struct qemud_server *server,
+                     const char *xmlStr,
+                     const char *displayName) {
     xmlDocPtr xml;
-    int newNetwork = 0;
+    struct qemud_network_def *def;
 
-    if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "network.xml", NULL,
+    if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "network.xml", NULL,
                            XML_PARSE_NOENT | XML_PARSE_NONET |
                            XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
         qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
         return NULL;
     }
 
-    if (!(def = qemudParseNetworkXML(server, xml))) {
-        xmlFreeDoc(xml);
-        return NULL;
-    }
+    def = qemudParseNetworkXML(server, xml);
+
     xmlFreeDoc(xml);
 
+    return def;
+}
+
+struct qemud_network *
+qemudAssignNetworkDef(struct qemud_server *server,
+                      struct qemud_network_def *def) {
+    struct qemud_network *network;
+
     if ((network = qemudFindNetworkByName(server, def->name))) {
         if (!qemudIsActiveNetwork(network)) {
             qemudFreeNetworkDef(network->def);
@@ -1581,87 +1603,203 @@ struct qemud_network *qemudLoadNetworkCo
                 qemudFreeNetworkDef(network->newDef);
             network->newDef = def;
         }
-    } else {
-        if (!(network = calloc(1, sizeof(struct qemud_network)))) {
-            qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
-            return NULL;
-        }
 
-        network->def = def;
-        newNetwork = 1;
+        return network;
     }
 
-    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) {
-                qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
-                if (newNetwork)
-                    qemudFreeNetwork(network);
-                return NULL;
-            }
+    if (!(network = calloc(1, sizeof(struct qemud_network)))) {
+        qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
+        return NULL;
+    }
 
-            if (qemudSaveNetworkConfig(server, network) < 0) {
-                if (newNetwork)
-                    qemudFreeNetwork(network);
-                return NULL;
-            }
-        } else {
-            network->configFile[0] = '\0';
-        }
+    network->def = def;
+    network->next = server->networks;
+
+    server->networks = network;
+    server->ninactivenetworks++;
+
+    return network;
+}
+
+void
+qemudRemoveInactiveNetwork(struct qemud_server *server,
+                           struct qemud_network *network)
+{
+    struct qemud_network *prev = NULL, *curr;
+
+    curr = server->networks;
+    while (curr != network) {
+        prev = curr;
+        curr = curr->next;
     }
 
-    if (newNetwork) {
-        network->next = server->networks;
-        server->networks = network;
-        server->ninactivenetworks++;
+    if (curr) {
+        if (prev)
+            prev->next = curr->next;
+        else
+            server->networks = curr->next;
+
+        server->ninactivenetworks--;
     }
 
-    return network;
+    qemudFreeNetwork(network);
 }
 
+int
+qemudSaveNetworkDef(struct qemud_server *server,
+                    struct qemud_network *network,
+                    struct qemud_network_def *def) {
+
+    if (network->configFile[0] == '\0') {
+        int err;
+
+        if ((err = qemudEnsureDir(server->networkConfigDir))) {
+            qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+                             "cannot create config directory %s: %s",
+                             server->networkConfigDir, strerror(err));
+            return -1;
+        }
+
+        if (qemudMakeConfigPath(server->networkConfigDir, def->name, ".xml",
+                                network->configFile, PATH_MAX) < 0) {
+            qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+                             "cannot construct config file path");
+            return -1;
+        }
+    }
+
+    return qemudSaveNetworkConfig(server, network, def);
+}
 
-/* Load a guest from its persistent config file */
-static void qemudLoadConfig(struct qemud_server *server,
-                            const char *file,
-                            int isGuest) {
+static int
+qemudReadFile(const char *path,
+              char *buf,
+              int maxlen) {
     FILE *fh;
     struct stat st;
-    char xml[QEMUD_MAX_XML_LEN];
-    int ret;
+    int ret = 0;
 
-    if (!(fh = fopen(file, "r"))) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open config file %s", file);
-        return;
+    if (!(fh = fopen(path, "r"))) {
+        qemudLog(QEMUD_WARN, "Failed to open file '%s': %s",
+                 path, strerror(errno));
+        goto error;
     }
 
     if (fstat(fileno(fh), &st) < 0) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot stat config file %s", file);
-        goto cleanup;
+        qemudLog(QEMUD_WARN, "Failed to stat file '%s': %s",
+                 path, strerror(errno));
+        goto error;
     }
 
-    if (st.st_size >= QEMUD_MAX_XML_LEN) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "config too large in file %s", file);
-        goto cleanup;
+    if (S_ISDIR(st.st_mode)) {
+        qemudLog(QEMUD_DEBUG, "Ignoring directory '%s' - clearly not a config file",
+                 path);
+        goto error;
     }
 
-    if ((ret = fread(xml, st.st_size, 1, fh)) != 1) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot read config file %s", file);
-        goto cleanup;
+    if (st.st_size >= maxlen) {
+        qemudLog(QEMUD_WARN, "File '%s' is too large", path);
+        goto error;
     }
-    xml[st.st_size] = '\0';
 
-    if (isGuest) {
-        qemudLoadConfigXML(server, file, xml, 1);
-    } else {
-        qemudLoadNetworkConfigXML(server, file, xml, 1);
+    if ((ret = fread(buf, st.st_size, 1, fh)) != 1) {
+        qemudLog(QEMUD_WARN, "Failed to read config file '%s': %s",
+                 path, strerror(errno));
+        goto error;
     }
- cleanup:
-    fclose(fh);
+
+    buf[st.st_size] = '\0';
+
+    ret = 1;
+
+ error:
+    if (fh)
+        fclose(fh);
+
+    return ret;
 }
 
+static int
+compareFileToNameSuffix(const char *file,
+                        const char *name,
+                        const char *suffix) {
+    int filelen = strlen(file);
+    int namelen = strlen(name);
+    int suffixlen = strlen(suffix);
+
+    if (filelen == (namelen + suffixlen) &&
+        !strncmp(file, name, namelen) &&
+        !strncmp(file + namelen, suffix, suffixlen))
+        return 1;
+    else
+        return 0;
+}
+
+static struct qemud_vm *
+qemudLoadConfig(struct qemud_server *server,
+                const char *file,
+                const char *path,
+                const char *xml) {
+    struct qemud_vm_def *def;
+    struct qemud_vm *vm;
+
+    if (!(def = qemudParseVMDef(server, xml, file))) {
+        qemudLog(QEMUD_WARN, "Error parsing QEMU guest config '%s' : %s",
+                 path, server->errorMessage);
+        return NULL;
+    }
+
+    if (!compareFileToNameSuffix(file, def->name, ".xml")) {
+        qemudLog(QEMUD_WARN, "QEMU guest config filename '%s' does not match guest name '%s'",
+                 path, def->name);
+        qemudFreeVMDef(def);
+        return NULL;
+    }
+
+    if (!(vm = qemudAssignVMDef(server, def))) {
+        qemudLog(QEMUD_WARN, "Failed to load QEMU guest config '%s': out of memory", path);
+        qemudFreeVMDef(def);
+        return NULL;
+    }
+
+    strncpy(vm->configFile, path, PATH_MAX);
+    vm->configFile[PATH_MAX-1] = '\0';
+
+    return vm;
+}
+
+static struct qemud_network *
+qemudLoadNetworkConfig(struct qemud_server *server,
+                       const char *file,
+                       const char *path,
+                       const char *xml) {
+    struct qemud_network_def *def;
+    struct qemud_network *network;
+
+    if (!(def = qemudParseNetworkDef(server, xml, file))) {
+        qemudLog(QEMUD_WARN, "Error parsing network config '%s' : %s",
+                 path, server->errorMessage);
+        return NULL;
+    }
+
+    if (!compareFileToNameSuffix(file, def->name, ".xml")) {
+        qemudLog(QEMUD_WARN, "Network config filename '%s' does not match network name '%s'",
+                 path, def->name);
+        qemudFreeNetworkDef(def);
+        return NULL;
+    }
+
+    if (!(network = qemudAssignNetworkDef(server, def))) {
+        qemudLog(QEMUD_WARN, "Failed to load network config '%s': out of memory", path);
+        qemudFreeNetworkDef(def);
+        return NULL;
+    }
+
+    strncpy(network->configFile, path, PATH_MAX);
+    network->configFile[PATH_MAX-1] = '\0';
+
+    return network;
+}
 
 static
 int qemudScanConfigDir(struct qemud_server *server,
@@ -1679,14 +1817,25 @@ int qemudScanConfigDir(struct qemud_serv
     }
 
     while ((entry = readdir(dir))) {
-        char file[PATH_MAX];
+        char xml[QEMUD_MAX_XML_LEN];
+        char path[PATH_MAX];
+
         if (entry->d_name[0] == '.')
             continue;
 
-        if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) < 0)
+        if (qemudMakeConfigPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) {
+            qemudLog(QEMUD_WARN, "Config filename '%s/%s' is too long",
+                     configDir, entry->d_name);
+            continue;
+        }
+
+        if (!qemudReadFile(path, xml, QEMUD_MAX_XML_LEN))
             continue;
 
-        qemudLoadConfig(server, file, isGuest);
+        if (isGuest)
+            qemudLoadConfig(server, entry->d_name, path, xml);
+        else
+            qemudLoadNetworkConfig(server, entry->d_name, path, xml);
     }
 
     closedir(dir);
@@ -1751,8 +1900,10 @@ int qemudBufferPrintf(struct qemudBuffer
 }
 
 /* Generate an XML document describing the guest's configuration */
-char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm, int live) {
-    struct qemud_vm_def *def = live ? vm->def : (vm->newDef ? vm->newDef : vm->def);
+char *qemudGenerateXML(struct qemud_server *server,
+                       struct qemud_vm *vm,
+                       struct qemud_vm_def *def,
+                       int live) {
     struct qemudBuffer buf;
     unsigned char *uuid;
     struct qemud_vm_disk_def *disk;
@@ -1986,9 +2137,8 @@ char *qemudGenerateXML(struct qemud_serv
 
 
 char *qemudGenerateNetworkXML(struct qemud_server *server,
-                              struct qemud_network *network,
-                              int live) {
-    struct qemud_network_def *def = live ? network->def : (network->newDef ? network->newDef : network->def);
+                              struct qemud_network *network ATTRIBUTE_UNUSED,
+                              struct qemud_network_def *def) {
     struct qemudBuffer buf;
     unsigned char *uuid;
 
Index: libvirt/qemud/conf.h
===================================================================
--- libvirt.orig/qemud/conf.h
+++ libvirt/qemud/conf.h
@@ -26,33 +26,55 @@
 
 #include "internal.h"
 
-int qemudBuildCommandLine(struct qemud_server *server,
-                          struct qemud_vm *vm,
-                          char ***argv);
-
-int qemudScanConfigs(struct qemud_server *server);
-int qemudDeleteConfig(struct qemud_server *server,
-                      const char *configFile,
-                      const char *name);
-
-void qemudFreeVMDef(struct qemud_vm_def *vm);
-void qemudFreeVM(struct qemud_vm *vm);
-struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
-                                    const char *file,
-                                    const char *doc,
-                                    int persist);
-char *qemudGenerateXML(struct qemud_server *server,
-                       struct qemud_vm *vm, int live);
-
-void qemudFreeNetworkDef(struct qemud_network_def *def);
-void qemudFreeNetwork(struct qemud_network *network);
-struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
-                                                const char *file,
-                                                const char *doc,
-                                                int persist);
-char *qemudGenerateNetworkXML(struct qemud_server *server,
-                              struct qemud_network *network,
-                              int live);
+int         qemudBuildCommandLine       (struct qemud_server *server,
+                                         struct qemud_vm *vm,
+                                         char ***argv);
+
+int         qemudScanConfigs            (struct qemud_server *server);
+int         qemudDeleteConfig           (struct qemud_server *server,
+                                         const char *configFile,
+                                         const char *name);
+
+void        qemudFreeVMDef              (struct qemud_vm_def *vm);
+void        qemudFreeVM                 (struct qemud_vm *vm);
+
+struct qemud_vm *
+            qemudAssignVMDef            (struct qemud_server *server,
+                                         struct qemud_vm_def *def);
+void        qemudRemoveInactiveVM       (struct qemud_server *server,
+                                         struct qemud_vm *vm);
+
+struct qemud_vm_def *
+            qemudParseVMDef             (struct qemud_server *server,
+                                         const char *xmlStr,
+                                         const char *displayName);
+int         qemudSaveVMDef              (struct qemud_server *server,
+                                         struct qemud_vm *vm,
+                                         struct qemud_vm_def *def);
+char *      qemudGenerateXML            (struct qemud_server *server,
+                                         struct qemud_vm *vm,
+                                         struct qemud_vm_def *def,
+                                         int live);
+
+void        qemudFreeNetworkDef         (struct qemud_network_def *def);
+void        qemudFreeNetwork            (struct qemud_network *network);
+
+struct qemud_network *
+            qemudAssignNetworkDef       (struct qemud_server *server,
+                                         struct qemud_network_def *def);
+void        qemudRemoveInactiveNetwork  (struct qemud_server *server,
+                                         struct qemud_network *network);
+
+struct qemud_network_def *
+            qemudParseNetworkDef        (struct qemud_server *server,
+                                         const char *xmlStr,
+                                         const char *displayName);
+int         qemudSaveNetworkDef         (struct qemud_server *server,
+                                         struct qemud_network *network,
+                                         struct qemud_network_def *def);
+char *      qemudGenerateNetworkXML     (struct qemud_server *server,
+                                         struct qemud_network *network,
+                                         struct qemud_network_def *def);
 
 #endif
 
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -279,14 +279,20 @@ int qemudNumDomains(struct qemud_server 
     return server->nactivevms;
 }
 struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
+
+    struct qemud_vm_def *def;
     struct qemud_vm *vm;
 
-    if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0))) {
+    if (!(def = qemudParseVMDef(server, xml, NULL)))
+        return NULL;
+
+    if (!(vm = qemudAssignVMDef(server, def))) {
+        qemudFreeVMDef(def);
         return NULL;
     }
 
     if (qemudStartVMDaemon(server, vm) < 0) {
-        qemudFreeVM(vm);
+        qemudRemoveInactiveVM(server, vm);
         return NULL;
     }
 
@@ -416,7 +422,7 @@ int qemudDomainDumpXML(struct qemud_serv
         return -1;
     }
 
-    vmxml = qemudGenerateXML(server, vm, 1);
+    vmxml = qemudGenerateXML(server, vm, vm->def, 1);
     if (!vmxml)
         return -1;
 
@@ -461,12 +467,27 @@ struct qemud_vm *qemudDomainStart(struct
 
 
 struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
-    return qemudLoadConfigXML(server, NULL, xml, 1);
+    struct qemud_vm_def *def;
+    struct qemud_vm *vm;
+
+    if (!(def = qemudParseVMDef(server, xml, NULL)))
+        return NULL;
+
+    if (!(vm = qemudAssignVMDef(server, def))) {
+        qemudFreeVMDef(def);
+        return NULL;
+    }
+
+    if (qemudSaveVMDef(server, vm, def) < 0) {
+        qemudRemoveInactiveVM(server, vm);
+        return NULL;
+    }
+
+    return vm;
 }
 
 int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
     struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
-    struct qemud_vm *prev = NULL, *curr = server->vms;
 
     if (!vm) {
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
@@ -483,22 +504,7 @@ int qemudDomainUndefine(struct qemud_ser
 
     vm->configFile[0] = '\0';
 
-    while (curr) {
-        if (curr == vm) {
-            if (prev) {
-                prev->next = curr->next;
-            } else {
-                server->vms = curr->next;
-            }
-            server->ninactivevms--;
-            break;
-        }
-
-        prev = curr;
-        curr = curr->next;
-    }
-
-    qemudFreeVM(vm);
+    qemudRemoveInactiveVM(server, vm);
 
     return 0;
 }
@@ -566,14 +572,19 @@ int qemudListDefinedNetworks(struct qemu
 }
 
 struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
+    struct qemud_network_def *def;
     struct qemud_network *network;
 
-    if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0))) {
+    if (!(def = qemudParseNetworkDef(server, xml, NULL)))
+        return NULL;
+
+    if (!(network = qemudAssignNetworkDef(server, def))) {
+        qemudFreeNetworkDef(def);
         return NULL;
     }
 
     if (qemudStartNetworkDaemon(server, network) < 0) {
-        qemudFreeNetwork(network);
+        qemudRemoveInactiveNetwork(server, network);
         return NULL;
     }
 
@@ -581,12 +592,27 @@ struct qemud_network *qemudNetworkCreate
 }
 
 struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
-    return qemudLoadNetworkConfigXML(server, NULL, xml, 1);
+    struct qemud_network_def *def;
+    struct qemud_network *network;
+
+    if (!(def = qemudParseNetworkDef(server, xml, NULL)))
+        return NULL;
+
+    if (!(network = qemudAssignNetworkDef(server, def))) {
+        qemudFreeNetworkDef(def);
+        return NULL;
+    }
+
+    if (qemudSaveNetworkDef(server, network, def) < 0) {
+        qemudRemoveInactiveNetwork(server, network);
+        return NULL;
+    }
+
+    return network;
 }
 
 int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
     struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
-    struct qemud_network *prev = NULL, *curr = server->networks;
 
     if (!network) {
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching uuid");
@@ -598,22 +624,7 @@ int qemudNetworkUndefine(struct qemud_se
 
     network->configFile[0] = '\0';
 
-    while (curr) {
-        if (curr == network) {
-            if (prev) {
-                prev->next = curr->next;
-            } else {
-                server->networks = curr->next;
-            }
-            server->ninactivenetworks--;
-            break;
-        }
-
-        prev = curr;
-        curr = curr->next;
-    }
-
-    qemudFreeNetwork(network);
+    qemudRemoveInactiveNetwork(server, network);
 
     return 0;
 }
@@ -650,7 +661,7 @@ int qemudNetworkDumpXML(struct qemud_ser
         return -1;
     }
 
-    networkxml = qemudGenerateNetworkXML(server, network, 1);
+    networkxml = qemudGenerateNetworkXML(server, network, network->def);
     if (!networkxml)
         return -1;
 
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -1255,8 +1255,7 @@ static int qemudDispatchPoll(struct qemu
     struct qemud_socket *sock = server->sockets;
     struct qemud_client *client = server->clients;
     struct qemud_vm *vm;
-    struct qemud_vm *tmp;
-    struct qemud_network *network, *prevnet;
+    struct qemud_network *network;
     int ret = 0;
     int fd = 0;
 
@@ -1336,42 +1335,24 @@ static int qemudDispatchPoll(struct qemu
     /* Cleanup any VMs which shutdown & dont have an associated
        config file */
     vm = server->vms;
-    tmp = NULL;
     while (vm) {
-        if (!qemudIsActiveVM(vm) && !vm->configFile[0]) {
-            struct qemud_vm *next = vm->next;
-            if (tmp) {
-                tmp->next = next;
-            } else {
-                server->vms = next;
-            }
-            qemudFreeVM(vm);
-            server->ninactivevms--;
-            vm = next;
-        } else {
-            tmp = vm;
-            vm = vm->next;
-        }
+        struct qemud_vm *next = vm->next;
+
+        if (!qemudIsActiveVM(vm) && !vm->configFile[0])
+            qemudRemoveInactiveVM(server, vm);
+
+        vm = next;
     }
 
     /* Cleanup any networks too */
     network = server->networks;
-    prevnet = NULL;
     while (network) {
-        if (!qemudIsActiveNetwork(network) && !network->configFile[0]) {
-            struct qemud_network *next = network->next;
-            if (prevnet) {
-                prevnet->next = next;
-            } else {
-                server->networks = next;
-            }
-            qemudFreeNetwork(network);
-            server->ninactivenetworks--;
-            network = next;
-        } else {
-            prevnet = network;
-            network = network->next;
-        }
+        struct qemud_network *next = network->next;
+
+        if (!qemudIsActiveNetwork(network) && !network->configFile[0])
+            qemudRemoveInactiveNetwork(server, network);
+
+        network = next;
     }
 
     return ret;
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [Libvir] [patch 2/9] Make Start() return an error message if uuid wasnt found
                        
                        
by Mark McLoughlin 22 Feb '07
                    by Mark McLoughlin 22 Feb '07
22 Feb '07
                    
                        qemudDispatchDomainStart() doesn't report an error if the uuid
lookup fails.
The patch not only fixes that, but also moves the uuid lookup
into the driver so that it matches the way we do Destroy().
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -285,7 +285,7 @@ struct qemud_vm *qemudDomainCreate(struc
         return NULL;
     }
 
-    if (qemudDomainStart(server, vm) < 0) {
+    if (qemudStartVMDaemon(server, vm) < 0) {
         qemudFreeVM(vm);
         return NULL;
     }
@@ -339,13 +339,14 @@ int qemudDomainResume(struct qemud_serve
 
 int qemudDomainDestroy(struct qemud_server *server, int id) {
     struct qemud_vm *vm = qemudFindVMByID(server, id);
+
     if (!vm) {
-        qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
+        qemudReportError(server, VIR_ERR_INVALID_DOMAIN,
+                         "no domain with matching id %d", id);
         return -1;
     }
-    if (qemudShutdownVMDaemon(server, vm) < 0)
-        return -1;
-    return 0;
+
+    return qemudShutdownVMDaemon(server, vm);
 }
 
 
@@ -446,8 +447,16 @@ int qemudNumDefinedDomains(struct qemud_
 }
 
 
-int qemudDomainStart(struct qemud_server *server, struct qemud_vm *vm) {
-    return qemudStartVMDaemon(server, vm);
+struct qemud_vm *qemudDomainStart(struct qemud_server *server, const unsigned char *uuid) {
+    struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+
+    if (!vm) {
+        qemudReportError(server, VIR_ERR_INVALID_DOMAIN,
+                         "no domain with matching uuid");
+        return NULL;
+    }
+
+    return qemudStartVMDaemon(server, vm) < 0 ? NULL : vm;
 }
 
 
@@ -563,7 +572,7 @@ struct qemud_network *qemudNetworkCreate
         return NULL;
     }
 
-    if (qemudNetworkStart(server, network) < 0) {
+    if (qemudStartNetworkDaemon(server, network) < 0) {
         qemudFreeNetwork(network);
         return NULL;
     }
@@ -609,21 +618,28 @@ int qemudNetworkUndefine(struct qemud_se
     return 0;
 }
 
-int qemudNetworkStart(struct qemud_server *server, struct qemud_network *network) {
-    return qemudStartNetworkDaemon(server, network);
+struct qemud_network *qemudNetworkStart(struct qemud_server *server, const unsigned char *uuid) {
+    struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+
+    if (!network) {
+        qemudReportError(server, VIR_ERR_INVALID_NETWORK,
+                         "no network with matching uuid");
+        return NULL;
+    }
+
+    return qemudStartNetworkDaemon(server, network) < 0 ? NULL : network;
 }
 
 int qemudNetworkDestroy(struct qemud_server *server, const unsigned char *uuid) {
     struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+
     if (!network) {
-        qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
+        qemudReportError(server, VIR_ERR_INVALID_NETWORK,
+                         "no network with matching uuid");
         return -1;
     }
 
-    if (qemudShutdownNetworkDaemon(server, network) < 0)
-        return -1;
-
-    return 0;
+    return qemudShutdownNetworkDaemon(server, network);
 }
 
 int qemudNetworkDumpXML(struct qemud_server *server, const unsigned char *uuid, char *xml, int xmllen) {
Index: libvirt/qemud/driver.h
===================================================================
--- libvirt.orig/qemud/driver.h
+++ libvirt/qemud/driver.h
@@ -79,8 +79,8 @@ int qemudListDefinedDomains(struct qemud
                             char *const*names,
                             int nnames);
 int qemudNumDefinedDomains(struct qemud_server *server);
-int qemudDomainStart(struct qemud_server *server,
-                     struct qemud_vm *vm);
+struct qemud_vm *qemudDomainStart(struct qemud_server *server,
+                                  const unsigned char *uuid);
 struct qemud_vm *qemudDomainDefine(struct qemud_server *server,
                                    const char *xml);
 int qemudDomainUndefine(struct qemud_server *server,
@@ -103,10 +103,10 @@ struct qemud_network *qemudNetworkCreate
                                          const char *xml);
 struct qemud_network *qemudNetworkDefine(struct qemud_server *server,
                                          const char *xml);
+struct qemud_network *qemudNetworkStart(struct qemud_server *server,
+                                        const unsigned char *uuid);
 int qemudNetworkUndefine(struct qemud_server *server,
                          const unsigned char *uuid);
-int qemudNetworkStart(struct qemud_server *server,
-                      struct qemud_network *network);
 int qemudNetworkDestroy(struct qemud_server *server,
                         const unsigned char *uuid);
 int qemudNetworkDumpXML(struct qemud_server *server,
Index: libvirt/qemud/dispatch.c
===================================================================
--- libvirt.orig/qemud/dispatch.c
+++ libvirt/qemud/dispatch.c
@@ -257,8 +257,7 @@ static int qemudDispatchDomainDestroy(st
     if (in->header.dataSize != sizeof(in->data.domainDestroyRequest))
         return -1;
 
-    int ret = qemudDomainDestroy(server, in->data.domainDestroyRequest.id);
-    if (ret < 0) {
+    if (qemudDomainDestroy(server, in->data.domainDestroyRequest.id) < 0) {
         if (qemudDispatchFailure(server, client, out) < 0)
             return -1;
     } else {
@@ -410,11 +409,12 @@ static int qemudDispatchNumDefinedDomain
 
 static int qemudDispatchDomainStart(struct qemud_server *server, struct qemud_client *client,
                                     struct qemud_packet *in, struct qemud_packet *out) {
+    struct qemud_vm *vm;
+
     if (in->header.dataSize != sizeof(in->data.domainStartRequest))
         return -1;
 
-    struct qemud_vm *vm = qemudFindVMByUUID(server, in->data.domainStartRequest.uuid);
-    if (!vm || qemudDomainStart(server, vm) < 0) {
+    if (!(vm = qemudDomainStart(server, in->data.domainStartRequest.uuid))) {
         if (qemudDispatchFailure(server, client, out) < 0)
             return -1;
     } else {
@@ -651,11 +651,12 @@ static int qemudDispatchNetworkUndefine(
 
 static int qemudDispatchNetworkStart(struct qemud_server *server, struct qemud_client *client,
                                      struct qemud_packet *in, struct qemud_packet *out) {
+    struct qemud_network *network;
+
     if (in->header.dataSize != sizeof(in->data.networkStartRequest))
         return -1;
 
-    struct qemud_network *network = qemudFindNetworkByUUID(server, in->data.networkStartRequest.uuid);
-    if (!network || qemudNetworkStart(server, network) < 0) {
+    if (!(network = qemudNetworkStart(server, in->data.networkStartRequest.uuid))) {
         if (qemudDispatchFailure(server, client, out) < 0)
             return -1;
     } else {
@@ -670,8 +671,7 @@ static int qemudDispatchNetworkDestroy(s
     if (in->header.dataSize != sizeof(in->data.networkDestroyRequest))
         return -1;
 
-    int ret = qemudNetworkDestroy(server, in->data.networkDestroyRequest.uuid);
-    if (ret < 0) {
+    if (qemudNetworkDestroy(server, in->data.networkDestroyRequest.uuid) < 0) {
         if (qemudDispatchFailure(server, client, out) < 0)
             return -1;
     } else {
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [Libvir] [patch 1/9] Merge the active and inactive network/guest lists
                        
                        
by Mark McLoughlin 22 Feb '07
                    by Mark McLoughlin 22 Feb '07
22 Feb '07
                    
                        Merge the ->activevms and ->inactivevms into a single
->vms list where each VM has a "active" flag in order
to make things easier to manage.
Likewise for networks.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1215,7 +1215,7 @@ struct qemud_vm *qemudLoadConfigXML(stru
     xmlFreeDoc(xml);
 
     if ((vm = qemudFindVMByName(server, def->name))) {
-        if (vm->id == -1) {
+        if (!qemudIsActiveVM(vm)) {
             qemudFreeVMDef(vm->def);
             vm->def = def;
         } else {
@@ -1263,8 +1263,8 @@ struct qemud_vm *qemudLoadConfigXML(stru
     }
 
     if (newVM) {
-        vm->next = server->inactivevms;
-        server->inactivevms = vm;
+        vm->next = server->vms;
+        server->vms = vm;
         server->ninactivevms++;
     }
 
@@ -1570,7 +1570,7 @@ struct qemud_network *qemudLoadNetworkCo
     xmlFreeDoc(xml);
 
     if ((network = qemudFindNetworkByName(server, def->name))) {
-        if (!network->active) {
+        if (!qemudIsActiveNetwork(network)) {
             qemudFreeNetworkDef(network->def);
             network->def = def;
         } else {
@@ -1611,8 +1611,8 @@ struct qemud_network *qemudLoadNetworkCo
     }
 
     if (newNetwork) {
-        network->next = server->inactivenetworks;
-        server->inactivenetworks = network;
+        network->next = server->networks;
+        server->networks = network;
         server->ninactivenetworks++;
     }
 
@@ -1777,7 +1777,7 @@ char *qemudGenerateXML(struct qemud_serv
         goto cleanup;
     }
 
-    if (vm->id >= 0 && live) {
+    if (qemudIsActiveVM(vm) && live) {
         if (qemudBufferPrintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id) < 0)
             goto no_memory;
     } else {
@@ -1945,7 +1945,7 @@ char *qemudGenerateXML(struct qemud_serv
 
         if (def->vncPort &&
             qemudBufferPrintf(&buf, " port='%d'",
-                              vm->id >= 0 && live ? def->vncActivePort : def->vncPort) < 0)
+                              qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort) < 0)
             goto no_memory;
 
         if (qemudBufferAdd(&buf, "/>\n") < 0)
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -222,10 +222,10 @@ static int qemudGetProcessInfo(unsigned 
 }
 
 struct qemud_vm *qemudFindVMByID(const struct qemud_server *server, int id) {
-    struct qemud_vm *vm = server->activevms;
+    struct qemud_vm *vm = server->vms;
 
     while (vm) {
-        if (vm->id == id)
+        if (qemudIsActiveVM(vm) && vm->id == id)
             return vm;
         vm = vm->next;
     }
@@ -235,7 +235,7 @@ struct qemud_vm *qemudFindVMByID(const s
 
 struct qemud_vm *qemudFindVMByUUID(const struct qemud_server *server,
                                    const unsigned char *uuid) {
-    struct qemud_vm *vm = server->activevms;
+    struct qemud_vm *vm = server->vms;
 
     while (vm) {
         if (!memcmp(vm->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
@@ -243,19 +243,12 @@ struct qemud_vm *qemudFindVMByUUID(const
         vm = vm->next;
     }
 
-    vm = server->inactivevms;
-    while (vm) {
-        if (!memcmp(vm->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
-            return vm;
-        vm = vm->next;
-    }
-
     return NULL;
 }
 
 struct qemud_vm *qemudFindVMByName(const struct qemud_server *server,
                                    const char *name) {
-    struct qemud_vm *vm = server->activevms;
+    struct qemud_vm *vm = server->vms;
 
     while (vm) {
         if (!strcmp(vm->def->name, name))
@@ -263,13 +256,6 @@ struct qemud_vm *qemudFindVMByName(const
         vm = vm->next;
     }
 
-    vm = server->inactivevms;
-    while (vm) {
-        if (!strcmp(vm->def->name, name))
-            return vm;
-        vm = vm->next;
-    }
-
     return NULL;
 }
 
@@ -278,12 +264,14 @@ int qemudGetVersion(struct qemud_server 
 }
 
 int qemudListDomains(struct qemud_server *server, int *ids, int nids) {
-    struct qemud_vm *vm = server->activevms;
+    struct qemud_vm *vm = server->vms;
     int got = 0;
     while (vm && got < nids) {
-        ids[got] = vm->id;
+        if (qemudIsActiveVM(vm)) {
+            ids[got] = vm->id;
+            got++;
+        }
         vm = vm->next;
-        got++;
     }
     return got;
 }
@@ -313,7 +301,7 @@ int qemudDomainSuspend(struct qemud_serv
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
         return -1;
     }
-    if (vm->pid == -1) {
+    if (!qemudIsActiveVM(vm)) {
         qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
         return -1;
     }
@@ -335,7 +323,7 @@ int qemudDomainResume(struct qemud_serve
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
         return -1;
     }
-    if (vm->pid == -1) {
+    if (!qemudIsActiveVM(vm)) {
         qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
         return -1;
     }
@@ -355,11 +343,6 @@ int qemudDomainDestroy(struct qemud_serv
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
         return -1;
     }
-    if (vm->pid == -1) {
-        qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
-        return -1;
-    }
-
     if (qemudShutdownVMDaemon(server, vm) < 0)
         return -1;
     return 0;
@@ -378,14 +361,14 @@ int qemudDomainGetInfo(struct qemud_serv
         return -1;
     }
 
-    if (vm->pid == -1) {
+    if (!qemudIsActiveVM(vm)) {
         *runstate = QEMUD_STATE_STOPPED;
     } else {
         /* XXX in future need to add PAUSED */
         *runstate = QEMUD_STATE_RUNNING;
     }
 
-    if (vm->pid == -1) {
+    if (!qemudIsActiveVM(vm)) {
         *cputime = 0;
     } else {
         if (qemudGetProcessInfo(cputime, vm->pid) < 0) {
@@ -408,7 +391,7 @@ int qemudDomainSave(struct qemud_server 
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
         return -1;
     }
-    if (vm->pid == -1) {
+    if (!qemudIsActiveVM(vm)) {
         qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
         return -1;
     }
@@ -444,13 +427,15 @@ int qemudDomainDumpXML(struct qemud_serv
 
 
 int qemudListDefinedDomains(struct qemud_server *server, char *const*names, int nnames) {
-    struct qemud_vm *vm = server->inactivevms;
+    struct qemud_vm *vm = server->vms;
     int got = 0;
     while (vm && got < nnames) {
-        strncpy(names[got], vm->def->name, QEMUD_MAX_NAME_LEN-1);
-        names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+        if (!qemudIsActiveVM(vm)) {
+            strncpy(names[got], vm->def->name, QEMUD_MAX_NAME_LEN-1);
+            names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+            got++;
+        }
         vm = vm->next;
-        got++;
     }
     return got;
 }
@@ -462,30 +447,7 @@ int qemudNumDefinedDomains(struct qemud_
 
 
 int qemudDomainStart(struct qemud_server *server, struct qemud_vm *vm) {
-    struct qemud_vm *prev = NULL, *curr = server->inactivevms;
-    if (qemudStartVMDaemon(server, vm) < 0) {
-        return 1;
-    }
-
-    while (curr) {
-        if (curr == vm) {
-            if (prev)
-                prev->next = curr->next;
-            else
-                server->inactivevms = curr->next;
-            server->ninactivevms--;
-            break;
-        }
-        prev = curr;
-        curr = curr->next;
-    }
-
-    vm->next = server->activevms;
-    server->activevms = vm;
-    server->nactivevms++;
-    server->nvmfds += 2;
-
-    return 0;
+    return qemudStartVMDaemon(server, vm);
 }
 
 
@@ -495,14 +457,14 @@ struct qemud_vm *qemudDomainDefine(struc
 
 int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
     struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
-    struct qemud_vm *prev = NULL, *curr = server->inactivevms;
+    struct qemud_vm *prev = NULL, *curr = server->vms;
 
     if (!vm) {
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
         return -1;
     }
 
-    if (vm->pid != -1) {
+    if (qemudIsActiveVM(vm)) {
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot delete active domain");
         return -1;
     }
@@ -517,7 +479,7 @@ int qemudDomainUndefine(struct qemud_ser
             if (prev) {
                 prev->next = curr->next;
             } else {
-                server->inactivevms = curr->next;
+                server->vms = curr->next;
             }
             server->ninactivevms--;
             break;
@@ -534,15 +496,8 @@ int qemudDomainUndefine(struct qemud_ser
 
 struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
                                              const unsigned char *uuid) {
-    struct qemud_network *network = server->activenetworks;
-
-    while (network) {
-        if (!memcmp(network->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
-            return network;
-        network = network->next;
-    }
+    struct qemud_network *network = server->networks;
 
-    network = server->inactivenetworks;
     while (network) {
         if (!memcmp(network->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
             return network;
@@ -554,7 +509,7 @@ struct qemud_network *qemudFindNetworkBy
 
 struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server,
                                              const char *name) {
-    struct qemud_network *network = server->activenetworks;
+    struct qemud_network *network = server->networks;
 
     while (network) {
         if (!strcmp(network->def->name, name))
@@ -562,13 +517,6 @@ struct qemud_network *qemudFindNetworkBy
         network = network->next;
     }
 
-    network = server->inactivenetworks;
-    while (network) {
-        if (!strcmp(network->def->name, name))
-            return network;
-        network = network->next;
-    }
-
     return NULL;
 }
 
@@ -577,13 +525,15 @@ int qemudNumNetworks(struct qemud_server
 }
 
 int qemudListNetworks(struct qemud_server *server, char *const*names, int nnames) {
-    struct qemud_network *network = server->activenetworks;
+    struct qemud_network *network = server->networks;
     int got = 0;
     while (network && got < nnames) {
-        strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
-        names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+        if (qemudIsActiveNetwork(network)) {
+            strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
+            names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+            got++;
+        }
         network = network->next;
-        got++;
     }
     return got;
 }
@@ -593,13 +543,15 @@ int qemudNumDefinedNetworks(struct qemud
 }
 
 int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int nnames) {
-    struct qemud_network *network = server->inactivenetworks;
+    struct qemud_network *network = server->networks;
     int got = 0;
     while (network && got < nnames) {
-        strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
-        names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+        if (!qemudIsActiveNetwork(network)) {
+            strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
+            names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+            got++;
+        }
         network = network->next;
-        got++;
     }
     return got;
 }
@@ -625,7 +577,7 @@ struct qemud_network *qemudNetworkDefine
 
 int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
     struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
-    struct qemud_network *prev = NULL, *curr = server->inactivenetworks;
+    struct qemud_network *prev = NULL, *curr = server->networks;
 
     if (!network) {
         qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching uuid");
@@ -642,7 +594,7 @@ int qemudNetworkUndefine(struct qemud_se
             if (prev) {
                 prev->next = curr->next;
             } else {
-                server->inactivenetworks = curr->next;
+                server->networks = curr->next;
             }
             server->ninactivenetworks--;
             break;
@@ -658,29 +610,7 @@ int qemudNetworkUndefine(struct qemud_se
 }
 
 int qemudNetworkStart(struct qemud_server *server, struct qemud_network *network) {
-    struct qemud_network *prev = NULL, *curr = server->inactivenetworks;
-    if (qemudStartNetworkDaemon(server, network) < 0) {
-        return 1;
-    }
-
-    while (curr) {
-        if (curr == network) {
-            if (prev)
-                prev->next = curr->next;
-            else
-                server->inactivenetworks = curr->next;
-            server->ninactivenetworks--;
-            break;
-        }
-        prev = curr;
-        curr = curr->next;
-    }
-
-    network->next = server->activenetworks;
-    server->activenetworks = network;
-    server->nactivenetworks++;
-
-    return 0;
+    return qemudStartNetworkDaemon(server, network);
 }
 
 int qemudNetworkDestroy(struct qemud_server *server, const unsigned char *uuid) {
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -280,14 +280,12 @@ struct qemud_server {
     int sigread;
     int nvmfds;
     int nactivevms;
-    struct qemud_vm *activevms;
     int ninactivevms;
-    struct qemud_vm *inactivevms;
+    struct qemud_vm *vms;
     int nextvmid;
     int nactivenetworks;
-    struct qemud_network *activenetworks;
     int ninactivenetworks;
-    struct qemud_network *inactivenetworks;
+    struct qemud_network *networks;
     brControl *brctl;
     iptablesContext *iptables;
     char configDir[PATH_MAX];
@@ -317,6 +315,18 @@ void qemudLog(int priority, const char *
 #define qemudDebug(fmt, ...) do { } while(0);
 #endif
 
+static inline int
+qemudIsActiveVM(struct qemud_vm *vm)
+{
+    return vm->id != -1;
+}
+
+static inline int
+qemudIsActiveNetwork(struct qemud_network *network)
+{
+    return network->active;
+}
+
 #endif
 
 /*
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -95,39 +95,43 @@ static int qemudDispatchSignal(struct qe
         qemudLog(QEMUD_WARN, "Shutting down on signal %d", sigc);
 
         /* shutdown active VMs */
-        vm = server->activevms;
+        vm = server->vms;
         while (vm) {
             struct qemud_vm *next = vm->next;
-            qemudShutdownVMDaemon(server, vm);
+            if (qemudIsActiveVM(vm))
+                qemudShutdownVMDaemon(server, vm);
             vm = next;
         }
 
         /* free inactive VMs */
-        vm = server->inactivevms;
+        vm = server->vms;
         while (vm) {
             struct qemud_vm *next = vm->next;
             qemudFreeVM(vm);
             vm = next;
         }
-        server->inactivevms = NULL;
+        server->vms = NULL;
+        server->nactivevms = 0;
         server->ninactivevms = 0;
 
         /* shutdown active networks */
-        network = server->activenetworks;
+        network = server->networks;
         while (network) {
             struct qemud_network *next = network->next;
-            qemudShutdownNetworkDaemon(server, network);
+            if (qemudIsActiveNetwork(network))
+                qemudShutdownNetworkDaemon(server, network);
             network = next;
         }
 
         /* free inactive networks */
-        network = server->inactivenetworks;
+        network = server->networks;
         while (network) {
             struct qemud_network *next = network->next;
             qemudFreeNetwork(network);
             network = next;
         }
-        server->inactivenetworks = NULL;
+        server->networks = NULL;
+        server->nactivenetworks = 0;
         server->ninactivenetworks = 0;
 
         server->shutdown = 1;
@@ -576,6 +580,12 @@ int qemudStartVMDaemon(struct qemud_serv
     char **argv = NULL;
     int i, ret = -1;
 
+    if (qemudIsActiveVM(vm)) {
+        qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+                         "VM is already active");
+        return -1;
+    }
+
     if (vm->def->vncPort < 0)
         vm->def->vncActivePort = 5900 + server->nextvmid;
     else
@@ -586,6 +596,11 @@ int qemudStartVMDaemon(struct qemud_serv
 
     if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
         vm->id = server->nextvmid++;
+
+        server->ninactivevms--;
+        server->nactivevms++;
+        server->nvmfds += 2;
+
         ret = 0;
     }
 
@@ -805,50 +820,24 @@ qemudNetworkIfaceDisconnect(struct qemud
 }
 
 int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
-    struct qemud_vm *prev = NULL, *curr = server->activevms;
     struct qemud_vm_net_def *net;
 
-    qemudLog(QEMUD_INFO, "Shutting down VM '%s'", vm->def->name);
-
-    /* Already cleaned-up */
-    if (vm->pid < 0)
+    if (!qemudIsActiveVM(vm))
         return 0;
 
-    kill(vm->pid, SIGTERM);
-
-    /* Move it to inactive vm list */
-    while (curr) {
-        if (curr == vm) {
-            if (prev) {
-                prev->next = curr->next;
-            } else {
-                server->activevms = curr->next;
-            }
-            server->nactivevms--;
-
-            curr->next = server->inactivevms;
-            server->inactivevms = curr;
-            server->ninactivevms++;
-            break;
-        }
-        prev = curr;
-        curr = curr->next;
-    }
+    qemudLog(QEMUD_INFO, "Shutting down VM '%s'", vm->def->name);
 
-    if (!curr) {
-        qemudDebug("Could not find VM to shutdown");
-        return 0;
-    }
+    kill(vm->pid, SIGTERM);
 
-    qemudVMData(server, vm, curr->stdout);
-    qemudVMData(server, vm, curr->stderr);
-    close(curr->stdout);
-    close(curr->stderr);
-    if (curr->monitor != -1)
-        close(curr->monitor);
-    curr->stdout = -1;
-    curr->stderr = -1;
-    curr->monitor = -1;
+    qemudVMData(server, vm, vm->stdout);
+    qemudVMData(server, vm, vm->stderr);
+    close(vm->stdout);
+    close(vm->stderr);
+    if (vm->monitor != -1)
+        close(vm->monitor);
+    vm->stdout = -1;
+    vm->stderr = -1;
+    vm->monitor = -1;
     server->nvmfds -= 2;
 
     net = vm->def->nets;
@@ -874,6 +863,9 @@ int qemudShutdownVMDaemon(struct qemud_s
         vm->newDef = NULL;
     }
 
+    server->nactivevms--;
+    server->ninactivevms++;
+
     return 0;
 }
 
@@ -1121,7 +1113,7 @@ int qemudStartNetworkDaemon(struct qemud
     const char *name;
     int err;
 
-    if (network->active) {
+    if (qemudIsActiveNetwork(network)) {
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
                          "network is already active");
         return -1;
@@ -1185,6 +1177,9 @@ int qemudStartNetworkDaemon(struct qemud
 
     network->active = 1;
 
+    server->ninactivenetworks--;
+    server->nactivenetworks++;
+
     return 0;
 
  err_delbr2:
@@ -1209,12 +1204,11 @@ int qemudStartNetworkDaemon(struct qemud
 
 int qemudShutdownNetworkDaemon(struct qemud_server *server,
                                struct qemud_network *network) {
-    struct qemud_network *prev, *curr;
     int err;
 
     qemudLog(QEMUD_INFO, "Shutting down network '%s'", network->def->name);
 
-    if (!network->active)
+    if (!qemudIsActiveNetwork(network))
         return 0;
 
     if (network->dnsmasqPid > 0)
@@ -1233,27 +1227,6 @@ int qemudShutdownNetworkDaemon(struct qe
                  network->bridge, strerror(err));
     }
 
-    /* Move it to inactive networks list */
-    prev = NULL;
-    curr = server->activenetworks;
-    while (curr) {
-        if (curr == network) {
-            if (prev) {
-                prev->next = curr->next;
-            } else {
-                server->activenetworks = curr->next;
-            }
-            server->nactivenetworks--;
-
-            curr->next = server->inactivenetworks;
-            server->inactivenetworks = curr;
-            server->ninactivenetworks++;
-            break;
-        }
-        prev = curr;
-        curr = curr->next;
-    }
-
     if (network->dnsmasqPid > 0 &&
         waitpid(network->dnsmasqPid, NULL, WNOHANG) != network->dnsmasqPid) {
         kill(network->dnsmasqPid, SIGKILL);
@@ -1271,6 +1244,9 @@ int qemudShutdownNetworkDaemon(struct qe
         network->newDef = NULL;
     }
 
+    server->nactivenetworks--;
+    server->ninactivenetworks++;
+
     return 0;
 }
 
@@ -1278,7 +1254,7 @@ int qemudShutdownNetworkDaemon(struct qe
 static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) {
     struct qemud_socket *sock = server->sockets;
     struct qemud_client *client = server->clients;
-    struct qemud_vm *vm = server->activevms;
+    struct qemud_vm *vm;
     struct qemud_vm *tmp;
     struct qemud_network *network, *prevnet;
     int ret = 0;
@@ -1314,12 +1290,18 @@ static int qemudDispatchPoll(struct qemu
         fd++;
         client = next;
     }
+    vm = server->vms;
     while (vm) {
         struct qemud_vm *next = vm->next;
         int failed = 0,
             stdoutfd = vm->stdout,
             stderrfd = vm->stderr;
 
+        if (!qemudIsActiveVM(vm)) {
+            vm = next;
+            continue;
+        }
+
         if (stdoutfd != -1) {
             if (fds[fd].revents) {
                 if (fds[fd].revents == POLLIN) {
@@ -1353,17 +1335,18 @@ static int qemudDispatchPoll(struct qemu
 
     /* Cleanup any VMs which shutdown & dont have an associated
        config file */
-    vm = server->inactivevms;
+    vm = server->vms;
     tmp = NULL;
     while (vm) {
-        if (!vm->configFile[0]) {
+        if (!qemudIsActiveVM(vm) && !vm->configFile[0]) {
             struct qemud_vm *next = vm->next;
             if (tmp) {
                 tmp->next = next;
             } else {
-                server->inactivevms = next;
+                server->vms = next;
             }
             qemudFreeVM(vm);
+            server->ninactivevms--;
             vm = next;
         } else {
             tmp = vm;
@@ -1372,17 +1355,18 @@ static int qemudDispatchPoll(struct qemu
     }
 
     /* Cleanup any networks too */
-    network = server->inactivenetworks;
+    network = server->networks;
     prevnet = NULL;
     while (network) {
-        if (!network->configFile[0]) {
+        if (!qemudIsActiveNetwork(network) && !network->configFile[0]) {
             struct qemud_network *next = network->next;
             if (prevnet) {
                 prevnet->next = next;
             } else {
-                server->inactivenetworks = next;
+                server->networks = next;
             }
             qemudFreeNetwork(network);
+            server->ninactivenetworks--;
             network = next;
         } else {
             prevnet = network;
@@ -1419,7 +1403,9 @@ static void qemudPreparePoll(struct qemu
             fds[fd].events = POLLIN | POLLERR | POLLHUP;
         fd++;
     }
-    for (vm = server->activevms ; vm ; vm = vm->next) {
+    for (vm = server->vms ; vm ; vm = vm->next) {
+        if (!qemudIsActiveVM(vm))
+            continue;
         if (vm->stdout != -1) {
             fds[fd].fd = vm->stdout;
             fds[fd].events = POLLIN | POLLERR | POLLHUP;
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        Hey,
	Here's the autostart patches again. If you're just
looking for what's changed, it's probably fine to just look
at patch 3 (some heavy re-factoring to make the autostart
stuff easier) and patch 7 (maintains symlinks in the autostart
dirs instead of config files).
Cheers,
Mark.
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        On Tue, Feb 20, 2007 at 07:26:39PM +0000, Mark McLoughlin wrote:
> server->autostartNetworkConfigDir etc. is starting to
> get a little unwieldly so put the config directory
> paths in an array.
 
> +    const char *paths[] = {
> +        "libvirt/qemu",                    /* QEMUD_DIR_DOMAINS */
> +        "libvirt/qemu/autostart",          /* QEMUD_DIR_AUTO_DOMAINS */
> +        "libvirt/qemu/networks",           /* QEMUD_DIR_NETWORKS */
> +        "libvirt/qemu/networks/autostart", /* QEMUD_DIR_AUTO_NETWORKS */
> +    };
> +
  
  
> -        if (snprintf(autostartNetworkConfigDir, maxlen, "%s/.libvirt/qemu/networks/autostart", pw->pw_dir) >= maxlen)
> -            goto snprintf_error;
> +        base = pw->pw_dir;
> +    }
>  
> -        if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen)
> +    for (i = 0; i < QEMUD_N_CONFIG_DIRS; i++)
> +        if (snprintf(server->configDirs[i], PATH_MAX, "%s/%s", base, paths[i]) >= PATH_MAX)
>              goto snprintf_error;
> -    }
I could be reading this wrong, but it looks as if this is going to make the
per-user daemon write its config files into
  $HOME/libvirt 
Instead of
  $HOME/.libvirt
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            Re: [Libvir] [patch 1/7] Merge the active and inactive network/guest lists
                        
                        
by Daniel P. Berrange 20 Feb '07
                    by Daniel P. Berrange 20 Feb '07
20 Feb '07
                    
                        On Tue, Feb 20, 2007 at 07:26:03PM +0000, Mark McLoughlin wrote:
> Merge the ->activevms and ->inactivevms into a single
> ->vms list where each VM has a "active" flag in order
> to make things easier to manage.
I'm sure I had some interesting reason for keeping the lists separate
when i wrote this. Damned if I can think of what it was now :-) The
patch does seem to make things simpler.  Having an explicit 'active'
flag though is redundant. Simply check for 'vm->id == -1' or equivalently
the 'vm->pid == -1'. We don't need a 3rd flag to mark inactivity :-)
>      net = vm->def->nets;
> @@ -867,6 +846,7 @@ int qemudShutdownVMDaemon(struct qemud_s
>  
>      vm->pid = -1;
>      vm->id = -1;
> +    vm->active = 0;
>  
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                     
                        
                    20 Feb '07
                    
                        On Tue, Feb 20, 2007 at 07:26:31PM +0000, Mark McLoughlin wrote:
> Actually implement the autostart API in qemud by saving
> autostart configs to a specific directory.
I think its desirable to keep all the master config files in the
same directory, because it gives a sanity check of name uniqueness
for files. Instead just create a symlink into the autostart directory
in the same way the XenD recommendation works. So setting/getting
autostart flag is just a matter of stat()'ing the symlink or using
symlink()/unlink() to change it.
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                    
                    
                        Add "autostart" and "net-autostart" commands
Also, cleanup the "list" and "net-list" commands a bit
and add autostart info to them
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/src/virsh.c
===================================================================
--- libvirt.orig/src/virsh.c
+++ libvirt/src/virsh.c
@@ -292,6 +292,51 @@ cmdHelp(vshControl * ctl, vshCmd * cmd)
 }
 
 /*
+ * "autostart" command
+ */
+static vshCmdInfo info_autostart[] = {
+    {"syntax", "autostart [--disable] <domain>"},
+    {"help", gettext_noop("autostart a domain")},
+    {"desc",
+     gettext_noop("Configure a domain to be automatically started at boot.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_autostart[] = {
+    {"domain",  VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+    {"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdAutostart(vshControl * ctl, vshCmd * cmd)
+{
+    virDomainPtr dom;
+    char *name;
+    int autostart;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &name)))
+        return FALSE;
+
+    autostart = !vshCommandOptBool(cmd, "disable");
+
+    if (virDomainSetAutostart(dom, autostart) < 0) {
+        vshError(ctl, FALSE, _("Failed to %smark domain %s as autostarted"),
+                 autostart ? "" : "un", name);
+        virDomainFree(dom);
+        return FALSE;
+    }
+
+    vshPrint(ctl, _("Domain %s %smarked as autostarted\n"),
+             name, autostart ? "" : "un");
+
+    return TRUE;
+}
+
+/*
  * "connect" command
  */
 static vshCmdInfo info_connect[] = {
@@ -473,53 +518,59 @@ cmdList(vshControl * ctl, vshCmd * cmd A
             qsort(&names[0], maxname, sizeof(char*), namesorter);
         }
     }
-    vshPrintExtra(ctl, "%3s %-20s %s\n", _("Id"), _("Name"), _("State"));
-    vshPrintExtra(ctl, "----------------------------------\n");
+    vshPrintExtra(ctl, "%3s %-20s %-10s %-10s\n", _("Id"), _("Name"), _("State"), _("Autostart"));
+    vshPrintExtra(ctl, "---------------------------------------------\n");
 
     for (i = 0; i < maxid; i++) {
-        int ret;
         virDomainInfo info;
         virDomainPtr dom = virDomainLookupByID(ctl->conn, ids[i]);
+        const char *state, *autostartStr;
+        int autostart = 0;
 
         /* this kind of work with domains is not atomic operation */
         if (!dom)
             continue;
-        ret = virDomainGetInfo(dom, &info);
 
-        vshPrint(ctl, "%3d %-20s %s\n",
+        if (virDomainGetInfo(dom, &info) < 0)
+            state = _("no state");
+        else
+            state = _N(vshDomainStateToString(info.state));
+
+        if (virDomainGetAutostart(dom, &autostart) < 0)
+            autostartStr = _("no autostart");
+        else
+            autostartStr = autostart ? "yes" : "no";
+
+        vshPrint(ctl, "%3d %-20s %-10s %-10s\n",
                  virDomainGetID(dom),
                  virDomainGetName(dom),
-                 ret <
-                 0 ? _("no state") : _N(vshDomainStateToString(info.state)));
+                 state,
+                 autostartStr);
         virDomainFree(dom);
     }
     for (i = 0; i < maxname; i++) {
-        int ret;
-        unsigned int id;
         virDomainInfo info;
         virDomainPtr dom = virDomainLookupByName(ctl->conn, names[i]);
+        const char *state, *autostartStr;
+        int autostart = 0;
 
         /* this kind of work with domains is not atomic operation */
         if (!dom) {
             free(names[i]);
             continue;
         }
-        ret = virDomainGetInfo(dom, &info);
-        id = virDomainGetID(dom);
 
-        if (id == ((unsigned int)-1)) {
-            vshPrint(ctl, "%3s %-20s %s\n",
-                     "-",
-                     names[i],
-                     ret <
-                     0 ? "no state" : vshDomainStateToString(info.state));
-        } else {
-            vshPrint(ctl, "%3d %-20s %s\n",
-                     id,
-                     names[i],
-                     ret <
-                     0 ? "no state" : vshDomainStateToString(info.state));
-        }
+        if (virDomainGetInfo(dom, &info) < 0)
+            state = _("no state");
+        else
+            state = _N(vshDomainStateToString(info.state));
+
+        if (virDomainGetAutostart(dom, &autostart) < 0)
+            autostartStr = _("no autostart");
+        else
+            autostartStr = autostart ? "yes" : "no";
+
+        vshPrint(ctl, "%3s %-20s %s %s\n", "-", names[i], state, autostartStr);
 
         virDomainFree(dom);
         free(names[i]);
@@ -1632,6 +1683,50 @@ cmdDomuuid(vshControl * ctl, vshCmd * cm
     return TRUE;
 }
 
+/*
+ * "net-autostart" command
+ */
+static vshCmdInfo info_network_autostart[] = {
+    {"syntax", "net-autostart [--disable] <network>"},
+    {"help", gettext_noop("autostart a network")},
+    {"desc",
+     gettext_noop("Configure a network to be automatically started at boot.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_network_autostart[] = {
+    {"network",  VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("network name or uuid")},
+    {"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdNetworkAutostart(vshControl * ctl, vshCmd * cmd)
+{
+    virNetworkPtr network;
+    char *name;
+    int autostart;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(network = vshCommandOptNetwork(ctl, cmd, "network", &name)))
+        return FALSE;
+
+    autostart = !vshCommandOptBool(cmd, "disable");
+
+    if (virNetworkSetAutostart(network, autostart) < 0) {
+        vshError(ctl, FALSE, _("Failed to %smark network %s as autostarted"),
+                 autostart ? "" : "un", name);
+        virNetworkFree(network);
+        return FALSE;
+    }
+
+    vshPrint(ctl, _("Network %s %smarked as autostarted\n"),
+             name, autostart ? "" : "un");
+
+    return TRUE;
+}
 
 /*
  * "net-create" command
@@ -1895,11 +1990,13 @@ cmdNetworkList(vshControl * ctl, vshCmd 
             qsort(&inactiveNames[0], maxinactive, sizeof(char*), namesorter);
         }
     }
-    vshPrintExtra(ctl, "%-20s\n", _("Name"));
-    vshPrintExtra(ctl, "----------------------------------\n");
+    vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), _("Autostart"));
+    vshPrintExtra(ctl, "-----------------------------------------\n");
 
     for (i = 0; i < maxactive; i++) {
         virNetworkPtr network = virNetworkLookupByName(ctl->conn, activeNames[i]);
+        const char *autostartStr;
+        int autostart = 0;
 
         /* this kind of work with networks is not atomic operation */
         if (!network) {
@@ -1907,13 +2004,22 @@ cmdNetworkList(vshControl * ctl, vshCmd 
             continue;
         }
 
-        vshPrint(ctl, "%-20s\n",
-                 virNetworkGetName(network));
+        if (virNetworkGetAutostart(network, &autostart) < 0)
+            autostartStr = _("no autostart");
+        else
+            autostartStr = autostart ? "yes" : "no";
+
+        vshPrint(ctl, "%-20s %-10s %-10s\n",
+                 virNetworkGetName(network),
+                 _("active"),
+                 autostartStr);
         virNetworkFree(network);
         free(activeNames[i]);
     }
     for (i = 0; i < maxinactive; i++) {
         virNetworkPtr network = virNetworkLookupByName(ctl->conn, inactiveNames[i]);
+        const char *autostartStr;
+        int autostart = 0;
 
         /* this kind of work with networks is not atomic operation */
         if (!network) {
@@ -1921,8 +2027,15 @@ cmdNetworkList(vshControl * ctl, vshCmd 
             continue;
         }
 
-        vshPrint(ctl, "%-20s\n",
-                 inactiveNames[i]);
+        if (virNetworkGetAutostart(network, &autostart) < 0)
+            autostartStr = _("no autostart");
+        else
+            autostartStr = autostart ? "yes" : "no";
+
+        vshPrint(ctl, "%-20s %s %s\n",
+                 inactiveNames[i],
+                 _("inactive"),
+                 autostartStr);
 
         virNetworkFree(network);
         free(inactiveNames[i]);
@@ -2268,6 +2381,7 @@ cmdQuit(vshControl * ctl, vshCmd * cmd A
  * Commands
  */
 static vshCmdDef commands[] = {
+    {"autostart", cmdAutostart, opts_autostart, info_autostart},
     {"connect", cmdConnect, opts_connect, info_connect},
     {"console", cmdConsole, opts_console, info_console},
     {"create", cmdCreate, opts_create, info_create},
@@ -2282,6 +2396,7 @@ static vshCmdDef commands[] = {
     {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
     {"help", cmdHelp, opts_help, info_help},
     {"list", cmdList, opts_list, info_list},
+    {"net-autostart", cmdNetworkAutostart, opts_network_autostart, info_network_autostart},
     {"net-create", cmdNetworkCreate, opts_network_create, info_network_create},
     {"net-define", cmdNetworkDefine, opts_network_define, info_network_define},
     {"net-destroy", cmdNetworkDestroy, opts_network_destroy, info_network_destroy},
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    20 Feb '07
                    
                        Add qemudAutostartConfigs() to autostart guests and
networks.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1705,6 +1705,37 @@ int qemudScanConfigDir(struct qemud_serv
     return 0;
 }
 
+static
+void qemudAutostartConfigs(struct qemud_server *server) {
+    struct qemud_network *network;
+    struct qemud_vm *vm;
+
+    network = server->networks;
+    while (network != NULL) {
+        struct qemud_network *next = network->next;
+        if (network->autostart &&
+            !network->active &&
+            qemudNetworkStart(server, network) < 0)
+            qemudLog(QEMUD_ERR, "Failed to autostart network '%s'",
+                     network->def->name);
+
+        network = next;
+    }
+
+    vm = server->vms;
+    while (vm != NULL) {
+        struct qemud_vm *next = vm->next;
+
+        if (vm->autostart &&
+            !vm->active &&
+            qemudDomainStart(server, vm) < 0)
+            qemudLog(QEMUD_ERR, "Failed to autostart VM '%s'",
+                     vm->def->name);
+
+        vm = next;
+    }
+}
+
 /* Scan for all guest and network config files */
 int qemudScanConfigs(struct qemud_server *server) {
     int i;
@@ -1721,6 +1752,8 @@ int qemudScanConfigs(struct qemud_server
             return -1;
     }
 
+    qemudAutostartConfigs(server);
+
     return 0;
 }
 
-- 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0