[PATCH 0 of 3] (#2) Add support for booting on multiple devices and for boot order

# HG changeset patch # User Richard Maciel <rmaciel@linux.vnet.ibm.com> # Date 1243891178 10800 # Node ID e18c6d4d2ea45d71dc04294364296ac25754bfcf # Parent 849171d2fbc0adbba613516bbdea4b78199178dd Added support to convert data in the internal format to the format used by the BootDevices property #2: - Code style changes - Added cu_statusf() calls to provide specific error messages to the user Signed-off-by: Richard Maciel <rmaciel@linux.vnet.ibm.com> diff -r 849171d2fbc0 -r e18c6d4d2ea4 schema/VSSD.mof --- a/schema/VSSD.mof Mon Jun 01 14:01:21 2009 -0700 +++ b/schema/VSSD.mof Mon Jun 01 18:19:38 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 849171d2fbc0 -r e18c6d4d2ea4 src/Virt_VSSD.c --- a/src/Virt_VSSD.c Mon Jun 01 14:01:21 2009 -0700 +++ b/src/Virt_VSSD.c Mon Jun 01 18:19:38 2009 -0300 @@ -38,20 +38,91 @@ const static CMPIBroker *_BROKER; -static void _set_fv_prop(struct domain *dominfo, - CMPIInstance *inst) +static CMPIStatus _set_fv_prop(const CMPIBroker *broker, + struct domain *dominfo, + CMPIInstance *inst) { bool fv = true; + CMPIArray *array; + CMPICount bl_ct; + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPICount i; 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); + bl_ct = dominfo->os_info.fv.bootlist_ct; + if (bl_ct < 0) + return s; + + CU_DEBUG("bootlist_ct = %d", bl_ct); + + array = CMNewArray(broker, + bl_ct, + CMPI_string, + &s); + + if (s.rc != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Error creating BootDevices list"); + CU_DEBUG("CMNewArray call failed"); + + goto out; + } + + for (i = 0; i < bl_ct; i++) { + CMPIString *cm_str; + + CU_DEBUG("BootList[%u]=%s", + i, + dominfo->os_info.fv.bootlist[i]); + + cm_str = CMNewString(broker, + (const char *)dominfo->os_info. + fv.bootlist[i], + &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error creating CMPIString"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Error creating CMPIString for " + "BootDevices item"); + + goto out; + } + + s = CMSetArrayElementAt(array, + i, + (CMPIValue *)&cm_str, + CMPI_string); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error in CMSetArrayElementAT call"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Error setting BootDevices array element"); + + goto out; + } + } + + s = CMSetProperty(inst, + "BootDevices", + (CMPIValue *)&array, + CMPI_stringA); + + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error in CMSetProperty call"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Error setting BootDevices property"); + + goto out; + } + + out: + return s; } static void _set_pv_prop(struct domain *dominfo, @@ -98,12 +169,14 @@ CMPI_chars); } -static int instance_from_dom(virDomainPtr dom, +static int instance_from_dom(const CMPIBroker *broker, + virDomainPtr dom, CMPIInstance *inst) { char *pfx = NULL; char *vsid = NULL; int ret = 1; + CMPIStatus s = {CMPI_RC_OK, NULL}; CMPIObjectPath *op; struct domain *dominfo = NULL; @@ -158,7 +231,12 @@ if ((dominfo->type == DOMAIN_XENFV) || (dominfo->type == DOMAIN_KVM) || (dominfo->type == DOMAIN_QEMU)) - _set_fv_prop(dominfo, inst); + s = _set_fv_prop(broker, dominfo, inst); + if (s.rc != CMPI_RC_OK) { + ret = 0; + goto out; + } + else if (dominfo->type == DOMAIN_XENPV) _set_pv_prop(dominfo, inst); else if (dominfo->type == DOMAIN_LXC) @@ -203,7 +281,7 @@ goto out; } - if (instance_from_dom(dom, inst) != 1) { + if (instance_from_dom(broker, dom, inst) != 1) { cu_statusf(broker, s, CMPI_RC_ERR_FAILED, "Unable to get VSSD instance from Domain");

diff -r 849171d2fbc0 -r e18c6d4d2ea4 src/Virt_VSSD.c --- a/src/Virt_VSSD.c Mon Jun 01 14:01:21 2009 -0700 +++ b/src/Virt_VSSD.c Mon Jun 01 18:19:38 2009 -0300 @@ -38,20 +38,91 @@
const static CMPIBroker *_BROKER;
-static void _set_fv_prop(struct domain *dominfo, - CMPIInstance *inst) +static CMPIStatus _set_fv_prop(const CMPIBroker *broker, + struct domain *dominfo, + CMPIInstance *inst) { bool fv = true; + CMPIArray *array; + CMPICount bl_ct; + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPICount i;
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); + bl_ct = dominfo->os_info.fv.bootlist_ct; + if (bl_ct < 0) + return s; + + CU_DEBUG("bootlist_ct = %d", bl_ct); + + array = CMNewArray(broker, + bl_ct, + CMPI_string, + &s); + + if (s.rc != CMPI_RC_OK) { + cu_statusf(_BROKER, &s,
This should be the broker that is passed in to the function, instead of using the provider's _BROKER.
+ CMPI_RC_ERR_FAILED, + "Error creating BootDevices list"); + CU_DEBUG("CMNewArray call failed"); + + goto out; + } + + for (i = 0; i < bl_ct; i++) { + CMPIString *cm_str; + + CU_DEBUG("BootList[%u]=%s", + i, + dominfo->os_info.fv.bootlist[i]); + + cm_str = CMNewString(broker, + (const char *)dominfo->os_info. + fv.bootlist[i], + &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error creating CMPIString"); + cu_statusf(_BROKER, &s,
Same here.
+ CMPI_RC_ERR_FAILED, + "Error creating CMPIString for " + "BootDevices item"); + + goto out; + } + + s = CMSetArrayElementAt(array, + i, + (CMPIValue *)&cm_str, + CMPI_string); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error in CMSetArrayElementAT call"); + cu_statusf(_BROKER, &s,
Here as well.
+ CMPI_RC_ERR_FAILED, + "Error setting BootDevices array element"); + + goto out; + } + } + + s = CMSetProperty(inst, + "BootDevices", + (CMPIValue *)&array, + CMPI_stringA); + + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error in CMSetProperty call"); + cu_statusf(_BROKER, &s,
And here.
+ CMPI_RC_ERR_FAILED, + "Error setting BootDevices property"); + + goto out; + } + + out: + return s; }
-- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com

