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

Kaitlin Rupert kaitlin at linux.vnet.ibm.com
Wed Aug 19 17:15:54 UTC 2009


> 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 =

You'll also need to include your link to Virt_CS here.
> +
> 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");

Be sure to remove this debug..

> +
>          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};

Since trigger isn't supported, I would remove this function and update 
the struct std_indication_handler csi so that the trigger function 
handler is NULL.

Here, you are returning a successful error code, but the function 
doesn't do anything.

> +}
> +
> +static void set_alert_ind_props(const CMPIBroker *broker,
> +                                const char *prefix,
> +                                const CMPIContext *ctx,
> +                                CMPIInstance *ind)
> +{
> +        CMPIStatus s;  
> +        CMPIString *str;
> +        CMPIUint16 uint16;

unit16 is an odd variable name here.. the providers usually use 
something like "val" - or you can use something more meaningful.

> +        CMPIArray *array;
> +
> +        
> +        //CMSetProperty(ind, "Description", &str, CMPI_string);

For those properties you don't plan on setting, be sure to remove them.

> +
> +        str = CMNewString(broker, prefix, &s);
> +        CMSetProperty(ind, "AlertingManagedElement", &str, CMPI_string);

Really, we should return information about the guest that has crashed. 
We should return an instance of the guest that has crashed.

If the guest has been defined prior to being started, then we should be 
able to get the instance of the guest.  If you are unable to get the 
instance of the guest, include it's name or some other identifying info.

> +
> +        // val 1
> +        uint16 = 1;
> +        CMSetProperty(ind, "AlertType", &uint16, CMPI_uint16);
> +
> +        str = CMNewString(broker, "VM Crash", &s);

Instead of saying "VM Crash" - you might want to say something like 
"Virtual guest crash" - it's possible this string will be displayed to 
the user.

> +        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);

You're using the prefix as the EventID here.  The EventID should be 
unique - and a value of "Xen" or "KVM" doesn't make sense here.

> +
> +        // 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);

This value should be set.

> +
> +        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};

Extra space at the beginning of the line.

> +        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 you are already passing args to the create_and_deliver_ind(), why not 
pull the prefix from args->classname in create_and_deliver_ind() itself?

> +
> +        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;
> +}
> +
> +


-- 
Kaitlin Rupert
IBM Linux Technology Center
kaitlin at linux.vnet.ibm.com




More information about the Libvirt-cim mailing list