[PATCH 0 of 6] (#3) VSMS support for KVM/XenFV

Changes from last time: - Changed isFullVirt to IsFullVirt - Added VSSD changes so the new fields are exposed

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200587101 28800 # Node ID 65402823a5f10e571e7ed2c61694f1743525006f # Parent 05fa2ceba145e9e93066bd66c74299680bd7d21d Update VSSD schemas for FullVirt This adds a flag to the Xen VSSD to enable full-virt or not, as well as the required boot device information. In the implementation, a "false" or missing value for the flag will indicate paravirt-ness. For KVM, I added the boot device as well, since that's something it will always need. For both, a missing boot device will imply "hd". Changes: - Fixed capitalization of IsFullVirt Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 05fa2ceba145 -r 65402823a5f1 schema/VSSD.mof --- a/schema/VSSD.mof Tue Jan 15 16:24:39 2008 -0800 +++ b/schema/VSSD.mof Thu Jan 17 08:25:01 2008 -0800 @@ -8,8 +8,17 @@ class Xen_VirtualSystemSettingData : CIM class Xen_VirtualSystemSettingData : CIM_VirtualSystemSettingData { + [Description ("Flag to determine whether this guest is fully-virtualized")] + boolean IsFullVirt; + + [Description ("The bootloader and arguments to use when in " + "para-virtualized mode")] string Bootloader; string BootloaderArgs; + + [Description ("The device to boot from when in fully-virtualized mode." + "One of hd,fd,cdrom.")] + string BootDevice; }; @@ -20,4 +29,8 @@ class Xen_VirtualSystemSettingData : CIM ] class KVM_VirtualSystemSettingData : CIM_VirtualSystemSettingData { + + [Description ("The device to boot from. One of hd,fd,cdrom.")] + string BootDevice; + };

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200587110 28800 # Node ID 2602553d1f9ac0bd6fc6ad41b54a466053f03c5d # Parent 65402823a5f10e571e7ed2c61694f1743525006f Fix xmlgen to include boot parameter for KVM Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 65402823a5f1 -r 2602553d1f9a libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Thu Jan 17 08:25:01 2008 -0800 +++ b/libxkutil/xmlgen.c Thu Jan 17 08:25:10 2008 -0800 @@ -462,21 +462,32 @@ static char *_kvm_os_xml(struct domain * int ret; char *xml; char *type; + char *boot; + struct kv bootattr = {"dev", NULL}; if (os->type == NULL) os->type = strdup("hvm"); + if (os->boot == NULL) + os->boot = strdup("hd"); + type = tagify("type", os->type, NULL, 0); + bootattr.val = os->boot; + boot = tagify("boot", NULL, &bootattr, 1); + ret = asprintf(&xml, "<os>\n" " %s\n" + " %s\n" "</os>\n", - type); + type, + boot); if (ret == -1) xml = NULL; free(type); + free(boot); return xml; }

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200587110 28800 # Node ID a1fe7e8ff84c4e27245beb259e64de71e6dca740 # Parent 2602553d1f9ac0bd6fc6ad41b54a466053f03c5d Add network interface parsing for KVM domains Changes: - Fixed printf() debugs - Changed the source/type validation to better catch unsupported configs. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 2602553d1f9a -r a1fe7e8ff84c libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Thu Jan 17 08:25:10 2008 -0800 +++ b/libxkutil/device_parsing.c Thu Jan 17 08:25:10 2008 -0800 @@ -44,6 +44,7 @@ #define GRAPHICS_XPATH (xmlChar *)"/domain/devices/graphics" #define DEFAULT_BRIDGE "xenbr0" +#define DEFAULT_NETWORK "default" #define XSTREQ(x, y) (STREQ((char *)x, y)) #define MAX(a,b) (((a)>(b))?(a):(b)) @@ -61,7 +62,7 @@ static void cleanup_net_device(struct ne { free(dev->type); free(dev->mac); - free(dev->bridge); + free(dev->source); } static void cleanup_emu_device(struct emu_device *dev) @@ -216,18 +217,35 @@ static int parse_net_device(xmlNode *ino if (ndev->mac == NULL) goto err; } else if (XSTREQ(child->name, "source")) { - ndev->bridge = get_attr_value(child, "bridge"); - if (ndev->bridge == NULL) - goto err; + ndev->source = get_attr_value(child, "bridge"); + if (ndev->source != NULL) + continue; + ndev->source = get_attr_value(child, "network"); + if (ndev->source != NULL) + continue; + goto err; } } if (ndev->mac == NULL) goto err; - if (ndev->bridge == NULL) { - ndev->bridge = strdup(DEFAULT_BRIDGE); - printf("No bridge, taking default of `%s'\n", ndev->bridge); + if (ndev->source == NULL) { + if (STREQC(ndev->type, "bridge")) { + ndev->source = strdup(DEFAULT_BRIDGE); + CU_DEBUG("No bridge, taking default of `%s'\n", + ndev->source); + } else if (STREQC(ndev->type, "network")) { + ndev->source = strdup(DEFAULT_NETWORK); + CU_DEBUG("No network, taking default of `%s'\n", + ndev->source); + } else { + /* This likely indicates an unsupported + * network configuration + */ + CU_DEBUG("No network source, and no known default"); + goto err; + } } vdev->type = VIRT_DEV_NET; @@ -517,7 +535,7 @@ struct virt_device *virt_device_dup(stru if (dev->type == VIRT_DEV_NET) { DUP_FIELD(dev, _dev, dev.net.mac); DUP_FIELD(dev, _dev, dev.net.type); - DUP_FIELD(dev, _dev, dev.net.bridge); + DUP_FIELD(dev, _dev, dev.net.source); } else if (dev->type == VIRT_DEV_DISK) { DUP_FIELD(dev, _dev, dev.disk.type); DUP_FIELD(dev, _dev, dev.disk.device); diff -r 2602553d1f9a -r a1fe7e8ff84c libxkutil/device_parsing.h --- a/libxkutil/device_parsing.h Thu Jan 17 08:25:10 2008 -0800 +++ b/libxkutil/device_parsing.h Thu Jan 17 08:25:10 2008 -0800 @@ -41,7 +41,7 @@ struct net_device { struct net_device { char *type; char *mac; - char *bridge; + char *source; }; struct mem_device { diff -r 2602553d1f9a -r a1fe7e8ff84c src/Virt_DevicePool.c --- a/src/Virt_DevicePool.c Thu Jan 17 08:25:10 2008 -0800 +++ b/src/Virt_DevicePool.c Thu Jan 17 08:25:10 2008 -0800 @@ -295,7 +295,7 @@ static char *netpool_member_of(const CMP for (i = 0; i < count; i++) { if (STREQ((devs[i].id), dev)) { result = _netpool_member_of(conn, - devs[i].dev.net.bridge); + devs[i].dev.net.source); break; } }

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200587110 28800 # Node ID e5053e45e1a4a799b0c07a96730fec7783e0b776 # Parent a1fe7e8ff84c4e27245beb259e64de71e6dca740 Fix KVM network xml to use virtual network type ...and default the network name for now. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r a1fe7e8ff84c -r e5053e45e1a4 libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Thu Jan 17 08:25:10 2008 -0800 +++ b/libxkutil/xmlgen.c Thu Jan 17 08:25:10 2008 -0800 @@ -169,7 +169,7 @@ static bool disk_to_xml(char **xml, stru return true; } -static bool net_to_xml(char **xml, struct virt_device *dev) +static bool xen_net_to_xml(char **xml, struct virt_device *dev) { int ret; char *_xml; @@ -193,6 +193,43 @@ static bool net_to_xml(char **xml, struc free(_xml); return true; +} + +static bool kvm_net_to_xml(char **xml, struct virt_device *dev) +{ + int ret; + char *_xml; + struct net_device *net = &dev->dev.net; + + if (net->source == NULL) + net->source = strdup("default"); + + ret = asprintf(&_xml, + "<interface type='%s'>\n" + " <mac address='%s'/>\n" + " <source network='%s'/>\n" + "</interface>\n", + net->type, + net->mac, + net->source); + if (ret == -1) + return false; + else + astrcat(xml, _xml); + + free(_xml); + + return true; +} + +static bool net_to_xml(char **xml, struct virt_device *dev) +{ + if (STREQ(dev->dev.net.type, "network")) + return kvm_net_to_xml(xml, dev); + else if (STREQ(dev->dev.net.type, "bridge")) + return xen_net_to_xml(xml, dev); + else + return false; } static bool vcpu_to_xml(char **xml, struct virt_device *dev)

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200588333 28800 # Node ID 019c2959e758e9bbc71a3d7e489f16100857fc68 # Parent e5053e45e1a4a799b0c07a96730fec7783e0b776 Changes to VSSD for fullvirt schema additions Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r e5053e45e1a4 -r 019c2959e758 src/Virt_VSSD.c --- a/src/Virt_VSSD.c Thu Jan 17 08:25:10 2008 -0800 +++ b/src/Virt_VSSD.c Thu Jan 17 08:45:33 2008 -0800 @@ -38,6 +38,41 @@ const static CMPIBroker *_BROKER; +static void _set_fv_prop(struct domain *dominfo, + CMPIInstance *inst) +{ + bool fv = true; + + 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); +} + +static void _set_pv_prop(struct domain *dominfo, + CMPIInstance *inst) +{ + bool fv = false; + + CMSetProperty(inst, "IsFullVirt", + (CMPIValue *)&fv, CMPI_boolean); + + if (dominfo->bootloader != NULL) + CMSetProperty(inst, "Bootloader", + (CMPIValue *)dominfo->bootloader, + CMPI_chars); + + if (dominfo->bootloader_args != NULL) + CMSetProperty(inst, "BootloaderArgs", + (CMPIValue *)dominfo->bootloader_args, + CMPI_chars); +} + static int instance_from_dom(virDomainPtr dom, CMPIInstance *inst) { @@ -75,15 +110,14 @@ static int instance_from_dom(virDomainPt CMSetProperty(inst, "AutomaticRecoveryAction", (CMPIValue *)&dominfo->on_crash, CMPI_uint16); - if (dominfo->bootloader) - CMSetProperty(inst, "Bootloader", - (CMPIValue *)dominfo->bootloader, - CMPI_chars); - - if (dominfo->bootloader_args) - CMSetProperty(inst, "BootloaderArgs", - (CMPIValue *)dominfo->bootloader_args, - CMPI_chars); + if ((dominfo->type == DOMAIN_XENFV) || + (dominfo->type == DOMAIN_KVM)) + _set_fv_prop(dominfo, inst); + else if (dominfo->type == DOMAIN_XENPV) + _set_pv_prop(dominfo, inst); + else + CU_DEBUG("Unknown domain type %i for creating VSSD", + dominfo->type); if (asprintf(&vsid, "%s:%s", pfx, dominfo->name) == -1) { ret = 0;

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200588333 28800 # Node ID 019c2959e758e9bbc71a3d7e489f16100857fc68 # Parent e5053e45e1a4a799b0c07a96730fec7783e0b776 Changes to VSSD for fullvirt schema additions
Signed-off-by: Dan Smith <danms@us.ibm.com>
The BootDevice property is not set on my system. But I can see the following with CU_DEBUG (the first one is my CU_DEBUG statement): device_parsing.c(672): dominfo->typestr: qemu Virt_VSSD.c(120): Unknown domain type -1 for creating VSSD device_parsing.c(841): Unknown domain type -1 I saw that DOMAIN_KVM is only set in case of typestr is "kvm". But on my system it contains "qemu". Now I'm not sure if this is a configuration problem of me or if the provider should be aware of the case where typestr is "qemu", which is then handled as KVM. device_parsing.c else if (STREQC(dominfo->typestr, "kvm")) dominfo->type = DOMAIN_KVM; Thanks ... Heidi -- Regards Heidi Eckhart Software Engineer IBM Linux Technology Center - Open Hypervisor

HE> The BootDevice property is not set on my system. But I can see the HE> following with CU_DEBUG (the first one is my CU_DEBUG statement): Okay, it is set for KVM domains on my system, but mine are type="kvm". HE> I saw that DOMAIN_KVM is only set in case of typestr is "kvm". But HE> on my system it contains "qemu". Now I'm not sure if this is a HE> configuration problem of me or if the provider should be aware of HE> the case where typestr is "qemu", which is then handled as KVM. HE> device_parsing.c Ah, interesting. The KVM xml specifies using type="kvm", but I just noticed that there is a different class of domain called "qemu". Apparently it's the same as a KVM domain, but with the ability to request a different emulation architecture. I'll add the extra bit of detection code. Thanks! -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1200588334 28800 # Node ID 2c754c60bfa8c0749571f10d2d95c273ce972a33 # Parent 019c2959e758e9bbc71a3d7e489f16100857fc68 FullVirt changes to VSMS This includes checking the isFullVirt flag in Xen VSSDs, and assuming it for KVM. Also, support creating Xen-type bridge interfaces and KVM-type virtual network interfaces. Changes: - Updated IsFullVirt property name Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 019c2959e758 -r 2c754c60bfa8 src/Virt_VirtualSystemManagementService.c --- a/src/Virt_VirtualSystemManagementService.c Thu Jan 17 08:45:33 2008 -0800 +++ b/src/Virt_VirtualSystemManagementService.c Thu Jan 17 08:45:34 2008 -0800 @@ -127,12 +127,73 @@ static CMPIStatus define_system_parse_ar return s; } +static int xenpv_vssd_to_domain(CMPIInstance *inst, + struct domain *domain) +{ + int ret; + const char *val; + + domain->type = DOMAIN_XENPV; + + ret = cu_get_str_prop(inst, "Bootloader", &val); + if (ret != CMPI_RC_OK) + val = ""; + + free(domain->bootloader); + domain->bootloader = strdup(val); + + ret = cu_get_str_prop(inst, "BootloaderArgs", &val); + if (ret != CMPI_RC_OK) + val = ""; + + free(domain->bootloader_args); + domain->bootloader_args = strdup(val); + + return 1; +} + +static int fv_vssd_to_domain(CMPIInstance *inst, + struct domain *domain, + const char *pfx) +{ + int ret; + const char *val; + + if (STREQC(pfx, "KVM")) + domain->type = DOMAIN_KVM; + else if (STREQC(pfx, "Xen")) + domain->type = DOMAIN_XENFV; + else { + CU_DEBUG("Unknown fullvirt domain type: %s", pfx); + 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); + + return 1; +} + static int vssd_to_domain(CMPIInstance *inst, struct domain *domain) { uint16_t tmp; int ret = 0; const char *val; + const char *cn; + char *pfx = NULL; + bool fullvirt; + + cn = CLASSNAME(CMGetObjectPath(inst, NULL)); + pfx = class_prefix_name(cn); + if (pfx == NULL) { + CU_DEBUG("Unknown prefix for class: %s", cn); + return 0; + } ret = cu_get_str_prop(inst, "VirtualSystemIdentifier", &val); if (ret != CMPI_RC_OK) @@ -153,23 +214,41 @@ static int vssd_to_domain(CMPIInstance * domain->on_crash = (int)tmp; - ret = cu_get_str_prop(inst, "Bootloader", &val); - if (ret != CMPI_RC_OK) - val = ""; - - free(domain->bootloader); - domain->bootloader = strdup(val); - - ret = cu_get_str_prop(inst, "BootloaderArgs", &val); - if (ret != CMPI_RC_OK) - val = ""; - - free(domain->bootloader_args); - domain->bootloader_args = strdup(val); - - ret = 1; - out: + if (STREQC(pfx, "KVM")) + fullvirt = true; + else if (cu_get_bool_prop(inst, "IsFullVirt", &fullvirt) != CMPI_RC_OK) + fullvirt = false; + + if (fullvirt) + ret = fv_vssd_to_domain(inst, domain, pfx); + else + ret = xenpv_vssd_to_domain(inst, domain); + + out: + free(pfx); + return ret; +} + +static int xen_net_rasd_to_vdev(CMPIInstance *inst, + struct virt_device *dev) +{ + free(dev->dev.net.type); + dev->dev.net.type = strdup("bridge"); + + return 1; +} + +static int kvm_net_rasd_to_vdev(CMPIInstance *inst, + struct virt_device *dev) +{ + free(dev->dev.net.type); + dev->dev.net.type = strdup("network"); + + free(dev->dev.net.source); + dev->dev.net.source = strdup("default"); + + return 1; } static int rasd_to_vdev(CMPIInstance *inst, @@ -211,11 +290,14 @@ static int rasd_to_vdev(CMPIInstance *in free(dev->dev.net.mac); dev->dev.net.mac = devid; - if (cu_get_str_prop(inst, "NetworkType", &val) != CMPI_RC_OK) - val = "bridge"; - - free(dev->dev.net.type); - dev->dev.net.type = strdup(val); + if (STARTS_WITH(CLASSNAME(op), "Xen")) + xen_net_rasd_to_vdev(inst, dev); + else if (STARTS_WITH(CLASSNAME(op), "KVM")) + kvm_net_rasd_to_vdev(inst, dev); + else + CU_DEBUG("Unknown class type for net device: %s", + CLASSNAME(op)); + } else if (type == VIRT_DEV_MEM) { cu_get_u64_prop(inst, "VirtualQuantity", &dev->dev.mem.size); cu_get_u64_prop(inst, "Reservation", &dev->dev.mem.size);

Dan Smith wrote:
Changes from last time: - Changed isFullVirt to IsFullVirt - Added VSSD changes so the new fields are exposed
No complaints from me. Although.. I didn't have any complaints on the second set either. ;) -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com
participants (3)
-
Dan Smith
-
Heidi Eckhart
-
Kaitlin Rupert