# HG changeset patch # User Richard Maciel <rmaciel@linux.vnet.ibm.com> # Date 1243891183 10800 # Node ID 670cdd8696c7247e5e8a66637fcd1ff71543cdf1 # Parent e18c6d4d2ea45d71dc04294364296ac25754bfcf Add support to fetch data from BootDevices property to the internal data structure #2: - Code style changes Signed-off-by: Richard Maciel <rmaciel@linux.vnet.ibm.com> diff -r e18c6d4d2ea4 -r 670cdd8696c7 src/Virt_VirtualSystemManagementService.c --- a/src/Virt_VirtualSystemManagementService.c Mon Jun 01 18:19:38 2009 -0300 +++ b/src/Virt_VirtualSystemManagementService.c Mon Jun 01 18:19:43 2009 -0300 @@ -197,6 +197,68 @@ return kvm; } +static int bootord_vssd_to_domain(CMPIInstance *inst, + struct domain *domain) +{ + int ret; + CMPICount i; + CMPICount bl_size; + CMPIArray *bootlist; + CMPIStatus s; + CMPIData boot_elem; + char **tmp_str_arr; + + for (i = 0; i < domain->os_info.fv.bootlist_ct; i++) + free(domain->os_info.fv.bootlist[i]); + + ret = cu_get_array_prop(inst, "BootDevices", &bootlist); + + if (ret != CMPI_RC_OK) + CU_DEBUG("Failed to get BootDevices property"); + + + 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; + } + + str = CMGetCharPtr(boot_elem.value.string); + + if (str == NULL) { + CU_DEBUG("Could not extract char pointer from " + "CMPIArray"); + return 0; + } + + tmp_str_arr[i] = strdup(str); + } + domain->os_info.fv.bootlist_ct = bl_size; + domain->os_info.fv.bootlist = tmp_str_arr; + + return 1; +} + static int fv_vssd_to_domain(CMPIInstance *inst, struct domain *domain, const char *pfx) @@ -216,12 +278,9 @@ return 0; } - ret = cu_get_str_prop(inst, "BootDevice", &val); - if (ret != CMPI_RC_OK) - val = "hd"; - - free(domain->os_info.fv.boot); - domain->os_info.fv.boot = strdup(val); + ret = bootord_vssd_to_domain(inst, domain); + if (ret != 1) + return 0; ret = cu_get_str_prop(inst, "Emulator", &val); if (ret != CMPI_RC_OK)

