[Libvirt-cim] [PATCH 2 of 2] Add boot order support

Richard Maciel rmaciel at linux.vnet.ibm.com
Wed May 13 18:45:37 UTC 2009


# HG changeset patch
# User Richard Maciel <rmaciel at linux.vnet.ibm.com>
# Date 1242237321 10800
# Node ID e3ea69df8ae9fa611605843b471894c2baaa8bc0
# Parent  c0bd6c9a2c0084398784bb1ae36649bd3400e36c
Add boot order support

Signed-off-by: Richard Maciel <rmaciel at linux.vnet.ibm.com>

diff -r c0bd6c9a2c00 -r e3ea69df8ae9 libxkutil/device_parsing.c
--- a/libxkutil/device_parsing.c	Mon May 11 16:47:15 2009 -0300
+++ b/libxkutil/device_parsing.c	Wed May 13 14:55:21 2009 -0300
@@ -810,6 +810,8 @@
 static int parse_os(struct domain *dominfo, xmlNode *os)
 {
         xmlNode *child;
+        char **blist = NULL;
+        unsigned bl_size = 0;
 
         for (child = os->children; child != NULL; child = child->next) {
                 if (XSTREQ(child->name, "type"))
@@ -822,10 +824,23 @@
                         STRPROP(dominfo, os_info.pv.cmdline, child);
                 else if (XSTREQ(child->name, "loader"))
                         STRPROP(dominfo, os_info.fv.loader, child);
-                else if (XSTREQ(child->name, "boot"))
-                        dominfo->os_info.fv.boot = get_attr_value(child,
-                                                                     "dev");
-                else if (XSTREQ(child->name, "init"))
+                else if (XSTREQ(child->name, "boot")) {
+                        char **tmp_list = NULL;
+
+                        tmp_list = (char **)realloc(blist, 
+                                                    (bl_size+1) * 
+                                                    sizeof(char *));
+                        if (tmp_list == NULL) {
+                                // Nothing you can do. Just go on.
+                                CU_DEBUG("Could not alloc space for "
+                                         "boot device");
+                                continue;  
+                        }
+                        blist = tmp_list;
+                        
+                        blist[bl_size] = get_attr_value(child, "dev");
+                        bl_size++;
+                } else if (XSTREQ(child->name, "init"))
                         STRPROP(dominfo, os_info.lxc.init, child);
         }
 
@@ -843,6 +858,9 @@
         else
                 dominfo->type = -1;
 
+        dominfo->os_info.fv.bootlist = blist;
+        dominfo->os_info.fv.bootlist_ct = bl_size;
+
         return 1;
 }
 
