[PATCH 0 of 5] VSMS Dynamic Devices

This set adds dynamic attach/detach support to device_parsing, as well as some other tweaks necessary for the changes to VSMS to work. This makes VSMS dynamically attach/detach devices if the domain is running. Currently this only works for Network and Disk devices, but adding processor and memory support in the attach functions should be easy.

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1194454604 28800 # Node ID b9eaad2ace9b71f7c6cb9feb3b6ea630050e3e0f # Parent 2626820d78b2d70564096dcacf6a2f1b2bc726e1 Add device attach/detach support to device_parsing Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 2626820d78b2 -r b9eaad2ace9b libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Wed Nov 07 08:52:51 2007 -0800 +++ b/libxkutil/device_parsing.c Wed Nov 07 08:56:44 2007 -0800 @@ -31,6 +31,7 @@ #include <libcmpiutil.h> #include "device_parsing.h" +#include "xmlgen.h" #include "../src/svpc_types.h" #define DISK_XPATH (xmlChar *)"/domain/devices/disk" @@ -614,6 +615,60 @@ void cleanup_dominfo(struct domain **dom *dominfo = NULL; } +static int change_device(virDomainPtr dom, + struct virt_device *dev, + bool attach) +{ + char *xml = NULL; + int ret = 0; + int (*func)(virDomainPtr, char *); + + if (attach) + func = virDomainAttachDevice; + else + func = virDomainDetachDevice; + + xml = device_to_xml(dev); + if (xml == NULL) { + CU_DEBUG("Failed to get XML for device `%s'", dev->id); + goto out; + } + + if (func(dom, xml) != 0) { + CU_DEBUG("Failed to dynamically change device:"); + CU_DEBUG("%s", xml); + goto out; + } + + ret = 1; + out: + free(xml); + + return ret; + +} + +int attach_device(virDomainPtr dom, struct virt_device *dev) +{ + if ((dev->type == VIRT_DEV_NET) || + (dev->type == VIRT_DEV_DISK)) + return change_device(dom, dev, true); + + CU_DEBUG("Unhandled device type %i", dev->type); + + return 0; +} + +int detach_device(virDomainPtr dom, struct virt_device *dev) +{ + if ((dev->type == VIRT_DEV_NET) || + (dev->type == VIRT_DEV_DISK)) + return change_device(dom, dev, false); + + CU_DEBUG("Unhandled device type %i", dev->type); + + return 0; +} /* * Local Variables: diff -r 2626820d78b2 -r b9eaad2ace9b libxkutil/device_parsing.h --- a/libxkutil/device_parsing.h Wed Nov 07 08:52:51 2007 -0800 +++ b/libxkutil/device_parsing.h Wed Nov 07 08:56:44 2007 -0800 @@ -111,6 +111,9 @@ char *get_fq_devid(char *host, char *_de char *get_fq_devid(char *host, char *_devid); int parse_fq_devid(char *devid, char **host, char **device); +int attach_device(virDomainPtr dom, struct virt_device *dev); +int detach_device(virDomainPtr dom, struct virt_device *dev); + #endif /* diff -r 2626820d78b2 -r b9eaad2ace9b libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Wed Nov 07 08:52:51 2007 -0800 +++ b/libxkutil/xmlgen.c Wed Nov 07 08:56:44 2007 -0800 @@ -192,7 +192,7 @@ static char *mem_to_xml(struct mem_devic return xml; } -static char *device_to_xml(struct virt_device *dev) +char *device_to_xml(struct virt_device *dev) { switch (dev->type) { case VIRT_DEV_NET: diff -r 2626820d78b2 -r b9eaad2ace9b libxkutil/xmlgen.h --- a/libxkutil/xmlgen.h Wed Nov 07 08:52:51 2007 -0800 +++ b/libxkutil/xmlgen.h Wed Nov 07 08:56:44 2007 -0800 @@ -31,5 +31,6 @@ struct kv { }; char *system_to_xml(struct domain *dominfo); +char *device_to_xml(struct virt_device *dev); #endif

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1194454618 28800 # Node ID e7bab3523bd443fe7aaeaf30a7cc97bb312e988d # Parent b9eaad2ace9b71f7c6cb9feb3b6ea630050e3e0f Add domain_online() helper function to return true if a domain is running or blocked. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r b9eaad2ace9b -r e7bab3523bd4 libxkutil/misc_util.c --- a/libxkutil/misc_util.c Wed Nov 07 08:56:44 2007 -0800 +++ b/libxkutil/misc_util.c Wed Nov 07 08:56:58 2007 -0800 @@ -360,6 +360,17 @@ bool provider_is_responsible(const CMPIB return rc; } +bool domain_online(virDomainPtr dom) +{ + virDomainInfo info; + + if (virDomainGetInfo(dom, &info) != 0) + return false; + + return (info.state == VIR_DOMAIN_BLOCKED) || + (info.state == VIR_DOMAIN_RUNNING); +} + /* * Local Variables: diff -r b9eaad2ace9b -r e7bab3523bd4 libxkutil/misc_util.h --- a/libxkutil/misc_util.h Wed Nov 07 08:56:44 2007 -0800 +++ b/libxkutil/misc_util.h Wed Nov 07 08:56:58 2007 -0800 @@ -82,6 +82,7 @@ char *get_key_from_ref_arg(const CMPIArg char *get_key_from_ref_arg(const CMPIArgs *args, char *arg, char *key); bool domain_exists(virConnectPtr conn, const char *name); +bool domain_online(virDomainPtr dom); uint64_t allocated_memory(virConnectPtr conn);

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1194454625 28800 # Node ID 03b92d27d21ea95b552642326fb4c357e643f989 # Parent e7bab3523bd443fe7aaeaf30a7cc97bb312e988d Remove ":disk" from target device in disk XML as it doesn't seem to be necessary for regular disk devices, and it causes virDetachDevice() to fail. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r e7bab3523bd4 -r 03b92d27d21e libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Wed Nov 07 08:56:58 2007 -0800 +++ b/libxkutil/xmlgen.c Wed Nov 07 08:57:05 2007 -0800 @@ -103,7 +103,7 @@ static char *disk_block_xml(const char * "<disk type='block' device='disk'>\n" " <driver name='phy'/>\n" " <source dev='%s'/>\n" - " <target dev='%s:disk'/>\n" + " <target dev='%s'/>\n" "</disk>\n", path, vdev); @@ -122,7 +122,7 @@ static char *disk_file_xml(const char *p "<disk type='file' device='disk'>\n" " <driver name='tap' type='aio'/>\n" " <source file='%s'/>\n" - " <target dev='%s:disk'/>\n" + " <target dev='%s'/>\n" "</disk>\n", path, vdev);

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1194454630 28800 # Node ID e1c63130f720d975822d7c8e3c8ed35c8e18dd15 # Parent 03b92d27d21ea95b552642326fb4c357e643f989 Don't regenerate a UUID if one already exists Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 03b92d27d21e -r e1c63130f720 libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Wed Nov 07 08:57:05 2007 -0800 +++ b/libxkutil/xmlgen.c Wed Nov 07 08:57:10 2007 -0800 @@ -317,8 +317,14 @@ char *system_to_xml(struct domain *domin uint8_t uuid[16]; char uuidstr[37]; - uuid_generate(uuid); - uuid_unparse(uuid, uuidstr); + if (dominfo->uuid) { + strcpy(uuidstr, dominfo->uuid); + CU_DEBUG("Using existing UUID: %s"); + } else { + CU_DEBUG("New UUID"); + uuid_generate(uuid); + uuid_unparse(uuid, uuidstr); + } concat_devxml(&devxml, dominfo->dev_net, dominfo->dev_net_ct); concat_devxml(&devxml, dominfo->dev_disk, dominfo->dev_disk_ct);

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1194454630 28800 # Node ID e1c63130f720d975822d7c8e3c8ed35c8e18dd15 # Parent 03b92d27d21ea95b552642326fb4c357e643f989 Don't regenerate a UUID if one already exists
Signed-off-by: Dan Smith <danms@us.ibm.com>
Seems reasonable to me. +1 -- Kaitlin Rupert IBM Linux Technology Center karupert@us.ibm.com

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1194454866 28800 # Node ID 92ed39296eb881deddc2d34fa9ee0524aefc1a53 # Parent e1c63130f720d975822d7c8e3c8ed35c8e18dd15 Make VSMS call the appropriate dynamic device functions Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r e1c63130f720 -r 92ed39296eb8 src/Virt_VirtualSystemManagementService.c --- a/src/Virt_VirtualSystemManagementService.c Wed Nov 07 08:57:10 2007 -0800 +++ b/src/Virt_VirtualSystemManagementService.c Wed Nov 07 09:01:06 2007 -0800 @@ -563,6 +563,59 @@ static struct virt_device **find_list(st return list; } +static CMPIStatus _resource_dynamic(struct domain *dominfo, + struct virt_device *dev, + bool attach) +{ + CMPIStatus s; + virConnectPtr conn; + virDomainPtr dom; + int (*func)(virDomainPtr, struct virt_device *); + + if (attach) + func = attach_device; + else + func = detach_device; + + conn = lv_connect(_BROKER, &s); + if (conn == NULL) { + CU_DEBUG("Failed to connect"); + return s; + } + + dom = virDomainLookupByName(conn, dominfo->name); + if (dom == NULL) { + CU_DEBUG("Failed to lookup VS `%s'", dominfo->name); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_FOUND, + "Virtual System `%s' not found", dominfo->name); + goto out; + } + + if (!domain_online(dom)) { + CU_DEBUG("VS `%s' not online; skipping dynamic update", + dominfo->name); + CMSetStatus(&s, CMPI_RC_OK); + goto out; + } + + CU_DEBUG("Doing dynamic device update for `%s'", dominfo->name); + + if (func(dom, dev) == 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to %s device", + attach ? "attach" : "detach"); + } else { + CMSetStatus(&s, CMPI_RC_OK); + } + out: + virDomainFree(dom); + virConnectClose(conn); + + return s; +} + static CMPIStatus resource_del(struct domain *dominfo, CMPIInstance *rasd, uint16_t type, @@ -593,8 +646,8 @@ static CMPIStatus resource_del(struct do struct virt_device *dev = &list[i]; if (STREQ(dev->id, devid)) { + s = _resource_dynamic(dominfo, dev, false); dev->type = VIRT_DEV_UNKNOWN; - CMSetStatus(&s, CMPI_RC_OK); break; } } @@ -611,6 +664,7 @@ static CMPIStatus resource_add(struct do CMPIStatus s; struct virt_device **_list; struct virt_device *list; + struct virt_device *dev; int *count; _list = find_list(dominfo, type, &count); @@ -643,12 +697,19 @@ static CMPIStatus resource_add(struct do *_list = list; memset(&list[*count], 0, sizeof(list[*count])); - list[*count].type = type; - list[*count].id = strdup(devid); - rasd_to_vdev(rasd, &list[*count]); + dev = &list[*count]; + + dev->type = type; + dev->id = strdup(devid); + rasd_to_vdev(rasd, dev); + + s = _resource_dynamic(dominfo, dev, true); + if (s.rc != CMPI_RC_OK) + goto out; + + CMSetStatus(&s, CMPI_RC_OK); (*count)++; - CMSetStatus(&s, CMPI_RC_OK); out: return s; } @@ -728,6 +789,10 @@ static CMPIStatus _update_resources_for( } s = func(dominfo, rasd, type, devid); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Resource transform function failed"); + goto out; + } xml = system_to_xml(dominfo); if (xml != NULL) {

Dan Smith wrote:
This set adds dynamic attach/detach support to device_parsing, as well as some other tweaks necessary for the changes to VSMS to work. This makes VSMS dynamically attach/detach devices if the domain is running. Currently this only works for Network and Disk devices, but adding processor and memory support in the attach functions should be easy.
This series looks good. When I first read this description I figured I should settle down for some serious reading, so I suppose it says some good things about the design that all of these patches were relatively simple and small. Well done. +1 -- -Jay

Dan Smith wrote:
This set adds dynamic attach/detach support to device_parsing, as well as some other tweaks necessary for the changes to VSMS to work. This makes VSMS dynamically attach/detach devices if the domain is running. Currently this only works for Network and Disk devices, but adding processor and memory support in the attach functions should be easy.
No additional comments from me. +1 -- Kaitlin Rupert IBM Linux Technology Center karupert@us.ibm.com
participants (3)
-
Dan Smith
-
Jay Gagnon
-
Kaitlin Rupert