[Libvirt-cim] [PATCH 2 of 2] Raises GuestCrashAlertIndication when QEMU crashes
Kaitlin Rupert
kaitlin at linux.vnet.ibm.com
Fri Aug 21 18:48:22 UTC 2009
> +typedef struct cb_info {
> + const CMPIContext *context;
> + const CMPIObjectPath *obj_path;
> +} *cb_info_ptr;
> +
> +static const CMPIBroker *_BROKER;
> +
> +#define CAI_NUM_PLATFORMS 3
> +enum CAI_PLATFORMS {CAI_XEN,
> + CAI_KVM,
> + CAI_LXC,
> +};
> +static int active_filters[CAI_NUM_PLATFORMS];
> +
> +static pthread_mutex_t cb_reg_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> +static void set_alert_ind_props(const CMPIBroker *broker,
> + const char *prefix,
> + const CMPIContext *ctx,
> + CMPIInstance *ind)
> +{
> + CMPIStatus s;
> + CMPIString *str = NULL;
> + CMPIUint16 val;
> + CMPIArray *array = NULL;
> + char *charsptr = NULL;
> + int rc;
> +
> +
> + //CMSetProperty(ind, "Description", &str, CMPI_string);
> +
> +
> + // val 1
> + val = 1;
> + CMSetProperty(ind, "AlertType", &val, CMPI_uint16);
> +
> + str = CMNewString(broker, "Virtual guest crash", &s);
> + CMSetProperty(ind, "OtherAlertType", &str, CMPI_string);
> +
> + val = 7;
> + CMSetProperty(ind, "PerceivedSeverity", &val, CMPI_uint16);
> +
> + // val 48
> + val = 48;
> + CMSetProperty(ind, "ProbableCause", &val, CMPI_uint16);
> +
> + //CMSetProperty(ind, "ProbableCauseDescription", &str, CMPI_string);
> +
> + // val 1
> + val = 1;
> + CMSetProperty(ind, "Trending", &val, CMPI_uint16);
> +
> + // This is an array
> + // CMSetProperty(ind, "RecommendedActions", &str, CMPI_string);
> +
> +
> + // Must find how to fill it
> + //CMSetProperty(ind, "EventTime", &, CMPI_dateTime);
> +
> + // Won't use it
> + //CMSetProperty(ind, "SystemCreationClassName", &str, CMPI_string);
> +
> + // Won't use it
> + // CMSetProperty(ind, "SystemName", &str, CMPI_string);
> +
> + // Combine GuestCrashAlertIndication with prefix
> + rc = asprintf(&charsptr, "%s%s", prefix, "_GuestCrashAlertIndication");
Instead of hardcoding the name of the provider in two places, I would
have this function take a const char * argument and then pass in the value.
> + str = CMNewString(broker, charsptr, &s);
> + CMSetProperty(ind, "ProviderName", &str, CMPI_string);
> + free(charsptr);
> +
> + str = CMNewString(broker, "DTMF", &s);
> + CMSetProperty(ind, "OwningEntity", &str, CMPI_string);
> +
> + str = CMNewString(broker, "PLAT0002", &s);
> + CMSetProperty(ind, "MessageID", &str, CMPI_string);
> +
> + //CMSetProperty(ind, "Message", &str, CMPI_string);
> +
> + // This is an string array
> + array = CMNewArray(broker, 1, CMPI_stringA, &s);
> + str = CMNewString(broker,
> + "Virtual machine execution ended "
> + "unexpectly",
> + &s);
> + s = CMSetArrayElementAt(array, 0, &str, CMPI_string);
> + CMSetProperty(ind, "MessageArguments", &array, CMPI_string);
> +}
> +
> +static CMPIStatus create_and_deliver_ind(const CMPIBroker *broker,
> + const CMPIContext *ctx,
> + struct ind_args *args)
> +{
> + const char *ind_type_name = "GuestCrashAlertIndication";
You set the name of the provider here - so you can pass this to
set_alert_ind_props(). This keeps you from having to change the name in
multiple locations if the name changes.
> + CMPIObjectPath *ind_op;
> + CMPIInstance *ind;
> + CMPIStatus s;
> + char *prefix = NULL;
> +
> + prefix = class_prefix_name(args->classname);
> +
> + ind = get_typed_instance(broker,
> + prefix,
> + ind_type_name,
> + args->ns);
You shouldn't need to create another indication here. You've already
created one in guest_crashed_cb(). If you create a new one here, you
overwrite the one created in guest_crashed_cb(). You lose the values of
the attributes you set in guest_crashed_cb().
> +
> + if (ind == NULL) {
> + cu_statusf(broker,
> + &s,
> + CMPI_RC_ERR_FAILED,
> + "Failed to create ind, type '%s:%s_%s'",
> + args->ns,
> + prefix,
> + ind_type_name);
> + goto out;
> + }
> +
> + ind_op = CMGetObjectPath(ind, &s);
> + if (s.rc != CMPI_RC_OK) {
> + //CU_DEBUG("Failed to get ind_op. Error: '%s'", s.msg);
> + goto out;
> + }
> + CMSetNameSpace(ind_op, args->ns);
> +
> + set_alert_ind_props(broker, prefix, ctx, ind);
> +
> + CU_DEBUG("Delivering Indication: %s",
> + CMGetCharPtr(CMObjectPathToString(ind_op, NULL)));
> +
> + s = stdi_deliver(broker, ctx, args, ind);
> + if (s.rc == CMPI_RC_OK) {
> + CU_DEBUG("Indication delivered");
> + } else {
> + CU_DEBUG("Not delivered: %s", CMGetCharPtr(s.msg));
> + }
> +
> + out:
> + free(prefix);
> +
> + return s;
> +}
> +
> +
> +static void preset_alert_ind_props(CMPIInstance *ind, virDomainPtr dom)
> +{
> + CMPIStatus s;
> + CMPIString *str = NULL;
> + char *dom_name = (char *)virDomainGetName(dom);
> + char *counter = NULL;
> +
> + if (dom_name == NULL) {
> + CU_DEBUG("Could not retrieve name of guest responsible for "
> + "crash");
> + dom_name = "Guest name not available";
> + }
> +
> + str = CMNewString(_BROKER, dom_name, &s);
> + CMSetProperty(ind, "AlertingManagedElement", &str, CMPI_string);
> +
> + // This property must be unique, retrieve a counter from infostore
> + counter = inc_counter(dom);
It seems like you'd want to use a mutex around this call to ensure that
you're note reading from the info store as it's being written to.
That'll ensure that each indication gets its own value.
> + if (counter == NULL) {
> + CU_DEBUG("Could not retrieve counter");
> + } else {
> + str = CMNewString(_BROKER, counter, &s);
> + CMSetProperty(ind, "EventID", &str, CMPI_string);
> + free(counter);
> + }
> +}
> +
--
Kaitlin Rupert
IBM Linux Technology Center
kaitlin at linux.vnet.ibm.com
More information about the Libvirt-cim
mailing list