@@ -1001,9 +1019,15 @@
                 free(dom->os_info.pv.cmdline);
         } else if ((dom->type == DOMAIN_XENFV) ||
                    (dom->type == DOMAIN_KVM) || (dom->type == DOMAIN_QEMU)) {
+                int i;
+
                 free(dom->os_info.fv.type);
                 free(dom->os_info.fv.loader);
-                free(dom->os_info.fv.boot);
+                
+                for (i = 0; i < dom->os_info.fv.bootlist_ct; i++) {
+                        free(dom->os_info.fv.bootlist[i]);
+                } 
+                free(dom->os_info.fv.bootlist);
         } else if (dom->type == DOMAIN_LXC) {
                 free(dom->os_info.lxc.type);
                 free(dom->os_info.lxc.init);
diff -r c0bd6c9a2c00 -r e3ea69df8ae9 libxkutil/device_parsing.h
--- a/libxkutil/device_parsing.h	Mon May 11 16:47:15 2009 -0300
+++ b/libxkutil/device_parsing.h	Wed May 13 14:55:21 2009 -0300
@@ -99,7 +99,8 @@
 struct fv_os_info {
         char *type; /* Should always be 'hvm' */
         char *loader;
-        char *boot;
+        unsigned bootlist_ct;
+        char **bootlist;
 };
 
 struct lxc_os_info {
diff -r c0bd6c9a2c00 -r e3ea69df8ae9 libxkutil/xml_parse_test.c
--- a/libxkutil/xml_parse_test.c	Mon May 11 16:47:15 2009 -0300
+++ b/libxkutil/xml_parse_test.c	Wed May 13 14:55:21 2009 -0300
@@ -28,6 +28,7 @@
 static void print_os(struct domain *dom,
                      FILE *d)
 {
+        int i;
 
         if (dom->type == DOMAIN_XENPV) {
                 print_value(d, "Domain Type", "Xen PV");
@@ -39,13 +40,18 @@
                 print_value(d, "Domain Type", "Xen FV");
                 print_value(d, "Type", dom->os_info.fv.type);
                 print_value(d, "Loader", dom->os_info.fv.loader);
-                print_value(d, "Boot", dom->os_info.fv.boot);
 
+                for (i = 0; i < dom->os_info.fv.bootlist_size; i++) {
+                        print_value(d, "Boot", dom->os_info.fv.bootlist[i]);
+                }
         } else if ((dom->type == DOMAIN_KVM) || (dom->type == DOMAIN_QEMU)) {
                 print_value(d, "Domain Type", "KVM/QEMU");
                 print_value(d, "Type", dom->os_info.fv.type);
                 print_value(d, "Loader", dom->os_info.fv.loader);
-                print_value(d, "Boot", dom->os_info.fv.boot);
+
+                for (i = 0; i < dom->os_info.fv.bootlist_size; i++) {
+                        print_value(d, "Boot", dom->os_info.fv.bootlist[i]);
+                }
         } else if (dom->type == DOMAIN_LXC) {
                 print_value(d, "Init", dom->os_info.lxc.init);
         } else {
diff -r c0bd6c9a2c00 -r e3ea69df8ae9 libxkutil/xmlgen.c
--- a/libxkutil/xmlgen.c	Mon May 11 16:47:15 2009 -0300
+++ b/libxkutil/xmlgen.c	Wed May 13 14:55:21 2009 -0300
@@ -439,6 +439,7 @@
 {
         struct fv_os_info *os = &domain->os_info.fv;
         xmlNodePtr tmp;
+        unsigned i;
 
         if (os->type == NULL)
                 os->type = strdup("hvm");
@@ -446,8 +447,11 @@
         if (os->loader == NULL)
                 os->loader = strdup("/usr/lib/xen/boot/hvmloader");
 
-        if (os->boot == NULL)
-                os->boot = strdup("hd");
+        if (os->bootlist_ct == 0) {
+                os->bootlist_ct = 1;
+                os->bootlist = (char **)calloc(1, sizeof(char *));
+                os->bootlist[0] = strdup("hd");
+        }
 
         tmp = xmlNewChild(root, NULL, BAD_CAST "type", BAD_CAST os->type);
         if (tmp == NULL)
@@ -457,11 +461,13 @@
         if (tmp == NULL)
                 return XML_ERROR;
 
-        tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL);
-        if (tmp == NULL)
-                return XML_ERROR;
+        for (i = 0; i < os->bootlist_ct; i++) {
+                tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL);
+                if (tmp == NULL)
+                        return XML_ERROR;
 
-        xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST os->boot);
+                xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST os->bootlist[i]);
+        }
 
         tmp = xmlNewChild(root, NULL, BAD_CAST "features", NULL);
         xmlNewChild(tmp, NULL, BAD_CAST "pae", NULL);
@@ -475,21 +481,28 @@
 {
         struct fv_os_info *os = &domain->os_info.fv;
         xmlNodePtr tmp;
+        unsigned i;
 
         if (os->type == NULL)
                 os->type = strdup("hvm");
 
-        if (os->boot == NULL)
-                os->boot = strdup("hd");
+        if (os->bootlist_ct == 0) {
+                os->bootlist_ct = 1;
+                os->bootlist = (char **)calloc(1, sizeof(char *));
+                os->bootlist[0] = strdup("hd");
+        }
 
         tmp = xmlNewChild(root, NULL, BAD_CAST "type", BAD_CAST os->type);
         if (tmp == NULL)
                 return XML_ERROR;
 
-        tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL);
-        if (tmp == NULL)
-                return XML_ERROR;
-        xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST os->boot);
+        for (i = 0; i < os->bootlist_ct; i++) {
+                tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL);
+                if (tmp == NULL)
+                        return XML_ERROR;
+
+                xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST os->bootlist[i]);
+        }
 
         return NULL;
 }
diff -r c0bd6c9a2c00 -r e3ea69df8ae9 schema/VSSD.mof
--- a/schema/VSSD.mof	Mon May 11 16:47:15 2009 -0300
+++ b/schema/VSSD.mof	Wed May 13 14:55:21 2009 -0300
@@ -27,7 +27,7 @@
 
   [Description ("The device to boot from when in fully-virtualized mode."
                 "One of hd,fd,cdrom.")]
-  string BootDevice;
+  string BootDevices[];
 
   [Description ("The emulator the guest should use during runtime.")]
   string Emulator;
