[Libvirt-cim] [PATCH 2 of 2] Raises GuestCrashAlertIndication when QEMU crashes

Richard Maciel rmaciel at linux.vnet.ibm.com
Sun Aug 16 07:27:25 UTC 2009


# HG changeset patch
# User Richard Maciel <rmaciel at linux.vnet.ibm.com>
# Date 1248549583 10800
# Node ID a9a9447fc6357f9fd47f40b5a9bc4b97a5541d0f
# Parent  0377e5c28fba407e7bf2aae4c5f81d8e521a2adb
Raises GuestCrashAlertIndication when QEMU crashes

Signed-off-by: Richard Maciel <rmaciel at linux.vnet.ibm.com>

diff -r 0377e5c28fba -r a9a9447fc635 src/Makefile.am
--- a/src/Makefile.am	Sat Jul 25 16:19:43 2009 -0300
+++ b/src/Makefile.am	Sat Jul 25 16:19:43 2009 -0300
@@ -75,7 +75,8 @@
                        libVirt_ServiceAffectsElement.la \
                        libVirt_HostedAccessPoint.la \
                        libVirt_ServiceAccessBySAP.la \
-                       libVirt_SAPAvailableForElement.la
+                       libVirt_SAPAvailableForElement.la \
+                       libVirt_GuestCrashAlertIndication.la
 
 libVirt_ComputerSystem_la_SOURCES = Virt_ComputerSystem.c
 libVirt_ComputerSystem_la_DEPENDENCIES = libVirt_VirtualSystemSnapshotService.la
@@ -233,3 +234,7 @@
 libVirt_SAPAvailableForElement_la_SOURCES = Virt_SAPAvailableForElement.c
 libVirt_SAPAvailableForElement_la_LIBADD = -lVirt_ComputerSystem -lVirt_KVMRedirectionSAP
 
+libVirt_GuestCrashAlertIndication_la_DEPENDENCIES = libVirt_ComputerSystem.la
+libVirt_GuestCrashAlertIndication_la_SOURCES = Virt_GuestCrashAlertIndication.c
+libVirt_GuestCrashAlertIndication_la_LIBADD =
+
diff -r 0377e5c28fba -r a9a9447fc635 src/Virt_ComputerSystemIndication.c
--- a/src/Virt_ComputerSystemIndication.c	Sat Jul 25 16:19:43 2009 -0300
+++ b/src/Virt_ComputerSystemIndication.c	Sat Jul 25 16:19:43 2009 -0300
@@ -692,6 +692,8 @@
         char *prefix = NULL;
         bool rc;
 