# HG changeset patch # User Richard Maciel <rmaciel@linux.vnet.ibm.com> # Date 1243891182 10800 # Node ID 19fa326e07bcb6cb8094be88929f5f613ada1ae4 # Parent 670cdd8696c7247e5e8a66637fcd1ff71543cdf1 XML generation and parsing for the BootDevices property #2: - Code style changes Signed-off-by: Richard Maciel <rmaciel@linux.vnet.ibm.com> diff -r 670cdd8696c7 -r 19fa326e07bc libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Mon Jun 01 18:19:43 2009 -0300 +++ b/libxkutil/device_parsing.c Mon Jun 01 18:19:42 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 670cdd8696c7 -r 19fa326e07bc libxkutil/device_parsing.h --- a/libxkutil/device_parsing.h Mon Jun 01 18:19:43 2009 -0300 +++ b/libxkutil/device_parsing.h Mon Jun 01 18:19:42 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 670cdd8696c7 -r 19fa326e07bc libxkutil/xml_parse_test.c --- a/libxkutil/xml_parse_test.c Mon Jun 01 18:19:43 2009 -0300 +++ b/libxkutil/xml_parse_test.c Mon Jun 01 18:19:42 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_ct; 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_ct; 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 670cdd8696c7 -r 19fa326e07bc libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Mon Jun 01 18:19:43 2009 -0300 +++ b/libxkutil/xmlgen.c Mon Jun 01 18:19:42 2009 -0300 @@ -435,10 +435,27 @@ return NULL; } +static int _fv_bootlist_xml(xmlNodePtr root, struct fv_os_info *os) +{ + unsigned i; + xmlNodePtr tmp; + + for (i = 0; i < os->bootlist_ct; i++) { + tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL); + if (tmp == NULL) + return 0; + + xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST os->bootlist[i]); + } + + return 1; +} + static char *_xenfv_os_xml(xmlNodePtr root, struct domain *domain) { struct fv_os_info *os = &domain->os_info.fv; xmlNodePtr tmp; + unsigned ret; if (os->type == NULL) os->type = strdup("hvm"); @@ -446,8 +463,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 +477,17 @@ if (tmp == NULL) return XML_ERROR; - tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL); - if (tmp == NULL) + ret = _fv_bootlist_xml(root, os); + if (ret == 0) 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]); + }*/ tmp = xmlNewChild(root, NULL, BAD_CAST "features", NULL); xmlNewChild(tmp, NULL, BAD_CAST "pae", NULL); @@ -475,21 +501,32 @@ { struct fv_os_info *os = &domain->os_info.fv; xmlNodePtr tmp; + unsigned ret; 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; + + ret = _fv_bootlist_xml(root, os); + if (ret == 0) + 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; }
participants (2)
-
Kaitlin Rupert
-
Richard Maciel