[PATCH 11/15] RASDIndication, fix debug print crash
by Wenchao Xia
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
src/Virt_ResourceAllocationSettingDataIndication.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
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
11 years, 10 months
[PATCH 12/15] device parsing, add debug print
by Wenchao Xia
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
libxkutil/device_parsing.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index ceb4552..2841662 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -1251,12 +1251,19 @@ int get_dominfo(virDomainPtr dom, struct domain **dominfo)
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)
+ if (ret != 1) {
+ CU_DEBUG("Failed to translate xml into struct domain");
+ }
+ if (virDomainGetAutostart(dom, &start) != 0) {
+ CU_DEBUG("Failed to get dom autostart with libvirt API.");
return 0;
+ }
(*dominfo)->autostrt = start;
--
1.7.1
11 years, 10 months
[PATCH 1/2] libcmpiutil, add time and thread info in debug print
by Wenchao Xia
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
debug_util.c | 19 ++++++++++++++++++-
1 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/debug_util.c b/debug_util.c
index 2912fb6..864a3f7 100644
--- a/debug_util.c
+++ b/debug_util.c
@@ -24,6 +24,9 @@
#include <stdarg.h>
#include <stdio.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
#include "libcmpiutil.h"
static int log_init = 0;
@@ -32,6 +35,15 @@ static FILE *log = NULL;
void debug_print(char *fmt, ...)
{
char *log_file = NULL;
+ pthread_t id = pthread_self();
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday(&tv, &tz);
+ time_t timep;
+ struct tm *p;
+ time(&timep);
+ p=localtime(&timep);
+
va_list ap;
va_start(ap, fmt);
@@ -49,8 +61,13 @@ void debug_print(char *fmt, ...)
log_init = 1;
}
- if (log != NULL)
+ if (log != NULL) {
vfprintf(log, fmt, ap);
+ fprintf(log, "time[%d-%02d-%02d %02d:%02d:%02d.%06d] "
+ "thread[%ld] ",
+ (1900+p->tm_year), (1+p->tm_mon), p->tm_mday,
+ p->tm_hour, p->tm_min, p->tm_sec, (int)tv.tv_usec, id);
+ }
va_end(ap);
}
--
1.7.1
11 years, 10 months
[PATCH 15/15] VSSD, fix a error report issue in VSSD enum
by Wenchao Xia
If user delete a VS and enum VSSD at the sametime, it may have chance
to report error, but actually it succeed just with some VS not found. This
Patch fixed it. It will continue if found one VS is missing in enum.
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
src/Virt_VSSD.c | 72 +++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 59 insertions(+), 13 deletions(-)
diff --git a/src/Virt_VSSD.c b/src/Virt_VSSD.c
index 499b157..1665ef5 100644
--- a/src/Virt_VSSD.c
+++ b/src/Virt_VSSD.c
@@ -36,6 +36,8 @@
#include "Virt_VSSD.h"
+#define VSSD_ERROR_RECOVERABLE (2)
+
const static CMPIBroker *_BROKER;
static CMPIStatus _set_fv_prop(const CMPIBroker *broker,
@@ -181,8 +183,19 @@ static int instance_from_dom(const CMPIBroker *broker,
struct domain *dominfo = NULL;
ret = get_dominfo(dom, &dominfo);
- if (!ret)
+ if (!ret) {
+ int active = virDomainIsActive(dom);
+ if (active < 0) {
+ /* ret > 1 indicate that it is recoverable */
+ CU_DEBUG("Failed to get dominfo, "
+ "it may not present now.");
+ ret = VSSD_ERROR_RECOVERABLE;
+ } else {
+ CU_DEBUG("Failed to get dominfo, "
+ "libvirt level error.");
+ }
goto out;
+ }
op = CMGetObjectPath(inst, NULL);
pfx = class_prefix_name(CLASSNAME(op));
@@ -246,6 +259,8 @@ static int instance_from_dom(const CMPIBroker *broker,
s = _set_fv_prop(broker, dominfo, inst);
if (s.rc != CMPI_RC_OK) {
ret = 0;
+ CU_DEBUG("Failed to set full virtual prop for %d dom.",
+ dominfo->type);
goto out;
}
}
@@ -260,6 +275,7 @@ static int instance_from_dom(const CMPIBroker *broker,
if (asprintf(&vsid, "%s:%s", pfx, dominfo->name) == -1) {
ret = 0;
+ CU_DEBUG("Failed in asprintf vsid.");
goto out;
}
@@ -278,7 +294,8 @@ static CMPIInstance *_get_vssd(const CMPIBroker *broker,
const CMPIObjectPath *reference,
virConnectPtr conn,
virDomainPtr dom,
- CMPIStatus *s)
+ CMPIStatus *s,
+ int *error_below)
{
CMPIInstance *inst = NULL;
@@ -294,10 +311,18 @@ static CMPIInstance *_get_vssd(const CMPIBroker *broker,
goto out;
}
- if (instance_from_dom(broker, dom, inst) != 1) {
- cu_statusf(broker, s,
- CMPI_RC_ERR_FAILED,
- "Unable to get VSSD instance from Domain");
+ *error_below = instance_from_dom(broker, dom, inst);
+ if (*error_below != 1) {
+ if (*error_below == VSSD_ERROR_RECOVERABLE) {
+ cu_statusf(broker, s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get VSSD instance from Domain, "
+ "Domain may not exist at this moment.");
+ } else {
+ cu_statusf(broker, s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get VSSD instance from Domain");
+ }
}
out:
@@ -312,6 +337,7 @@ static CMPIStatus return_enum_vssd(const CMPIObjectPath *reference,
virDomainPtr *list;
int count;
int i;
+ int error_below;
CMPIStatus s = {CMPI_RC_OK, NULL};
conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
@@ -327,14 +353,33 @@ static CMPIStatus return_enum_vssd(const CMPIObjectPath *reference,
} else if (count == 0)
goto out;
+ int fail_count = 0;
for (i = 0; i < count; i++) {
CMPIInstance *inst = NULL;
-
- inst = _get_vssd(_BROKER, reference, conn, list[i], &s);
-
+
+ inst = _get_vssd(_BROKER, reference, conn, list[i],
+ &s, &error_below);
+
virDomainFree(list[i]);
- if (inst == NULL)
- continue;
+
+ if ((inst == NULL) || (s.rc != CMPI_RC_OK)) {
+ fail_count++;
+ CU_DEBUG("VSSD got %d fail instance, total %d,"
+ " error %d.",
+ fail_count, count, error_below);
+ if (error_below == VSSD_ERROR_RECOVERABLE) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_OK,
+ "%d/%d VSSD not got,"
+ " some VS may not exist now",
+ fail_count, count);
+ CU_DEBUG("Continue to next VSSD for enum.");
+ continue;
+ } else {
+ CU_DEBUG("Met unrecoverable error.");
+ break;
+ }
+ }
if (names_only)
cu_return_instance_name(results, inst);
@@ -358,7 +403,8 @@ CMPIStatus get_vssd_by_name(const CMPIBroker *broker,
virDomainPtr dom;
CMPIStatus s = {CMPI_RC_OK, NULL};
CMPIInstance *inst = NULL;
-
+ int error_below;
+
conn = connect_by_classname(broker, CLASSNAME(reference), &s);
if (conn == NULL) {
cu_statusf(broker, &s,
@@ -377,7 +423,7 @@ CMPIStatus get_vssd_by_name(const CMPIBroker *broker,
goto out;
}
- inst = _get_vssd(broker, reference, conn, dom, &s);
+ inst = _get_vssd(broker, reference, conn, dom, &s, &error_below);
virDomainFree(dom);
--
1.7.1
11 years, 10 months
[PATCH 14/15] disable cgroup by default
by Wenchao Xia
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
libxkutil/device_parsing.c | 9 ++++++++-
src/Virt_ComputerSystem.c | 7 ++++++-
src/Virt_VirtualSystemManagementService.c | 6 ++++++
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index 2841662..83d4590 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -34,6 +34,8 @@
#include "xmlgen.h"
#include "../src/svpc_types.h"
+#include "config.h"
+
#define DISK_XPATH (xmlChar *)"/domain/devices/disk | "\
"/domain/devices/filesystem"
#define VCPU_XPATH (xmlChar *)"/domain/vcpu"
@@ -1407,7 +1409,9 @@ static int change_vcpus(virDomainPtr dom, struct virt_device *dev)
strncpy(param.field, "cpu_shares", VIR_DOMAIN_SCHED_FIELD_LENGTH);
param.type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
param.value.ul = dev->dev.vcpu.weight;
-
+
+ /* skip cgroup setting */
+#ifdef SUPPORT_CGROUP_CPU
if (virDomainSetSchedulerParameters(dom, ¶m, 1) != 0) {
CU_DEBUG("Failed to set scheduler params for domain");
return 0;
@@ -1416,6 +1420,9 @@ static int change_vcpus(virDomainPtr dom, struct virt_device *dev)
CU_DEBUG("Changed %s vcpu cgroup cpu_shares to %i",
virDomainGetName(dom),
dev->dev.vcpu.weight);
+#else
+ CU_DEBUG("Skipped setting cpu cgroup.");
+#endif
}
if (dev->dev.vcpu.quantity <= 0) {
diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c
index adef85e..c422e3b 100644
--- a/src/Virt_ComputerSystem.c
+++ b/src/Virt_ComputerSystem.c
@@ -935,8 +935,13 @@ static void set_scheduler_params(virDomainPtr dom)
goto out;
}
- if (count > 0)
+ if (count > 0) {
+#ifdef SUPPORT_CGROUP_CPU
virDomainSetSchedulerParameters(dom, params, count);
+#else
+ CU_DEBUG("Skipped setting cpu cgroup.");
+#endif
+ }
else
CU_DEBUG("No sched parameters to set");
out:
diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c
index 059b852..9a9b635 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -1778,11 +1778,17 @@ static CMPIStatus update_dominfo(const struct domain *dominfo,
params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
params.value.ul = dev->dev.vcpu.weight;
+#ifdef SUPPORT_CGROUP_CPU
CU_DEBUG("setting %s scheduler param cpu_shares=%d",
dominfo->name,
dev->dev.vcpu.weight);
ret = virDomainSetSchedulerParametersFlags(dom, ¶ms, 1,
VIR_DOMAIN_AFFECT_CONFIG);
+#else
+ CU_DEBUG("Skipped cgroup cpu setting.");
+ ret = 0;
+#endif
+
if (ret != 0) {
CU_DEBUG("Failed to set config scheduler param");
cu_statusf(_BROKER, &s,
--
1.7.1
11 years, 10 months
[PATCH 13/15] CSI Discard libvirt event by default
by Wenchao Xia
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.
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
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
src/Virt_ComputerSystem.c | 46 +++-
src/Virt_ComputerSystemIndication.c | 540 ++++++++++++++++++++++++++++-
src/Virt_VirtualSystemManagementService.c | 36 ++-
3 files changed, 616 insertions(+), 6 deletions(-)
diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c
index e6c7e55..adef85e 100644
--- a/src/Virt_ComputerSystem.c
+++ b/src/Virt_ComputerSystem.c
@@ -45,8 +45,45 @@
#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 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 ComputerSystem indication");
+
+ ind = get_typed_instance(_BROKER,
+ CLASSNAME(ref),
+ ind_name,
+ NAMESPACE(ref));
+ if (ind == NULL) {
+ CU_DEBUG("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;
+}
+#endif
+
/* Set the "Name" property of an instance from a domain */
static int set_name_from_dom(virDomainPtr dom, CMPIInstance *instance)
{
@@ -1256,8 +1293,15 @@ static CMPIStatus state_change(CMPIMethodMI *self,
s = __state_change(name, state, reference);
- if (s.rc == CMPI_RC_OK)
+ if (s.rc == CMPI_RC_OK) {
+#ifndef USE_LIBVIRT_EVENT
+ bool ind_rc= trigger_mod_indication(context, prev_inst,
+ reference);
+ if (!ind_rc)
+ CU_DEBUG("Unable to trigger indication");
+#endif
rc = 0;
+ }
out:
CMReturnData(results, &rc, CMPI_uint32);
diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c
index 3159ca0..d6f31cc 100644
--- a/src/Virt_ComputerSystemIndication.c
+++ b/src/Virt_ComputerSystemIndication.c
@@ -48,6 +48,8 @@
#include "Virt_ComputerSystemIndication.h"
#include "Virt_HostSystem.h"
+#define WAIT_TIME 60
+#define FAIL_WAIT_TIME 2
#define CSI_NUM_PLATFORMS 3
enum CSI_PLATFORMS {
@@ -80,6 +82,7 @@ struct _csi_thread_data_t {
};
static const CMPIBroker *_BROKER;
+static pthread_cond_t lifecycle_cond = PTHREAD_COND_INITIALIZER;
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}};
@@ -580,6 +583,376 @@ static void csi_domain_event_cb(virConnectPtr conn,
free(prefix);
}
+/* libvirt-cim's private CSI implement */
+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));
+ 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 true;
+}
+
+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 diliv 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");
+ 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);
+ }
+ }
+
+ for (i = 0; i < prev_count; i++) {
+ res = dom_changed(prev_xml[i], cur_xml, cur_count);
+ if (res) {
+ 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;
+}
+
static CMPI_THREAD_RETURN lifecycle_thread(void *params)
{
csi_thread_data_t *thread = (csi_thread_data_t *) params;
@@ -696,13 +1069,24 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
csi_thread_data_t *thread = NULL;
static int events_registered = 0;
+#ifndef USE_LIBVIRT_EVENT
+ int use_libvirt_event = 0;
+#else
+ int use_libvirt_event = 1;
+#endif
+
CU_DEBUG("ActivateFilter for %s", CLASSNAME(op));
pthread_mutex_lock(&lifecycle_mutex);
- if (events_registered == 0) {
- events_registered = 1;
- virEventRegisterDefaultImpl();
+ if (use_libvirt_event == 1) {
+ if (events_registered == 0) {
+ events_registered = 1;
+ CU_DEBUG("Registering libvirt event.");
+ virEventRegisterDefaultImpl();
+ }
+ } else {
+ CU_DEBUG("Using libvirt-cim's event implemention.");
}
_ctx = (struct std_indication_ctx *)mi->hdl;
@@ -753,7 +1137,20 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
args->_ctx = _ctx;
thread->args = args;
- thread->id = _BROKER->xft->newThread(lifecycle_thread, thread, 0);
+
+ if (use_libvirt_event == 0) {
+ thread->id = _BROKER->xft->newThread(
+ lifecycle_thread_native,
+ thread, 0);
+ } else {
+ 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) {
@@ -791,6 +1188,10 @@ static CMPIStatus DeActivateFilter(CMPIIndicationMI* mi,
csi_thread_data[platform].active_filters -= 1;
pthread_mutex_unlock(&lifecycle_mutex);
+#ifndef USE_LIBVIRT_EVENT
+ pthread_cond_signal(&lifecycle_cond);
+#endif
+
out:
return s;
}
@@ -817,6 +1218,7 @@ static _EI_RTYPE DisableIndications(CMPIIndicationMI* mi,
_EI_RET();
}
+
DECLARE_FILTER(xen_created, "Xen_ComputerSystemCreatedIndication");
DECLARE_FILTER(xen_deleted, "Xen_ComputerSystemDeletedIndication");
DECLARE_FILTER(xen_modified, "Xen_ComputerSystemModifiedIndication");
@@ -840,7 +1242,137 @@ static struct std_ind_filter *filters[] = {
NULL,
};
+#ifndef USE_LIBVIRT_EVENT
+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));
+ 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 10adf8b..059b852 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -107,6 +107,24 @@ enum ResourceAction {
RESOURCE_MOD,
};
+#ifndef USE_LIBVIRT_EVENT
+static bool trigger_indication(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;
+}
+#endif
+
#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
static CMPIStatus add_qos_for_mac(const uint64_t qos,
@@ -2166,6 +2184,11 @@ static CMPIStatus define_system(CMPIMethodMI *self,
CMAddArg(argsout, "ResultingSystem", &result, CMPI_ref);
}
+#ifndef USE_LIBVIRT_EVENT
+ trigger_indication(context,
+ "ComputerSystemCreatedIndication",
+ reference);
+#endif
out:
if (s.rc == CMPI_RC_OK)
rc = CIM_SVPC_RETURN_COMPLETED;
@@ -2268,6 +2291,11 @@ error:
NULL,
reference,
&list);
+#ifndef USE_LIBVIRT_EVENT
+ trigger_indication(context,
+ "ComputerSystemDeletedIndication",
+ reference);
+#endif
}
virDomainFree(dom);
@@ -2349,8 +2377,14 @@ 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);
+#ifndef USE_LIBVIRT_EVENT
+ trigger_indication(context,
+ "ComputerSystemModifiedIndication",
+ ref);
+#endif
+ }
out:
free(xml);
--
1.7.1
11 years, 10 months
[PATCH] libcmpiutil, fix potential debug print crash
by xiaxia347work
It seems libcmpiutil still uses HG, sorry I forgot how to send patch with HG, so
paste the patch directly here and attach the patch generated from "hg export"
as attachement.
exporting patch:
# HG changeset patch
# User Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
# Date 1351243349 -28800
# Node ID 67a7b959ed47188efb8eb2f462bc7fc9ee145041
# Parent 2984ede9c082bab48b3494ef4b9f5561fadef2ad
fix potential crash bug
diff -r 2984ede9c082 -r 67a7b959ed47 std_indication.c
--- a/std_indication.c Tue May 24 10:45:46 2011 -0400
+++ b/std_indication.c Fri Oct 26 17:22:29 2012 +0800
@@ -141,7 +141,12 @@
enabled = is_ind_enabled(ctx, ind_name, &s);
if (s.rc != CMPI_RC_OK) {
- CU_DEBUG("Problem checking enabled: '%s'", CMGetCharPtr(s.msg));
+ if (s.msg != NULL) {
+ CU_DEBUG("Problem checking enabled: '%s'",
+ CMGetCharPtr(s.msg));
+ } else {
+ CU_DEBUG("Problem checking enabled, msg is NULL");
+ }
goto out;
}
@@ -176,7 +181,12 @@
enabled = is_ind_enabled(args->_ctx, ind_name, &s);
if (s.rc != CMPI_RC_OK) {
- CU_DEBUG("Problem checking enabled: '%s'", CMGetCharPtr(s.msg));
+ if (s.msg != NULL) {
+ CU_DEBUG("Problem checking enabled: '%s'",
+ CMGetCharPtr(s.msg));
+ } else {
+ CU_DEBUG("Problem checking enabled, msg is NULL");
+ }
goto out;
}
11 years, 10 months
[PATCH] libcmpiutil, add time and thread info in CU_DEBUG
by xiaxia347work
It seems libcmpiutil still uses HG, sorry I forgot how to send patch with HG, so
paste the patch directly here and attach the patch generated from "hg export"
as attachement.
exporting patch:
# HG changeset patch
# User Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
# Date 1351254054 -28800
# Node ID 4c82c8f418757be40bdd87575d309f17232545c0
# Parent 67a7b959ed47188efb8eb2f462bc7fc9ee145041
debug print, add time and thread info
diff -r 67a7b959ed47 -r 4c82c8f41875 debug_util.c
--- a/debug_util.c Fri Oct 26 17:22:29 2012 +0800
+++ b/debug_util.c Fri Oct 26 20:20:54 2012 +0800
@@ -23,7 +23,9 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
-
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
#include "libcmpiutil.h"
static int log_init = 0;
@@ -32,6 +34,15 @@
void debug_print(char *fmt, ...)
{
char *log_file = NULL;
+ pthread_t id = pthread_self();
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday(&tv, &tz);
+ time_t timep;
+ struct tm *p;
+ time(&timep);
+ p=localtime(&timep);
+
va_list ap;
va_start(ap, fmt);
@@ -49,8 +60,10 @@
log_init = 1;
}
- if (log != NULL)
+ if (log != NULL) {
+ fprintf(log, "time[%d-%02d-%02d %02d:%02d:%02d.%06d] thread[%ld] ", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, (int)tv.tv_usec, id);
vfprintf(log, fmt, ap);
+ }
va_end(ap);
}
11 years, 10 months
Fwd: Re: [PATCH 4/4] DevicePool, reimplement get_diskpool_config with libvirt
by Wenchao Xia
> On Mon, Oct 22, 2012 at 5:38 AM, Wenchao Xia <xiawenc(a)linux.vnet.ibm.com> wrote:
>> Oringinal implement have risk, this patch should fix it
>>
>> Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
>> ---
>> src/Virt_DevicePool.c | 47 +++++++++++++++++++++++++++++++++++------------
>> 1 files changed, 35 insertions(+), 12 deletions(-)
>>
>> diff --git a/src/Virt_DevicePool.c b/src/Virt_DevicePool.c
>> index 79dc108..0cb9124 100644
>> --- a/src/Virt_DevicePool.c
>> +++ b/src/Virt_DevicePool.c
>> @@ -117,52 +117,75 @@ int get_disk_pool(virStoragePoolPtr poolptr, struct virt_pool **pool)
>> return ret;
>> }
>>
>> +/* This function returns the real number of pools, no negative value should be
>> + returned, if error happens it returns zero. */
>> static int get_diskpool_config(virConnectPtr conn,
>> struct tmp_disk_pool **_pools)
>> {
>> - int count = 0;
>> + int count = 0, realcount = 0;
>> int i;
>> char ** names = NULL;
>> struct tmp_disk_pool *pools = NULL;
>> + int have_err = 0;
>>
>> count = virConnectNumOfStoragePools(conn);
>> - if (count <= 0)
>> + if (count <= 0) {
>> + have_err = 1;
>> goto out;
>> + }
>>
>> names = calloc(count, sizeof(char *));
>> if (names == NULL) {
>> CU_DEBUG("Failed to alloc space for %i pool names", count);
>> count = 0;
>> + have_err = 1;
>> goto out;
>> }
>>
>> - if (virConnectListStoragePools(conn, names, count) == -1) {
>> + realcount = virConnectListStoragePools(conn, names, count);
>> + if (realcount == -1) {
>> CU_DEBUG("Failed to get storage pools");
>> - count = 0;
>> + realcount = 0;
>> + have_err = 1;
>> + goto out;
>> + }
>> + if (realcount == 0) {
>> + CU_DEBUG("zero pools got, but prelist is %d.", count);
>> goto out;
>> }
>>
>> - pools = calloc(count, sizeof(*pools));
>> + pools = calloc(realcount, sizeof(*pools));
>> if (pools == NULL) {
>> - CU_DEBUG("Failed to alloc space for %i pool structs", count);
>> + CU_DEBUG("Failed to alloc space for %i pool structs", realcount);
>> + realcount = 0;
>> + have_err = 1;
>> goto out;
>> }
>>
>> - for (i = 0; i < count; i++) {
>> + i = 0;
>> + while (i < realcount) {
>> pools[i].tag = strdup(names[i]);
>> pools[i].primordial = false;
>> + i++;
>> }
>
> Any specific reason for changing the for() loop for a while() one??
>
>>
>> out:
>> - for (i = 0; i < count; i++)
>> - free(names[i]);
>> - free(names);
>> + if (count > 0) {
>> + i = 0;
>> + while (i < count) {
>> + free(names[i]);
>> + i++;
>> + }
>> + free(names);
>> + }
>
> Same here.
>
> Best regards,
>
Good to see you again, there is one for() before which may take
one execution if count == 0,where it should not. For safe and code
style unifying I switch it all to while.
I am tring to fix some bugs after libvirt CSI patch applied, which
make cimtest report strange error, A bit brute, could u help share some
findings for those strange errors? (2 profile test case failing
strangely, if CSI test case is executed with CSI patched libvirt-cim).
--
Best Regards
Wenchao Xia
11 years, 10 months
[PATCH 1/4] CSI, fix debug print crash
by Wenchao Xia
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
src/Virt_ComputerSystemIndication.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c
index 2d0a94e..b1b9fa0 100644
--- a/src/Virt_ComputerSystemIndication.c
+++ b/src/Virt_ComputerSystemIndication.c
@@ -503,7 +503,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;
}
--
1.7.1
11 years, 10 months