+        CU_DEBUG("Raise indication");
+
         if (!lifecycle_enabled) {
                 cu_statusf(_BROKER, &s,
                            CMPI_RC_ERR_FAILED,
diff -r 0377e5c28fba -r a9a9447fc635 src/Virt_GuestCrashAlertIndication.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Virt_GuestCrashAlertIndication.c	Sat Jul 25 16:19:43 2009 -0300
@@ -0,0 +1,409 @@
+/*
+ * Copyright IBM Corp. 2009
+ *
+ * Authors:
+ * Richard Maciel <rmaciel at linux.vnet.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include <libvirt/libvirt.h>
+
+#include <libcmpiutil/libcmpiutil.h>
+#include <misc_util.h>
+#include <libcmpiutil/std_indication.h>
+#include <cs_util.h>
+
+#include "config.h"
+
+typedef struct cb_info {
+        const CMPIContext *context;
+        const CMPIObjectPath *ref;
+} *cb_info_ptr;
+
+static const CMPIBroker *_BROKER;
+
+static CMPIStatus trigger_indication(const CMPIContext *context)
+{
+        CU_DEBUG("guest crash indication triggered");
+        return(CMPIStatus){CMPI_RC_OK, NULL};
+}
+
+static void set_alert_ind_props(const CMPIBroker *broker,
+                                const char *prefix,
+                                const CMPIContext *ctx,
+                                CMPIInstance *ind)
+{
+        CMPIStatus s;
+        CMPIString *str;
+        CMPIUint16 uint16;
+        CMPIArray *array;
+
+        
+        //CMSetProperty(ind, "Description", &str, CMPI_string);
+
+        str = CMNewString(broker, prefix, &s);
+        CMSetProperty(ind, "AlertingManagedElement", &str, CMPI_string);
+
+        // val 1
+        uint16 = 1;
+        CMSetProperty(ind, "AlertType", &uint16, CMPI_uint16);
+
+        str = CMNewString(broker, "VM Crash", &s);
+        CMSetProperty(ind, "OtherAlertType", &str, CMPI_string);
+
+        uint16 = 7;
+        CMSetProperty(ind, "PerceivedSeverity", &uint16, CMPI_uint16);
+
+        // val 48
+        uint16 = 48;
+        CMSetProperty(ind, "ProbableCause", &uint16, CMPI_uint16);
+        
+        //CMSetProperty(ind, "ProbableCauseDescription", &str, CMPI_string);
+
+        // val 1
+        uint16 = 1;
+        CMSetProperty(ind, "Trending", &uint16, CMPI_uint16);
+
+        // This is an array
+        // CMSetProperty(ind, "RecommendedActions", &str, CMPI_string);
+
+        CMSetProperty(ind, "EventID", &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);
+
+        // Won't use it
+        // CMSetProperty(ind, "ProviderName", &str, CMPI_string);
+
+        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,
+                                         char *prefix,
+                                         struct ind_args *args)
+{
+        const char *ind_type_name = "GuestCrashAlertIndication";
+        CMPIObjectPath *ind_op;
+        CMPIInstance *ind;
+        CMPIStatus s;
+
+        ind = get_typed_instance(broker,
+                                 prefix,
+                                 ind_type_name,
+                                 args->ns);
+
+        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:
+        return s;
+}
+
+DECLARE_FILTER(xen_crashed, "Xen_GuestCrashAlertIndication");
+DECLARE_FILTER(kvm_crashed, "KVM_GuestCrashAlertIndication");
+
+static struct std_ind_filter *filters[] = {
+        &xen_crashed,
+        &kvm_crashed,
+        NULL,
+};
+
+static CMPIStatus raise_indication(const CMPIBroker *broker,
+                                   const CMPIContext *ctx,
+                                   const CMPIInstance *ind)
+{
+         CMPIStatus s = {CMPI_RC_OK, NULL};
+        CMPIObjectPath *ref = NULL;
+        struct std_indication_ctx *_ctx = NULL;
+        struct ind_args *args = NULL;
+        char *prefix = NULL;
+
+        CU_DEBUG("Guest Crash Raise indication");
+
+        ref = CMGetObjectPath(ind, &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 = true;
+
+        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);
+
+        s = create_and_deliver_ind(broker, ctx, prefix, args);
+
+        if (s.rc != CMPI_RC_OK) {
+                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 void free_cb(void *opaque)
+{
+        cb_info_ptr cbinfo = NULL;
+
+        CU_DEBUG("Releasing memory from guest crash callback");
+
+        cbinfo = (cb_info_ptr)opaque;
+        free(cbinfo);
+}
+
+static int guest_crashed_cb(virConnectPtr conn,
+                            virDomainPtr dom,
+                            int event,
+                            int detail,
+                            void *opaque)
+{
+        char *type = NULL;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        const char *ind_name = "GuestCrashedAlertIndication";
+        CMPIInstance *ind = NULL;
+        cb_info_ptr cbinfo = NULL;         
+        const CMPIObjectPath *ref =  NULL;        
+        const CMPIContext *context = NULL; 
+        
+        CU_DEBUG("Preparing GuestCrashedAlertIndication");
+
+        if (event != VIR_DOMAIN_EVENT_STOPPED_FAILED) {
+                CU_DEBUG("Event not monitored. Ignoring...");
+                return 0;
+        }
+
+        cbinfo = (cb_info_ptr)opaque;
+        ref = cbinfo->ref;
+        context = cbinfo->context;
+
+        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;
+        }
+
+        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;
+}
+
+static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
+                                 const CMPIContext* ctx,
+                                 const CMPISelectExp* se,
+                                 const char *ns,
+                                 const CMPIObjectPath* op,
+                                 CMPIBoolean first)
+{
+        virConnectPtr conn = NULL;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        cb_info_ptr cbinfo = NULL;
+        int ret = 0;
+
+        cbinfo = (cb_info_ptr)malloc(sizeof(struct cb_info));
+        cbinfo->context = ctx;
+        cbinfo->ref = op;
+
+        CU_DEBUG("ActivateFilter for %s", CLASSNAME(op));
+
+        conn = connect_by_classname(_BROKER, CLASSNAME(op), &s); 
+
+        CU_DEBUG("Registering callback function");
+        ret = virConnectDomainEventRegister(conn, 
+                                            guest_crashed_cb, 
+                                            (void *)cbinfo, 
+                                            free_cb);
+        CU_DEBUG("ret val: %d\n", ret);
+        
+        return s;
+}
+
+static CMPIStatus DeActivateFilter(CMPIIndicationMI* mi,
+                                   const CMPIContext* ctx,
+                                   const CMPISelectExp* se,
+                                   const  char *ns,
+                                   const CMPIObjectPath* op,
+                                   CMPIBoolean last)
+{
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+
+        CU_DEBUG("DeActivateFilter for %s", CLASSNAME(op));
+
+        return s;
+}
+
+static _EI_RTYPE EnableIndications(CMPIIndicationMI* mi,
+                                   const CMPIContext *ctx)
+{
+        CU_DEBUG("EnableIndications");
+
+        _EI_RET();
+
+}
+
+static _EI_RTYPE DisableIndications(CMPIIndicationMI* mi,
+                                    const CMPIContext *ctx)
+{
+        CU_DEBUG("DisableIndications");
+
+        _EI_RET();
+}
+
+
+
+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,
+};
+
+DEFAULT_IND_CLEANUP();
+DEFAULT_AF();
+DEFAULT_MP();
+
+STDI_IndicationMIStub(, 
+                      Virt_GuestCrashAlertIndicationProvider,
+                      _BROKER,
+                      libvirt_cim_init(), 
+                      &csi,
+                      filters);
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-set-style: "K&R"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * indent-tabs-mode: nil
+ * End:
+ */




More information about the Libvirt-cim mailing list