OpenWbem 的介绍及其 CMPI 接口的 CIM provider 的开发实现

来源:developerWorks 中国 作者:徐 晔
  
通用信息模型 (Common Information Module) 相关的技术正在被广泛地应用于设备管理,网络控制,信息处理等领域, CIM 模型已经被 IT 界各大公司广泛用作上层管理软件的基础信息模型,如 IBM,HP,EMC 等。当设备提供商需要将其设备纳入信息模型和管理体系时, CIM provider 的开发就显得尤为重要。虽然如今 CIM 技术及其 provider 开发已经成为一项热门技术。但是大量的文档集中在 sfcb 及 pegasus 方面。基于 Openwbem 的 provider 开发的资料是少之又少。本文希望能填补一些空白,让需要基于 Openwbem 的 CIM provider 开发者快速越过开发前期的技术瓶颈障碍。

概述

本文介绍了 OpenWbem 相关的基本概念及其 CMPI 接口的 CIM provider 的开发。从 OpenWbem 的安装入手,到其 CIM provider 的编写,编译,注册和调试,希望对基于 Openwbem 的 CIM provider 初次开发者有所帮助。





Openwbem 及相关标准的介绍

WBEM/CIM 及其相关标准

WBEM (Web-Based Enterprise Management) 是由分布式管理工作组 (DMTF) 负责开发的一套使用 Internet 标准技术的一体化企业计算管理环境。它提供了基于 WEB 技术的完整的工业统一管理工具。促进了完全不同技术和平台的数据交换。

CIM (Common Information Module) 通用信息模型作为 WBEM 的核心定义了一种分层次的、面向对象的信息模型和架构,该架构可以为企业网络管理整个范围内的系统,网络,应用程序和服务的信息管理提供公共定义,而且允许用户扩充。它描述了管理的概念模型,可以使得用户可以通过网络在彼此的系统之间交换语义丰富的管理信息。目前 CIM 模型已经被 IT 界各大公司 IBM, HP, EMC 等广泛用作上层管理软件的基础信息模型,相关的技术正在被广泛地应用于设备管理,网络控制,数据库信息处理等领域。

Openwbem 的相关概念及用途

CIMOM 即公共信息模型对象管理器,在 CIM 模型的实现中是最重要的部件。它是一个描述信息系统构成单元的对象数据库,为其他程序提供了一个访问信息系统构成单元的公共接口集,实现在 HTTP 操作和 CIMXML HTTP 编码之上的 CIM 操作,还有一个为客户端和供给端提供的接口类库。

CIMOM 的实现项目很多,有 OpenPegasus, SFCB 和 Openwbem 等。其中 Openwbem 是一个企业级 wbem (Web Based Enterprise Management) 实现的开源项目。它在 Linux 平台 SUSE 企业服务器9和10 中都已经存在。

CIM provider 为数据提供者,当客户管理者需要 CIMOM 提供管理信息时,它在可以从广泛的设备上提取出需要的信息返回给 CIMOM, 进而提供给客户端程序。

下图为 CIM 模型管理体系中的各个部件的位置:


图 1 CIM 模型管理体系
CIM 模型管理体系

Openwbem 的安装及配置

由于 Openwbem 在 SUSE linux 安装包中已经存在,它的安装变得十分便利,可以直接通过 Yast2 安装。在使用之前,必须确保以下3个包已经装在开发平台上,它们是 openwbem, openwbem-devel, cim-schema。

Openwbem 的基本操作

若想看出 Openwbem 是否安装成功,可以通过查看帮助信息 ”-h” 来达到目的:


图 2. 查看 Openwbem 是否安装命令
查看 Openwbem 是否安装命令

在帮助信息的选项中, -d 能让 CIMOM 这个后台程序运行在前台,因而能显性的实时追踪到 debug 信息和状态。选项 –c 后面必须指定配置文件的路径,否则 CIMOM 将默认地认为配置文件为 /etc/openwbem/openwbem.conf.

通常,我们不会对配置文件作过多的修改,在 Openwbem 安装完毕后直接后台运行。


图 3. 启动 openwbem 命令
启动 openwbem 命令

虽然 CIMOM 已经正常运行,但是它的数据库里既没有用户的命名空间,也没有标准的 CIM schema 的类库集。而这些必须通过 OpenWbem 的命令手动操作建立。


图 4. 创建 namespace 命令
创建 namespace 命令

图 5. 注册基类命令
注册基类命令

注册基类命令操作可能会持续一段时间,并且用户可以看到不断输出的实时状态信息。若处理期间发生错误,错误断点通过输出信息可以很快被找到。





CIM Provider 开发现状及主要接口介绍

Openwbem 所支持的 provider 接口介绍