@@ -42,8 +42,8 @@
 class KVM_VirtualSystemSettingData : Virt_VirtualSystemSettingData
 {
 
-  [Description ("The device to boot from.  One of hd,fd,cdrom.")]
-  string BootDevice;
+  [Description ("The list of devices to boot from. hd,fd,cdrom.")]
+  string BootDevices[];
 
   [Description ("The emulator the guest should use during runtime.")]
   string Emulator;
diff -r c0bd6c9a2c00 -r e3ea69df8ae9 src/Virt_VSSD.c
--- a/src/Virt_VSSD.c	Mon May 11 16:47:15 2009 -0300
+++ b/src/Virt_VSSD.c	Wed May 13 14:55:21 2009 -0300
@@ -42,16 +42,58 @@
                          CMPIInstance *inst)
 {
         bool fv = true;
+        CMPIArray *array;
 
         if (dominfo->type == DOMAIN_XENFV)
                 CMSetProperty(inst, "IsFullVirt",
                               (CMPIValue *)&fv, CMPI_boolean);
 
-        if (dominfo->os_info.fv.boot != NULL)
-                CMSetProperty(inst,
-                              "BootDevice",
-                              (CMPIValue *)dominfo->os_info.fv.boot,
-                              CMPI_chars);
+        if (dominfo->os_info.fv.bootlist_ct > 0) {
+                CMPICount i;
+                CMPICount bl_size;
+                CMPIStatus s;
+
+                bl_size = (CMPICount)dominfo->os_info.fv.bootlist_ct;
+
+                array = CMNewArray(_BROKER, 
+                                   bl_size,
+                                   CMPI_string,
+                                   &s);
+
+                if (s.rc != CMPI_RC_OK) {
+                        CU_DEBUG("Error creating BootDevice list");
+                        return;
+                }
+
+                for (i = 0; i < bl_size; i++) {
+                        CMPIString *cm_str;
+
+                        cm_str = CMNewString(_BROKER,
+                                             (const char *)dominfo->os_info.fv.bootlist[i],
+                                             &s);
+                        if (s.rc != CMPI_RC_OK) {
+                                CU_DEBUG("Error adding item to BootDevice " 
+                                         "list");
+                                continue;
+                        }
+
+                        s = CMSetArrayElementAt(array,
+                                                i,
+                                                cm_str,
+                                                CMPI_string);
+                        if (s.rc != CMPI_RC_OK)
+                                CU_DEBUG("Error setting BootDevice array "
+                                         "element");
+                }
+
+                s = CMSetProperty(inst,
+                                  "BootDevices",
+                                  (CMPIValue *)array,
+                                  CMPI_stringA);
+
+                if (s.rc != CMPI_RC_OK)
+                        CU_DEBUG("Error setting BootDevices property");
+        }
 }
 
 static void _set_pv_prop(struct domain *dominfo,
diff -r c0bd6c9a2c00 -r e3ea69df8ae9 src/Virt_VirtualSystemManagementService.c
--- a/src/Virt_VirtualSystemManagementService.c	Mon May 11 16:47:15 2009 -0300
+++ b/src/Virt_VirtualSystemManagementService.c	Wed May 13 14:55:21 2009 -0300
@@ -202,7 +202,13 @@
                              const char *pfx)
 {
         int ret;
+        CMPICount i;
         const char *val;
+        CMPIArray *bootlist;
+        CMPIStatus s;
+        CMPIData boot_elem;
+        char **tmp_str_arr;
+
 
         if (STREQC(pfx, "KVM")) {
                 if (system_has_kvm(pfx))
@@ -216,12 +222,69 @@
                 return 0;
         }
 
-        ret = cu_get_str_prop(inst, "BootDevice", &val);
-        if (ret != CMPI_RC_OK)
-                val = "hd";
+        for (i = 0; i < domain->os_info.fv.bootlist_ct; i++)
+                free(domain->os_info.fv.bootlist[i]);
 
-        free(domain->os_info.fv.boot);
-        domain->os_info.fv.boot = strdup(val);
+        ret = cu_get_array_prop(inst, "BootDevices", &bootlist);
+       
+        if (ret == CMPI_RC_OK) {
+                CMPICount bl_size;
+
+                bl_size = CMGetArrayCount(bootlist, &s);
+                if (s.rc != CMPI_RC_OK) {
+                        CU_DEBUG("Invalid BootDevice array size");
+                        return 0;
+                }
+
+                tmp_str_arr = (char **)realloc(domain->os_info.fv.bootlist,
+                                               bl_size * sizeof(char *));
+
+                if (tmp_str_arr == NULL) {
+                        CU_DEBUG("Could not alloc BootDevices array");
+                        return 0;
+                }
+
+                for (i = 0; i < bl_size; i++) {
+                        const char *str;
+
+                        boot_elem = CMGetArrayElementAt(bootlist, 
+                                                        i, 
+                                                        NULL); 
+
+                        if (CMIsNullValue(boot_elem)) {
+                                CU_DEBUG("Null BootDevice");
+                                return 0;
+                        }
+
+                        free(domain->os_info.fv.bootlist[i]);
+                        CU_DEBUG("Freed item from bootlist");
+
+                        str = CMGetCharPtr(boot_elem.value.string);
+
+                        if (s.rc != CMPI_RC_OK) {
+                                CU_DEBUG("Could not extract char pointer from "
+                                         "CMPIArray");
+                        }
+
+                        tmp_str_arr[i] = strdup(str);
+                }
+                domain->os_info.fv.bootlist_ct = bl_size;
+                domain->os_info.fv.bootlist = tmp_str_arr;
+
+        } else {
+                
+                CU_DEBUG("Failed to get BootDevices property");
+
+                tmp_str_arr = (char **)realloc(domain->os_info.fv.bootlist,
+                                               sizeof(char *));
+                if (tmp_str_arr == NULL)
+                        return 0;
+
+                tmp_str_arr[0] = strdup("hd");
+
+                domain->os_info.fv.bootlist = tmp_str_arr;
+                domain->os_info.fv.bootlist_ct = 1;
+        }
 
         ret = cu_get_str_prop(inst, "Emulator", &val);
         if (ret != CMPI_RC_OK)




More information about the Libvirt-cim mailing list