[Libvirt-cim] [PATCH] (#4) Changed the output of AllocationCapability association when using DiskPool as input

Richard Maciel rmaciel at linux.vnet.ibm.com
Fri Mar 27 18:19:22 UTC 2009


# HG changeset patch
# User Richard Maciel <rmaciel at linux.vnet.ibm.com>
# Date 1236119796 10800
# Node ID 6277cea336817d6a8885d0caeb2e7a0a92705150
# Parent  9010a4ffa133439c3e66a64552840e2a76ef9ad9
(#4) Changed the output of AllocationCapability association when using DiskPool as input

This patch fix the results of a 'association instances' query when passing a disk pool AllocationCapabilities reference as input. Before this patch, this query returned RASD templates for the disk pools, but now it returns the RASD templates for each of the volumes which composes the disk pool passed as input.

4:
  - Joined both set_disk_props functions in only one (using #if to separate versions). This removed duplicated code.
  - Fixed memory leak points

3:
  - Kept code for versions which doesn't support disk pools

2:
  - Changed code style based on feedback
  - When emulation_type = 1 (cdrom device), the VirtualQuantity property of the template is not set
  - Changed ID of cdrom device
  - LXC is handled in a special way, because it doesn't have volumes

To test:
- Create a domain containing a diskpool and some volumes
- Execute query: wbemcli ein 'http://localhost:5988/root/virt:CIM_AllocationCapabilities'
- Select the reference to a diskpool and use in an association query like the one below:

wbemcli ai -nl -ac KVM_SettingsDefineCapabilities 'http://@localhost:5988/root/virt:KVM_AllocationCapabilities.InstanceID="DiskPool/default"'

- There must be four templates for each volume in the diskpool (MINIMUM, MAXIMUM, DEFAULT, INCREMENT) and their address must correspond to the address of the volume

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

diff -r 9010a4ffa133 -r 6277cea33681 src/Virt_SettingsDefineCapabilities.c
--- a/src/Virt_SettingsDefineCapabilities.c	Tue Mar 17 15:18:27 2009 -0700
+++ b/src/Virt_SettingsDefineCapabilities.c	Tue Mar 03 19:36:36 2009 -0300
@@ -4,6 +4,7 @@
  * Authors:
  *  Dan Smith <danms at us.ibm.com>
  *  Jay Gagnon <grendel at linux.vnet.ibm.com>
+ *  Richard Maciel <richardm at linux.vnet.ibm.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -50,6 +51,16 @@
 #include "Virt_AllocationCapabilities.h"
 #include "Virt_Device.h"
 
+/*
+ * Right now, detect support and use it, if available.
+ * Later, this can be a configure option if needed
+ */
+#if LIBVIR_VERSION_NUMBER > 4000
+# define VIR_USE_LIBVIRT_STORAGE 1
+#else
+# define VIR_USE_LIBVIRT_STORAGE 0
+#endif
+
 const static CMPIBroker *_BROKER;
 
 /* These are used in more than one place so they are defined here. */
@@ -561,7 +572,385 @@
  out:
         return s;
 }
+
+static CMPIStatus set_disk_props(int type,
+                                 const CMPIObjectPath *ref,
+                                 const char *id,
+                                 const char *disk_path,
+                                 uint64_t disk_size,
+                                 uint16_t emu_type,
+                                 struct inst_list *list)
+{
+        const char *dev;
+        CMPIInstance *inst;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+
+        if (type == DOMAIN_LXC) {
+                dev = "/lxc_mnt/tmp";
+        }
+        else {
+                dev = "hda";
+        }
+
+        inst = sdc_rasd_inst(&s, ref, CIM_RES_TYPE_DISK);
+        if ((inst == NULL) || (s.rc != CMPI_RC_OK))
+                goto out;
+
+        CMSetProperty(inst, "InstanceID", (CMPIValue *)id, CMPI_chars);
+        CMSetProperty(inst, "AllocationQuantity",
+                      (CMPIValue *)"MegaBytes", CMPI_chars);
+        CMSetProperty(inst, "Address", (CMPIValue *)disk_path, CMPI_chars);
+
+#if !VIR_USE_LIBVIRT_STORAGE
+        CMSetProperty(inst, "VirtualQuantity",
+                      (CMPIValue *)&disk_size, CMPI_uint64);
+#endif
+
+        if (type == DOMAIN_LXC)
+                CMSetProperty(inst, "MountPoint", (CMPIValue *)dev, CMPI_chars);
+        else {
+#if VIR_USE_LIBVIRT_STORAGE
+                if (emu_type == 0)
+                        CMSetProperty(inst, "VirtualQuantity",
+                                      (CMPIValue *)&disk_size, CMPI_uint64);
+#endif
+
+                if (type == DOMAIN_XENPV) {
+                        dev = "xvda";
+                        CMSetProperty(inst, "Caption",
+                                      (CMPIValue *)"PV disk", CMPI_chars);
+                } else if (type == DOMAIN_XENFV) {
+                        CMSetProperty(inst, "Caption",
+                                      (CMPIValue *)"FV disk", CMPI_chars);
+                }
+
+                CMSetProperty(inst, "VirtualDevice",
+                              (CMPIValue *)dev, CMPI_chars);
+                CMSetProperty(inst, "EmulatedType",
+                              (CMPIValue *)&emu_type, CMPI_uint16);
+        }
+
+        inst_list_add(list, inst);
+
+ out:
+        return s;
+}
+
+#if VIR_USE_LIBVIRT_STORAGE
+static CMPIStatus cdrom_template(const CMPIObjectPath *ref,
+                                  int template_type,
+                                  struct inst_list *list)
+{
+        char *pfx = NULL;
+        const char *id;
+        const char *vol_path = "/dev/null";
+        uint64_t vol_size = 0;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        uint16_t emu_type = 1;
+
+        switch(template_type) {
+        case SDC_RASD_MIN:
+                id = "Minimum CDROM";
+                break;
+        case SDC_RASD_MAX:
+                id = "Maximum CDROM";
+                break;
+        case SDC_RASD_INC:
+                id = "Increment CDROM";
+                break;
+        case SDC_RASD_DEF:
+                id = "Default CDROM";
+                break;
+        default:
+                cu_statusf(_BROKER, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Unsupported sdc_rasd type");
+                goto out;
+        }
+
+        pfx = class_prefix_name(CLASSNAME(ref));
+        if (STREQ(pfx, "Xen")) {
+                int xen_type[2] = {DOMAIN_XENFV, DOMAIN_XENPV};
+                int i = 0;
  
+                for (; i < 2; i++) {
+                        s = set_disk_props(xen_type[i],
+                                           ref, 
+                                           id,
+                                           vol_path, 
+                                           vol_size, 
+                                           emu_type, 
+                                           list); 
+                }
+        } else if (STREQ(pfx, "KVM")) {
+                s = set_disk_props(DOMAIN_KVM,
+                                   ref, 
+                                   id,
+                                   vol_path, 
+                                   vol_size, 
+                                   emu_type, 
+                                   list); 
+
+        } else if (!STREQ(pfx, "LXC")){
+                cu_statusf(_BROKER, &s, 
+                            CMPI_RC_ERR_FAILED,
+                           "Unsupported virtualization type");
+       }
+
+ out:
+        free(pfx);
+
+        return s;
+}
+
+static CMPIStatus volume_template(const CMPIObjectPath *ref,
+                                  int template_type,
+                                  virStorageVolPtr volume_ptr,
+                                  struct inst_list *list)
+{
+        char *pfx = NULL;
+        const char *id;
+        char *vol_path = NULL;
+        uint64_t vol_size;
+        virStorageVolInfo vol_info;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        int ret;
+        uint16_t emu_type = 0;
+
+        ret = virStorageVolGetInfo(volume_ptr, &vol_info);
+        if (ret == -1) {
+                virt_set_status(_BROKER, &s,
+                                CMPI_RC_ERR_FAILED,
+                                virStorageVolGetConnect(volume_ptr),
+                                "Unable to get volume information");
+                goto out;
+        }
+        
+        switch(template_type) {
+        case SDC_RASD_MIN:
+                if (SDC_DISK_MIN > (uint64_t)vol_info.capacity)
+                        vol_size = (uint64_t)vol_info.capacity;
+                else
+                        vol_size = SDC_DISK_MIN;
+                id = "Minimum";
+                break;
+        case SDC_RASD_MAX:
+                vol_size = (uint64_t)vol_info.capacity;
+                id = "Maximum";
+                break;
+        case SDC_RASD_INC:
+                vol_size = SDC_DISK_INC;
+                id = "Increment";
+                break;
+        case SDC_RASD_DEF:
+                vol_size = (uint64_t)vol_info.allocation;
+                id = "Default";
+                break;
+        default:
+                cu_statusf(_BROKER, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Unsupported sdc_rasd type");
+                goto out;
+        }
+
+        vol_path = virStorageVolGetPath(volume_ptr);
+        if (vol_path == NULL) {
+                virt_set_status(_BROKER, &s,
+                                CMPI_RC_ERR_FAILED,
+                                virStorageVolGetConnect(volume_ptr),
+                                "Unable to get volume path");
+                goto out;
+        }
+        
+        pfx = class_prefix_name(CLASSNAME(ref));
+
+        if (STREQ(pfx, "Xen")) {
+                int xen_type[2] = {DOMAIN_XENFV, DOMAIN_XENPV};
+                int i = 0;
+ 
+                for (; i < 2; i++) {
+                        s = set_disk_props(xen_type[i],
+                                           ref, 
+                                           id,
+                                           vol_path, 
+                                           vol_size, 
+                                           emu_type, 
+                                           list); 
+                }
+        } else if (STREQ(pfx, "KVM")) {
+                s = set_disk_props(DOMAIN_KVM,
+                                   ref, 
+                                   id,
+                                   vol_path, 
+                                   vol_size, 
+                                   emu_type, 
+                                   list); 
+        } else {
+                cu_statusf(_BROKER, &s, 
+                            CMPI_RC_ERR_FAILED,
+                           "Unsupported virtualization type");
+       }
+
+ out:
+        free(pfx);
+        free(vol_path);
+
+        return s;
+}
+
+static CMPIStatus lxc_template(const CMPIObjectPath *ref,
+                               int template_type,
+                               struct inst_list *list)
+{
+        uint64_t vol_size = 0;
+        int emu_type = 0;
+        const char *vol_path = "/tmp";
+        const char *id;
+
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        
+        switch(template_type) {
+        case SDC_RASD_MIN:
+                id = "Minimum";
+                break;
+        case SDC_RASD_MAX:
+                id = "Maximum";
+                break;
+        case SDC_RASD_INC:
+                id = "Increment";
+                break;
+        case SDC_RASD_DEF:
+                id = "Default";
+                break;
+        default:
+                cu_statusf(_BROKER, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Unsupported sdc_rasd type");
+                goto out;
+        }
+
+        s = set_disk_props(DOMAIN_LXC,
+                           ref, 
+                           id, 
+                           vol_path,
+                           vol_size, 
+                           emu_type, 
+                           list); 
+
+ out:
+        return s;
+
+}
+
+static CMPIStatus disk_template(const CMPIObjectPath *ref,
+                                int template_type,
+                                struct inst_list *list)
+{
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        virConnectPtr conn = NULL;
+        virStoragePoolPtr poolptr = NULL;
+        virStorageVolPtr volptr = NULL;
+        const char *instid = NULL;
+        char *host = NULL;
+        const char *poolname = NULL;
+        char **volnames = NULL;
+        int numvols = 0;
+        int numvolsret = 0;
+        int i;
+        char *pfx = NULL;
+
+        pfx = class_prefix_name(CLASSNAME(ref));
+        if (STREQ(pfx, "LXC")) {
+                s = lxc_template(ref, template_type, list);
+                goto out;
+        }
+
+        conn = connect_by_classname(_BROKER, CLASSNAME(ref), &s);
+
+        if (cu_get_str_path(ref, "InstanceID", &instid) != CMPI_RC_OK) {
+               cu_statusf(_BROKER, &s,
+                          CMPI_RC_ERR_FAILED,
+                          "Unable to get InstanceID for disk device");
+               goto out;
+        }
+
+        if (parse_fq_devid(instid, &host, (char **)&poolname) != 1) {
+                cu_statusf(_BROKER, &s, 
+                           CMPI_RC_ERR_FAILED,
+                           "Unable to get pool device id");
+                goto out;
+        }
+
+        if ((poolptr = virStoragePoolLookupByName(conn, poolname)) == NULL) {
+                virt_set_status(_BROKER, &s,
+                                CMPI_RC_ERR_NOT_FOUND,
+                                conn,
+                                "Storage pool `%s' not found",
+                                poolname);
+                goto out;
+        }
+
+        if ((numvols = virStoragePoolNumOfVolumes(poolptr)) == -1) {
+                virt_set_status(_BROKER, &s,
+                                CMPI_RC_ERR_FAILED,
+                                conn,
+                                "Unable to get the number of volumes \
+                                of storage pool `%s'",
+                                poolname);
+                goto out;
+        }
+
+        volnames = (char **)malloc(sizeof(char *) * numvols);
+        if (volnames == NULL) {
+               cu_statusf(_BROKER, &s,
+                          CMPI_RC_ERR_FAILED,
+                          "Could not allocate space for list of volumes \
+                          of storage pool `%s'",
+                          poolname);
+               goto out;
+        }
+
+        numvolsret = virStoragePoolListVolumes(poolptr, volnames, numvols);
+
+        if (numvolsret == -1) {
+                virt_set_status(_BROKER, &s,
+                                CMPI_RC_ERR_FAILED,
+                                conn,
+                                "Unable to get a pointer to volumes \
+                                of storage pool `%s'",
+                                poolname);
+                goto out;
+        }
+
+        for (i = 0; i < numvolsret; i++) {
+                volptr = virStorageVolLookupByName(poolptr, volnames[i]);
+                if (volptr == NULL) {
+                        virt_set_status(_BROKER, &s,
+                                        CMPI_RC_ERR_NOT_FOUND,
+                                        conn,
+                                        "Storage Volume `%s' not found",
+                                        volnames[i]);
+                        goto out;
+                }         
+                
+                s = volume_template(ref, template_type, volptr, list);
+                if (s.rc != CMPI_RC_OK)
+                        goto out;            
+        }
+
+        s = cdrom_template(ref, template_type, list);
+
+ out:
+        free(pfx);
+        free(volnames);
+        free(host);
+        virStorageVolFree(volptr);
+        virStoragePoolFree(poolptr);
+        virConnectClose(conn);
+
+        return s;
+}
+#else
 static int get_disk_freespace(const CMPIObjectPath *ref,
                               CMPIStatus *s,
                               uint64_t *free_space)
@@ -608,62 +997,6 @@
         return ret;
 }
 
-static CMPIStatus set_disk_props(int type,
-                                 const CMPIObjectPath *ref,
-                                 const char *id,
-                                 uint64_t disk_size,
-                                 uint16_t emu_type,
-                                 struct inst_list *list)
-{
-        const char *addr;
-        const char *dev;
-        CMPIInstance *inst;
-        CMPIStatus s = {CMPI_RC_OK, NULL};
-
-        if (type == DOMAIN_LXC) {
-                addr = "/tmp";
-                dev = "/lxc_mnt/tmp";
-        }
-        else {
-                dev = "hda";
-                addr = "/dev/null";
-        }
-
-        inst = sdc_rasd_inst(&s, ref, CIM_RES_TYPE_DISK);
-        if ((inst == NULL) || (s.rc != CMPI_RC_OK))
-                goto out;
-
-        CMSetProperty(inst, "InstanceID", (CMPIValue *)id, CMPI_chars);
-        CMSetProperty(inst, "AllocationQuantity",
-                      (CMPIValue *)"MegaBytes", CMPI_chars);
-        CMSetProperty(inst, "VirtualQuantity",
-                      (CMPIValue *)&disk_size, CMPI_uint64);
-        CMSetProperty(inst, "Address", (CMPIValue *)addr, CMPI_chars);
-
-        if (type == DOMAIN_LXC)
-                CMSetProperty(inst, "MountPoint", (CMPIValue *)dev, CMPI_chars);
-        else {
-                if (type == DOMAIN_XENPV) {
-                        dev = "xvda";
-                        CMSetProperty(inst, "Caption",
-                                      (CMPIValue *)"PV disk", CMPI_chars);
-                } else if (type == DOMAIN_XENFV) {
-                        CMSetProperty(inst, "Caption",
-                                      (CMPIValue *)"FV disk", CMPI_chars);
-                }
-
-                CMSetProperty(inst, "VirtualDevice",
-                              (CMPIValue *)dev, CMPI_chars);
-                CMSetProperty(inst, "EmulatedType",
-                              (CMPIValue *)&emu_type, CMPI_uint16);
-        }
-
-        inst_list_add(list, inst);
-
- out:
-        return s;
-}
-
 static CMPIStatus disk_template(const CMPIObjectPath *ref,
                                 int template_type,
                                 struct inst_list *list)
@@ -673,6 +1006,7 @@
         const char *id;
         uint64_t disk_size;
         uint16_t emu_type = 0;
+        const char *addr = "/dev/null";
         CMPIStatus s = {CMPI_RC_OK, NULL};
 
         switch(template_type) {
@@ -702,7 +1036,6 @@
         }
 
         pfx = class_prefix_name(CLASSNAME(ref));
-
         if (STREQ(pfx, "Xen")) {
                 int xen_type[2] = {DOMAIN_XENFV, DOMAIN_XENPV};
                 int i = 0;
@@ -712,6 +1045,7 @@
                         s = set_disk_props(xen_type[i],
                                            ref, 
                                            id, 
+                                           addr,
                                            disk_size, 
                                            emu_type, 
                                            list); 
@@ -721,7 +1055,8 @@
                         emu_type = 1;
                         s = set_disk_props(xen_type[i],
                                            ref, 
-                                           id, 
+                                           id,
+                                           addr, 
                                            disk_size, 
                                            emu_type, 
                                            list); 
@@ -731,7 +1066,8 @@
         } else if (STREQ(pfx, "KVM")) {
                 s = set_disk_props(DOMAIN_KVM,
                                    ref, 
-                                   id, 
+                                   id,
+                                   addr, 
                                    disk_size, 
                                    emu_type, 
                                    list); 
@@ -742,13 +1078,16 @@
                 s = set_disk_props(DOMAIN_KVM,
                                    ref, 
                                    id, 
+                                   addr,
                                    disk_size, 
                                    emu_type, 
                                    list); 
         } else if (STREQ(pfx, "LXC")) {
+                addr = "/tmp";
                 s = set_disk_props(DOMAIN_LXC,
                                    ref, 
                                    id, 
+                                   addr,
                                    disk_size, 
                                    emu_type, 
                                    list); 
@@ -761,6 +1100,7 @@
  out:
         return s;
 }
+#endif
 
 static CMPIStatus graphics_template(const CMPIObjectPath *ref,
                                     int template_type,




More information about the Libvirt-cim mailing list