在 CIM 模型的管理体系中, CIMOM 使用合适的接口来访问各种类型的提供者 (provider) 中的数据。当然, Openwbem 也不例外,他支持的 provider 接口有 CMPI(Common Manageability Programming Interface), C++, NPI (network provider interface) 等。

CMPI 接口的概念和优势

CMPI 接口是 Open Group 发布的基于 CIM provider 的标准接口。它独立于各个 CIMOM 的不同的实现方式,并被大多数 CIMOM 所接受,包括 OpenPegasus, OpenWBEM 和 SFCB 等都已经支持了 CMPI 接口。因此,基于 CMPI 接口开发的提供者 (provider) 也就成为了移植性最好,用途最广泛的和最流行的 provider 。这也是本文专注于 CMPI 接口的 provider 开发的原因。





基于 Openwbem CMPI 接口的 CIM provider 开发实现样例

编写代码过程及其注意事项

我们知道, CIM Provider 根据功能需求基本分为 Instance Provider, Method provider, Indication Provider, Association Provider 等。其中最为广泛应用和最具有代表性的为 Instance Provider, 因此,本文以 Instance Provider 为例,介绍基于 Openwbem CMPI 接口的 provider 开发实现。

在开发 provider 之前,我们必须指定 CMPI 接口函数库的路径,如下:


清单 1. CMPI 接口函数库的路径
#include <openwbem/cmpidt.h>
#include <openwbem/cmpift.h>
#include <openwbem/cmpimacs.h>

随后,我们通过 CMPI 接口函数库可以看出 Instance provider 的接口函数为 EnumerateInstanceNames,EnumerateInstances,GetInstance,SetInstance,CreateInstance,DeleteInstance 等。这些函数可以被部分实现,也可以被全部实现。根据需要,以下为其中 EnumerateInstanceNames 函数的实现样例:


清单 2. EnumerateInstanceNames 函数的实现样例
// ----------------------------------------------------------------------------
// EnumInstanceNames()
// Return a list of all the instances names (return their object paths only).
// ----------------------------------------------------------------------------
static CMPIStatus EnumInstanceNames(
         CMPIInstanceMI * self,   /* [in] Handle to this provider (i.e. 'self'). */
         CMPIContext * context,  /* [in] Additional context info, if any. */
         CMPIResult * results,       /* [out] Results of this operation. */
         CMPIObjectPath * reference)   /* [in] Contains target namespace and classname. */
{
CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */

printf("In EnumInstanceNames... \n");

//parsing namespace
char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); 

/* Create a new CMPIInstance to store this resource. */
CMPIObjectPath * op = CMNewObjectPath(_BROKER, namespace,  “Test_Service”, &status);
CMPIInstance * instance = CMNewInstance(_BROKER, op, &status);

CMSetProperty(instance, "SystemName",(CMPIValue *)"TestSystem", CMPI_chars);
CMSetProperty(instance, "SystemCreationClassName",(CMPIValue *)"Test", CMPI_chars);
CMSetProperty(instance, "Name",(CMPIValue *)"Example", CMPI_chars);
CMSetProperty(instance, "CreationClassName",(CMPIValue *)"TestService", CMPI_chars);

CMPIObjectPath * objectpath = CMGetObjectPath(instance, &status);
CMSetNameSpace(objectpath, namespace);
                
CMReturnObjectPath(results, objectpath);
CMReturnDone(results);

return status;

}

通过上例可以看出,用户调用 EnumInstanceNames 这个函数接口后,我们就创建了一个 “Test_Service” 类 的 Instance, 随后给这个 Instance 设定了4个 property, 分别为:

SystemName = "TestSystem",
SystemCreationClassName = "Test",
Name = "Example",
CreationClassName = "TestService"。

最后将这个 Instance 的 ObjectPath 通过 “CMReturnObjectPath(results, objectpath);” 返回给了用户。

在完成了一个接口函数的实体实现后,provider 的开发并没有完全结束。我们必须在代码最后建立 provider 的功能表,才能被 CIMOM 所识别。如下:


清单 3. 建立 provider 的功能表
CMInstanceMIStub( , Instance_provder_name, _BROKER, Initialize(&mi, ctx));

如何安装注册 provider

在完成 provider 的代码编写之后,我们需要将其安装注册,才能真正的在 CIMOM 需要时为它所调用提供数据。

首先,我们必须将 provider 的代码编译成动态连接库(.so 文件),动态库的名字必须以 lib 打头,后跟 Instance_provder_name ,然后将此文件放在 /usr/lib/cmpi/ 或 /usr/lib/openwbem/cmpiproviders 文件夹下。 CIMOM 会去这两个路径寻找它所需要的 provider 函数。

