[PATCH V6 00/20] Bug fix patches for 0.6.2

This serial fix a batch of issues. v6: general change: rebase and add John Ferlan's patches after the tail. 2/20: do not add this property now, just fixed the spelling in code, since it is only set when Xen is used in libvirt-cim, so it is OK. 3/20: also fixed debug print spelling. 5/20: squashed patch for debug print crash issues. 6/20: spelling fix in commit message. 7/20: skipped free_diskpool on fail of setting parent pool, refined the code in get_diskpool_config() when libvirt pool was not used, removed the duplicated macro in .c file, set member to NULL in parse_diskpool_line when fail. 8/20: squashed the patch with John Ferlan's one about "adjust logic" for it. 11/20: free the domain ptr after domain name retrieving. 13/20: rename no_root_ssh_key to use_non_root_ssh_key, fail when file can't be deleted before copy in ssh_key_copy(). 17/20: small code style change for {} in if condition. 18/20: added a macro to activate it. 19/20: added three macro to activate them, added {} in if statement when only one sentence follow. John Ferlan (7): 14 Makefile.am: Remove the $(top_srcdir) from subst command 15 libvirt-cim.spec: Use systemctl for tog-pegasus restart 16 Remove empty newline at bottom 17 xmlgen: Only support script on bridge for xen domains 18 libxkutil: Use virConnectListAllDomains() to fetch domains 19 DevicePool: Use the virConnectListAll interfaces 20 register: Adjust the chatter output Wenchao Xia (13): 1 Remove property CreationClassName in some instance 2 SDC: Fix spelling for property IsFullVirt 3 SDC: use property BootDevices instead of BootDevice 4 do not deregister virt classes in yum upgrade 5 CSI, DevicePool, RASDIndication: fix debug print crash 6 CSI, add lock to protect shared data in lifecycle_thread 7 DevicePool, reimplement get_diskpool_config with libvirt 8 device parsing, add debug print 9 CSI Discard libvirt event by default 10 CSI: Move native CSI code together 11 VSSD: report success if not all VS fail in enum 12 misc_util: better way to read config 13 migration: allow ssh based migration with non root's key file Makefile.am | 18 +- libvirt-cim.conf | 19 + libvirt-cim.spec.in | 24 +- libxkutil/cs_util_instance.c | 26 + libxkutil/device_parsing.c | 19 +- libxkutil/misc_util.c | 135 +++- libxkutil/misc_util.h | 6 +- libxkutil/xmlgen.c | 26 +- provider-register.sh | 9 +- schema/SwitchService.registration | 1 - src/Virt_AllocationCapabilities.c | 3 +- src/Virt_ComputerSystem.c | 66 ++- src/Virt_ComputerSystemIndication.c | 1018 +++++++++++++++++--- src/Virt_ConsoleRedirectionService.c | 3 +- src/Virt_ConsoleRedirectionServiceCapabilities.c | 3 +- src/Virt_Device.c | 18 +- src/Virt_DevicePool.c | 480 ++++++++-- src/Virt_DevicePool.h | 4 + src/Virt_EnabledLogicalElementCapabilities.c | 3 +- src/Virt_FilterEntry.c | 3 +- src/Virt_FilterList.c | 3 +- src/Virt_HostSystem.c | 3 +- src/Virt_KVMRedirectionSAP.c | 3 +- src/Virt_RASD.c | 3 +- src/Virt_ReferencedProfile.c | 3 +- src/Virt_RegisteredProfile.c | 3 +- src/Virt_ResourceAllocationSettingDataIndication.c | 6 +- src/Virt_ResourcePoolConfigurationCapabilities.c | 3 +- src/Virt_ResourcePoolConfigurationService.c | 8 +- src/Virt_SettingsDefineCapabilities.c | 14 +- src/Virt_SwitchService.c | 3 +- src/Virt_VSMigrationCapabilities.c | 3 +- src/Virt_VSMigrationService.c | 270 +++++- src/Virt_VSMigrationSettingData.c | 3 +- src/Virt_VSSD.c | 50 +- src/Virt_VirtualSystemManagementCapabilities.c | 3 +- src/Virt_VirtualSystemManagementService.c | 67 ++- src/Virt_VirtualSystemSnapshotService.c | 3 +- ...Virt_VirtualSystemSnapshotServiceCapabilities.c | 3 +- 39 files changed, 1990 insertions(+), 348 deletions(-)

