Wrong EmbeddedInstances from CIMOM callback

Jan Safranek <[email protected]> Tue, 02 Apr 2013 17:17:26 +0200
Newsgroups gmane.network.open-pegasus.general
Message-ID <[email protected]>
I'm still working on the job control and I've found out that if I call
CBGetInstance() from inside my CMPI provider to get an instance of
CIM_MethodResult, I get instance with wrong properties. It's quite hard
to describe the bug, I'm sure I'm hitting some weird corner case here.

CIM_MethodResult has two properties Pre/PosCallIndication, which are
embedded instances of CIM_MethodCall. And the CIM_MethodCall has Error
property with embedded instance of CIM_Error class. All this seems to be
somewhat important to reproduce the bug.

Attached is a sample CMPI provider & MOF file. Implemented are only
these intrinsic methods:
EnumerateInstances - in TST_MethodResultEnumInstances ()
GetInstance - in TST_MethodResultGetInstance()
InvokeMethod - TST_MethodResultInvokeMethod ()

There is very little checking, e.g. GetInstance does not check the
instance ObjectPath etc. Also only few properties are implemented, this
is the smallest provider to reproduce the bug.

GetInstance works well if it is called from outside, i.e. from a WBEM
client. It returns a TST_MethodResult instance with PreCallIndication
and PostCallIndication properties, both embedded instances of
CIM_InstMethodCall class. So far so good.

If I call GetInstance from inside the provider via CIMOM using
CBGetInstance, I can get good PostCallIndication, but PreCallIndication
has wrong class, CIM_Error instead of CIM_InstMethodCall. You can try to
call DoTest() method of my TST_MethodResult class - it calls
CBGetInstance to get instance of TST_MethodResult and prints all its
property names it gets and dives into embedded instances.

To reproduce the bug, run Pegasus this way, it will print debug output
to stderr:

$ cimserver daemon=false

Then call DoTest() on a TST_MethodResult instance and you should get
output similar to bad.log. Note the class names of embedded instances of
TST_MethodResult properties:

...
    Property: PreCallIndication
        class: CIM_Error     <--- should be CIM_InstMethodCall
