
+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@linux.vnet.ibm.com