There are some instances which did not register this property, so this patch added a parameter in get_typed_instance(). The caller must set it clearly whether to set the property. When tog-pegasus > 2.12 and its log >= WARNING, tog-pegasus will report this problem in log. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- libxkutil/misc_util.c | 12 ++++++++---- libxkutil/misc_util.h | 3 ++- src/Virt_AllocationCapabilities.c | 3 ++- src/Virt_ComputerSystem.c | 6 ++++-- src/Virt_ComputerSystemIndication.c | 3 ++- src/Virt_ConsoleRedirectionService.c | 3 ++- src/Virt_ConsoleRedirectionServiceCapabilities.c | 3 ++- src/Virt_Device.c | 18 ++++++++++++------ src/Virt_DevicePool.c | 20 +++++++++++++------- src/Virt_EnabledLogicalElementCapabilities.c | 3 ++- src/Virt_FilterEntry.c | 3 ++- src/Virt_FilterList.c | 3 ++- src/Virt_HostSystem.c | 3 ++- src/Virt_KVMRedirectionSAP.c | 3 ++- src/Virt_RASD.c | 3 ++- src/Virt_ReferencedProfile.c | 3 ++- src/Virt_RegisteredProfile.c | 3 ++- src/Virt_ResourcePoolConfigurationCapabilities.c | 3 ++- src/Virt_ResourcePoolConfigurationService.c | 8 ++++++-- src/Virt_SettingsDefineCapabilities.c | 6 ++++-- src/Virt_SwitchService.c | 3 ++- src/Virt_VSMigrationCapabilities.c | 3 ++- src/Virt_VSMigrationService.c | 6 ++++-- src/Virt_VSMigrationSettingData.c | 3 ++- src/Virt_VSSD.c | 3 ++- src/Virt_VirtualSystemManagementCapabilities.c | 3 ++- src/Virt_VirtualSystemManagementService.c | 6 ++++-- src/Virt_VirtualSystemSnapshotService.c | 3 ++- ...Virt_VirtualSystemSnapshotServiceCapabilities.c | 3 ++- 29 files changed, 97 insertions(+), 48 deletions(-) diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c index 2d149ae..f1b93e4 100644 --- a/libxkutil/misc_util.c +++ b/libxkutil/misc_util.c @@ -341,7 +341,8 @@ char *get_typed_class(const char *refcn, const char *new_base) CMPIInstance *get_typed_instance(const CMPIBroker *broker, const char *refcn, const char *base, - const char *namespace) + const char *namespace, + bool ccn_flag) { char *new_cn; CMPIObjectPath *op; @@ -360,8 +361,10 @@ CMPIInstance *get_typed_instance(const CMPIBroker *broker, if ((s.rc != CMPI_RC_OK) || CMIsNullObject(inst)) goto out; - CMSetProperty(inst, "CreationClassName", - (CMPIValue *)new_cn, CMPI_chars); + if (ccn_flag) { + CMSetProperty(inst, "CreationClassName", + (CMPIValue *)new_cn, CMPI_chars); + } out: free(new_cn); @@ -467,7 +470,8 @@ CMPIInstance *make_reference(const CMPIBroker *broker, ref_inst = get_typed_instance(broker, CLASSNAME(source_ref), assoc_classname, - NAMESPACE(source_ref)); + NAMESPACE(source_ref), + false); if (ref_inst != NULL) { CMPIObjectPath *target_ref; diff --git a/libxkutil/misc_util.h b/libxkutil/misc_util.h index c7a2122..90fb2da 100644 --- a/libxkutil/misc_util.h +++ b/libxkutil/misc_util.h @@ -85,7 +85,8 @@ char *get_typed_class(const char *refcn, const char *new_base); CMPIInstance *get_typed_instance(const CMPIBroker *broker, const char *refcn, const char *base, - const char *namespace); + const char *namespace, + bool ccn_flag); /* Parse an OrgID:LocID string into its constituent parts */ int parse_instance_id(char *iid, char **orgid, char **locid); diff --git a/src/Virt_AllocationCapabilities.c b/src/Virt_AllocationCapabilities.c index 970abeb..b358fac 100644 --- a/src/Virt_AllocationCapabilities.c +++ b/src/Virt_AllocationCapabilities.c @@ -46,7 +46,8 @@ static CMPIStatus ac_from_pool(const CMPIBroker *broker, *alloc_cap = get_typed_instance(broker, CLASSNAME(ref), "AllocationCapabilities", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (*alloc_cap == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c index e6c7e55..4a9b26d 100644 --- a/src/Virt_ComputerSystem.c +++ b/src/Virt_ComputerSystem.c @@ -440,7 +440,8 @@ CMPIStatus instance_from_dominfo(const CMPIBroker *broker, inst = get_typed_instance(broker, prefix, "ComputerSystem", - namespace); + namespace, + true); if (inst == NULL) { CU_DEBUG("Could not init CS instance. " @@ -560,7 +561,8 @@ static CMPIStatus instance_from_dom(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "ComputerSystem", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c index 2d0a94e..3096683 100644 --- a/src/Virt_ComputerSystemIndication.c +++ b/src/Virt_ComputerSystemIndication.c @@ -239,7 +239,8 @@ static bool _do_indication(const CMPIBroker *broker, ind = get_typed_instance(broker, prefix, ind_type_name, - args->ns); + args->ns, + false); /* Generally report errors and hope to continue, since we have no one to actually return status to. */ diff --git a/src/Virt_ConsoleRedirectionService.c b/src/Virt_ConsoleRedirectionService.c index 7b20c0d..16cade8 100644 --- a/src/Virt_ConsoleRedirectionService.c +++ b/src/Virt_ConsoleRedirectionService.c @@ -129,7 +129,8 @@ CMPIStatus get_console_rs(const CMPIObjectPath *reference, inst = get_typed_instance(broker, pfx_from_conn(conn), "ConsoleRedirectionService", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { CU_DEBUG("Failed to get typed instance"); diff --git a/src/Virt_ConsoleRedirectionServiceCapabilities.c b/src/Virt_ConsoleRedirectionServiceCapabilities.c index 11f2986..88fb3a4 100644 --- a/src/Virt_ConsoleRedirectionServiceCapabilities.c +++ b/src/Virt_ConsoleRedirectionServiceCapabilities.c @@ -91,7 +91,8 @@ CMPIStatus get_console_rs_caps(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "ConsoleRedirectionServiceCapabilities", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_Device.c b/src/Virt_Device.c index e047a94..c7dcbc3 100644 --- a/src/Virt_Device.c +++ b/src/Virt_Device.c @@ -100,7 +100,8 @@ static CMPIInstance *net_instance(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "NetworkPort", - ns); + ns, + true); if (inst == NULL) { CU_DEBUG("Failed to get instance for NetworkPort"); @@ -138,7 +139,8 @@ static CMPIInstance *disk_instance(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "LogicalDisk", - ns); + ns, + true); if (inst == NULL) { CU_DEBUG("Failed to get instance for LogicalDisk"); @@ -185,7 +187,8 @@ static CMPIInstance *mem_instance(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "Memory", - ns); + ns, + true); if (inst == NULL) { CU_DEBUG("Failed to get instance for Memory"); @@ -234,7 +237,8 @@ static CMPIInstance *graphics_instance(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "DisplayController", - ns); + ns, + true); if (inst == NULL) { CU_DEBUG("Failed to get instance for DisplayController"); @@ -320,7 +324,8 @@ static CMPIInstance *input_instance(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "PointingDevice", - ns); + ns, + true); if (inst == NULL) { CU_DEBUG("Failed to get instance of %s_PointingDevice", pfx_from_conn(conn)); @@ -407,7 +412,8 @@ static bool vcpu_inst(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "Processor", - ns); + ns, + true); if (inst == NULL) return false; diff --git a/src/Virt_DevicePool.c b/src/Virt_DevicePool.c index 202e509..56c9715 100644 --- a/src/Virt_DevicePool.c +++ b/src/Virt_DevicePool.c @@ -803,7 +803,8 @@ static CMPIStatus mempool_instance(virConnectPtr conn, inst = get_typed_instance(broker, pfx_from_conn(conn), "MemoryPool", - ns); + ns, + false); if (inst == NULL) { cu_statusf(broker, &s, @@ -842,7 +843,8 @@ static CMPIStatus procpool_instance(virConnectPtr conn, inst = get_typed_instance(broker, pfx_from_conn(conn), "ProcessorPool", - ns); + ns, + false); if (inst == NULL) { cu_statusf(broker, &s, @@ -872,7 +874,8 @@ static CMPIStatus _netpool_for_parent(struct inst_list *list, inst = get_typed_instance(broker, refcn, "NetworkPool", - ns); + ns, + false); if (inst == NULL) { CU_DEBUG("Unable to get instance: %s:%s_NetworkPool", ns, refcn); @@ -928,7 +931,8 @@ static CMPIStatus _netpool_for_network(struct inst_list *list, inst = get_typed_instance(broker, refcn, "NetworkPool", - ns); + ns, + false); if (inst == NULL) { CU_DEBUG("Unable to get instance: %s:%s_NetworkPool", ns, refcn); @@ -1046,7 +1050,7 @@ static CMPIInstance *diskpool_from_path(struct tmp_disk_pool *pool, CMPIInstance *inst; char *poolid = NULL; - inst = get_typed_instance(broker, refcn, "DiskPool", ns); + inst = get_typed_instance(broker, refcn, "DiskPool", ns, false); if (inst == NULL) { cu_statusf(broker, &s, @@ -1136,7 +1140,8 @@ static CMPIStatus graphicspool_instance(virConnectPtr conn, inst = get_typed_instance(broker, pfx_from_conn(conn), "GraphicsPool", - ns); + ns, + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, @@ -1172,7 +1177,8 @@ static CMPIStatus inputpool_instance(virConnectPtr conn, inst = get_typed_instance(broker, pfx_from_conn(conn), "InputPool", - ns); + ns, + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_EnabledLogicalElementCapabilities.c b/src/Virt_EnabledLogicalElementCapabilities.c index 7ba5eae..2fcdef1 100644 --- a/src/Virt_EnabledLogicalElementCapabilities.c +++ b/src/Virt_EnabledLogicalElementCapabilities.c @@ -61,7 +61,8 @@ static CMPIInstance *_get_elec(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "EnabledLogicalElementCapabilities", - NAMESPACE(reference)); + NAMESPACE(reference), + false); if (inst == NULL) { cu_statusf(broker, s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_FilterEntry.c b/src/Virt_FilterEntry.c index 126615b..3c4a3e6 100644 --- a/src/Virt_FilterEntry.c +++ b/src/Virt_FilterEntry.c @@ -546,7 +546,8 @@ static CMPIInstance *convert_rule_to_instance( inst = get_typed_instance(broker, CLASSNAME(reference), basename, - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { cu_statusf(broker, s, diff --git a/src/Virt_FilterList.c b/src/Virt_FilterList.c index 9b5dbae..79776cd 100644 --- a/src/Virt_FilterList.c +++ b/src/Virt_FilterList.c @@ -50,7 +50,8 @@ static CMPIInstance *convert_filter_to_instance( inst = get_typed_instance(broker, CLASSNAME(reference), "FilterList", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { cu_statusf(broker, s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_HostSystem.c b/src/Virt_HostSystem.c index 724a5ea..c31d6cf 100644 --- a/src/Virt_HostSystem.c +++ b/src/Virt_HostSystem.c @@ -135,7 +135,8 @@ static CMPIStatus fake_host(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "HostSystem", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { cu_statusf(broker, &s, diff --git a/src/Virt_KVMRedirectionSAP.c b/src/Virt_KVMRedirectionSAP.c index db34d57..38ad468 100644 --- a/src/Virt_KVMRedirectionSAP.c +++ b/src/Virt_KVMRedirectionSAP.c @@ -125,7 +125,8 @@ static CMPIInstance *get_console_sap(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "KVMRedirectionSAP", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { cu_statusf(broker, s, diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c index 9493077..6e8a244 100644 --- a/src/Virt_RASD.c +++ b/src/Virt_RASD.c @@ -716,7 +716,8 @@ CMPIInstance *rasd_from_vdev(const CMPIBroker *broker, inst = get_typed_instance(broker, CLASSNAME(ref), base, - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) return inst; diff --git a/src/Virt_ReferencedProfile.c b/src/Virt_ReferencedProfile.c index 150be1f..e78a8d3 100644 --- a/src/Virt_ReferencedProfile.c +++ b/src/Virt_ReferencedProfile.c @@ -242,7 +242,8 @@ static CMPIInstance *make_ref(const CMPIObjectPath *source_ref, ref_inst = get_typed_instance(_BROKER, CLASSNAME(source_ref), assoc_classname, - NAMESPACE(source_ref)); + NAMESPACE(source_ref), + false); source = get_reg_prof_by_ref(source_ref); if (source->scoping_profile != NULL) diff --git a/src/Virt_RegisteredProfile.c b/src/Virt_RegisteredProfile.c index 389a179..e644708 100644 --- a/src/Virt_RegisteredProfile.c +++ b/src/Virt_RegisteredProfile.c @@ -54,7 +54,8 @@ CMPIStatus get_profile(const CMPIBroker *broker, instance = get_typed_instance(broker, pfx, "RegisteredProfile", - CIM_INTEROP_NS); + CIM_INTEROP_NS, + false); if (instance == NULL) { cu_statusf(broker, &s, diff --git a/src/Virt_ResourcePoolConfigurationCapabilities.c b/src/Virt_ResourcePoolConfigurationCapabilities.c index 32274ed..2dcbbcf 100644 --- a/src/Virt_ResourcePoolConfigurationCapabilities.c +++ b/src/Virt_ResourcePoolConfigurationCapabilities.c @@ -69,7 +69,8 @@ static CMPIStatus get_rpc_cap(const CMPIObjectPath *reference, inst = get_typed_instance(_BROKER, pfx_from_conn(conn), "ResourcePoolConfigurationCapabilities", - NAMESPACE(reference)); + NAMESPACE(reference), + false); if (inst == NULL) { cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_ResourcePoolConfigurationService.c b/src/Virt_ResourcePoolConfigurationService.c index 751d016..0c0cc06 100644 --- a/src/Virt_ResourcePoolConfigurationService.c +++ b/src/Virt_ResourcePoolConfigurationService.c @@ -781,6 +781,8 @@ static const char *rasd_to_res(CMPIInstance *inst, return msg; } +/* Warning: returned instance is not freed manually in caller, need confirm + if server will auto free it. */ static CMPIInstance *get_resource_rasd(struct virt_pool_res *res, const CMPIObjectPath *ref, CMPIStatus *s) @@ -798,7 +800,8 @@ static CMPIInstance *get_resource_rasd(struct virt_pool_res *res, inst = get_typed_instance(_BROKER, CLASSNAME(ref), "StorageVolumeResourceAllocationSettingData", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(_BROKER, s, CMPI_RC_ERR_FAILED, @@ -1279,7 +1282,8 @@ CMPIStatus get_rpcs(const CMPIObjectPath *reference, inst = get_typed_instance(broker, pfx_from_conn(conn), "ResourcePoolConfigurationService", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_SettingsDefineCapabilities.c b/src/Virt_SettingsDefineCapabilities.c index 9eb9e57..5091205 100644 --- a/src/Virt_SettingsDefineCapabilities.c +++ b/src/Virt_SettingsDefineCapabilities.c @@ -113,7 +113,8 @@ static CMPIInstance *default_vssd_instance(const char *prefix, inst = get_typed_instance(_BROKER, prefix, "VirtualSystemSettingData", - ns); + ns, + false); if (inst == NULL) { CU_DEBUG("Failed to create default VSSD instance"); goto out; @@ -303,7 +304,8 @@ static CMPIInstance *sdc_rasd_inst(CMPIStatus *s, inst = get_typed_instance(_BROKER, CLASSNAME(ref), base, - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(_BROKER, s, diff --git a/src/Virt_SwitchService.c b/src/Virt_SwitchService.c index 7e59d38..8991426 100644 --- a/src/Virt_SwitchService.c +++ b/src/Virt_SwitchService.c @@ -229,7 +229,8 @@ static CMPIStatus get_switchservice(const CMPIObjectPath *reference, inst = get_typed_instance(broker, pfx_from_conn(conn), "SwitchService", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { CU_DEBUG("Failed to get typed instance"); diff --git a/src/Virt_VSMigrationCapabilities.c b/src/Virt_VSMigrationCapabilities.c index 4f0e434..3e53f68 100644 --- a/src/Virt_VSMigrationCapabilities.c +++ b/src/Virt_VSMigrationCapabilities.c @@ -134,7 +134,8 @@ CMPIStatus get_migration_caps(const CMPIObjectPath *ref, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemMigrationCapabilities", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c index 76e3d25..1f6659d 100644 --- a/src/Virt_VSMigrationService.c +++ b/src/Virt_VSMigrationService.c @@ -831,7 +831,8 @@ static CMPIInstance *prepare_indication(const CMPIBroker *broker, ind = get_typed_instance(broker, pfx, ind_name, - job->ref_ns); + job->ref_ns, + false); if (ind == NULL) { CU_DEBUG("Failed to create ind, type '%s:%s_%s'", job->ref_ns, pfx, ind_name); @@ -1686,7 +1687,8 @@ CMPIStatus get_migration_service(const CMPIObjectPath *ref, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemMigrationService", - NAMESPACE(ref)); + NAMESPACE(ref), + true); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_VSMigrationSettingData.c b/src/Virt_VSMigrationSettingData.c index a6707bd..eb545f1 100644 --- a/src/Virt_VSMigrationSettingData.c +++ b/src/Virt_VSMigrationSettingData.c @@ -79,7 +79,8 @@ CMPIStatus get_migration_sd(const CMPIObjectPath *ref, inst = get_typed_instance(broker, CLASSNAME(ref), "VirtualSystemMigrationSettingData", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_VSSD.c b/src/Virt_VSSD.c index 499b157..975623b 100644 --- a/src/Virt_VSSD.c +++ b/src/Virt_VSSD.c @@ -285,7 +285,8 @@ static CMPIInstance *_get_vssd(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemSettingData", - NAMESPACE(reference)); + NAMESPACE(reference), + false); if (inst == NULL) { cu_statusf(broker, s, diff --git a/src/Virt_VirtualSystemManagementCapabilities.c b/src/Virt_VirtualSystemManagementCapabilities.c index 020ce8a..51738ee 100644 --- a/src/Virt_VirtualSystemManagementCapabilities.c +++ b/src/Virt_VirtualSystemManagementCapabilities.c @@ -129,7 +129,8 @@ CMPIStatus get_vsm_cap(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemManagementCapabilities", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 10adf8b..96c8a03 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -1928,7 +1928,8 @@ static CMPIStatus raise_rasd_indication(const CMPIContext *context, ind = get_typed_instance(_BROKER, CLASSNAME(ref), base_type, - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (ind == NULL) { CU_DEBUG("Failed to get indication instance"); s.rc = CMPI_RC_ERR_FAILED; @@ -3293,7 +3294,8 @@ CMPIStatus get_vsms(const CMPIObjectPath *reference, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemManagementService", - NAMESPACE(reference)); + NAMESPACE(reference), + true); if (inst == NULL) { CU_DEBUG("Failed to get typed instance"); diff --git a/src/Virt_VirtualSystemSnapshotService.c b/src/Virt_VirtualSystemSnapshotService.c index aae628f..8c0889d 100644 --- a/src/Virt_VirtualSystemSnapshotService.c +++ b/src/Virt_VirtualSystemSnapshotService.c @@ -681,7 +681,8 @@ CMPIStatus get_vsss(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemSnapshotService", - NAMESPACE(ref)); + NAMESPACE(ref), + true); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, diff --git a/src/Virt_VirtualSystemSnapshotServiceCapabilities.c b/src/Virt_VirtualSystemSnapshotServiceCapabilities.c index 69c8e97..04a9c7a 100644 --- a/src/Virt_VirtualSystemSnapshotServiceCapabilities.c +++ b/src/Virt_VirtualSystemSnapshotServiceCapabilities.c @@ -117,7 +117,8 @@ CMPIStatus get_vss_cap(const CMPIBroker *broker, inst = get_typed_instance(broker, pfx_from_conn(conn), "VirtualSystemSnapshotServiceCapabilities", - NAMESPACE(ref)); + NAMESPACE(ref), + false); if (inst == NULL) { cu_statusf(broker, &s, CMPI_RC_ERR_FAILED, -- 1.7.1

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- src/Virt_SettingsDefineCapabilities.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Virt_SettingsDefineCapabilities.c b/src/Virt_SettingsDefineCapabilities.c index 5091205..b255cf5 100644 --- a/src/Virt_SettingsDefineCapabilities.c +++ b/src/Virt_SettingsDefineCapabilities.c @@ -160,7 +160,7 @@ static CMPIStatus _xen_vsmc_to_vssd(virConnectPtr conn, CMSetProperty(inst, "Bootloader", (CMPIValue *)"/usr/bin/pygrub", CMPI_chars); - CMSetProperty(inst, "isFullVirt", + CMSetProperty(inst, "IsFullVirt", (CMPIValue *)&isfv, CMPI_boolean); inst_list_add(list, inst); @@ -175,7 +175,7 @@ static CMPIStatus _xen_vsmc_to_vssd(virConnectPtr conn, CMSetProperty(inst, "BootDevice", (CMPIValue *)"hda", CMPI_chars); - CMSetProperty(inst, "isFullVirt", + CMSetProperty(inst, "IsFullVirt", (CMPIValue *)&isfv, CMPI_boolean); inst_list_add(list, inst); -- 1.7.1

The property registerted is BootDevices, so correct it, also fix the spelling in debug message. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- src/Virt_SettingsDefineCapabilities.c | 4 ++-- src/Virt_VirtualSystemManagementService.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Virt_SettingsDefineCapabilities.c b/src/Virt_SettingsDefineCapabilities.c index b255cf5..3b39a80 100644 --- a/src/Virt_SettingsDefineCapabilities.c +++ b/src/Virt_SettingsDefineCapabilities.c @@ -172,7 +172,7 @@ static CMPIStatus _xen_vsmc_to_vssd(virConnectPtr conn, if (inst == NULL) goto error; - CMSetProperty(inst, "BootDevice", + CMSetProperty(inst, "BootDevices", (CMPIValue *)"hda", CMPI_chars); CMSetProperty(inst, "IsFullVirt", @@ -211,7 +211,7 @@ static CMPIStatus _kvm_vsmc_to_vssd(virConnectPtr conn, CMSetProperty(inst, "VirtualSystemIdentifier", (CMPIValue *)"KVM_guest", CMPI_chars); - CMSetProperty(inst, "BootDevice", + CMSetProperty(inst, "BootDevices", (CMPIValue *)"hda", CMPI_chars); inst_list_add(list, inst); diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 96c8a03..6322daf 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -408,7 +408,7 @@ static int bootord_vssd_to_domain(CMPIInstance *inst, bl_size = CMGetArrayCount(bootlist, &s); if (s.rc != CMPI_RC_OK) { - CU_DEBUG("Invalid BootDevice array size"); + CU_DEBUG("Invalid BootDevices array size"); return 0; } @@ -428,7 +428,7 @@ static int bootord_vssd_to_domain(CMPIInstance *inst, NULL); if (CMIsNullValue(boot_elem)) { - CU_DEBUG("Null BootDevice"); + CU_DEBUG("Null BootDevices"); free(tmp_str_arr); return 0; } -- 1.7.1

Now yum upgrade will deregister the virt classes, make libvirt-cim not workable. This patch fixed it from now on. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- libvirt-cim.spec.in | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in index d78eee7..3def978 100644 --- a/libvirt-cim.spec.in +++ b/libvirt-cim.spec.in @@ -104,18 +104,22 @@ rm -fr $RPM_BUILD_ROOT -r %{CIMV2_REG} -m %{CIMV2_MOF} -v >/dev/null 2>&1 || true %preun -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ +#Deregister only in uninstall, do nothing in upgrade. +if [ "$1" = "0" ]; then + echo "Deleting registered classes in libvirt-cim..." + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n @CIM_VIRT_NS@ \ -r %{REGISTRATION} -m %{SCHEMA} >/dev/null 2>&1 || true -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n root/interop \ -r %{INTEROP_REG} -m %{INTEROP_MOF} >/dev/null 2>&1 || true -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n root/PG_InterOp \ -r %{PGINTEROP_REG} -m %{PGINTEROP_MOF} >/dev/null 2>&1 || true -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n root/cimv2 \ -r %{CIMV2_REG} -m %{CIMV2_MOF} >/dev/null 2>&1 || true +fi %postun -p /sbin/ldconfig -- 1.7.1

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Sharad Mishra <snmishra@us.ibm.com> --- src/Virt_ComputerSystemIndication.c | 2 +- src/Virt_DevicePool.c | 2 +- src/Virt_ResourceAllocationSettingDataIndication.c | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c index 3096683..8250850 100644 --- a/src/Virt_ComputerSystemIndication.c +++ b/src/Virt_ComputerSystemIndication.c @@ -504,7 +504,7 @@ static void csi_domain_event_cb(virConnectPtr conn, CMPIStatus s = {CMPI_RC_OK, NULL}; if (lifecycle_enabled == false || thread->active_filters <= 0) { - CU_DEBUG("%s indications deactivated, return"); + CU_DEBUG("%s indications deactivated, return", prefix); return; } diff --git a/src/Virt_DevicePool.c b/src/Virt_DevicePool.c index 56c9715..08677e2 100644 --- a/src/Virt_DevicePool.c +++ b/src/Virt_DevicePool.c @@ -710,7 +710,7 @@ static bool mempool_set_consumed(CMPIInstance *inst, virConnectPtr conn) dom = virDomainLookupByID(conn, domain_ids[i]); if (dom == NULL) { - CU_DEBUG("Cannot connect to domain %n: excluding", + CU_DEBUG("Cannot connect to domain %d: excluding", domain_ids[i]); continue; } diff --git a/src/Virt_ResourceAllocationSettingDataIndication.c b/src/Virt_ResourceAllocationSettingDataIndication.c index a386132..93fb563 100644 --- a/src/Virt_ResourceAllocationSettingDataIndication.c +++ b/src/Virt_ResourceAllocationSettingDataIndication.c @@ -122,7 +122,11 @@ static CMPIStatus raise_indication(const CMPIBroker *broker, if (s.rc == CMPI_RC_OK) { CU_DEBUG("Indication delivered"); } else { - CU_DEBUG("Not delivered: %s", CMGetCharPtr(s.msg)); + if (s.msg == NULL) { + CU_DEBUG("Not delivered: msg is NULL."); + } else { + CU_DEBUG("Not delivered: %s", CMGetCharPtr(s.msg)); + } } out: -- 1.7.1

This patch use lock 'lifecycle_mutex' to protect global shared data in lifecycle_thread(). This lock exist in Activate/Deactivate Enable/Disable method, which is meant to protect the global shared data, but forgot to be added in new libvirt based CSI thread. This patch can avoid following risk at least: Original code have a small chance to free thread->args in child thread just after main thread malloc it, for that thread->id is set to zero allowing main thread to enter that code. This patch focus on adding missing lock, the CSI can be still improved as: smaller lock, folder lock into a structure with data to tip better what it is doing. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- src/Virt_ComputerSystemIndication.c | 39 ++++++++++++++++++++++++++++++++-- 1 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c index 8250850..3df47fa 100644 --- a/src/Virt_ComputerSystemIndication.c +++ b/src/Virt_ComputerSystemIndication.c @@ -174,9 +174,11 @@ static void csi_free_thread_data(void *data) if (data == NULL) return; + pthread_mutex_lock(&lifecycle_mutex); list_free(thread->dom_list); thread->dom_list = NULL; stdi_free_ind_args(&thread->args); + pthread_mutex_unlock(&lifecycle_mutex); } void set_source_inst_props(const CMPIBroker *broker, @@ -491,6 +493,8 @@ static int update_domain_list(virConnectPtr conn, csi_thread_data_t *thread) return s.rc; } +/* following function will protect global data with lifecycle_mutex. + TODO: improve it with seperate lock later. */ static void csi_domain_event_cb(virConnectPtr conn, virDomainPtr dom, int event, @@ -503,10 +507,13 @@ static void csi_domain_event_cb(virConnectPtr conn, char *prefix = class_prefix_name(thread->args->classname); CMPIStatus s = {CMPI_RC_OK, NULL}; + pthread_mutex_lock(&lifecycle_mutex); if (lifecycle_enabled == false || thread->active_filters <= 0) { CU_DEBUG("%s indications deactivated, return", prefix); + pthread_mutex_unlock(&lifecycle_mutex); return; } + pthread_mutex_unlock(&lifecycle_mutex); CU_DEBUG("Event: Domain %s(%d) event: %d detail: %d\n", virDomainGetName(dom), virDomainGetID(dom), event, detail); @@ -538,7 +545,9 @@ static void csi_domain_event_cb(virConnectPtr conn, if (cs_event != CS_CREATED) { char uuid[VIR_UUID_STRING_BUFLEN] = {0}; virDomainGetUUIDString(dom, &uuid[0]); + pthread_mutex_lock(&lifecycle_mutex); dom_xml = list_find(thread->dom_list, uuid); + pthread_mutex_unlock(&lifecycle_mutex); } if (dom_xml == NULL) { @@ -546,12 +555,16 @@ static void csi_domain_event_cb(virConnectPtr conn, goto end; } + pthread_mutex_lock(&lifecycle_mutex); async_ind(thread->args, cs_event, dom_xml, prefix); + pthread_mutex_unlock(&lifecycle_mutex); /* Update the domain list accordingly */ if (event == VIR_DOMAIN_EVENT_DEFINED) { if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED) { + pthread_mutex_lock(&lifecycle_mutex); csi_thread_dom_list_append(thread, dom_xml); + pthread_mutex_unlock(&lifecycle_mutex); } else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED) { free(dom_xml->name); free(dom_xml->xml); @@ -559,7 +572,9 @@ static void csi_domain_event_cb(virConnectPtr conn, } } else if (event == VIR_DOMAIN_EVENT_DEFINED && detail == VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) { + pthread_mutex_lock(&lifecycle_mutex); list_remove(thread->dom_list, dom_xml); + pthread_mutex_unlock(&lifecycle_mutex); } end: @@ -580,10 +595,12 @@ static CMPI_THREAD_RETURN lifecycle_thread(void *params) if (prefix == NULL) goto init_out; + pthread_mutex_lock(&lifecycle_mutex); conn = connect_by_classname(_BROKER, args->classname, &s); if (conn == NULL) { CU_DEBUG("Unable to start lifecycle thread: " "Failed to connect (cn: %s)", args->classname); + pthread_mutex_unlock(&lifecycle_mutex); goto conn_out; } @@ -595,33 +612,47 @@ static CMPI_THREAD_RETURN lifecycle_thread(void *params) if (cb_id == -1) { CU_DEBUG("Failed to register domain event watch for '%s'", - args->classname) + args->classname); + pthread_mutex_unlock(&lifecycle_mutex); goto cb_out; } CBAttachThread(_BROKER, args->context); /* Get currently defined domains */ - if (update_domain_list(conn, thread) != CMPI_RC_OK) + if (update_domain_list(conn, thread) != CMPI_RC_OK) { + pthread_mutex_unlock(&lifecycle_mutex); goto end; + } + pthread_mutex_unlock(&lifecycle_mutex); CU_DEBUG("Entering CSI event loop (%s)", prefix); - while (thread->active_filters > 0) { + while (1) { + pthread_mutex_lock(&lifecycle_mutex); + if (thread->active_filters <= 0) { + pthread_mutex_unlock(&lifecycle_mutex); + break; + } + pthread_mutex_unlock(&lifecycle_mutex); if (virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); CU_DEBUG("Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } + usleep(1); } CU_DEBUG("Exiting CSI event loop (%s)", prefix); + pthread_mutex_lock(&lifecycle_mutex); CBDetachThread(_BROKER, args->context); + pthread_mutex_unlock(&lifecycle_mutex); end: virConnectDomainEventDeregisterAny(conn, cb_id); cb_out: + pthread_mutex_lock(&lifecycle_mutex); thread->id = 0; thread->active_filters = 0; @@ -629,6 +660,8 @@ static CMPI_THREAD_RETURN lifecycle_thread(void *params) if (thread->args != NULL) stdi_free_ind_args(&thread->args); + pthread_mutex_unlock(&lifecycle_mutex); + conn_out: virConnectClose(conn); -- 1.7.1

Original implemetion may return pools with NULL name if some pool disappear between two libvirt pool API call. And originally it return the number of pools and negative value when error happens, but caller of this function consider number = 0 as error. As a fix, this patch changed the function prototype, it do not return the pool number anymore, it returns 0 on success and negative on fail now. Code for checking the risk of returning pools with NULL name is also added. Other small fixes are: return false in get_disk_parent() when strdup() fail, set member to NULL in parse_diskpool_line() after free, removed the duplicated macro declaration in Virt_DevicePool.c file for VIR_USE_LIBVIRT_STORAGE, refined the code in get_diskpool_config() when VIR_USE_LIBVIRT_STORAGE == 0. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- src/Virt_DevicePool.c | 220 ++++++++++++++++++++++++++++++++----------------- src/Virt_DevicePool.h | 4 + 2 files changed, 149 insertions(+), 75 deletions(-) diff --git a/src/Virt_DevicePool.c b/src/Virt_DevicePool.c index 08677e2..a8dc9cd 100644 --- a/src/Virt_DevicePool.c +++ b/src/Virt_DevicePool.c @@ -51,21 +51,30 @@ struct tmp_disk_pool { bool primordial; }; +static void free_diskpool(struct tmp_disk_pool *pools, int count) +{ + int i; + + if (pools == NULL) { + return; + } + + for (i = 0; i < count; i++) { + free(pools[i].tag); + free(pools[i].path); + } + + free(pools); +} + /* - * Right now, detect support and use it, if available. - * Later, this can be a configure option if needed + * If fail, *_pools will be freed and set to NULL, and *_count will be set to + * zero. */ -#if LIBVIR_VERSION_NUMBER > 4000 -# define VIR_USE_LIBVIRT_STORAGE 1 -#else -# define VIR_USE_LIBVIRT_STORAGE 0 -#endif - static bool get_disk_parent(struct tmp_disk_pool **_pools, int *_count) { struct tmp_disk_pool *pools = NULL; - int ret = false; int count; count = *_count; @@ -74,23 +83,31 @@ static bool get_disk_parent(struct tmp_disk_pool **_pools, pools = realloc(pools, (count + 1) * (sizeof(*pools))); if (pools == NULL) { CU_DEBUG("Failed to alloc new pool"); - goto out; + pools = *_pools; + goto fail; } - pools[count].tag = strdup("0"); pools[count].path = NULL; pools[count].primordial = true; + pools[count].tag = strdup("0"); + if (pools[count].tag == NULL) { + count++; + goto fail; + } count++; *_count = count; *_pools = pools; - ret = true; + return true; - out: - return ret; + fail: + free_diskpool(pools, count); + /* old pool is invalid, update it */ + *_count = 0; + *_pools = NULL; + return false; } - #if VIR_USE_LIBVIRT_STORAGE int get_disk_pool(virStoragePoolPtr poolptr, struct virt_pool **pool) { @@ -117,52 +134,80 @@ int get_disk_pool(virStoragePoolPtr poolptr, struct virt_pool **pool) return ret; } +/* + * return 0 on success, negative on fail, *pools and *_count will be set + * only on success . + */ static int get_diskpool_config(virConnectPtr conn, - struct tmp_disk_pool **_pools) + struct tmp_disk_pool **_pools, + int *_count) { - int count = 0; + int count = 0, realcount = 0; int i; char ** names = NULL; struct tmp_disk_pool *pools = NULL; + int ret = 0; count = virConnectNumOfStoragePools(conn); - if (count <= 0) + if (count < 0) { + ret = count; goto out; + } else if (count == 0) { + goto set_parent; + } names = calloc(count, sizeof(char *)); if (names == NULL) { CU_DEBUG("Failed to alloc space for %i pool names", count); - count = 0; + ret = -1; goto out; } - if (virConnectListStoragePools(conn, names, count) == -1) { - CU_DEBUG("Failed to get storage pools"); - count = 0; - goto out; + realcount = virConnectListStoragePools(conn, names, count); + if (realcount < 0) { + CU_DEBUG("Failed to get storage pools, return %d.", realcount); + ret = realcount; + goto free_names; + } + if (realcount == 0) { + CU_DEBUG("Zero pools got, but prelist is %d.", count); + goto set_parent; } - pools = calloc(count, sizeof(*pools)); + pools = calloc(realcount, sizeof(*pools)); if (pools == NULL) { - CU_DEBUG("Failed to alloc space for %i pool structs", count); - goto out; + CU_DEBUG("Failed to alloc space for %i pool structs", + realcount); + ret = -2; + goto free_names; } - for (i = 0; i < count; i++) { - pools[i].tag = strdup(names[i]); + for (i = 0; i < realcount; i++) { + pools[i].tag = names[i]; + names[i] = NULL; pools[i].primordial = false; } - out: - for (i = 0; i < count; i++) - free(names[i]); - free(names); - - get_disk_parent(&pools, &count); + set_parent: + if (!get_disk_parent(&pools, &realcount)) { + CU_DEBUG("Failed in adding parentpool."); + ret = -4; + /* pools is already freed in get_disk_parent().*/ + goto free_names; + } + /* succeed */ *_pools = pools; + *_count = realcount; + + free_names: + for (i = 0; i < count; i++) { + free(names[i]); + } + free(names); - return count; + out: + return ret; } static bool diskpool_set_capacity(virConnectPtr conn, @@ -279,8 +324,8 @@ static bool _diskpool_is_member(virConnectPtr conn, return result; } #else -static int parse_diskpool_line(struct tmp_disk_pool *pool, - const char *line) +static bool parse_diskpool_line(struct tmp_disk_pool *pool, + const char *line) { int ret; @@ -288,48 +333,81 @@ static int parse_diskpool_line(struct tmp_disk_pool *pool, if (ret != 2) { free(pool->tag); free(pool->path); + pool->tag = NULL; + pool->path = NULL; } pool->primordial = false; return (ret == 2); } +/* + * return 0 on success, negative on fail, *pools and *_count will be set + * only on success . + */ static int get_diskpool_config(virConnectPtr conn, - struct tmp_disk_pool **_pools) + struct tmp_disk_pool **_pools, + int *_count) { const char *path = DISK_POOL_CONFIG; FILE *config; char *line = NULL; size_t len = 0; - int count = 0; - struct tmp_disk_pool *pools = NULL; + int count = 0, ret = 0; + struct tmp_disk_pool *pools = NULL, *new_pools = NULL, *pool = NULL; config = fopen(path, "r"); if (config == NULL) { CU_DEBUG("Failed to open %s: %m", path); - return 0; + ret = -1; + goto out; } + pool = calloc(1, sizeof(*pool)); + if (!pool) { + CU_DEBUG("Failed to calloc pool"); + ret = -2; + goto close; + } + + /* *line will be automatically freed by getline() */ while (getline(&line, &len, config) > 0) { - pools = realloc(pools, - (count + 1) * (sizeof(*pools))); - if (pools == NULL) { - CU_DEBUG("Failed to alloc new pool"); - goto out; + if (parse_diskpool_line(pool, line)) { + new_pools = realloc(pools, + (count + 1) * (sizeof(*pools))); + if (new_pools == NULL) { + CU_DEBUG("Failed to alloc new pool"); + ret = -3; + goto free_pools; + } + pools = new_pools; + pools[count] = *pool; + memset(pool, 0, sizeof(*pool)); + count++; } + } - if (parse_diskpool_line(&pools[count], line)) - count++; + if (!get_disk_parent(&pools, &count)) { + CU_DEBUG("Failed in adding parentpool."); + ret = -4; + /* pools is already freed by get_disk_parent() */ + goto clean; } + /* succeed */ + *_pools = pools; + *_count = count; + goto clean; - get_disk_parent(&pools, &count); - out: + free_pools: + free_diskpool(pools, count); + clean: free(line); - *_pools = pools; + free_diskpool(pool, 1); + close: fclose(config); - - return count; + out: + return ret; } static bool diskpool_set_capacity(virConnectPtr conn, @@ -367,39 +445,23 @@ static bool diskpool_set_capacity(virConnectPtr conn, } static bool _diskpool_is_member(virConnectPtr conn, - const struct disk_pool *pool, + const struct tmp_disk_pool *pool, const char *file) { return STARTS_WITH(file, pool->path); } #endif -static void free_diskpool(struct tmp_disk_pool *pools, int count) -{ - int i; - - if (pools == NULL) - return; - - for (i = 0; i < count; i++) { - free(pools[i].tag); - free(pools[i].path); - } - - free(pools); -} - static char *_diskpool_member_of(virConnectPtr conn, const char *file) { struct tmp_disk_pool *pools = NULL; int count; - int i; + int i, ret; char *pool = NULL; - count = get_diskpool_config(conn, &pools); - if (count == 0) { - free(pools); + ret = get_diskpool_config(conn, &pools, &count); + if (ret < 0) { return NULL; } @@ -1088,9 +1150,17 @@ static CMPIStatus diskpool_instance(virConnectPtr conn, CMPIStatus s = {CMPI_RC_OK, NULL}; struct tmp_disk_pool *pools = NULL; int count = 0; - int i; + int i, ret; - count = get_diskpool_config(conn, &pools); + ret = get_diskpool_config(conn, &pools, &count); + if (ret < 0) { + CU_DEBUG("Failed to get diskpool config, return is %d.", ret); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed to get diskpool config, return is %d.", + ret); + return s; + } if ((id == NULL) && (count == 0)) { CU_DEBUG("No defined DiskPools"); free(pools); diff --git a/src/Virt_DevicePool.h b/src/Virt_DevicePool.h index d160bf1..6b44863 100644 --- a/src/Virt_DevicePool.h +++ b/src/Virt_DevicePool.h @@ -28,6 +28,10 @@ #include "pool_parsing.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 -- 1.7.1

Sometimes libvirt will fail in these APIs if there is low level error, what we saw is libvirt can't got xml for some domain. This patch adds debug log when met this error, so in future we can know what is wrong. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: John Ferlan <jferlan@redhat.com> --- libxkutil/device_parsing.c | 19 ++++++++++++++----- 1 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index ceb4552..264d4cc 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1246,20 +1246,29 @@ int get_dominfo_from_xml(const char *xml, struct domain **dominfo) int get_dominfo(virDomainPtr dom, struct domain **dominfo) { char *xml; - int ret; + int ret = 0; int start; xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE); - if (xml == NULL) + if (xml == NULL) { + CU_DEBUG("Failed to get dom xml with libvirt API."); return 0; + } - ret = get_dominfo_from_xml(xml, dominfo); - if (virDomainGetAutostart(dom, &start) != 0) - return 0; + if (get_dominfo_from_xml(xml, dominfo) == 0) { + CU_DEBUG("Failed to translate xml into struct domain"); + goto out; + } + if (virDomainGetAutostart(dom, &start) != 0) { + CU_DEBUG("Failed to get dom autostart with libvirt API."); + goto out; + } (*dominfo)->autostrt = start; + ret = 1; + out: free(xml); return ret; -- 1.7.1

From cimtest, Calling to virEventRegisterDefaultImpl() of libvirt API, resulting random fail in cases, which seems most likely tog-pegasus's internal data is damaged. The root cause may be: 1 libvirt event API have a bug, we called it from thread A and then do other things in thread B, maybe it did not handle this well. 2 tog-pegasus have confilict with libvirt's event. 3 Potential requirement in libvirt event API or tog-pegasus's thread, which is not document so we used them in a wrong way. Most possible is that tog-pegasus tries to manage all threads resulting the error. This patch bring back libvirt-cim's own old event implemention, which is by default used now. CSI from libvirt can still be activated with a macro. This patch also have changed some buglike code of old libvirt-cim's event implemention. Tested with cimtest on following Env, no more strange error found: RH6.3 libvirt-0.9.10-21.el6.x86_64 tog-pegasus-2.11.0-3.el6.x86_64 Note that to make review easy, this patch try move the code as little as possible, a following "clean up" patch will move the code together. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- src/Virt_ComputerSystem.c | 60 +++- src/Virt_ComputerSystemIndication.c | 663 ++++++++++++++++++++++++++++- src/Virt_VirtualSystemManagementService.c | 57 +++- 3 files changed, 777 insertions(+), 3 deletions(-) diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c index 4a9b26d..d37159f 100644 --- a/src/Virt_ComputerSystem.c +++ b/src/Virt_ComputerSystem.c @@ -45,8 +45,58 @@ #include "Virt_HostSystem.h" #include "Virt_VirtualSystemSnapshotService.h" +#include "config.h" + const static CMPIBroker *_BROKER; +#ifndef USE_LIBVIRT_EVENT +static bool trigger_mod_indication(const CMPIBroker *broker, + const CMPIContext *context, + CMPIInstance *prev_inst, + const CMPIObjectPath *ref) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *ind_name = "ComputerSystemModifiedIndication"; + CMPIInstance *ind = NULL; + char *type = NULL; + + CU_DEBUG("Preparing libvirt-cim native ComputerSystem indication"); + + ind = get_typed_instance(broker, + CLASSNAME(ref), + ind_name, + NAMESPACE(ref), + false); + if (ind == NULL) { + CU_DEBUG("Failed to create ind '%s'", ind_name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed to create ind '%s'", ind_name); + goto out; + } + + CU_DEBUG("Setting PreviousInstance"); + CMSetProperty(ind, "PreviousInstance", + (CMPIValue *)&prev_inst, CMPI_instance); + + type = get_typed_class(CLASSNAME(ref), ind_name); + + s = stdi_raise_indication(broker, context, type, NAMESPACE(ref), ind); + + out: + free(type); + return s.rc == CMPI_RC_OK; +} +#else +static bool trigger_mod_indication(const CMPIBroker *broker, + const CMPIContext *context, + CMPIInstance *prev_inst, + const CMPIObjectPath *ref) +{ + return true; +} +#endif + /* Set the "Name" property of an instance from a domain */ static int set_name_from_dom(virDomainPtr dom, CMPIInstance *instance) { @@ -1258,8 +1308,16 @@ static CMPIStatus state_change(CMPIMethodMI *self, s = __state_change(name, state, reference); - if (s.rc == CMPI_RC_OK) + if (s.rc == CMPI_RC_OK) { rc = 0; + /* try trigger indication */ + bool ind_rc = trigger_mod_indication(_BROKER, context, + prev_inst, reference); + if (!ind_rc) { + CU_DEBUG("Unable to trigger indication for " + "state change, dom is '%s'", name); + } + } out: CMReturnData(results, &rc, CMPI_uint32); diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c index 3df47fa..ef449ff 100644 --- a/src/Virt_ComputerSystemIndication.c +++ b/src/Virt_ComputerSystemIndication.c @@ -48,7 +48,6 @@ #include "Virt_ComputerSystemIndication.h" #include "Virt_HostSystem.h" - #define CSI_NUM_PLATFORMS 3 enum CSI_PLATFORMS { CSI_XEN, @@ -84,6 +83,8 @@ static pthread_mutex_t lifecycle_mutex = PTHREAD_MUTEX_INITIALIZER; static bool lifecycle_enabled = false; static csi_thread_data_t csi_thread_data[CSI_NUM_PLATFORMS] = {{0}, {0}, {0}}; +#ifndef USE_LIBVIRT_EVENT +#else /* * Domain manipulation */ @@ -180,6 +181,7 @@ static void csi_free_thread_data(void *data) stdi_free_ind_args(&thread->args); pthread_mutex_unlock(&lifecycle_mutex); } +#endif void set_source_inst_props(const CMPIBroker *broker, const CMPIContext *context, @@ -386,6 +388,394 @@ static bool create_deleted_guest_inst(const char *xml, return rc; } +#ifndef USE_LIBVIRT_EVENT +/* libvirt-cim's private CSI implement */ + +#define WAIT_TIME 60 +#define FAIL_WAIT_TIME 2 + +static pthread_cond_t lifecycle_cond = PTHREAD_COND_INITIALIZER; + +struct dom_xml { + char uuid[VIR_UUID_STRING_BUFLEN]; + char *xml; + enum {DOM_OFFLINE, + DOM_ONLINE, + DOM_PAUSED, + DOM_CRASHED, + DOM_GONE, + } state; +}; + +static void free_dom_xml(struct dom_xml dom) +{ + free(dom.xml); + dom.xml = NULL; +} + +static char *sys_name_from_xml(char *xml) +{ + char *tmp = NULL; + char *name = NULL; + int rc; + + tmp = strstr(xml, "<name>"); + if (tmp == NULL) { + goto out; + } + + rc = sscanf(tmp, "<name>%a[^<]s</name>", &name); + if (rc != 1) { + name = NULL; + } + + out: + return name; +} + +static int dom_state(virDomainPtr dom) +{ + virDomainInfo info; + int ret; + + ret = virDomainGetInfo(dom, &info); + if (ret != 0) { + return DOM_GONE; + } + + switch (info.state) { + case VIR_DOMAIN_NOSTATE: + case VIR_DOMAIN_RUNNING: + case VIR_DOMAIN_BLOCKED: + return DOM_ONLINE; + + case VIR_DOMAIN_PAUSED: + return DOM_PAUSED; + + case VIR_DOMAIN_SHUTOFF: + return DOM_OFFLINE; + + case VIR_DOMAIN_CRASHED: + return DOM_CRASHED; + + default: + return DOM_GONE; + }; +} + +static CMPIStatus doms_to_xml(struct dom_xml **dom_xml_list, + virDomainPtr *dom_ptr_list, + int dom_ptr_count) +{ + int i; + int rc; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (dom_ptr_count <= 0) { + *dom_xml_list = NULL; + return s; + } + *dom_xml_list = calloc(dom_ptr_count, sizeof(struct dom_xml)); + if (!dom_xml_list) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed calloc %d dom_xml.", dom_ptr_count); + return s; + } + for (i = 0; i < dom_ptr_count; i++) { + rc = virDomainGetUUIDString(dom_ptr_list[i], + (*dom_xml_list)[i].uuid); + if (rc == -1) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to get UUID"); + /* If any domain fails, we fail. */ + break; + } + + (*dom_xml_list)[i].xml = virDomainGetXMLDesc(dom_ptr_list[i], + VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE); + if ((*dom_xml_list)[i].xml == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to get xml desc"); + break; + } + + (*dom_xml_list)[i].state = dom_state(dom_ptr_list[i]); + } + + return s; +} + +static bool dom_changed(struct dom_xml prev_dom, + struct dom_xml *cur_xml, + int cur_count) +{ + int i; + bool ret = false; + + for (i = 0; i < cur_count; i++) { + if (strcmp(cur_xml[i].uuid, prev_dom.uuid) != 0) { + continue; + } + + if (strcmp(cur_xml[i].xml, prev_dom.xml) != 0) { + CU_DEBUG("Domain config changed"); + ret = true; + } + + if (prev_dom.state != cur_xml[i].state) { + CU_DEBUG("Domain state changed"); + ret = true; + } + + break; + } + + return ret; +} + +static bool wait_for_event(int wait_time) +{ + struct timespec timeout; + int ret; + + + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_sec += wait_time; + + ret = pthread_cond_timedwait(&lifecycle_cond, + &lifecycle_mutex, + &timeout); + return !ret; +} + +static bool dom_in_list(char *uuid, int count, struct dom_xml *list) +{ + int i; + + for (i = 0; i < count; i++) { + if (STREQ(uuid, list[i].uuid)) { + return true; + } + } + + return false; +} + +static bool async_ind_native(CMPIContext *context, + int ind_type, + struct dom_xml prev_dom, + char *prefix, + struct ind_args *args) +{ + bool rc = false; + char *name = NULL; + char *cn = NULL; + CMPIObjectPath *op; + CMPIInstance *prev_inst; + CMPIInstance *affected_inst; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + CU_DEBUG("Entering native indication dilivery with type %d.", ind_type) + if (!lifecycle_enabled) { + CU_DEBUG("CSI not enabled, skipping indication delivery"); + return false; + } + + name = sys_name_from_xml(prev_dom.xml); + CU_DEBUG("Name for system: '%s'", name); + if (name == NULL) { + rc = false; + goto out; + } + + cn = get_typed_class(prefix, "ComputerSystem"); + + op = CMNewObjectPath(_BROKER, args->ns, cn, &s); + if ((s.rc != CMPI_RC_OK) || CMIsNullObject(op)) { + CU_DEBUG("op error"); + goto out; + } + + if (ind_type == CS_CREATED || ind_type == CS_MODIFIED) { + s = get_domain_by_name(_BROKER, op, name, &affected_inst); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("domain by name error"); + goto out; + } + } else if (ind_type == CS_DELETED) { + rc = create_deleted_guest_inst(prev_dom.xml, + args->ns, + prefix, + &affected_inst); + if (!rc) { + CU_DEBUG("Could not recreate guest instance"); + goto out; + } + } else { + CU_DEBUG("Unrecognized indication type %d", ind_type); + goto out; + } + + /* FIXME: We are unable to get the previous CS instance after it has + been modified. Consider keeping track of the previous + state in the place we keep track of the requested state */ + prev_inst = affected_inst; + + CMSetProperty(affected_inst, "Name", + (CMPIValue *)name, CMPI_chars); + CMSetProperty(affected_inst, "UUID", + (CMPIValue *)prev_dom.uuid, CMPI_chars); + + rc = _do_indication(_BROKER, context, prev_inst, affected_inst, + ind_type, prefix, args); + + out: + free(cn); + free(name); + return rc; +} + +static CMPI_THREAD_RETURN lifecycle_thread_native(void *params) +{ + CU_DEBUG("Entering libvirtc-cim native CSI thread."); + csi_thread_data_t *thread = (csi_thread_data_t *) params; + struct ind_args *args = thread->args; + CMPIContext *context = args->context; + char *prefix = class_prefix_name(args->classname); + virConnectPtr conn; + CMPIStatus s; + int retry_time = FAIL_WAIT_TIME; + + struct dom_xml *cur_xml = NULL; + struct dom_xml *prev_xml = NULL; + int prev_count = 0; + int cur_count = 0; + virDomainPtr *tmp_list = NULL; + int CBAttached = 0; + + if (prefix == NULL) { + goto init_out; + } + + pthread_mutex_lock(&lifecycle_mutex); + conn = connect_by_classname(_BROKER, args->classname, &s); + if (conn == NULL) { + CU_DEBUG("Unable to start lifecycle thread: " + "Failed to connect (cn: %s)", args->classname); + pthread_mutex_unlock(&lifecycle_mutex); + goto conn_out; + } + + CBAttachThread(_BROKER, args->context); + CBAttached = 1; + prev_count = get_domain_list(conn, &tmp_list); + s = doms_to_xml(&prev_xml, tmp_list, prev_count); + free_domain_list(tmp_list, prev_count); + free(tmp_list); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("doms_to_xml failed. Attempting to continue."); + } + + CU_DEBUG("Entering libvirt-cim native CSI event loop (%s)", prefix); + + int i; + while (1) { + if (thread->active_filters <= 0) { + break; + } + + bool res; + bool failure = false; + + cur_count = get_domain_list(conn, &tmp_list); + s = doms_to_xml(&cur_xml, tmp_list, cur_count); + free_domain_list(tmp_list, cur_count); + free(tmp_list); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("doms_to_xml failed. retry in %d seconds", + retry_time); + failure = true; + goto fail; + } + + /* CU_DEBUG("cur_count %d, prev_count %d.", + cur_count, prev_count); */ + for (i = 0; i < cur_count; i++) { + res = dom_in_list(cur_xml[i].uuid, + prev_count, prev_xml); + if (!res) { + async_ind_native(context, CS_CREATED, + cur_xml[i], prefix, args); + } + + } + + for (i = 0; i < prev_count; i++) { + res = dom_in_list(prev_xml[i].uuid, + cur_count, cur_xml); + if (!res) { + async_ind_native(context, CS_DELETED, + prev_xml[i], prefix, args); + } else if (dom_changed(prev_xml[i], + cur_xml, cur_count)) { + async_ind_native(context, CS_MODIFIED, + prev_xml[i], prefix, args); + } + free_dom_xml(prev_xml[i]); + } + + fail: + if (failure) { + wait_for_event(FAIL_WAIT_TIME); + } else { + free(prev_xml); + prev_xml = cur_xml; + cur_xml = NULL; + prev_count = cur_count; + cur_count = 0; + wait_for_event(WAIT_TIME); + } + } + + CU_DEBUG("Exiting libvirt-cim native CSI event loop (%s)", prefix); + + if (prev_xml != NULL) { + for (i = 0; i < prev_count; i++) { + free_dom_xml(prev_xml[i]); + } + free(prev_xml); + prev_xml = NULL; + } + + pthread_mutex_unlock(&lifecycle_mutex); + + virConnectClose(conn); + + conn_out: + free(prefix); + + init_out: + pthread_mutex_lock(&lifecycle_mutex); + thread->id = 0; + thread->active_filters = 0; + + /* it seems tog-pegasus try kill this thread after detached, use this + flag to delay detach as much as possible. */ + if (CBAttached > 0) { + CBDetachThread(_BROKER, args->context); + } + if (thread->args != NULL) { + stdi_free_ind_args(&thread->args); + } + + pthread_mutex_unlock(&lifecycle_mutex); + + return (CMPI_THREAD_RETURN) 0; +} +#else static bool async_ind(struct ind_args *args, int ind_type, csi_dom_xml_t *dom, @@ -669,6 +1059,7 @@ static CMPI_THREAD_RETURN lifecycle_thread(void *params) free(prefix); return (CMPI_THREAD_RETURN) 0; } +#endif static int platform_from_class(const char *cn) { @@ -682,6 +1073,162 @@ static int platform_from_class(const char *cn) return -1; } +#ifndef USE_LIBVIRT_EVENT +static CMPIStatus ActivateFilter(CMPIIndicationMI *mi, + const CMPIContext *ctx, + const CMPISelectExp *se, + const char *ns, + const CMPIObjectPath *op, + CMPIBoolean first) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + struct std_indication_ctx *_ctx; + struct ind_args *args = NULL; + int platform; + bool error = false; + csi_thread_data_t *thread = NULL; + + CU_DEBUG("ActivateFilter for %s", CLASSNAME(op)); + + pthread_mutex_lock(&lifecycle_mutex); + + CU_DEBUG("Using libvirt-cim's event implemention."); + + _ctx = (struct std_indication_ctx *)mi->hdl; + + if (CMIsNullObject(op)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "No ObjectPath given"); + goto out; + } + + /* FIXME: op is stale the second time around, for some reason */ + platform = platform_from_class(CLASSNAME(op)); + if (platform < 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unknown platform"); + goto out; + } + + thread = &csi_thread_data[platform]; + thread->active_filters += 1; + + /* Check if thread is already running */ + if (thread->id > 0) { + goto out; + } + + args = malloc(sizeof(*args)); + if (args == NULL) { + CU_DEBUG("Failed to allocate ind_args"); + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Unable to allocate ind_args"); + error = true; + goto out; + } + + args->context = CBPrepareAttachThread(_BROKER, ctx); + if (args->context == NULL) { + CU_DEBUG("Failed to create thread context"); + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Unable to create thread context"); + error = true; + goto out; + } + + args->ns = strdup(NAMESPACE(op)); + args->classname = strdup(CLASSNAME(op)); + args->_ctx = _ctx; + + thread->args = args; + + thread->id = _BROKER->xft->newThread(lifecycle_thread_native, + thread, 0); + + if (thread->id <= 0) { + CU_DEBUG("Error, failed to create new thread."); + error = true; + } + + out: + if (error == true) { + thread->active_filters -= 1; + free(args); + } + + pthread_mutex_unlock(&lifecycle_mutex); + + return s; +} + +static CMPIStatus DeActivateFilter(CMPIIndicationMI *mi, + const CMPIContext *ctx, + const CMPISelectExp *se, + const char *ns, + const CMPIObjectPath *op, + CMPIBoolean last) +{ + int platform; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + CU_DEBUG("DeActivateFilter for %s", CLASSNAME(op)); + + platform = platform_from_class(CLASSNAME(op)); + if (platform < 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unknown platform"); + goto out; + } + + + pthread_mutex_lock(&lifecycle_mutex); + csi_thread_data[platform].active_filters -= 1; + pthread_mutex_unlock(&lifecycle_mutex); + + pthread_cond_signal(&lifecycle_cond); + + out: + return s; +} + +static CMPIStatus trigger_indication(const CMPIContext *context) +{ + CU_DEBUG("triggered"); + pthread_cond_signal(&lifecycle_cond); + return (CMPIStatus){CMPI_RC_OK, NULL}; +} + +static CMPIInstance *get_prev_inst(const CMPIBroker *broker, + const CMPIInstance *ind, + CMPIStatus *s) +{ + CMPIData data; + CMPIInstance *prev_inst = NULL; + + data = CMGetProperty(ind, "PreviousInstance", s); + if (s->rc != CMPI_RC_OK || CMIsNullValue(data)) { + cu_statusf(broker, s, + CMPI_RC_ERR_NO_SUCH_PROPERTY, + "Unable to get PreviousInstance of the indication"); + goto out; + } + + if (data.type != CMPI_instance) { + cu_statusf(broker, s, + CMPI_RC_ERR_TYPE_MISMATCH, + "Indication SourceInstance is of unexpected type"); + goto out; + } + + prev_inst = data.value.inst; + + out: + return prev_inst; +} +#else static CMPIStatus ActivateFilter(CMPIIndicationMI* mi, const CMPIContext* ctx, const CMPISelectExp* se, @@ -703,6 +1250,7 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi, if (events_registered == 0) { events_registered = 1; + CU_DEBUG("Registering libvirt event."); virEventRegisterDefaultImpl(); } @@ -756,6 +1304,11 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi, thread->args = args; thread->id = _BROKER->xft->newThread(lifecycle_thread, thread, 0); + if (thread->id <= 0) { + CU_DEBUG("Error, failed to create new thread."); + error = true; + } + out: if (error == true) { thread->active_filters -= 1; @@ -795,6 +1348,7 @@ static CMPIStatus DeActivateFilter(CMPIIndicationMI* mi, out: return s; } +#endif static _EI_RTYPE EnableIndications(CMPIIndicationMI* mi, const CMPIContext *ctx) @@ -841,7 +1395,114 @@ static struct std_ind_filter *filters[] = { NULL, }; +#ifndef USE_LIBVIRT_EVENT +static CMPIStatus raise_indication(const CMPIBroker *broker, + const CMPIContext *ctx, + const CMPIObjectPath *ref, + const CMPIInstance *ind) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *prev_inst; + CMPIInstance *src_inst; + CMPIObjectPath *_ref = NULL; + struct std_indication_ctx *_ctx = NULL; + struct ind_args *args = NULL; + char *prefix = NULL; + bool rc; + + if (!lifecycle_enabled) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "CSI not enabled, skipping indication delivery"); + goto out; + } + + prev_inst = get_prev_inst(broker, ind, &s); + if (s.rc != CMPI_RC_OK || CMIsNullObject(prev_inst)) { + goto out; + } + + _ref = CMGetObjectPath(prev_inst, &s); + if (s.rc != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to get a reference to the guest"); + goto out; + } + + /* FIXME: This is a Pegasus work around. Pegsus loses the namespace + when an ObjectPath is pulled from an instance */ + if (STREQ(NAMESPACE(_ref), "")) { + CMSetNameSpace(_ref, "root/virt"); + } + + s = get_domain_by_ref(broker, _ref, &src_inst); + if (s.rc != CMPI_RC_OK || CMIsNullObject(src_inst)) { + goto out; + } + + _ctx = malloc(sizeof(struct std_indication_ctx)); + if (_ctx == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to allocate indication context"); + goto out; + } + + _ctx->brkr = broker; + _ctx->handler = NULL; + _ctx->filters = filters; + _ctx->enabled = lifecycle_enabled; + + args = malloc(sizeof(struct ind_args)); + if (args == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to allocate ind_args"); + goto out; + } + + args->ns = strdup(NAMESPACE(_ref)); + args->classname = strdup(CLASSNAME(_ref)); + if (!args->classname || !args->ns) { + CU_DEBUG("Failed in strdup"); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed in strdup in indication raising"); + goto out; + } + args->_ctx = _ctx; + + prefix = class_prefix_name(args->classname); + + rc = _do_indication(broker, ctx, prev_inst, src_inst, + CS_MODIFIED, prefix, args); + + if (!rc) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to generate indication"); + } + + out: + if (args != NULL) { + stdi_free_ind_args(&args); + } + + if (_ctx != NULL) { + free(_ctx); + } + + free(prefix); + return s; +} +#endif + static struct std_indication_handler csi = { +#ifndef USE_LIBVIRT_EVENT + .raise_fn = raise_indication, + .trigger_fn = trigger_indication, +#endif .activate_fn = ActivateFilter, .deactivate_fn = DeActivateFilter, .enable_fn = EnableIndications, diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 6322daf..cbb646d 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -107,6 +107,33 @@ enum ResourceAction { RESOURCE_MOD, }; +#ifndef USE_LIBVIRT_EVENT +static bool trigger_indication(const CMPIBroker *broker, + const CMPIContext *context, + const char *base_type, + const CMPIObjectPath *ref) +{ + char *type; + CMPIStatus s; + + type = get_typed_class(CLASSNAME(ref), base_type); + + s = stdi_trigger_indication(broker, context, type, NAMESPACE(ref)); + + free(type); + + return s.rc == CMPI_RC_OK; +} +#else +static bool trigger_indication(const CMPIBroker *broker; + const CMPIContext *context, + const char *base_type, + const CMPIObjectPath *ref) +{ + return true; +} +#endif + #if LIBVIR_VERSION_NUMBER < 9000 /* Network QoS support */ static CMPIStatus add_qos_for_mac(const uint64_t qos, @@ -2167,6 +2194,16 @@ static CMPIStatus define_system(CMPIMethodMI *self, CMAddArg(argsout, "ResultingSystem", &result, CMPI_ref); } + /* try trigger indication */ + bool ind_rc = trigger_indication(_BROKER, context, + "ComputerSystemCreatedIndication", reference); + if (!ind_rc) { + const char *dom_name = NULL; + cu_get_str_prop(vssd, "VirtualSystemIdentifier", &dom_name); + CU_DEBUG("Unable to trigger indication for " + "system create, dom is '%s'", dom_name); + } + out: if (s.rc == CMPI_RC_OK) rc = CIM_SVPC_RETURN_COMPLETED; @@ -2269,6 +2306,15 @@ error: NULL, reference, &list); + + /* try trigger indication */ + bool ind_rc = trigger_indication(_BROKER, context, + "ComputerSystemDeletedIndication", reference); + if (!ind_rc) { + CU_DEBUG("Unable to trigger indication for " + "system delete, dom is '%s'", dom_name); + } + } virDomainFree(dom); @@ -2350,8 +2396,17 @@ static CMPIStatus update_system_settings(const CMPIContext *context, connect_and_create(xml, ref, &s); } - if (s.rc == CMPI_RC_OK) + if (s.rc == CMPI_RC_OK) { set_autostart(vssd, ref, dom); + /* try trigger indication */ + bool ind_rc = trigger_indication(_BROKER, context, + "ComputerSystemModifiedIndication", ref); + if (!ind_rc) { + CU_DEBUG("Unable to trigger indication for " + "system modify, dom is '%s'", name); + } + + } out: free(xml); -- 1.7.1

This is a pure code move patch. Now codes using libvirt event or native event, are moved into one macro protection, which make code easy to read, and in futher they can be moved into new file as CSI-libvirt.c. This patch also fix code style problem in moved code. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- src/Virt_ComputerSystemIndication.c | 851 ++++++++++++++++++----------------- 1 files changed, 429 insertions(+), 422 deletions(-) diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c index ef449ff..247143c 100644 --- a/src/Virt_ComputerSystemIndication.c +++ b/src/Virt_ComputerSystemIndication.c @@ -83,106 +83,6 @@ static pthread_mutex_t lifecycle_mutex = PTHREAD_MUTEX_INITIALIZER; static bool lifecycle_enabled = false; static csi_thread_data_t csi_thread_data[CSI_NUM_PLATFORMS] = {{0}, {0}, {0}}; -#ifndef USE_LIBVIRT_EVENT -#else -/* - * Domain manipulation - */ -static void csi_dom_xml_free(void *data) -{ - csi_dom_xml_t *dom = (csi_dom_xml_t *) data; - free(dom->xml); - free(dom->name); - free(dom); -} - -static int csi_dom_xml_cmp(void *data, void *cmp_cb_data) -{ - csi_dom_xml_t *dom = (csi_dom_xml_t *) data; - const char *uuid = (const char *) cmp_cb_data; - - return strcmp(dom->uuid, uuid); -} - -static int csi_dom_xml_set(csi_dom_xml_t *dom, virDomainPtr dom_ptr, CMPIStatus *s) -{ - const char *name; - - name = virDomainGetName(dom_ptr); - if (name == NULL) { - cu_statusf(_BROKER, s, - CMPI_RC_ERR_FAILED, - "Failed to get domain name"); - return -1; - } - - dom->name = strdup(name); - - /* xml */ - dom->xml = virDomainGetXMLDesc(dom_ptr, - VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE); - if (dom->xml == NULL) { - cu_statusf(_BROKER, s, - CMPI_RC_ERR_FAILED, - "Failed to get xml desc"); - return -1; - } - - return 0; -} - -static csi_dom_xml_t *csi_dom_xml_new(virDomainPtr dom_ptr, CMPIStatus *s) -{ - int rc; - csi_dom_xml_t *dom; - - dom = calloc(1, sizeof(*dom)); - if (dom == NULL) - return NULL; - - /* uuid */ - rc = virDomainGetUUIDString(dom_ptr, dom->uuid); - if (rc == -1) { - cu_statusf(_BROKER, s, - CMPI_RC_ERR_FAILED, - "Failed to get domain UUID"); - goto error; - } - - if (csi_dom_xml_set(dom, dom_ptr, s) == -1) - goto error; - - return dom; - - error: - csi_dom_xml_free(dom); - return NULL; -} - -static void csi_thread_dom_list_append(csi_thread_data_t *thread, - csi_dom_xml_t *dom) -{ - if (thread->dom_list == NULL) - thread->dom_list = list_new(csi_dom_xml_free, csi_dom_xml_cmp); - - list_append(thread->dom_list, dom); -} - -static void csi_free_thread_data(void *data) -{ - csi_thread_data_t *thread = (csi_thread_data_t *) data; - - if (data == NULL) - return; - - pthread_mutex_lock(&lifecycle_mutex); - list_free(thread->dom_list); - thread->dom_list = NULL; - stdi_free_ind_args(&thread->args); - pthread_mutex_unlock(&lifecycle_mutex); -} -#endif - void set_source_inst_props(const CMPIBroker *broker, const CMPIContext *context, const CMPIObjectPath *ref, @@ -388,6 +288,64 @@ static bool create_deleted_guest_inst(const char *xml, return rc; } +static int platform_from_class(const char *cn) +{ + if (STARTS_WITH(cn, "Xen")) { + return CSI_XEN; + } else if (STARTS_WITH(cn, "KVM")) { + return CSI_KVM; + } else if (STARTS_WITH(cn, "LXC")) { + return CSI_LXC; + } else { + return -1; + } +} + +static _EI_RTYPE EnableIndications(CMPIIndicationMI *mi, + const CMPIContext *ctx) +{ + CU_DEBUG("EnableIndications"); + pthread_mutex_lock(&lifecycle_mutex); + lifecycle_enabled = true; + pthread_mutex_unlock(&lifecycle_mutex); + + _EI_RET(); +} + +static _EI_RTYPE DisableIndications(CMPIIndicationMI *mi, + const CMPIContext *ctx) +{ + CU_DEBUG("DisableIndications"); + pthread_mutex_lock(&lifecycle_mutex); + lifecycle_enabled = false; + pthread_mutex_unlock(&lifecycle_mutex); + + _EI_RET(); +} + +DECLARE_FILTER(xen_created, "Xen_ComputerSystemCreatedIndication"); +DECLARE_FILTER(xen_deleted, "Xen_ComputerSystemDeletedIndication"); +DECLARE_FILTER(xen_modified, "Xen_ComputerSystemModifiedIndication"); +DECLARE_FILTER(kvm_created, "KVM_ComputerSystemCreatedIndication"); +DECLARE_FILTER(kvm_deleted, "KVM_ComputerSystemDeletedIndication"); +DECLARE_FILTER(kvm_modified, "KVM_ComputerSystemModifiedIndication"); +DECLARE_FILTER(lxc_created, "LXC_ComputerSystemCreatedIndication"); +DECLARE_FILTER(lxc_deleted, "LXC_ComputerSystemDeletedIndication"); +DECLARE_FILTER(lxc_modified, "LXC_ComputerSystemModifiedIndication"); + +static struct std_ind_filter *filters[] = { + &xen_created, + &xen_deleted, + &xen_modified, + &kvm_created, + &kvm_deleted, + &kvm_modified, + &lxc_created, + &lxc_deleted, + &lxc_modified, + NULL, +}; + #ifndef USE_LIBVIRT_EVENT /* libvirt-cim's private CSI implement */ @@ -775,7 +733,377 @@ static CMPI_THREAD_RETURN lifecycle_thread_native(void *params) return (CMPI_THREAD_RETURN) 0; } + +static CMPIStatus ActivateFilter(CMPIIndicationMI *mi, + const CMPIContext *ctx, + const CMPISelectExp *se, + const char *ns, + const CMPIObjectPath *op, + CMPIBoolean first) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + struct std_indication_ctx *_ctx; + struct ind_args *args = NULL; + int platform; + bool error = false; + csi_thread_data_t *thread = NULL; + + CU_DEBUG("ActivateFilter for %s", CLASSNAME(op)); + + pthread_mutex_lock(&lifecycle_mutex); + + CU_DEBUG("Using libvirt-cim's event implemention."); + + _ctx = (struct std_indication_ctx *)mi->hdl; + + if (CMIsNullObject(op)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "No ObjectPath given"); + goto out; + } + + /* FIXME: op is stale the second time around, for some reason */ + platform = platform_from_class(CLASSNAME(op)); + if (platform < 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unknown platform"); + goto out; + } + + thread = &csi_thread_data[platform]; + thread->active_filters += 1; + + /* Check if thread is already running */ + if (thread->id > 0) { + goto out; + } + + args = malloc(sizeof(*args)); + if (args == NULL) { + CU_DEBUG("Failed to allocate ind_args"); + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Unable to allocate ind_args"); + error = true; + goto out; + } + + args->context = CBPrepareAttachThread(_BROKER, ctx); + if (args->context == NULL) { + CU_DEBUG("Failed to create thread context"); + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Unable to create thread context"); + error = true; + goto out; + } + + args->ns = strdup(NAMESPACE(op)); + args->classname = strdup(CLASSNAME(op)); + args->_ctx = _ctx; + + thread->args = args; + + thread->id = _BROKER->xft->newThread(lifecycle_thread_native, + thread, 0); + + if (thread->id <= 0) { + CU_DEBUG("Error, failed to create new thread."); + error = true; + } + + out: + if (error == true) { + thread->active_filters -= 1; + free(args); + } + + pthread_mutex_unlock(&lifecycle_mutex); + + return s; +} + +static CMPIStatus DeActivateFilter(CMPIIndicationMI *mi, + const CMPIContext *ctx, + const CMPISelectExp *se, + const char *ns, + const CMPIObjectPath *op, + CMPIBoolean last) +{ + int platform; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + CU_DEBUG("DeActivateFilter for %s", CLASSNAME(op)); + + platform = platform_from_class(CLASSNAME(op)); + if (platform < 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unknown platform"); + goto out; + } + + + pthread_mutex_lock(&lifecycle_mutex); + csi_thread_data[platform].active_filters -= 1; + pthread_mutex_unlock(&lifecycle_mutex); + + pthread_cond_signal(&lifecycle_cond); + + out: + return s; +} + +static CMPIStatus trigger_indication(const CMPIContext *context) +{ + CU_DEBUG("triggered"); + pthread_cond_signal(&lifecycle_cond); + return (CMPIStatus){CMPI_RC_OK, NULL}; +} + +static CMPIInstance *get_prev_inst(const CMPIBroker *broker, + const CMPIInstance *ind, + CMPIStatus *s) +{ + CMPIData data; + CMPIInstance *prev_inst = NULL; + + data = CMGetProperty(ind, "PreviousInstance", s); + if (s->rc != CMPI_RC_OK || CMIsNullValue(data)) { + cu_statusf(broker, s, + CMPI_RC_ERR_NO_SUCH_PROPERTY, + "Unable to get PreviousInstance of the indication"); + goto out; + } + + if (data.type != CMPI_instance) { + cu_statusf(broker, s, + CMPI_RC_ERR_TYPE_MISMATCH, + "Indication SourceInstance is of unexpected type"); + goto out; + } + + prev_inst = data.value.inst; + + out: + return prev_inst; +} + +static CMPIStatus raise_indication(const CMPIBroker *broker, + const CMPIContext *ctx, + const CMPIObjectPath *ref, + const CMPIInstance *ind) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *prev_inst; + CMPIInstance *src_inst; + CMPIObjectPath *_ref = NULL; + struct std_indication_ctx *_ctx = NULL; + struct ind_args *args = NULL; + char *prefix = NULL; + bool rc; + + if (!lifecycle_enabled) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "CSI not enabled, skipping indication delivery"); + goto out; + } + + prev_inst = get_prev_inst(broker, ind, &s); + if (s.rc != CMPI_RC_OK || CMIsNullObject(prev_inst)) { + goto out; + } + + _ref = CMGetObjectPath(prev_inst, &s); + if (s.rc != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to get a reference to the guest"); + goto out; + } + + /* FIXME: This is a Pegasus work around. Pegsus loses the namespace + when an ObjectPath is pulled from an instance */ + if (STREQ(NAMESPACE(_ref), "")) { + CMSetNameSpace(_ref, "root/virt"); + } + + s = get_domain_by_ref(broker, _ref, &src_inst); + if (s.rc != CMPI_RC_OK || CMIsNullObject(src_inst)) { + goto out; + } + + _ctx = malloc(sizeof(struct std_indication_ctx)); + if (_ctx == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to allocate indication context"); + goto out; + } + + _ctx->brkr = broker; + _ctx->handler = NULL; + _ctx->filters = filters; + _ctx->enabled = lifecycle_enabled; + + args = malloc(sizeof(struct ind_args)); + if (args == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to allocate ind_args"); + goto out; + } + + args->ns = strdup(NAMESPACE(_ref)); + args->classname = strdup(CLASSNAME(_ref)); + if (!args->classname || !args->ns) { + CU_DEBUG("Failed in strdup"); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed in strdup in indication raising"); + goto out; + } + args->_ctx = _ctx; + + prefix = class_prefix_name(args->classname); + + rc = _do_indication(broker, ctx, prev_inst, src_inst, + CS_MODIFIED, prefix, args); + + if (!rc) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to generate indication"); + } + + out: + if (args != NULL) { + stdi_free_ind_args(&args); + } + + if (_ctx != NULL) { + free(_ctx); + } + + free(prefix); + return s; +} + +static struct std_indication_handler csi = { + .raise_fn = raise_indication, + .trigger_fn = trigger_indication, + .activate_fn = ActivateFilter, + .deactivate_fn = DeActivateFilter, + .enable_fn = EnableIndications, + .disable_fn = DisableIndications, +}; #else +/* Using libvirt's event to implement CSI */ + +/* + * Domain manipulation + */ +static void csi_dom_xml_free(void *data) +{ + csi_dom_xml_t *dom = (csi_dom_xml_t *) data; + free(dom->xml); + free(dom->name); + free(dom); +} + +static int csi_dom_xml_cmp(void *data, void *cmp_cb_data) +{ + csi_dom_xml_t *dom = (csi_dom_xml_t *) data; + const char *uuid = (const char *) cmp_cb_data; + + return strcmp(dom->uuid, uuid); +} + +static int csi_dom_xml_set(csi_dom_xml_t *dom, + virDomainPtr dom_ptr, + CMPIStatus *s) +{ + const char *name; + + name = virDomainGetName(dom_ptr); + if (name == NULL) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "Failed to get domain name"); + return -1; + } + + dom->name = strdup(name); + + /* xml */ + dom->xml = virDomainGetXMLDesc(dom_ptr, + VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE); + if (dom->xml == NULL) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "Failed to get xml desc"); + return -1; + } + + return 0; +} + +static csi_dom_xml_t *csi_dom_xml_new(virDomainPtr dom_ptr, CMPIStatus *s) +{ + int rc; + csi_dom_xml_t *dom; + + dom = calloc(1, sizeof(*dom)); + if (dom == NULL) { + return NULL; + } + + /* uuid */ + rc = virDomainGetUUIDString(dom_ptr, dom->uuid); + if (rc == -1) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "Failed to get domain UUID"); + goto error; + } + + if (csi_dom_xml_set(dom, dom_ptr, s) == -1) { + goto error; + } + + return dom; + + error: + csi_dom_xml_free(dom); + return NULL; +} + +static void csi_thread_dom_list_append(csi_thread_data_t *thread, + csi_dom_xml_t *dom) +{ + if (thread->dom_list == NULL) { + thread->dom_list = list_new(csi_dom_xml_free, csi_dom_xml_cmp); + } + + list_append(thread->dom_list, dom); +} + +static void csi_free_thread_data(void *data) +{ + csi_thread_data_t *thread = (csi_thread_data_t *) data; + + if (data == NULL) { + return; + } + + pthread_mutex_lock(&lifecycle_mutex); + list_free(thread->dom_list); + thread->dom_list = NULL; + stdi_free_ind_args(&thread->args); + pthread_mutex_unlock(&lifecycle_mutex); +} + static bool async_ind(struct ind_args *args, int ind_type, csi_dom_xml_t *dom, @@ -1059,176 +1387,7 @@ static CMPI_THREAD_RETURN lifecycle_thread(void *params) free(prefix); return (CMPI_THREAD_RETURN) 0; } -#endif - -static int platform_from_class(const char *cn) -{ - if (STARTS_WITH(cn, "Xen")) - return CSI_XEN; - else if (STARTS_WITH(cn, "KVM")) - return CSI_KVM; - else if (STARTS_WITH(cn, "LXC")) - return CSI_LXC; - else - return -1; -} - -#ifndef USE_LIBVIRT_EVENT -static CMPIStatus ActivateFilter(CMPIIndicationMI *mi, - const CMPIContext *ctx, - const CMPISelectExp *se, - const char *ns, - const CMPIObjectPath *op, - CMPIBoolean first) -{ - CMPIStatus s = {CMPI_RC_OK, NULL}; - struct std_indication_ctx *_ctx; - struct ind_args *args = NULL; - int platform; - bool error = false; - csi_thread_data_t *thread = NULL; - - CU_DEBUG("ActivateFilter for %s", CLASSNAME(op)); - - pthread_mutex_lock(&lifecycle_mutex); - - CU_DEBUG("Using libvirt-cim's event implemention."); - - _ctx = (struct std_indication_ctx *)mi->hdl; - - if (CMIsNullObject(op)) { - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "No ObjectPath given"); - goto out; - } - - /* FIXME: op is stale the second time around, for some reason */ - platform = platform_from_class(CLASSNAME(op)); - if (platform < 0) { - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "Unknown platform"); - goto out; - } - - thread = &csi_thread_data[platform]; - thread->active_filters += 1; - - /* Check if thread is already running */ - if (thread->id > 0) { - goto out; - } - - args = malloc(sizeof(*args)); - if (args == NULL) { - CU_DEBUG("Failed to allocate ind_args"); - cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, - "Unable to allocate ind_args"); - error = true; - goto out; - } - - args->context = CBPrepareAttachThread(_BROKER, ctx); - if (args->context == NULL) { - CU_DEBUG("Failed to create thread context"); - cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, - "Unable to create thread context"); - error = true; - goto out; - } - - args->ns = strdup(NAMESPACE(op)); - args->classname = strdup(CLASSNAME(op)); - args->_ctx = _ctx; - - thread->args = args; - - thread->id = _BROKER->xft->newThread(lifecycle_thread_native, - thread, 0); - - if (thread->id <= 0) { - CU_DEBUG("Error, failed to create new thread."); - error = true; - } - - out: - if (error == true) { - thread->active_filters -= 1; - free(args); - } - - pthread_mutex_unlock(&lifecycle_mutex); - - return s; -} - -static CMPIStatus DeActivateFilter(CMPIIndicationMI *mi, - const CMPIContext *ctx, - const CMPISelectExp *se, - const char *ns, - const CMPIObjectPath *op, - CMPIBoolean last) -{ - int platform; - CMPIStatus s = {CMPI_RC_OK, NULL}; - - CU_DEBUG("DeActivateFilter for %s", CLASSNAME(op)); - platform = platform_from_class(CLASSNAME(op)); - if (platform < 0) { - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "Unknown platform"); - goto out; - } - - - pthread_mutex_lock(&lifecycle_mutex); - csi_thread_data[platform].active_filters -= 1; - pthread_mutex_unlock(&lifecycle_mutex); - - pthread_cond_signal(&lifecycle_cond); - - out: - return s; -} - -static CMPIStatus trigger_indication(const CMPIContext *context) -{ - CU_DEBUG("triggered"); - pthread_cond_signal(&lifecycle_cond); - return (CMPIStatus){CMPI_RC_OK, NULL}; -} - -static CMPIInstance *get_prev_inst(const CMPIBroker *broker, - const CMPIInstance *ind, - CMPIStatus *s) -{ - CMPIData data; - CMPIInstance *prev_inst = NULL; - - data = CMGetProperty(ind, "PreviousInstance", s); - if (s->rc != CMPI_RC_OK || CMIsNullValue(data)) { - cu_statusf(broker, s, - CMPI_RC_ERR_NO_SUCH_PROPERTY, - "Unable to get PreviousInstance of the indication"); - goto out; - } - - if (data.type != CMPI_instance) { - cu_statusf(broker, s, - CMPI_RC_ERR_TYPE_MISMATCH, - "Indication SourceInstance is of unexpected type"); - goto out; - } - - prev_inst = data.value.inst; - - out: - return prev_inst; -} -#else static CMPIStatus ActivateFilter(CMPIIndicationMI* mi, const CMPIContext* ctx, const CMPISelectExp* se, @@ -1348,166 +1507,14 @@ static CMPIStatus DeActivateFilter(CMPIIndicationMI* mi, out: return s; } -#endif - -static _EI_RTYPE EnableIndications(CMPIIndicationMI* mi, - const CMPIContext *ctx) -{ - CU_DEBUG("EnableIndications"); - pthread_mutex_lock(&lifecycle_mutex); - lifecycle_enabled = true; - pthread_mutex_unlock(&lifecycle_mutex); - - _EI_RET(); -} - -static _EI_RTYPE DisableIndications(CMPIIndicationMI* mi, - const CMPIContext *ctx) -{ - CU_DEBUG("DisableIndications"); - pthread_mutex_lock(&lifecycle_mutex); - lifecycle_enabled = false; - pthread_mutex_unlock(&lifecycle_mutex); - - _EI_RET(); -} - -DECLARE_FILTER(xen_created, "Xen_ComputerSystemCreatedIndication"); -DECLARE_FILTER(xen_deleted, "Xen_ComputerSystemDeletedIndication"); -DECLARE_FILTER(xen_modified, "Xen_ComputerSystemModifiedIndication"); -DECLARE_FILTER(kvm_created, "KVM_ComputerSystemCreatedIndication"); -DECLARE_FILTER(kvm_deleted, "KVM_ComputerSystemDeletedIndication"); -DECLARE_FILTER(kvm_modified, "KVM_ComputerSystemModifiedIndication"); -DECLARE_FILTER(lxc_created, "LXC_ComputerSystemCreatedIndication"); -DECLARE_FILTER(lxc_deleted, "LXC_ComputerSystemDeletedIndication"); -DECLARE_FILTER(lxc_modified, "LXC_ComputerSystemModifiedIndication"); - -static struct std_ind_filter *filters[] = { - &xen_created, - &xen_deleted, - &xen_modified, - &kvm_created, - &kvm_deleted, - &kvm_modified, - &lxc_created, - &lxc_deleted, - &lxc_modified, - NULL, -}; - -#ifndef USE_LIBVIRT_EVENT -static CMPIStatus raise_indication(const CMPIBroker *broker, - const CMPIContext *ctx, - const CMPIObjectPath *ref, - const CMPIInstance *ind) -{ - CMPIStatus s = {CMPI_RC_OK, NULL}; - CMPIInstance *prev_inst; - CMPIInstance *src_inst; - CMPIObjectPath *_ref = NULL; - struct std_indication_ctx *_ctx = NULL; - struct ind_args *args = NULL; - char *prefix = NULL; - bool rc; - - if (!lifecycle_enabled) { - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "CSI not enabled, skipping indication delivery"); - goto out; - } - - prev_inst = get_prev_inst(broker, ind, &s); - if (s.rc != CMPI_RC_OK || CMIsNullObject(prev_inst)) { - goto out; - } - - _ref = CMGetObjectPath(prev_inst, &s); - if (s.rc != CMPI_RC_OK) { - cu_statusf(broker, &s, - CMPI_RC_ERR_FAILED, - "Unable to get a reference to the guest"); - goto out; - } - - /* FIXME: This is a Pegasus work around. Pegsus loses the namespace - when an ObjectPath is pulled from an instance */ - if (STREQ(NAMESPACE(_ref), "")) { - CMSetNameSpace(_ref, "root/virt"); - } - - s = get_domain_by_ref(broker, _ref, &src_inst); - if (s.rc != CMPI_RC_OK || CMIsNullObject(src_inst)) { - goto out; - } - - _ctx = malloc(sizeof(struct std_indication_ctx)); - if (_ctx == NULL) { - cu_statusf(broker, &s, - CMPI_RC_ERR_FAILED, - "Unable to allocate indication context"); - goto out; - } - - _ctx->brkr = broker; - _ctx->handler = NULL; - _ctx->filters = filters; - _ctx->enabled = lifecycle_enabled; - - args = malloc(sizeof(struct ind_args)); - if (args == NULL) { - cu_statusf(broker, &s, - CMPI_RC_ERR_FAILED, - "Unable to allocate ind_args"); - goto out; - } - - args->ns = strdup(NAMESPACE(_ref)); - args->classname = strdup(CLASSNAME(_ref)); - if (!args->classname || !args->ns) { - CU_DEBUG("Failed in strdup"); - cu_statusf(broker, &s, - CMPI_RC_ERR_FAILED, - "Failed in strdup in indication raising"); - goto out; - } - args->_ctx = _ctx; - - prefix = class_prefix_name(args->classname); - - rc = _do_indication(broker, ctx, prev_inst, src_inst, - CS_MODIFIED, prefix, args); - - if (!rc) { - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "Unable to generate indication"); - } - - out: - if (args != NULL) { - stdi_free_ind_args(&args); - } - - if (_ctx != NULL) { - free(_ctx); - } - - free(prefix); - return s; -} -#endif static struct std_indication_handler csi = { -#ifndef USE_LIBVIRT_EVENT - .raise_fn = raise_indication, - .trigger_fn = trigger_indication, -#endif .activate_fn = ActivateFilter, .deactivate_fn = DeActivateFilter, .enable_fn = EnableIndications, .disable_fn = DisableIndications, }; +#endif DEFAULT_IND_CLEANUP(); DEFAULT_AF(); -- 1.7.1

Original code 'continue' in the 'for' in return_enum_vssd() when one VSDS fail in retrieving, but forgot to set s to normal. This patch fix this case. Also many debug message is added to log the error if met. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- src/Virt_VSSD.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/Virt_VSSD.c b/src/Virt_VSSD.c index 975623b..24bf908 100644 --- a/src/Virt_VSSD.c +++ b/src/Virt_VSSD.c @@ -181,8 +181,10 @@ static int instance_from_dom(const CMPIBroker *broker, struct domain *dominfo = NULL; ret = get_dominfo(dom, &dominfo); - if (!ret) + if (!ret) { + CU_DEBUG("Failed in get_dominfo()."); goto out; + } op = CMGetObjectPath(inst, NULL); pfx = class_prefix_name(CLASSNAME(op)); @@ -245,6 +247,7 @@ static int instance_from_dom(const CMPIBroker *broker, (dominfo->type == DOMAIN_KVM) || (dominfo->type == DOMAIN_QEMU)) { s = _set_fv_prop(broker, dominfo, inst); if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Failed to set full virtual props."); ret = 0; goto out; } @@ -259,6 +262,7 @@ static int instance_from_dom(const CMPIBroker *broker, dominfo->type); if (asprintf(&vsid, "%s:%s", pfx, dominfo->name) == -1) { + CU_DEBUG("Failed in asprintf()."); ret = 0; goto out; } @@ -312,7 +316,7 @@ static CMPIStatus return_enum_vssd(const CMPIObjectPath *reference, virConnectPtr conn; virDomainPtr *list; int count; - int i; + int i, fail_count = 0; CMPIStatus s = {CMPI_RC_OK, NULL}; conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s); @@ -333,9 +337,29 @@ static CMPIStatus return_enum_vssd(const CMPIObjectPath *reference, inst = _get_vssd(_BROKER, reference, conn, list[i], &s); - virDomainFree(list[i]); - if (inst == NULL) + if (inst == NULL) { + /* log the error */ + const char *dom_name = virDomainGetName(list[i]); + if (s.msg) { + CU_DEBUG("Failed to get VSSD instance from " + "domain [%s], status msg [%s].", + dom_name, CMGetCharPtr(s.msg)); + } else { + CU_DEBUG("Failed to get VSSD instance from " + "domain [%s].", + dom_name); + } + /* restore s until last one */ + if (i < count - 1) { + cu_statusf(_BROKER, &s, + CMPI_RC_OK, + "NULL"); + } + fail_count++; + virDomainFree(list[i]); continue; + } + virDomainFree(list[i]); if (names_only) cu_return_instance_name(results, inst); @@ -343,6 +367,21 @@ static CMPIStatus return_enum_vssd(const CMPIObjectPath *reference, CMReturnInstance(results, inst); } + /* check if some VS fail */ + if (fail_count > 0) { + CU_DEBUG("Failed to get %d VSSD in enum, total is %d.", + fail_count, count); + if (fail_count < count) { + /* consider it succeed, some VSSD will be returned */ + cu_statusf(_BROKER, &s, + CMPI_RC_OK, + "Got %d/%d VSSD, " + "some VS may changed during enum", + count - fail_count, count); + } + } + + out: free(list); virConnectClose(conn); -- 1.7.1

This patch adds an common internal function to get property from libvirt-cim config, so it is easy to add properties later. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- libxkutil/misc_util.c | 114 +++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 100 insertions(+), 14 deletions(-) diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c index f1b93e4..820b42d 100644 --- a/libxkutil/misc_util.c +++ b/libxkutil/misc_util.c @@ -106,14 +106,40 @@ static const char *cn_to_uri(const char *classname) return NULL; } -static int is_read_only(void) -{ - int readonly = 0; +/* config support */ +typedef enum LibvirtcimConfigType { + CONFIG_BOOL, + CONFIG_STRING, +} LibvirtcimConfigType; + +typedef struct LibvirtcimConfigProperty { + const char *name; + LibvirtcimConfigType value_type; + union { + int value_bool; + char *value_string; + }; + int have_read; +} LibvirtcimConfigProperty; #ifdef HAVE_LIBCONFIG +/* + * @prop must be initialized with zeros, except default value, return 0 means + * OK. prop->value_string will be automatically freed if not NULL, caller must + * never set it to const char*. + */ +static int libvirt_cim_config_get(LibvirtcimConfigProperty *prop) +{ + int error = 0; config_t conf; - int ret; - const char *readonly_str = "readonly"; + int ret = 0; + const char *value_string = NULL; + + /* try only once */ + if (prop->have_read == 1) { + return 0; + } + prop->have_read = 1; config_init(&conf); @@ -121,24 +147,84 @@ static int is_read_only(void) if (ret == CONFIG_FALSE) { CU_DEBUG("Error reading config file at line %d: '%s'\n", conf.error_line, conf.error_text); + error = -1; goto out; } - ret = config_lookup_bool(&conf, readonly_str, &readonly); - if (ret == CONFIG_FALSE) { - CU_DEBUG("'%s' not found in config file, assuming false\n", - readonly_str); - goto out; + switch (prop->value_type) { + case CONFIG_BOOL: + ret = config_lookup_bool(&conf, + prop->name, &prop->value_bool); + if (ret == CONFIG_FALSE) { + CU_DEBUG("Bool property '%s' in config file '%s' " + "not found.", + prop->name, LIBVIRTCIM_CONF); + error = -1; + goto out; + } + + CU_DEBUG("Bool property '%s' in config file '%s' is '%d'.", + prop->name, LIBVIRTCIM_CONF, prop->value_bool); + break; + case CONFIG_STRING: + ret = config_lookup_string(&conf, + prop->name, &value_string); + if (ret == CONFIG_FALSE) { + CU_DEBUG("String property '%s' in config file '%s' " + "not found.", + prop->name, LIBVIRTCIM_CONF); + error = -1; + goto out; + } + + CU_DEBUG("String property '%s' in config file '%s' is '%s'.", + prop->name, LIBVIRTCIM_CONF, value_string); + + if (prop->value_string) { + CU_DEBUG("String property '%s' have value '%s', will " + "be overwritten.", + prop->name, prop->value_string); + free(prop->value_string); + } + prop->value_string = strdup(value_string); + if (!prop->value_string) { + CU_DEBUG("Failed in duplicate value '%s'", + value_string); + error = -1; + goto out; + } + break; + default: + CU_DEBUG("Got invalid property type request %d.", + prop->value_type); + error = -1; + break; } - CU_DEBUG("'%s' value in '%s' config file: %d\n", readonly_str, - LIBVIRTCIM_CONF, readonly); out: config_destroy(&conf); + return error; +} +#else +static int libvirt_cim_config_get(LibvirtcimConfigProperty *prop) +{ + /* try only once */ + if (prop->have_read == 1) { + return 0; + } + prop->have_read = 1; + + CU_DEBUG("Built without libconfig, can't read '%s'.", prop->name); + return -2; +} #endif - /* Default value is 0 (false) */ - return readonly; +static int is_read_only(void) +{ + static LibvirtcimConfigProperty prop = { + "readonly", CONFIG_BOOL, {0}, 0}; + libvirt_cim_config_get(&prop); + return prop.value_bool; } virConnectPtr connect_by_classname(const CMPIBroker *broker, -- 1.7.1

This patch allow libvirt-cim to use non-root's ssh key in migration to avoid exposing root's ssh login on server. In some case server are forbidden to expose or provide any root ssh login, and still use ssh encryption between two migration nodes with key of special account created for virtual machine management. When it is enabled in config file: 1 MigrateSSHKeyCopy, use string property [SSH_Key_Src] to tell which key to be copied. It will be copied to [migrate_ssh_temp_key]. 2 MigrateVirtualSystemToHost and CheckVirtualSystemIsMigratableToHost, use bool property [MigrationWithoutRootKey], to tell whether to use the key as [migrate_ssh_temp_key]. 3 MigrateSSHKeyDelete, when it is called [migrate_ssh_temp_key] will be deleted. Details: libvirt-cim would run shell command "cp -f [SSH_Key_Src] [migrate_ssh_temp_key]", then use [migrate_ssh_temp_key] to generate uri suffix for remote connection to migration destination. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libvirt-cim.conf | 19 +++ libxkutil/misc_util.c | 9 ++ libxkutil/misc_util.h | 3 + src/Virt_VSMigrationService.c | 264 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 290 insertions(+), 5 deletions(-) diff --git a/libvirt-cim.conf b/libvirt-cim.conf index d3cb2c3..37d7b0f 100644 --- a/libvirt-cim.conf +++ b/libvirt-cim.conf @@ -11,3 +11,22 @@ # Default value: false # # readonly = false; + +# migrate_ssh_temp_key (string) +# Defines a temp key file which would be used as ssh key in ssh migration, +# Only when it is set, following methods in VirtualSystemMigrationService +# could be used: +# 1 MigrateSSHKeyCopy, use string property [SSH_Key_Src] to tell which key +# to be copied. It will be copied to [migrate_ssh_temp_key]. +# 2 MigrateVirtualSystemToHost and CheckVirtualSystemIsMigratableToHost, +# use bool property [MigrationWithoutRootKey], to tell whether to use the key +# as [migrate_ssh_temp_key]. +# 3 MigrateSSHKeyDelete, when it is called [migrate_ssh_temp_key] will be +# deleted. +# Note: migrate_ssh_temp_key must be set in a directory completely owned by +# root from bottom to top, such as /root/A, or /tmp/A. +# +# Possible values: {any path plus filename on host} +# Default value: NULL, that is not set. +# +# migrate_ssh_temp_key = "/root/vm_migrate_tmp_id_rsa"; diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c index 820b42d..00eb4b1 100644 --- a/libxkutil/misc_util.c +++ b/libxkutil/misc_util.c @@ -227,6 +227,15 @@ static int is_read_only(void) return prop.value_bool; } +const char *get_mig_ssh_tmp_key(void) +{ + static LibvirtcimConfigProperty prop = { + "migrate_ssh_temp_key", CONFIG_STRING, {0}, 0}; + + libvirt_cim_config_get(&prop); + return prop.value_string; +} + virConnectPtr connect_by_classname(const CMPIBroker *broker, const char *classname, CMPIStatus *s) diff --git a/libxkutil/misc_util.h b/libxkutil/misc_util.h index 90fb2da..0f52290 100644 --- a/libxkutil/misc_util.h +++ b/libxkutil/misc_util.h @@ -152,6 +152,9 @@ int virt_set_status(const CMPIBroker *broker, #define REF2STR(r) CMGetCharPtr(CMObjectPathToString(r, NULL)) +/* get libvirt-cim config */ +const char *get_mig_ssh_tmp_key(void); + /* * Local Variables: * mode: C diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c index 1f6659d..c701e7d 100644 --- a/src/Virt_VSMigrationService.c +++ b/src/Virt_VSMigrationService.c @@ -150,6 +150,7 @@ static CMPIStatus get_migration_uri(CMPIInstance *msd, static char *dest_uri(const char *cn, const char *dest, + const char *dest_params, uint16_t transport) { const char *prefix; @@ -157,6 +158,7 @@ static char *dest_uri(const char *cn, const char *param = ""; char *uri = NULL; int rc; + int param_labeled = 0; if (STARTS_WITH(cn, "Xen")) prefix = "xen"; @@ -197,16 +199,54 @@ static char *dest_uri(const char *cn, goto out; } - if (!STREQC(param, "")) + if (!STREQC(param, "")) { rc = asprintf(&uri, "%s/%s", uri, param); + param_labeled = 1; + } - if (rc == -1) + if (rc == -1) { uri = NULL; + goto out; + } + if (dest_params) { + if (param_labeled == 0) { + rc = asprintf(&uri, "%s?%s", uri, dest_params); + } else { + /* ? is already added */ + rc = asprintf(&uri, "%s%s", uri, dest_params); + } + if (rc == -1) { + uri = NULL; + goto out; + } + } out: return uri; } +/* Todo: move it to libcmpiutil */ +static CMPIrc cu_get_bool_arg_my(const CMPIArgs *args, + const char *name, + bool *target) +{ + CMPIData argdata; + CMPIStatus s; + + argdata = CMGetArg(args, name, &s); + if ((s.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) { + return CMPI_RC_ERR_INVALID_PARAMETER; + } + + if (argdata.type != CMPI_boolean) { + return CMPI_RC_ERR_TYPE_MISMATCH; + } + + *target = (bool)argdata.value.boolean; + + return CMPI_RC_OK; +} + static CMPIStatus get_msd_values(const CMPIObjectPath *ref, const char *destination, const CMPIArgs *argsin, @@ -217,6 +257,13 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, CMPIInstance *msd; uint16_t uri_type; char *uri = NULL; + bool use_non_root_ssh_key = false; + char *dest_params = NULL; + int ret; + + cu_get_bool_arg_my(argsin, + "MigrationWithoutRootKey", + &use_non_root_ssh_key); s = get_msd(ref, argsin, &msd); if (s.rc != CMPI_RC_OK) @@ -230,7 +277,27 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, if (s.rc != CMPI_RC_OK) goto out; - uri = dest_uri(CLASSNAME(ref), destination, uri_type); + if (use_non_root_ssh_key) { + const char *tmp_keyfile = get_mig_ssh_tmp_key(); + if (!tmp_keyfile) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Migration with special ssh key " + "is not enabled in config file."); + CU_DEBUG("Migration with special ssh key " + "is not enabled in config file."); + goto out; + } + CU_DEBUG("Trying migrate with specified ssh key file [%s].", + tmp_keyfile); + ret = asprintf(&dest_params, "keyfile=%s", tmp_keyfile); + if (ret < 0) { + CU_DEBUG("Failed in generating param string."); + goto out; + } + } + + uri = dest_uri(CLASSNAME(ref), destination, dest_params, uri_type); if (uri == NULL) { cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, @@ -238,6 +305,7 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, goto out; } + CU_DEBUG("Migrate tring to connect remote host with uri %s.", uri); *conn = virConnectOpen(uri); if (*conn == NULL) { CU_DEBUG("Failed to connect to remote host (%s)", uri); @@ -249,7 +317,7 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, out: free(uri); - + free(dest_params); return s; } @@ -1538,7 +1606,7 @@ static CMPIStatus migrate_vs_host(CMPIMethodMI *self, const char *dhost = NULL; CMPIObjectPath *system; const char *name = NULL; - + cu_get_str_arg(argsin, "DestinationHost", &dhost); cu_get_ref_arg(argsin, "ComputerSystem", &system); @@ -1604,11 +1672,179 @@ static CMPIStatus migrate_vs_system(CMPIMethodMI *self, return migrate_do(ref, ctx, name, dname, argsin, results, argsout); } +/* return 0 on success */ +static int pipe_exec(const char *cmd) +{ + FILE *stream = NULL; + int ret = 0; + char buf[256]; + + CU_DEBUG("executing system cmd [%s].", cmd); + /* Todo: We need a better popen, currently stdout have been closed + and SIGCHILD is handled by tog-pegasus, so fgets always got NULL + making error detection not possible. */ + stream = popen(cmd, "r"); + if (stream == NULL) { + CU_DEBUG("Failed to open pipe to run the command."); + ret = -1; + goto out; + } + usleep(10000); + + buf[255] = 0; + while (fgets(buf, sizeof(buf), stream) != NULL) { + CU_DEBUG("Exception got: [%s].", buf); + ret = -2; + goto out; + } + + out: + if (stream != NULL) { + pclose(stream); + } + return ret; +} + +/* + * libvirt require private key specified to be placed in a directory owned by + * root, because libvirt-cim now runs as root. So here the key would be copied. + * In this way libvirt-cim could borrow a non-root ssh private key, instead of + * using root's private key, avoid security risk. + */ +static int ssh_key_copy(const char *src, const char *dest) +{ + char *cmd = NULL; + int ret = 0; + struct stat sb; + + /* try delete it */ + unlink(dest); + ret = stat(dest, &sb); + if (ret == 0) { + CU_DEBUG("Can not delete [%s] before copy, " + "maybe someone is using it.", + dest); + ret = -1; + goto out; + } + + ret = asprintf(&cmd, "cp -f %s %s", src, dest); + if (ret < 0) { + CU_DEBUG("Failed in combination for shell command."); + goto out; + } + + ret = pipe_exec(cmd); + if (ret < 0) { + CU_DEBUG("Error in executing command [%s]"); + goto out; + } + + ret = stat(dest, &sb); + if (ret < 0) { + CU_DEBUG("Can not find file [%s] after copy.", dest); + } + out: + free(cmd); + return ret; +} + +static CMPIStatus migrate_sshkey_copy(CMPIMethodMI *self, + const CMPIContext *ctx, + const CMPIResult *results, + const CMPIObjectPath *ref, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *ssh_key_src = NULL; + int ret; + + const char *tmp_keyfile = get_mig_ssh_tmp_key(); + if (!tmp_keyfile) { + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Migration with special ssh key " + "is not enabled in config file."); + CU_DEBUG("Migration with special ssh key " + "is not enabled in config file."); + goto out; + } + + cu_get_str_arg(argsin, "SSH_Key_Src", &ssh_key_src); + if (!ssh_key_src) { + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Failed to get property 'SSH_Key_Src'."); + CU_DEBUG("Failed to get property 'SSH_Key_Src'."); + goto out; + } + + ret = ssh_key_copy(ssh_key_src, tmp_keyfile); + if (ret < 0) { + cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, + "Got error in copying ssh key from [%s] to [%s].", + ssh_key_src, tmp_keyfile); + CU_DEBUG("Got error in copying ssh key from [%s] to [%s].", + ssh_key_src, tmp_keyfile); + } + + out: + METHOD_RETURN(results, s.rc); + return s; +} + +static CMPIStatus migrate_sshkey_delete(CMPIMethodMI *self, + const CMPIContext *ctx, + const CMPIResult *results, + const CMPIObjectPath *ref, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + int ret; + struct stat sb; + + const char *tmp_keyfile = get_mig_ssh_tmp_key(); + if (!tmp_keyfile) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Migration with special ssh key " + "is not enabled in config file."); + CU_DEBUG("Migration with special ssh key " + "is not enabled in config file."); + goto out; + } + + ret = stat(tmp_keyfile, &sb); + if (ret == 0) { + /* need delete */ + ret = unlink(tmp_keyfile); + if (ret < 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to delete [%s].", + tmp_keyfile); + CU_DEBUG("Failed to delete [%s].", tmp_keyfile); + } + } else { + /* not exist */ + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Can not find file [%s] before delete.", + tmp_keyfile); + CU_DEBUG("Can not find file [%s] before delete.", tmp_keyfile); + } + + out: + METHOD_RETURN(results, s.rc); + return s; +}; + static struct method_handler vsimth = { .name = "CheckVirtualSystemIsMigratableToHost", .handler = vs_migratable_host, .args = {{"ComputerSystem", CMPI_ref, false}, {"DestinationHost", CMPI_string, false}, + {"MigrationWithoutRootKey", CMPI_boolean, true}, {"MigrationSettingData", CMPI_instance, true}, {"NewSystemSettingData", CMPI_instance, true}, {"NewResourceSettingData", CMPI_instanceA, true}, @@ -1633,6 +1869,7 @@ static struct method_handler mvsth = { .handler = migrate_vs_host, .args = {{"ComputerSystem", CMPI_ref, false}, {"DestinationHost", CMPI_string, false}, + {"MigrationWithoutRootKey", CMPI_boolean, true}, {"MigrationSettingData", CMPI_instance, true}, {"NewSystemSettingData", CMPI_instance, true}, {"NewResourceSettingData", CMPI_instanceA, true}, @@ -1652,11 +1889,28 @@ static struct method_handler mvsts = { } }; +static struct method_handler msshkc = { + .name = "MigrateSSHKeyCopy", + .handler = migrate_sshkey_copy, + .args = {{"SSH_Key_Src", CMPI_string, true}, + ARG_END + } +}; + +static struct method_handler msshkd = { + .name = "MigrateSSHKeyDelete", + .handler = migrate_sshkey_delete, + .args = {ARG_END + } +}; + static struct method_handler *my_handlers[] = { &vsimth, &vsimts, &mvsth, &mvsts, + &msshkc, + &msshkd, NULL }; -- 1.7.1

From: John Ferlan <jferlan@redhat.com> During the postinstall and preuninstall phases various variables are modified to build up the list of mofs to be installed. The generated output had ".//usr/local/share/libvirt-cim/*" which caused issues finding files. This is a followup to commit '22022870' which changed the paths using to schema for each of the variables. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- Makefile.am | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0fdd8bb..63ed3c7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -189,7 +189,7 @@ install-data-local: $(install_sh_DATA) -t "$(DESTDIR)$(pkgdatadir)" $(INTEROP_MOFS) $(install_sh_DATA) -t "$(DESTDIR)$(pkgdatadir)" $(INTEROP_REGS) if [[ @CIMSERVER@ != pegasus ]]; then \ - sed -i '/^# --/,/^# --!/d' $(subst ./schema,$(DESTDIR)$(pkgdatadir), $(PGINTEROP_REGS)); \ + sed -i '/^# --/,/^# --!/d' $(subst $(top_srcdir)/schema,$(DESTDIR)$(pkgdatadir), $(PGINTEROP_REGS)); \ fi uninstall-local: @@ -206,21 +206,21 @@ preinstall: # Un/Register the providers and class definitions from/to the current CIMOM. # @CIMSERVER@ is set by the configure script postinstall: - sh provider-register.sh -v -t @CIMSERVER@ -n @CIM_VIRT_NS@ -r $(subst schema,$(pkgdatadir), $(REGS)) -m $(subst schema,$(pkgdatadir), $(MOFS)) - sh provider-register.sh -v -t @CIMSERVER@ -n root/interop -r $(subst schema,$(pkgdatadir), $(INTEROP_REGS)) -m $(subst schema,$(pkgdatadir), $(INTEROP_MOFS)) - sh provider-register.sh -v -t @CIMSERVER@ -n root/cimv2 -r $(subst schema,$(pkgdatadir), $(CIMV2_REGS)) -m $(subst schema,$(pkgdatadir), $(CIMV2_MOFS)) + sh provider-register.sh -v -t @CIMSERVER@ -n @CIM_VIRT_NS@ -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(MOFS)) + sh provider-register.sh -v -t @CIMSERVER@ -n root/interop -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(INTEROP_REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(INTEROP_MOFS)) + sh provider-register.sh -v -t @CIMSERVER@ -n root/cimv2 -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(CIMV2_REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(CIMV2_MOFS)) if [[ @CIMSERVER@ = pegasus ]]; then \ - sh provider-register.sh -v -t @CIMSERVER@ -n root/PG_InterOp -r $(subst schema,$(pkgdatadir), $(PGINTEROP_REGS)) -m $(subst schema,$(pkgdatadir), $(PGINTEROP_MOFS)); \ + sh provider-register.sh -v -t @CIMSERVER@ -n root/PG_InterOp -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(PGINTEROP_REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(PGINTEROP_MOFS)); \ fi virsh -v | grep -q '^0.3' && cp examples/diskpool.conf $(DISK_POOL_CONFIG) || true mkdir -p $(INFO_STORE) preuninstall: - sh provider-register.sh -v -d -t @CIMSERVER@ -n @CIM_VIRT_NS@ -r $(subst schema,$(pkgdatadir), $(REGS)) -m $(subst schema,$(pkgdatadir), $(MOFS)) - sh provider-register.sh -v -d -t @CIMSERVER@ -n root/interop -r $(subst schema,$(pkgdatadir), $(INTEROP_REGS)) -m $(subst schema,$(pkgdatadir), $(INTEROP_MOFS)) - sh provider-register.sh -v -d -t @CIMSERVER@ -n root/cimv2 -r $(subst schema,$(pkgdatadir), $(CIMV2_REGS)) -m $(subst schema,$(pkgdatadir), $(CIMV2_MOFS)) + sh provider-register.sh -v -d -t @CIMSERVER@ -n @CIM_VIRT_NS@ -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(MOFS)) + sh provider-register.sh -v -d -t @CIMSERVER@ -n root/interop -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(INTEROP_REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(INTEROP_MOFS)) + sh provider-register.sh -v -d -t @CIMSERVER@ -n root/cimv2 -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(CIMV2_REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(CIMV2_MOFS)) if [[ @CIMSERVER@ = pegasus ]]; then \ - sh provider-register.sh -v -d -t @CIMSERVER@ -n root/PG_InterOp -r $(subst schema,$(pkgdatadir), $(PGINTEROP_REGS)) -m $(subst schema,$(pkgdatadir), $(PGINTEROP_MOFS)); \ + sh provider-register.sh -v -d -t @CIMSERVER@ -n root/PG_InterOp -r $(subst $(top_srcdir)/schema,$(pkgdatadir), $(PGINTEROP_REGS)) -m $(subst $(top_srcdir)/schema,$(pkgdatadir), $(PGINTEROP_MOFS)); \ fi rpm: clean -- 1.7.1

From: John Ferlan <jferlan@redhat.com> For Fedora 17 and RHEL7 use systemd, so change the pegasus startup to use that and make a dependency upon it. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libvirt-cim.spec.in | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in index 3def978..0679d7f 100644 --- a/libvirt-cim.spec.in +++ b/libvirt-cim.spec.in @@ -6,7 +6,7 @@ Version: @PACKAGE_VERSION@ Release: 1%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries -Source: libvirt-cim-%{version}.tar.gz +Source: ftp://libvirt.org/libvirt-cim/libvirt-cim-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/CIM/ Requires: libxml2 >= 2.6.0 @@ -27,6 +27,9 @@ BuildRequires: libconfig-devel BuildRequires: libxml2-devel BuildRequires: libcmpiutil-devel +%if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 +BuildRequires: systemd-units +%endif BuildConflicts: sblim-cmpi-devel %description @@ -85,7 +88,12 @@ rm -fr $RPM_BUILD_ROOT %{_datadir}/%{name}/install_base_schema.sh %{_datadir}/%{name} -/etc/init.d/tog-pegasus condrestart +# Fedora 17 / RHEL-7 are first where we use systemd. +%if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 + systemctl restart tog-pegasus +%else + /etc/init.d/tog-pegasus condrestart +%endif %{_datadir}/%{name}/provider-register.sh -t pegasus \ -n @CIM_VIRT_NS@ \ -- 1.7.1

From: John Ferlan <jferlan@redhat.com> Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- schema/SwitchService.registration | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/schema/SwitchService.registration b/schema/SwitchService.registration index b8e4f23..82a5c04 100644 --- a/schema/SwitchService.registration +++ b/schema/SwitchService.registration @@ -3,4 +3,3 @@ Xen_SwitchService root/virt Virt_SwitchService Virt_SwitchService instance KVM_SwitchService root/virt Virt_SwitchService Virt_SwitchService instance LXC_SwitchService root/virt Virt_SwitchService Virt_SwitchService instance - -- 1.7.1

From: John Ferlan <jferlan@redhat.com> A change was made in 0.9.10 to disallow a script on a bridge device for qemu guests, see 'libvirt' commit id '1734cdb99'. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 2dcd0d2..94fb7d3 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -270,16 +270,22 @@ static const char *set_net_source(xmlNodePtr nic, } -static const char *bridge_net_to_xml(xmlNodePtr nic, struct net_device *dev) +static const char *bridge_net_to_xml(xmlNodePtr nic, struct net_device *dev, + int domtype) { const char *script = "vif-bridge"; xmlNodePtr tmp; const char *msg = NULL; - tmp = xmlNewChild(nic, NULL, BAD_CAST "script", NULL); - if (tmp == NULL) - return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "path", BAD_CAST script); + /* Scripts only supported on Xen guests see 'libvirt' + * commit id 1734cdb99 (since 0.9.10) */ + if (domtype == DOMAIN_XENPV || domtype == DOMAIN_XENFV) { + tmp = xmlNewChild(nic, NULL, BAD_CAST "script", NULL); + if (tmp == NULL) { + return XML_ERROR; + } + xmlNewProp(tmp, BAD_CAST "path", BAD_CAST script); + } msg = set_net_source(nic, dev, "bridge"); @@ -375,13 +381,13 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo) } #endif - if (STREQ(dev->dev.net.type, "network")) + if (STREQ(dev->dev.net.type, "network")) { msg = set_net_source(nic, net, "network"); - else if (STREQ(dev->dev.net.type, "bridge")) - msg = bridge_net_to_xml(nic, net); - else if (STREQ(dev->dev.net.type, "user")) + } else if (STREQ(dev->dev.net.type, "bridge")) { + msg = bridge_net_to_xml(nic, net, dominfo->type); + } else if (STREQ(dev->dev.net.type, "user")) { continue; - else if (STREQ(dev->dev.net.type, "direct")) { + } else if (STREQ(dev->dev.net.type, "direct")) { msg = set_net_source(nic, net, "direct"); if (net->vsi.vsi_type != NULL) { struct vsi_device *vsi = &dev->dev.net.vsi; -- 1.7.1

From: John Ferlan <jferlan@redhat.com> This is an optimization over using the multistep approach to get a count, get some memory, and get the list of domains (active and defined). Followed other examples to ensure only building the code if the libvirt version is correct. The API was added in 0.9.13. Macro USE_VIR_CONNECT_LIST_ALL_DOMAINS is used to activate it, which should be added in configure in the future. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libxkutil/cs_util_instance.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/libxkutil/cs_util_instance.c b/libxkutil/cs_util_instance.c index a383147..490017c 100644 --- a/libxkutil/cs_util_instance.c +++ b/libxkutil/cs_util_instance.c @@ -33,6 +33,31 @@ #include "cs_util.h" #include <libcmpiutil/libcmpiutil.h> +#define USE_VIR_CONNECT_LIST_ALL_DOMAINS 0 + +#if LIBVIR_VERSION_NUMBER >= 9013 && USE_VIR_CONNECT_LIST_ALL_DOMAINS +int get_domain_list(virConnectPtr conn, virDomainPtr **_list) +{ + virDomainPtr *nameList = NULL; + int n_names; + int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE; + + n_names = virConnectListAllDomains(conn, + &nameList, + flags); + if (n_names > 0) { + *_list = nameList; + } else if (n_names == 0) { + /* Since there are no elements, no domain ptrs to free + * but still must free the nameList returned + */ + free(nameList); + } + + return n_names; +} +#else int get_domain_list(virConnectPtr conn, virDomainPtr **_list) { char **names = NULL; @@ -113,6 +138,7 @@ int get_domain_list(virConnectPtr conn, virDomainPtr **_list) return idx; } +#endif /* LIBVIR_VERSION_NUMBER >= 0913 */ void set_instance_class_name(CMPIInstance *instance, char *name) { -- 1.7.1

From: John Ferlan <jferlan@redhat.com> Rather than the somewhat unreliable get a count and get a list of active names, use the newer virConnectListAll* interfaces in order to retrieve both a count and list in one call. Macro USE_VIR_CONNECT_LIST_ALL_STORAGE_POOLS, USE_VIR_CONNECT_LIST_ALL_NETWORKS and USE_VIR_CONNECT_LIST_ALL_DOMAINS are used to activate thses functions. It require libvirt > 1.0.0, and the code should be moved into a condition in configure later. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- src/Virt_DevicePool.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 238 insertions(+), 0 deletions(-) diff --git a/src/Virt_DevicePool.c b/src/Virt_DevicePool.c index a8dc9cd..e375acc 100644 --- a/src/Virt_DevicePool.c +++ b/src/Virt_DevicePool.c @@ -109,6 +109,10 @@ static bool get_disk_parent(struct tmp_disk_pool **_pools, } #if VIR_USE_LIBVIRT_STORAGE +#define USE_VIR_CONNECT_LIST_ALL_STORAGE_POOLS 0 +#define USE_VIR_CONNECT_LIST_ALL_NETWORKS 0 +#define USE_VIR_CONNECT_LIST_ALL_DOMAINS 0 + int get_disk_pool(virStoragePoolPtr poolptr, struct virt_pool **pool) { char *xml; @@ -138,6 +142,77 @@ int get_disk_pool(virStoragePoolPtr poolptr, struct virt_pool **pool) * return 0 on success, negative on fail, *pools and *_count will be set * only on success . */ +#if LIBVIR_VERSION_NUMBER >= 100002 && USE_VIR_CONNECT_LIST_ALL_STORAGE_POOLS +static int get_diskpool_config(virConnectPtr conn, + struct tmp_disk_pool **_pools, + int *_count) +{ + int i, realcount = 0; + virStoragePoolPtr *nameList = NULL; + int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE; + struct tmp_disk_pool *pools = NULL; + int ret = 0; + bool bret; + + realcount = virConnectListAllStoragePools(conn, + &nameList, + flags); + if (realcount < 0) { + CU_DEBUG("Failed to get storage pools, return %d.", realcount); + ret = realcount; + goto out; + } + if (realcount == 0) { + CU_DEBUG("Zero pools got."); + goto set_parent; + } + + pools = calloc(realcount, sizeof(*pools)); + if (pools == NULL) { + CU_DEBUG("Failed to alloc space for %i pool structs", + realcount); + ret = -2; + goto free_names; + } + + for (i = 0; i < realcount; i++) { + pools[i].tag = strdup(virStoragePoolGetName(nameList[i])); + if (pools[i].tag == NULL) { + CU_DEBUG("Failed in strdup for storage pool name."); + ret = -3; + goto free_pools; + } + pools[i].primordial = false; + } + + set_parent: + bret = get_disk_parent(&pools, &realcount); + if (bret != true) { + CU_DEBUG("Failed in adding parentpool."); + ret = -4; + goto free_pools; + } + + /* succeed */ + *_pools = pools; + *_count = realcount; + goto free_names; + + free_pools: + free_diskpool(pools, realcount); + + free_names: + if (nameList != NULL) { + for (i = 0; i < realcount; i++) { + virStoragePoolFree(nameList[i]); + } + free(nameList); + } + + out: + return ret; +} +#else static int get_diskpool_config(virConnectPtr conn, struct tmp_disk_pool **_pools, int *_count) @@ -209,6 +284,7 @@ static int get_diskpool_config(virConnectPtr conn, out: return ret; } +#endif /* LIBVIR_VERSION_NUMBER >= 100002 */ static bool diskpool_set_capacity(virConnectPtr conn, CMPIInstance *inst, @@ -530,6 +606,46 @@ static char *diskpool_member_of(const CMPIBroker *broker, return pool; } + +#if LIBVIR_VERSION_NUMBER >= 100002 && USE_VIR_CONNECT_LIST_ALL_NETWORKS +static virNetworkPtr bridge_to_network(virConnectPtr conn, + const char *bridge) +{ + int i, num; + virNetworkPtr *nameList = NULL; + virNetworkPtr network = NULL; + int flags = VIR_CONNECT_LIST_NETWORKS_ACTIVE; + + num = virConnectListAllNetworks(conn, + &nameList, + flags); + if (num < 0) { + CU_DEBUG("Failed to get network pools."); + return NULL; + } + + for (i = 0; i < num; i++) { + const char *_netname; + char *_bridge; + + _netname = virNetworkGetName(nameList[i]); + _bridge = virNetworkGetBridgeName(network); + CU_DEBUG("Network `%s' has bridge `%s'", _netname, _bridge); + if (STREQ(bridge, _bridge)) { + network = nameList[i]; + nameList[i] = NULL; + i = num; /* Loop breaker */ + } + free(_bridge); + } + + for (i = 0; i < num; i++) { + virNetworkFree(nameList[i]); + } + free(nameList); + return network; +} +#else static virNetworkPtr bridge_to_network(virConnectPtr conn, const char *bridge) { @@ -573,6 +689,7 @@ static virNetworkPtr bridge_to_network(virConnectPtr conn, return network; } +#endif /* LIBVIR_VERSION_NUMBER >= 100002 */ static char *_netpool_member_of(virConnectPtr conn, const struct net_device *ndev) @@ -749,6 +866,40 @@ static bool mempool_set_total(CMPIInstance *inst, virConnectPtr conn) return memory != 0; } +#if LIBVIR_VERSION_NUMBER >= 9013 && USE_VIR_CONNECT_LIST_ALL_DOMAINS +static bool mempool_set_consumed(CMPIInstance *inst, virConnectPtr conn) +{ + uint64_t memory = 0; + virDomainPtr *nameList = NULL; + int n_names, i; + int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE; + + n_names = virConnectListAllDomains(conn, + &nameList, + flags); + if (n_names < 0) { + CU_DEBUG("Failed to get a list of all domains"); + goto out; + } + + for (i = 0; i < n_names; i++) { + virDomainInfo dom_info; + if (virDomainGetInfo(nameList[i], &dom_info) == 0) { + memory += dom_info.memory; + } + virDomainFree(nameList[i]); + } + free(nameList); + + out: + CMSetProperty(inst, "Reserved", + (CMPIValue *)&memory, CMPI_uint64); + CMSetProperty(inst, "CurrentlyConsumedResource", + (CMPIValue *)&memory, CMPI_uint64); + + return memory != 0; +} +#else static bool mempool_set_consumed(CMPIInstance *inst, virConnectPtr conn) { uint64_t memory = 0; @@ -793,6 +944,7 @@ static bool mempool_set_consumed(CMPIInstance *inst, virConnectPtr conn) return memory != 0; } +#endif /* LIBVIR_VERSION_NUMBER >= 9013 */ static bool procpool_set_total(CMPIInstance *inst, virConnectPtr conn) { @@ -1032,6 +1184,91 @@ static CMPIStatus _netpool_for_network(struct inst_list *list, return s; } +#if LIBVIR_VERSION_NUMBER >= 100002 && USE_VIR_CONNECT_LIST_ALL_NETWORKS +static CMPIStatus netpool_instance(virConnectPtr conn, + struct inst_list *list, + const char *ns, + const char *id, + const CMPIBroker *broker) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + char **netnames = NULL; + int i; + int nets = 0; + virNetworkPtr *nameList = NULL; + int flags = VIR_CONNECT_LIST_NETWORKS_ACTIVE; + + if (id != NULL) { + return _netpool_for_network(list, + ns, + conn, + id, + pfx_from_conn(conn), + broker); + } + + nets = virConnectListAllNetworks(conn, + &nameList, + flags); + if (nets < 0) { + virt_set_status(broker, &s, + CMPI_RC_ERR_FAILED, + conn, + "Unable to list networks"); + + goto out; + } + + /* +1 for our primordial entry */ + netnames = calloc(nets+1, sizeof(*netnames)); + if (netnames == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed to allocate memory for %i net names", nets); + goto out; + } + + for (i = 0; i < nets; i++) { + netnames[i] = strdup(virNetworkGetName(nameList[i])); + if (netnames[i] == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed to strdup memory for %i net names", + nets); + goto out; + } + } + + /* Remember we allocated extra slot already */ + netnames[nets] = strdup("0"); + + for (i = 0; i < nets + 1; i++) { + _netpool_for_network(list, + ns, + conn, + netnames[i], + pfx_from_conn(conn), + broker); + } + + out: + if (nameList != NULL) { + for (i = 0; i < nets; i++) { + virNetworkFree(nameList[i]); + } + free(nameList); + } + if (netnames != NULL) { + /* +1 to account for primordial */ + for (i = 0; i < nets + 1; i++) { + free(netnames[i]); + } + free(netnames); + } + + return s; +} +#else static CMPIStatus netpool_instance(virConnectPtr conn, struct inst_list *list, const char *ns, @@ -1101,6 +1338,7 @@ static CMPIStatus netpool_instance(virConnectPtr conn, return s; } +#endif /* LIBVIR_VERSION_NUMBER >= 100002 */ static CMPIInstance *diskpool_from_path(struct tmp_disk_pool *pool, virConnectPtr conn, -- 1.7.1

From: John Ferlan <jferlan@redhat.com> Caused error during make postinstall. Rather than print the $PROVIDERMODULES it attempted to execute the second one in the list. Added extra output just prior to CIMMOF commands to show which namespace is being modified from which directory. There appears to be some sort of issue registering some mofs as the following message is generated numerous times: Warning: the instance already exists. In this implementation, that means it cannot be changed. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- provider-register.sh | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/provider-register.sh b/provider-register.sh index 0616a14..b907df1 100755 --- a/provider-register.sh +++ b/provider-register.sh @@ -90,10 +90,10 @@ pegasus_transform() chatter "cimserver version is " $version if compare_version "$version" "2.11.0" then - chatter "Processing provider modules (w/o ModuleGroupName):" \ - $PROVIDERMODULES + chatter "Processing provider modules (w/o ModuleGroupName):" for pm in $PROVIDERMODULES do + chatter "...processing " $pm cat >> $OUTFILE <<EOFPM instance of PG_ProviderModule { @@ -109,10 +109,10 @@ EOFPM done else - chatter "Processing provider modules (w/ ModuleGroupName):" \ - $PROVIDERMODULES + chatter "Processing provider modules (w/ ModuleGroupName):" for pm in $PROVIDERMODULES do + chatter "...processing " $pm cat >> $OUTFILE <<EOFPM instance of PG_ProviderModule { @@ -272,6 +272,7 @@ pegasus_install() if pegasus_transform $_REGFILENAME $namespace $myregs then chatter Registering providers with $state cimserver '('$version')' + chatter Installing mofs into namespace $namespace from path $mofpath $CIMMOF -uc -I $mofpath -n $namespace $mymofs && $CIMMOF -uc -n root/PG_Interop $_REGFILENAME else -- 1.7.1

Hi, John This is the complete serial include your patches, I tested it on my RH6.3 env, seems fine. If you are installing RH system, can you have a test on RH6.4?
This serial fix a batch of issues.
v6: general change: rebase and add John Ferlan's patches after the tail. 2/20: do not add this property now, just fixed the spelling in code, since it is only set when Xen is used in libvirt-cim, so it is OK. 3/20: also fixed debug print spelling. 5/20: squashed patch for debug print crash issues. 6/20: spelling fix in commit message. 7/20: skipped free_diskpool on fail of setting parent pool, refined the code in get_diskpool_config() when libvirt pool was not used, removed the duplicated macro in .c file, set member to NULL in parse_diskpool_line when fail. 8/20: squashed the patch with John Ferlan's one about "adjust logic" for it. 11/20: free the domain ptr after domain name retrieving. 13/20: rename no_root_ssh_key to use_non_root_ssh_key, fail when file can't be deleted before copy in ssh_key_copy(). 17/20: small code style change for {} in if condition. 18/20: added a macro to activate it. 19/20: added three macro to activate them, added {} in if statement when only one sentence follow.
John Ferlan (7): 14 Makefile.am: Remove the $(top_srcdir) from subst command 15 libvirt-cim.spec: Use systemctl for tog-pegasus restart 16 Remove empty newline at bottom 17 xmlgen: Only support script on bridge for xen domains 18 libxkutil: Use virConnectListAllDomains() to fetch domains 19 DevicePool: Use the virConnectListAll interfaces 20 register: Adjust the chatter output
Wenchao Xia (13): 1 Remove property CreationClassName in some instance 2 SDC: Fix spelling for property IsFullVirt 3 SDC: use property BootDevices instead of BootDevice 4 do not deregister virt classes in yum upgrade 5 CSI, DevicePool, RASDIndication: fix debug print crash 6 CSI, add lock to protect shared data in lifecycle_thread 7 DevicePool, reimplement get_diskpool_config with libvirt 8 device parsing, add debug print 9 CSI Discard libvirt event by default 10 CSI: Move native CSI code together 11 VSSD: report success if not all VS fail in enum 12 misc_util: better way to read config 13 migration: allow ssh based migration with non root's key file
Makefile.am | 18 +- libvirt-cim.conf | 19 + libvirt-cim.spec.in | 24 +- libxkutil/cs_util_instance.c | 26 + libxkutil/device_parsing.c | 19 +- libxkutil/misc_util.c | 135 +++- libxkutil/misc_util.h | 6 +- libxkutil/xmlgen.c | 26 +- provider-register.sh | 9 +- schema/SwitchService.registration | 1 - src/Virt_AllocationCapabilities.c | 3 +- src/Virt_ComputerSystem.c | 66 ++- src/Virt_ComputerSystemIndication.c | 1018 +++++++++++++++++--- src/Virt_ConsoleRedirectionService.c | 3 +- src/Virt_ConsoleRedirectionServiceCapabilities.c | 3 +- src/Virt_Device.c | 18 +- src/Virt_DevicePool.c | 480 ++++++++-- src/Virt_DevicePool.h | 4 + src/Virt_EnabledLogicalElementCapabilities.c | 3 +- src/Virt_FilterEntry.c | 3 +- src/Virt_FilterList.c | 3 +- src/Virt_HostSystem.c | 3 +- src/Virt_KVMRedirectionSAP.c | 3 +- src/Virt_RASD.c | 3 +- src/Virt_ReferencedProfile.c | 3 +- src/Virt_RegisteredProfile.c | 3 +- src/Virt_ResourceAllocationSettingDataIndication.c | 6 +- src/Virt_ResourcePoolConfigurationCapabilities.c | 3 +- src/Virt_ResourcePoolConfigurationService.c | 8 +- src/Virt_SettingsDefineCapabilities.c | 14 +- src/Virt_SwitchService.c | 3 +- src/Virt_VSMigrationCapabilities.c | 3 +- src/Virt_VSMigrationService.c | 270 +++++- src/Virt_VSMigrationSettingData.c | 3 +- src/Virt_VSSD.c | 50 +- src/Virt_VirtualSystemManagementCapabilities.c | 3 +- src/Virt_VirtualSystemManagementService.c | 67 ++- src/Virt_VirtualSystemSnapshotService.c | 3 +- ...Virt_VirtualSystemSnapshotServiceCapabilities.c | 3 +- 39 files changed, 1990 insertions(+), 348 deletions(-)
-- Best Regards Wenchao Xia

It should not be default as XENPV, which will bring trouble when this value is not set. One case is script section in bridge xml generation, in resource add method it will be always added since this value is XENPV, so change it to unknown. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index d652f0f..6f6b0b4 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -147,10 +147,11 @@ struct lxc_os_info { }; struct domain { - enum { DOMAIN_XENPV, + enum { DOMAIN_UNKNOWN, + DOMAIN_XENPV, DOMAIN_XENFV, - DOMAIN_KVM, - DOMAIN_QEMU, + DOMAIN_KVM, + DOMAIN_QEMU, DOMAIN_LXC } type; char *name; char *typestr; /*xen, kvm, etc */ -- 1.7.1

Sorry, This is a missed patch. Since Domain_XENPV was default value and in resource adding method it is not set causing the script will be added xml string, so change the default value to UNKNOWN.
It should not be default as XENPV, which will bring trouble when this value is not set. One case is script section in bridge xml generation, in resource add method it will be always added since this value is XENPV, so change it to unknown.
Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index d652f0f..6f6b0b4 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -147,10 +147,11 @@ struct lxc_os_info { };
struct domain { - enum { DOMAIN_XENPV, + enum { DOMAIN_UNKNOWN, + DOMAIN_XENPV, DOMAIN_XENFV, - DOMAIN_KVM, - DOMAIN_QEMU, + DOMAIN_KVM, + DOMAIN_QEMU, DOMAIN_LXC } type; char *name; char *typestr; /*xen, kvm, etc */
-- Best Regards Wenchao Xia

On 03/25/2013 05:52 AM, Wenchao Xia wrote:
This serial fix a batch of issues.
v6: general change: rebase and add John Ferlan's patches after the tail. 2/20: do not add this property now, just fixed the spelling in code, since it is only set when Xen is used in libvirt-cim, so it is OK. 3/20: also fixed debug print spelling. 5/20: squashed patch for debug print crash issues. 6/20: spelling fix in commit message. 7/20: skipped free_diskpool on fail of setting parent pool, refined the code in get_diskpool_config() when libvirt pool was not used, removed the duplicated macro in .c file, set member to NULL in parse_diskpool_line when fail. 8/20: squashed the patch with John Ferlan's one about "adjust logic" for it. 11/20: free the domain ptr after domain name retrieving. 13/20: rename no_root_ssh_key to use_non_root_ssh_key, fail when file can't be deleted before copy in ssh_key_copy(). 17/20: small code style change for {} in if condition. 18/20: added a macro to activate it. 19/20: added three macro to activate them, added {} in if statement when only one sentence follow.
John Ferlan (7): 14 Makefile.am: Remove the $(top_srcdir) from subst command 15 libvirt-cim.spec: Use systemctl for tog-pegasus restart 16 Remove empty newline at bottom 17 xmlgen: Only support script on bridge for xen domains 18 libxkutil: Use virConnectListAllDomains() to fetch domains 19 DevicePool: Use the virConnectListAll interfaces 20 register: Adjust the chatter output
Wenchao Xia (13): 1 Remove property CreationClassName in some instance 2 SDC: Fix spelling for property IsFullVirt 3 SDC: use property BootDevices instead of BootDevice 4 do not deregister virt classes in yum upgrade 5 CSI, DevicePool, RASDIndication: fix debug print crash 6 CSI, add lock to protect shared data in lifecycle_thread 7 DevicePool, reimplement get_diskpool_config with libvirt 8 device parsing, add debug print 9 CSI Discard libvirt event by default 10 CSI: Move native CSI code together 11 VSSD: report success if not all VS fail in enum 12 misc_util: better way to read config 13 migration: allow ssh based migration with non root's key file
Makefile.am | 18 +- libvirt-cim.conf | 19 + libvirt-cim.spec.in | 24 +- libxkutil/cs_util_instance.c | 26 + libxkutil/device_parsing.c | 19 +- libxkutil/misc_util.c | 135 +++- libxkutil/misc_util.h | 6 +- libxkutil/xmlgen.c | 26 +- provider-register.sh | 9 +- schema/SwitchService.registration | 1 - src/Virt_AllocationCapabilities.c | 3 +- src/Virt_ComputerSystem.c | 66 ++- src/Virt_ComputerSystemIndication.c | 1018 +++++++++++++++++--- src/Virt_ConsoleRedirectionService.c | 3 +- src/Virt_ConsoleRedirectionServiceCapabilities.c | 3 +- src/Virt_Device.c | 18 +- src/Virt_DevicePool.c | 480 ++++++++-- src/Virt_DevicePool.h | 4 + src/Virt_EnabledLogicalElementCapabilities.c | 3 +- src/Virt_FilterEntry.c | 3 +- src/Virt_FilterList.c | 3 +- src/Virt_HostSystem.c | 3 +- src/Virt_KVMRedirectionSAP.c | 3 +- src/Virt_RASD.c | 3 +- src/Virt_ReferencedProfile.c | 3 +- src/Virt_RegisteredProfile.c | 3 +- src/Virt_ResourceAllocationSettingDataIndication.c | 6 +- src/Virt_ResourcePoolConfigurationCapabilities.c | 3 +- src/Virt_ResourcePoolConfigurationService.c | 8 +- src/Virt_SettingsDefineCapabilities.c | 14 +- src/Virt_SwitchService.c | 3 +- src/Virt_VSMigrationCapabilities.c | 3 +- src/Virt_VSMigrationService.c | 270 +++++- src/Virt_VSMigrationSettingData.c | 3 +- src/Virt_VSSD.c | 50 +- src/Virt_VirtualSystemManagementCapabilities.c | 3 +- src/Virt_VirtualSystemManagementService.c | 67 ++- src/Virt_VirtualSystemSnapshotService.c | 3 +- ...Virt_VirtualSystemSnapshotServiceCapabilities.c | 3 +- 39 files changed, 1990 insertions(+), 348 deletions(-)
ACK on series. There were a couple of grammar things seen in commit messages and comments, but nothing that isn't understandable ;-) I was able to test using my fedora box, but haven't had the cycles to do the same on the rh64 box. With my cimtest changes I am down to very few errors now - mostly config type stuff (indications don't work for me and I don't have the right setup for a couple of network tests). John

于 2013-3-26 6:18, John Ferlan 写道:
On 03/25/2013 05:52 AM, Wenchao Xia wrote:
This serial fix a batch of issues.
v6: general change: rebase and add John Ferlan's patches after the tail. 2/20: do not add this property now, just fixed the spelling in code, since it is only set when Xen is used in libvirt-cim, so it is OK. 3/20: also fixed debug print spelling. 5/20: squashed patch for debug print crash issues. 6/20: spelling fix in commit message. 7/20: skipped free_diskpool on fail of setting parent pool, refined the code in get_diskpool_config() when libvirt pool was not used, removed the duplicated macro in .c file, set member to NULL in parse_diskpool_line when fail. 8/20: squashed the patch with John Ferlan's one about "adjust logic" for it. 11/20: free the domain ptr after domain name retrieving. 13/20: rename no_root_ssh_key to use_non_root_ssh_key, fail when file can't be deleted before copy in ssh_key_copy(). 17/20: small code style change for {} in if condition. 18/20: added a macro to activate it. 19/20: added three macro to activate them, added {} in if statement when only one sentence follow.
John Ferlan (7): 14 Makefile.am: Remove the $(top_srcdir) from subst command 15 libvirt-cim.spec: Use systemctl for tog-pegasus restart 16 Remove empty newline at bottom 17 xmlgen: Only support script on bridge for xen domains 18 libxkutil: Use virConnectListAllDomains() to fetch domains 19 DevicePool: Use the virConnectListAll interfaces 20 register: Adjust the chatter output
Wenchao Xia (13): 1 Remove property CreationClassName in some instance 2 SDC: Fix spelling for property IsFullVirt 3 SDC: use property BootDevices instead of BootDevice 4 do not deregister virt classes in yum upgrade 5 CSI, DevicePool, RASDIndication: fix debug print crash 6 CSI, add lock to protect shared data in lifecycle_thread 7 DevicePool, reimplement get_diskpool_config with libvirt 8 device parsing, add debug print 9 CSI Discard libvirt event by default 10 CSI: Move native CSI code together 11 VSSD: report success if not all VS fail in enum 12 misc_util: better way to read config 13 migration: allow ssh based migration with non root's key file
Makefile.am | 18 +- libvirt-cim.conf | 19 + libvirt-cim.spec.in | 24 +- libxkutil/cs_util_instance.c | 26 + libxkutil/device_parsing.c | 19 +- libxkutil/misc_util.c | 135 +++- libxkutil/misc_util.h | 6 +- libxkutil/xmlgen.c | 26 +- provider-register.sh | 9 +- schema/SwitchService.registration | 1 - src/Virt_AllocationCapabilities.c | 3 +- src/Virt_ComputerSystem.c | 66 ++- src/Virt_ComputerSystemIndication.c | 1018 +++++++++++++++++--- src/Virt_ConsoleRedirectionService.c | 3 +- src/Virt_ConsoleRedirectionServiceCapabilities.c | 3 +- src/Virt_Device.c | 18 +- src/Virt_DevicePool.c | 480 ++++++++-- src/Virt_DevicePool.h | 4 + src/Virt_EnabledLogicalElementCapabilities.c | 3 +- src/Virt_FilterEntry.c | 3 +- src/Virt_FilterList.c | 3 +- src/Virt_HostSystem.c | 3 +- src/Virt_KVMRedirectionSAP.c | 3 +- src/Virt_RASD.c | 3 +- src/Virt_ReferencedProfile.c | 3 +- src/Virt_RegisteredProfile.c | 3 +- src/Virt_ResourceAllocationSettingDataIndication.c | 6 +- src/Virt_ResourcePoolConfigurationCapabilities.c | 3 +- src/Virt_ResourcePoolConfigurationService.c | 8 +- src/Virt_SettingsDefineCapabilities.c | 14 +- src/Virt_SwitchService.c | 3 +- src/Virt_VSMigrationCapabilities.c | 3 +- src/Virt_VSMigrationService.c | 270 +++++- src/Virt_VSMigrationSettingData.c | 3 +- src/Virt_VSSD.c | 50 +- src/Virt_VirtualSystemManagementCapabilities.c | 3 +- src/Virt_VirtualSystemManagementService.c | 67 ++- src/Virt_VirtualSystemSnapshotService.c | 3 +- ...Virt_VirtualSystemSnapshotServiceCapabilities.c | 3 +- 39 files changed, 1990 insertions(+), 348 deletions(-)
ACK on series. There were a couple of grammar things seen in commit messages and comments, but nothing that isn't understandable ;-)
I was able to test using my fedora box, but haven't had the cycles to do the same on the rh64 box. With my cimtest changes I am down to very few errors now - mostly config type stuff (indications don't work for me and I don't have the right setup for a couple of network tests).
John
So nice to know patches are OK. Do you think it can be pulled?
_______________________________________________ Libvirt-cim mailing list Libvirt-cim@redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cim
-- Best Regards Wenchao Xia

On 03/28/2013 10:08 PM, Wenchao Xia wrote:
于 2013-3-26 6:18, John Ferlan 写道:
On 03/25/2013 05:52 AM, Wenchao Xia wrote:
ACK on series. There were a couple of grammar things seen in commit messages and comments, but nothing that isn't understandable ;-)
I was able to test using my fedora box, but haven't had the cycles to do the same on the rh64 box. With my cimtest changes I am down to very few errors now - mostly config type stuff (indications don't work for me and I don't have the right setup for a couple of network tests).
John
So nice to know patches are OK. Do you think it can be pulled?
I think DV is the maintainer, right? Not sure how that part works quite yet. That is - what the process is from here. I do know he also handles the libvirt releases as well and is in the middle of a release for that right now. I would be nice to perhaps include the cimtest changes that I posted as well, although not a requirement for the release. John

So nice to know patches are OK. Do you think it can be pulled?
I think DV is the maintainer, right? Not sure how that part works quite yet. That is - what the process is from here. I do know he also handles the libvirt releases as well and is in the middle of a release for that right now.
I would be nice to perhaps include the cimtest changes that I posted as well, although not a requirement for the release. Yes it should be pushed also, another folks will come to check cimtest in about two weeks, I will also check it.
John
Daniel: I am a bit eager for a steady release, do you have a plan for release libvirt-cim 0.6.2? Best Regards Wenchao Xia

On Fri, Mar 29, 2013 at 06:17:37AM -0400, John Ferlan wrote:
On 03/28/2013 10:08 PM, Wenchao Xia wrote:
于 2013-3-26 6:18, John Ferlan 写道:
On 03/25/2013 05:52 AM, Wenchao Xia wrote:
ACK on series. There were a couple of grammar things seen in commit messages and comments, but nothing that isn't understandable ;-)
I was able to test using my fedora box, but haven't had the cycles to do the same on the rh64 box. With my cimtest changes I am down to very few errors now - mostly config type stuff (indications don't work for me and I don't have the right setup for a couple of network tests).
John
So nice to know patches are OK. Do you think it can be pulled?
I think DV is the maintainer, right? Not sure how that part works quite yet. That is - what the process is from here. I do know he also handles the libvirt releases as well and is in the middle of a release for that right now.
Well both of you have commit acces rights, so you can just push your changes to git (I didn't see them !)
I would be nice to perhaps include the cimtest changes that I posted as well, although not a requirement for the release.
push all you need in git master, test from there (make rpm , cimtest...) and when you feel it is ready tell me i will build a release ! Daniel -- Daniel Veillard | Open Source and Standards, Red Hat veillard@redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | virtualization library http://libvirt.org/

于 2013-4-5 19:15, Daniel Veillard 写道:
On Fri, Mar 29, 2013 at 06:17:37AM -0400, John Ferlan wrote:
On 03/28/2013 10:08 PM, Wenchao Xia wrote:
于 2013-3-26 6:18, John Ferlan 写道:
On 03/25/2013 05:52 AM, Wenchao Xia wrote:
ACK on series. There were a couple of grammar things seen in commit messages and comments, but nothing that isn't understandable ;-)
I was able to test using my fedora box, but haven't had the cycles to do the same on the rh64 box. With my cimtest changes I am down to very few errors now - mostly config type stuff (indications don't work for me and I don't have the right setup for a couple of network tests).
John
So nice to know patches are OK. Do you think it can be pulled?
I think DV is the maintainer, right? Not sure how that part works quite yet. That is - what the process is from here. I do know he also handles the libvirt releases as well and is in the middle of a release for that right now.
Well both of you have commit acces rights, so you can just push your changes to git (I didn't see them !)
I would be nice to perhaps include the cimtest changes that I posted as well, although not a requirement for the release.
push all you need in git master, test from there (make rpm , cimtest...) and when you feel it is ready tell me i will build a release !
Daniel
Hi, Daniel Thanks for you help, I have just spent one day testing it on RH6.4, will try push tommorrow. -- Best Regards Wenchao Xia

Hi, Danial Patches pushed.
On Fri, Mar 29, 2013 at 06:17:37AM -0400, John Ferlan wrote:
On 03/28/2013 10:08 PM, Wenchao Xia wrote:
于 2013-3-26 6:18, John Ferlan 写道:
On 03/25/2013 05:52 AM, Wenchao Xia wrote:
ACK on series. There were a couple of grammar things seen in commit messages and comments, but nothing that isn't understandable ;-)
I was able to test using my fedora box, but haven't had the cycles to do the same on the rh64 box. With my cimtest changes I am down to very few errors now - mostly config type stuff (indications don't work for me and I don't have the right setup for a couple of network tests).
John
So nice to know patches are OK. Do you think it can be pulled?
I think DV is the maintainer, right? Not sure how that part works quite yet. That is - what the process is from here. I do know he also handles the libvirt releases as well and is in the middle of a release for that right now.
Well both of you have commit acces rights, so you can just push your changes to git (I didn't see them !)
I would be nice to perhaps include the cimtest changes that I posted as well, although not a requirement for the release.
push all you need in git master, test from there (make rpm , cimtest...) and when you feel it is ready tell me i will build a release !
Daniel
-- Best Regards Wenchao Xia
participants (4)
-
Daniel Veillard
-
John Ferlan
-
Wenchao Xia
-
xiaxia347work