在可执行的 provider 函数编译安装到位后,我们必须将其在 CIMOM 的 repository 中进行注册。而被注册的 provider 信息就写在 mof 文件中,如下:


清单 4. mof 实现样例
[provider("cmpi:: Instance_provder_name ")]

class Test_Service : CIM_Service
{
};

Mof 文件的内容信息表明,provider 的可执行文件为 libInstance_provder_name.so ,它遵守 CMPI 接口标准。它所实现的 cim 类对象为Test_Service 类,继承于 CIM_Service 类。

有一点必须强调一下,读者可能已经注意到 Instance_provder_name 不论在 provider 编写过程中还是注册安装中都已经出现过多次。 Instance_provder_name 包含了多重意义,既代表了 provider 的名字,也是动态库的名字。我们必须在 Instance_provder_name 出现的所有地方保持一致。否则,会造成 CIMOM 拿到 provider 信息不匹配,造成错误。

在 mof 文件完成后,可以通过 openwbem 的工具将其注册进 CIMOM。


图 6. 注册用户类命令
注册用户类命令

使用 wbemcli 测试及 debug 过程

到现在为止,provider 的开发已经全部完成。用户已经可以利用 CIMOM 向 provider 索要信息。如下:


清单 5. 测试 provider 结果
linux:~ # wbemcli ein http://root:password@localhost:5988/root/cimv2:Test_Service

localhost:5988/root/cimv2: Test_Service.SystemCreationClassName="Test",
SystemName="TestSystem",CreationClassName="TestService",Name=" Example "

可以看出,provider 提供的信息正是我们在 provider 内部实现4个 property 的功能。若此时功能不符合用户预期,用户可以通过查看 debug 信息去发掘问题,方法如下:

首先,确保 CIMOM 运行在前台,正如我们在介绍 Openwbem 的基本操作时提到的那样,利用 –d 来达到此效果。


图 7. 前台运行 CIMOM 命令
前台运行 CIMOM 命令

此时我们可以发现,很多实时信息被不断的显示在屏幕上。当我们用 wbemcli 调用上例中的 provider 时,可以看到屏幕输出入下:


清单 6. Debug 输出信息
[3050199952] Request Handler /usr/lib/openwbem/requesthandlers/libowrequesthandlercimxml.so 
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
                         handling request for content type application/xml
[3050199952] safeLibCreate::create called.  createFuncName = createIndicationRepLayer
[3050199952] Got function name. calling function enumerateinstancenames
[3050199952] CIMServer doing operation: EnumerateInstanceNames on  \
                                            root/cimv2:Test_Service for user: root
[3050199952] CIMRepository got class: Test_Service from namespace: root/cimv2
[3050199952] CIMServer InstNameEnumerator enumerated derived instance names:  \
                                            root/cimv2:Test_Service
[3050199952] CMPIProviderIFC::getProvider loading     \
                                            library: /usr/lib/cmpi/libTest_Service.so
In Initialize...
[3050199952] CMPI provider ifc: provider Test_Service loaded and initialized
[3050199952] CMPIProviderIFC found instance provider Test_Service
[3050199952] CMPIInstanceProviderProxy::enumInstanceNames()
[3050199952] CMPIPrepareContext. User:   Full User:   Flgs: 0
In EnumInstanceNames …
[3050199952] CMPIBrokerEnc: mbEncNewObjectPath()
[3050199952] CMPIBrokerEnc: mbEncNewInstance()
[3050199952] CMPIBroker: mbGetClass()
[3050199952] safeLibCreate::create called.  createFuncName = createIndicationRepLayer
[3050199952] CIMServer doing operation: GetClass on root/cimv2:Test_Service for user: root
[3050199952] CIMRepository got class: Test_Service from namespace: root/cimv2
In EnumInstanceNames...
[3050199952] CIMRepository enumerated classes: root/cimv2:Test_Service

用户可以注意到,这些信息不仅是 CIMOM 运行过程中输出的一些 log 信息,还有一些是 Provider 本身输出的信息。如倒数第2行的 ”In EnumInstanceNames...” 是在上例 provider 代码中 printf("In EnumInstanceNames... \n"); 实现的结果。





总结

Openwbem 存在于 SUSE Linux 安装包中,安装与使用极其方便。 基于 Openwbem 的 CIM provider 的开发不论在编写规则还是调试方面都可以与闻名的 SFCB 或 Pegasus 相媲美。可以作为基于 CIM 开发的不错的选择。(责任编辑:A6)


时间:2008-09-27 16:31 来源:developerWorks 中国 作者:徐 晔 原文链接

好文,顶一下
(2)
66.7%
文章真差,踩一下
(1)
33.3%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量