...
    Property: PostCallIndication
        class: CIM_InstMethodCall
        ...
        Property: Error
            array 1{
                class: CIM_InstMethodCall  <---should be CIM_Error
...

If the cimserver is started with forceProviderProcesses=false, the bug
disappears, see good.log:

...
    Property: PreCallIndication
        class: CIM_InstMethodCall
...
    Property: PostCallIndication
        class: CIM_InstMethodCall
        ...
        Property: Error
            array 1{
                class: CIM_Error
...

Working 'forceProviderProcesses' indicates the bug is related  to
communication  between CIMOM and the provider process, but I haven't
found any way how to debug this.

In addition, if I switch the order, in which  my provider sets
PreCallIndication and PostCallIndication properties (= switch lines 133
and 135 in methodresult.c), it starts working too.

That's where I stopped debugging, I wasn't able to find any logging
related to inter process communication.

I hope this report does make some sense, feel free to ask if you need
additional information.

Jan
bad.log (text/x-log, 2.7 KB)
TST_MethodResultGetInstance() called, ctx 0x7f8192b01910, rslt 0x7f8192b01970, op 0x7f8192b018f0, properties (nil)
Entering TST get_instance()
Creating error
error created
Creating PreCall
PreCall created
Creating array of errors
array created
Creating PostCall
PostCall created
Creating MethodResult
Set PreCall
Set PostCall
TST finished
TST_MethodResultGetInstance() succeeded
    class: TST_MethodResult
    Property: Caption
    Property: Description
    Property: ElementName
    Property: Generation
    Property: InstanceID
    Property: PreCallIndication
        class: CIM_Error
        Property: OwningEntity
        Property: MessageID
        Property: ContinuedInNextMessage
        Property: Message
        Property: MessageArguments
        Property: ErrorType
        Property: OtherErrorType
        Property: PerceivedSeverity
        Property: ProbableCause
        Property: ProbableCauseDescription
        Property: RecommendedActions
        Property: ErrorSource
        Property: ErrorSourceFormat
        Property: OtherErrorSourceFormat
        Property: CIMStatusCode
        Property: CIMStatusCodeDescription
    Property: PostCallIndication
        class: CIM_InstMethodCall
        Property: IndicationIdentifier
        Property: CorrelatedIndications
        Property: IndicationTime
        Property: PerceivedSeverity
        Property: OtherSeverity
        Property: IndicationFilterName
        Property: SequenceContext
        Property: SequenceNumber
        Property: SourceInstance
            (NULL)
        Property: SourceInstanceModelPath
        Property: SourceInstanceHost
        Property: MethodName
        Property: MethodParameters
            (NULL)
        Property: ReturnValue
        Property: ReturnValueType
        Property: Error
            array 1{
                class: CIM_InstMethodCall
                Property: IndicationIdentifier
                Property: CorrelatedIndications
                Property: IndicationTime
                Property: PerceivedSeverity
                Property: OtherSeverity
                Property: IndicationFilterName
                Property: SequenceContext
                Property: SequenceNumber
                Property: SourceInstance
                    (NULL)
                Property: SourceInstanceModelPath
                Property: SourceInstanceHost
                Property: MethodName
                Property: MethodParameters
                    (NULL)
                Property: ReturnValue
                Property: ReturnValueType
                Property: Error
                    (empty array)
                Property: PreCall
            } array
        Property: PreCall
invokeMethod() succeeded
embedded.mof (text/x-mof, 68 B)
class TST_MethodResult : CIM_MethodResult
{
    uint32 DoTest();
};
good.log (text/x-log, 2.6 KB)
TST_MethodResultGetInstance() called, ctx 0x7f24374fa3e0, rslt 0x7f24374fa440, op 0x7f24374fa3c0, properties (nil)
Entering TST get_instance()
Creating error
error created
Creating PreCall
PreCall created
Creating array of errors
array created
Creating PostCall
PostCall created
Creating MethodResult
Set PreCall
Set PostCall
TST finished
TST_MethodResultGetInstance() succeeded
    class: TST_MethodResult
    Property: Caption
    Property: Description
    Property: ElementName
    Property: Generation
    Property: InstanceID
    Property: PreCallIndication
        class: CIM_InstMethodCall
        Property: IndicationIdentifier
        Property: CorrelatedIndications
        Property: IndicationTime
        Property: PerceivedSeverity
        Property: OtherSeverity
        Property: IndicationFilterName
        Property: SequenceContext
        Property: SequenceNumber
        Property: SourceInstance
            (NULL)
        Property: SourceInstanceModelPath
        Property: SourceInstanceHost
        Property: MethodName
        Property: MethodParameters
            (NULL)
        Property: ReturnValue
        Property: ReturnValueType
        Property: Error
            (empty array)
        Property: PreCall
    Property: PostCallIndication
        class: CIM_InstMethodCall
        Property: IndicationIdentifier
        Property: CorrelatedIndications
        Property: IndicationTime
        Property: PerceivedSeverity
        Property: OtherSeverity
        Property: IndicationFilterName
        Property: SequenceContext
        Property: SequenceNumber
        Property: SourceInstance
            (NULL)
        Property: SourceInstanceModelPath
        Property: SourceInstanceHost
        Property: MethodName
        Property: MethodParameters
            (NULL)
        Property: ReturnValue
        Property: ReturnValueType
        Property: Error
            array 1{
                class: CIM_Error
                Property: OwningEntity
                Property: MessageID
                Property: ContinuedInNextMessage
                Property: Message
                Property: MessageArguments
                Property: ErrorType
                Property: OtherErrorType
                Property: PerceivedSeverity
                Property: ProbableCause
                Property: ProbableCauseDescription
                Property: RecommendedActions
                Property: ErrorSource
                Property: ErrorSourceFormat
                Property: OtherErrorSourceFormat
                Property: CIMStatusCode
                Property: CIMStatusCodeDescription
            } array
        Property: PreCall
invokeMethod() succeeded
make.sh (application/x-shellscript, 243 B)
gcc -c methodresult.c -g -O0 -fPIC -Wall

gcc -fPIC -std=c99 -Wall -pedantic -g -O0 -Wextra -Wno-unused-parameter -Wformat -Wparentheses -Wl,--no-undefined    -shared -Wl,-soname,libcmpiMethodResult.so -o libcmpiMethodResult.so methodresult.o
methodresult.c (text/plain, 14.5 KB)
/* Public domain. */

#include <stdio.h>
#include <stdarg.h>

#include <cmpi/cmpidt.h>
#include <cmpi/cmpift.h>
#include <cmpi/cmpimacs.h>

/* A simple stderr logging/tracing facility. */
#ifndef _CMPI_TRACE
#define _CMPI_TRACE(tracelevel,args) _logstderr args
static void _logstderr(char *fmt,...)
{
    va_list ap;
    va_start(ap,fmt);
    vfprintf(stderr,fmt,ap);
    va_end(ap);
    fprintf(stderr,"\n");
}
#endif

/* Global handle to the CIM broker. This is initialized by the CIMOM when
 * the provider is loaded */
static const CMPIBroker * _broker = NULL;

static CMPIStatus TST_MethodResultCleanup(
       CMPIInstanceMI * self,
       const CMPIContext * ctx,
       CMPIBoolean terminating)
{
     CMPIStatus st = { CMPI_RC_OK, NULL };
     return st;
}
static CMPIStatus TST_MethodResultMethodCleanup(
       CMPIMethodMI * self,
       const CMPIContext * ctx,
       CMPIBoolean terminating)
{
     CMPIStatus st = { CMPI_RC_OK, NULL };
     return st;
}


static CMPIStatus TST_MethodResultEnumInstanceNames(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op)
{
     _CMPI_TRACE(1, ("TST_MethodResultEnumInstanceNames() called, ctx %p,"
                " result %p, op %p", ctx, rslt, op));
     CMPIStatus status = {CMPI_RC_OK, NULL};

     _CMPI_TRACE(1,("TST_MethodResultEnumInstanceNames() %s",
                (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
     return status;
}

CMPIInstance *get_instance(
        const CMPIBroker *_broker,
        const CMPIContext * ctx,
        const CMPIObjectPath * op)
{
    CMPIInstance *ipost, *ipre, *imresult, *ierror;
    CMPIObjectPath *ppost, *ppre, *pmresult, *perror;
    CMPIValue vmname, vpostindication, vpreindication, vinstanceid, verror, vstatuscode, vmessage, verrors, vprecall;
    CMPIString *ns;
    CMPIArray *aerrors;
    CMPIStatus status;

    fprintf(stderr, "Entering TST get_instance()\n");

    fprintf(stderr, "Creating error\n");
    /* Create Error embedded instance */
    ns=CMGetNameSpace(op, &status);
    perror = CMNewObjectPath(_broker, CMGetCharPtr(ns), "CIM_Error", &status);
    ierror = CMNewInstance(_broker, perror, &status);
    vstatuscode.uint32 = 1; // TST_ERR_FAILED
    CMSetProperty(ierror, "CIMStatusCode", &vstatuscode, CMPI_uint32);
    vmessage.string = CMNewString(_broker, "Test error message", &status);
    CMSetProperty(ierror, "Message", &vmessage, CMPI_string);
    fprintf(stderr, "error created\n");

    fprintf(stderr, "Creating PreCall\n");
    /* create PreCallIndication embedded instance */
    ppre = CMNewObjectPath(_broker, CMGetCharPtr(ns), "CIM_InstMethodCall", &status);
    ipre = CMNewInstance(_broker, ppre, &status);
    /* set MethodName */
    vmname.string = CMNewString(_broker, "TestMethod", &status);
    CMSetProperty(ipre, "MethodName", &vmname, CMPI_string);
    /* set PreCall */
    vprecall.boolean = 0;
    CMSetProperty(ipre, "PreCall", &vprecall, CMPI_boolean);
    fprintf(stderr, "PreCall created\n");

    fprintf(stderr, "Creating array of errors\n");
    /* create array with the Error instance */
    aerrors = CMNewArray(_broker, 1, CMPI_instance, &status);
    verror.inst = ierror;
    CMSetArrayElementAt(aerrors, 0, &verror, CMPI_instance);
    fprintf(stderr, "array created\n");

    fprintf(stderr, "Creating PostCall\n");
    /* create PostCallIndication embedded instance */
    ns=CMGetNameSpace(op, &status);
    ppost = CMNewObjectPath(_broker,CMGetCharPtr(ns),"CIM_InstMethodCall",&status);
    ipost = CMNewInstance(_broker, ppost, &status);
    /* set MethodName */
    vmname.string = CMNewString(_broker, "TestMethod", &status);
    CMSetProperty(ipost, "MethodName", &vmname, CMPI_string);
    /* set Error */
    verrors.array = aerrors;
    CMSetProperty(ipost, "Error", &verrors, CMPI_instanceA);
    /* set PreCall */
    vprecall.boolean = 1;
    CMSetProperty(ipost, "PreCall", &vprecall, CMPI_boolean);
    fprintf(stderr, "PostCall created\n");

    fprintf(stderr, "Creating MethodResult\n");
    /* create MethodResult instance */
    ns=CMGetNameSpace(op, &status);
    pmresult = CMNewObjectPath(_broker, CMGetCharPtr(ns), "TST_MethodResult", &status);
    vinstanceid.string = CMNewString(_broker, "TestInstanceID", &status);
    CMAddKey(pmresult, "InstanceID", &vinstanceid, CMPI_string);
    imresult = CMNewInstance(_broker, pmresult, &status);

    CMSetProperty(imresult, "InstanceID", &vinstanceid, CMPI_string);
    /* store PostCallIndication in the property */
    vpostindication.inst = ipost;
    vpreindication.inst = ipre;
    fprintf(stderr, "Set PreCall\n");
    CMSetProperty(imresult, "PreCallIndication", &vpreindication, CMPI_instance);
    fprintf(stderr, "Set PostCall\n");
    CMSetProperty(imresult, "PostCallIndication", &vpostindication, CMPI_instance);
 
    fprintf(stderr, "TST finished\n");
    return imresult;
}


static CMPIStatus TST_MethodResultEnumInstances(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op,
        const char ** properties)
{
    CMPIStatus status = {CMPI_RC_OK, NULL};

    _CMPI_TRACE(1, ("TST_MethodResultEnumInstances() called, ctx %p, rslt %p,"
                " op %p, properties %p", ctx, rslt, op, properties));


    CMReturnInstance(rslt, get_instance(_broker, ctx, op));
    CMReturnDone(rslt);


    status.rc = CMPI_RC_OK;
    status.msg = NULL;

    _CMPI_TRACE(1, ("TST_MethodResultEnumInstances() %s",
          (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

static CMPIStatus TST_MethodResultGetInstance(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op,
        const char ** properties)
{
    CMPIStatus status = {CMPI_RC_OK, NULL};

    _CMPI_TRACE(1, ("TST_MethodResultGetInstance() called, ctx %p, rslt %p,"
        " op %p, properties %p", ctx, rslt, op, properties));

    CMReturnInstance(rslt, get_instance(_broker, ctx, op));
    CMReturnDone(rslt);

    status.rc = CMPI_RC_OK;
    status.msg = NULL;

    _CMPI_TRACE(1, ("TST_MethodResultGetInstance() %s",
         (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

static CMPIStatus TST_MethodResultCreateInstance(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op,
        const CMPIInstance * inst)
{
    CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("TST_MethodResultCreateInstance() called, ctx %p, rslt %p,"
        " op %p, inst %p", ctx, rslt, op, inst));
    _CMPI_TRACE(1, ("TST_MethodResultCreateInstance() %s",
        (status.rc == CMPI_RC_OK) ? "succeeded":"failed"));
    return status;
}


// ----------------------------------------------------------------------------

#ifdef CMPI_VER_100
#define TST_MethodResultSetInstance TST_MethodResultModifyInstance
#endif

static CMPIStatus TST_MethodResultSetInstance(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op,
        const CMPIInstance * inst,
        const char ** properties)
{
    CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("TST_MethodResultSetInstance() called, ctx %p, rslt %p,"
        " op %p, inst %p, properties %p", ctx, rslt, op, inst, properties));
    _CMPI_TRACE(1, ("TST_MethodResultSetInstance() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

// ----------------------------------------------------------------------------


/* DeleteInstance() - delete/remove the specified instance. */
static CMPIStatus TST_MethodResultDeleteInstance(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op)
{
    CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("TST_MethodResultDeleteInstance() called, ctx %p, rslt %p,"
        " op %p", ctx, rslt, op));
    _CMPI_TRACE(1, ("TST_MethodResultDeleteInstance() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

// ----------------------------------------------------------------------------


static CMPIStatus TST_MethodResultExecQuery(
        CMPIInstanceMI * self,
        const CMPIContext * ctx,
        const CMPIResult * rslt,
        const CMPIObjectPath * op,
        const char * query,
        const char * lang)
{
    /* Return status of CIM operations. */
    CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("TST_MethodResultExecQuery() called, ctx %p, rslt %p, op %p,"
        " query %s, lang %s", ctx, rslt, op, query, lang));
    _CMPI_TRACE(1, ("TST_MethodResultExecQuery() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

//  associatorMIFT
//

CMPIStatus TST_MethodResultAssociatorNames(
        CMPIAssociationMI* self,
        const CMPIContext* ctx,
        const CMPIResult* rslt,
        const CMPIObjectPath* op,
        const char* assocClass,
        const char* resultClass,
        const char* role,
        const char* resultRole)
{
         CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("associatorNames() called, ctx %p, rslt %p, op %p,"
        " assocClass %s, resultClass %s, role %s, resultRole %s",
        ctx, rslt, op, assocClass, resultClass, role, resultRole));

    _CMPI_TRACE(1, ("associatorNames() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

/***************************************************************************/
CMPIStatus TST_MethodResultAssociators(
        CMPIAssociationMI* self,
        const CMPIContext* ctx,
        const CMPIResult* rslt,
        const CMPIObjectPath* op,
        const char* assocClass,
        const char* resultClass,
        const char* role,
        const char* resultRole,
        const char** properties)
{
     CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

     _CMPI_TRACE(1, ("associators() called, ctx %p, rslt %p, op %p,"
         " assocClass %s, resultClass %s, role %s, resultRole %s",
         ctx, rslt, op, assocClass, resultClass, role, resultRole));

    _CMPI_TRACE(1, ("associators() %s",
         (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

/***************************************************************************/
CMPIStatus TST_MethodResultReferenceNames(
        CMPIAssociationMI* self,
        const CMPIContext* ctx,
        const CMPIResult* rslt,
        const CMPIObjectPath* op,
        const char* resultClass,
        const char* role)
{
    CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("referenceNames() called, ctx %p, rslt %p, op %p,"
        " resultClass %s, role %s", ctx, rslt, op, resultClass, role));

    _CMPI_TRACE(1, ("referenceNames() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}


/***************************************************************************/
CMPIStatus TST_MethodResultReferences(
        CMPIAssociationMI* self,
        const CMPIContext* ctx,
        const CMPIResult* rslt,
        const CMPIObjectPath* op,
        const char* resultClass,
        const char* role,
        const char** properties)
{
    CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL};

    _CMPI_TRACE(1, ("references() called, ctx %p, rslt %p, op %p,"
            " resultClass %s, role %s, properties %p",
            ctx, rslt, op, resultClass, role, properties));

    _CMPI_TRACE(1, ("references() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

static void print_instance(CMPIInstance *inst, int indent)
{
    int i, j;
    CMPIStatus st;
    CMPIData p;
    CMPIString *str;
    CMPIObjectPath *path;

    if (inst == NULL) {
        for (j=0; j<indent; j++) fprintf(stderr, " ");
        fprintf(stderr, "(NULL)\n");
        return;
    }

    path = inst->ft->getObjectPath(inst, &st);
    str = path->ft->getClassName(path, &st);
    for (j=0; j<indent; j++) fprintf(stderr, " ");
    fprintf(stderr, "class: %s\n", CMGetCharPtr(str));
 
    for (i=0; i<inst->ft->getPropertyCount(inst, &st); i++) {
        p = inst->ft->getPropertyAt(inst, i, &str, &st);
        for (j=0; j<indent; j++) fprintf(stderr, " ");
        fprintf(stderr, "Property: %s\n", CMGetCharPtr(str));
        if (p.type == CMPI_instance)
            print_instance(p.value.inst, indent + 4);
        if (p.type == (CMPI_instance | CMPI_ARRAY)){
            CMPIArray *a = p.value.array;
            int k, siz;
            if (!a) {
                for (j=0; j<indent+4; j++) fprintf(stderr, " ");
                fprintf(stderr, "(empty array)\n");
                continue;
            }
            siz = a->ft->getSize(a, &st);
            for (j=0; j<indent+4; j++) fprintf(stderr, " ");
            fprintf(stderr, "array %d{\n", siz);
            for (k=0; k<siz; k++){
                CMPIData q = a->ft->getElementAt(a, k, &st);
                print_instance(q.value.inst, indent+8);
            }
            for (j=0; j<indent+4; j++) fprintf(stderr, " ");
            fprintf(stderr, "} array\n");
        }
    }

}

static void get_inst(const CMPIObjectPath *op, const CMPIContext *ctx, const char* classname)
{
    CMPIStatus status = {CMPI_RC_OK, NULL};
    CMPIObjectPath *path;
    CMPIInstance *inst;
    CMPIString *ns;
    CMPIValue vid;

    ns=CMGetNameSpace(op, &status);
    path = CMNewObjectPath(_broker, CMGetCharPtr(ns), classname, &status);
    vid.string = CMNewString(_broker, "TestInstanceID", &status);
    CMAddKey(path, "InstanceID", &vid, CMPI_string);
  
    /* call GetInstance */
    inst = CBGetInstance(_broker, ctx, path, NULL, &status);
    print_instance(inst, 4);

 }

/***************************************************************************/
CMPIStatus TST_MethodResultInvokeMethod(
        CMPIMethodMI* self,
        const CMPIContext* ctx,
        const CMPIResult* rslt,
        const CMPIObjectPath* op,
        const char* method,
        const CMPIArgs* in,
        CMPIArgs* out)
{
    CMPIStatus status = {CMPI_RC_OK, NULL};


    get_inst(op, ctx, "TST_MethodResult");
   _CMPI_TRACE(1, ("invokeMethod() %s",
        (status.rc == CMPI_RC_OK)? "succeeded":"failed"));
    return status;
}

/***************************************************************************/


CMMethodMIStub( TST_MethodResult, TST_MethodResult, _broker, CMNoHook);
CMInstanceMIStub( TST_MethodResult, TST_MethodResult, _broker, CMNoHook);
//CMAssociationMIStub( TST_MethodResult, TST_MethodResult, _broker, CMNoHook);
register.mof (text/x-mof, 673 B)
instance of PG_ProviderModule
{
    Name = "cmpiMethodResult";
    Location = "cmpiMethodResult";
    Vendor = "RedHat";
    Version = "0.0.1";
    InterfaceType = "CMPI";
    InterfaceVersion = "2.0.0";
    ModuleGroupName = "cmpiMethodResult";
};

instance of PG_Provider
{
    Name = "TST_MethodResult";
    ProviderModuleName = "cmpiMethodResult";
};

instance of PG_ProviderCapabilities
{
   ProviderModuleName = "cmpiMethodResult";
   ProviderName = "TST_MethodResult";
   CapabilityID = "TST_MethodResult";
   ClassName = "TST_MethodResult";
   Namespaces = { "root/cimv2" };
   ProviderType = { 2,5 };
   SupportedProperties = NULL;
   SupportedMethods = NULL;
};