[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