存储那些事儿(一):异构虚拟化一种实现SMIS

1. 背景

        企业存储是企业信息系统管理很重要的组成部分。企业存储包含了大量的数据,供大量人使用。对于航空系统和金融系统来说,信息存储就更加重要了。 作为企业信息存储,扩展性是非常重要的,因为现在企业对于空间的使用越来越多。 

         那么一个企业可能会采用其他存储厂商的产品,原来信息如何保留? 使用数据迁移功能(migration),可以将数据转移到其他系统上。但是企业数据数以P级,还是占企业IT支出很大的一部分的。因此除非是热点数据,否则大部分的数据肯定还是保留在原有系统上。那么,如何保证这些原有系统可以正常使用呢?或者说,存储产品如何管理其他存储厂商的产品? 答案就是存储产品支持异构虚拟化!

         异构虚拟化指的是对第三方阵列的支持。这个技术最先由HDS引入高端存储,后来各大存储厂商也相继支持。异构虚拟化给客户带来的价值主要有两点,一是无缝接管原来的第三方阵列数据,统一管理;二是原来的数据可以享受高端存储的高级数据服务功能,比如自动分层,远程复制等等。一句话,保护投资,简化管理。


      本文讲讲述一种异构虚拟化的具体实现- Windows 8 如何通过System Center Virtual Machine Manager(SCVMM),管理第三方存储厂商的存储资源。管理是通过SMI-S(Storage Management Initiative Specification)协议实现的。

2. SMI-S技术背景

     SMI-SSNIA(全球网络存储工业协会)发起并主导,众多存储厂商共同参与开发的一种标准管理接口。其目标是在存储网络中的存储设备和管理软件之间提供标准化的通信方式,从而使存储管理实现厂商无关性,提高管理效率、降低管理成本,促进存储网络的发展。
        一方面,SMI-S为存储管理提供了一个统一的理界面,使用户能够在SAN中轻松的集成和管理来自多个厂商的产品,从而提升了灵活性、可管理性和可靠性;同时,用户的资源利用率也将获得极大的提高。
        另一方面,它为网络存储行业定义了一个全新、开放的开发模式,使存储厂商能够专注于附加值功能上,而省去了异构和专有接口开发整合所需的技术支持。SMI-S在统一理解存储管理上对所有厂商都是至关重要的。有了一个公共平台,厂商就可以加速产品的开发进程,并且终端用户可以更*地选择厂商,同时也降低了复杂性。
        SMI-S是建立在一些已有的标准基础上,主要是CIM(Common Information公共Model信息模型)和WBEM(Web-Based Enterprise Management基于Web的企业管理)。
        WBEM是由DMTF(分布式管理工作组)负责开发的一套使用 Internet 标准技术的一体化企业计算管理环境。它提供了基于WEB技术的完整的工业统一管理工具。促进了完全不同技术和平台的数据交换。
        CIM为WBEM的核心定义了一种分层次的、面向对象的信息模型和架构,该架构可以为企业网络管理整个范围内的系统,网络,应用程序和服务的信息管理提供公共定义,而且允许用户扩充。它描述了管理的概念模型,可以使得用户可以通过网络在彼此的系统之间交换语义丰富的管理信息。

3. SMI-S的简介

     Well, it’s basically a cookbook that explains how to use the model elements to do useful work, like discover and provision storage. Actually, it has grown into multiple cookbooks now, divided into topics like Common Profiles, Block, Filesystems, Fabric, etc. The SNIA has active working groups updating the specification every year or two to keep up with the latest technologies. The current (recently) published version is 1.6.0, with some updates expected by the end of the year.

     简单翻译一下。SMIS就像是一个食谱,说明了怎么样使用每个元素去实现相应的功能,比如发现存储系统和使用存储。它提供不同的食谱,被分成不同的主题,比如Common Profile, Block Profile(提供存储系统的块功能), Filesystems(文件系统操作,比如查询,创建,修改,删除,扩展),Fabric等等。

    Model elements可以简单的理解为class。比如Filesystems里面定义了class SNIA_FileExportService,来提供Filesystem的服务。比如使用SNIA_CreateExportedShare创建一个Filesystem或者叫ExportedShare。详细的定义如下,通过它详细的说明,我们可以看到对于编程来说,已经足够。

// Copyright (c) 2013 SNIA.  All rights reserved.
// ==================================================================
//  SNIA_FileExportService
// ==================================================================
   [Experimental, Version ( "1.5.0" ), 
    UMLPackagePath ( "SNIA::FileServices" ), 
    Description ( 
       "Provides configuration support for exporting elements "
       "(\"files\") of a FileSystem. FileExportService(s) are hosted "
       "by a ComputerSystem that exports the files (these would be the "
       "Filer Servers in a NAS Head). These shared elements "
       "(FileShares) are accessed through ProtocolEndpoint(s) hosted "
       "by the File Servers that support the specified file-sharing "
       "protocol. FileShares are associated with this Service via "
       "ServiceAffectsElement and with the ProtocolEndpoint(s) via "
       "SAPAvailableForElement." )
    ]
class SNIA_FileExportService : CIM_FileExportService {


      [Description ( 
          "This extrinsic method, SNIA_CreateExportedShare, starts "
          "a job to createa FileShare for a contained sub-element "
          "of a FileSystem (either aLogicalFile or its sub-class "
          "Directory). The output parameterTheShare returns a "
          "reference to the created FileShare. TheFileShare is "
          "hosted by the ComputerSystem that is the host of "
          "theFileExportService (i.e the File Server "
          "ComputerSystem) -- theHostedFileShare association will "
          "be surfaced. The FileShare willalso be associated to the"
          "short for 100 lines... Please refer to MOF file for detail info"
         "or more ServiceAccessPointsvia SAPAvailableForElement." ), 
       ValueMap { "0", "1", "2", "3", "4", "10..0x1000", "0x1001", 
          "0x1002..0x7FFF", "0x8000.." }, 
       Values { "Job Completed with No Error", "Not Supported", 
          "Unknown", "Timeout", "Failed", "DMTF Reserved", 
          "Method Parameters Checked - Job Started", 
          "Method Reserved", "Vendor Specific" }
       ]
   uint32 SNIA_CreateExportedShare(
         [Description ( 
             "An end user relevant name for the FileShare being "
             "created. If NULL, then a implementation-supplied "
             "default name can be used. The value shall be "
             "stored in the \'ElementName\' property for the "
             "created FileShare." ), 
          IN]
      string ElementName, 
         [Description ( 
             "An end user relevant comment for the FileShare "
             "being created. If NULL, then a "
             "implementation-supplied default comment can be "
             "used. The value shall be stored in the \'Comment\' "
             "property for the created element." ), 
          IN]
      string Comment, 
         [Description ( 
             "Reference to the job (may be null if job completed)."
              ), 
          OUT, IN ( false )]
      CIM_ConcreteJob REF Job, 
         [Required, Description ( 
             "A non-NULL reference indicating a FileSystem whose "
             "sub-element is being exported. \n"
             "As an OUT parameter, a reference to the FileSystem "
             "is returned. (Or should we not allow this to be an "
             "OUT parameter)." ), 
          OUT, IN]
      CIM_LogicalElement REF Root, 
         [Description ( 
             "A string representing a path to the shared "
             "element, either file or directory, from the root "
             "directory of the FileSystem indicated by Root. \n"
             "If SharedElementPath is NULL or the empty string, "
             "it indicates the root directory of Root." ), 
          IN]
      string SharedElementPath, 
         [Description ( 
             "The client-specified requirements for how the "
             "specified FileShare element is to be shared or "
             "exported by the FileExportService. This is an "
             "element of the ExportedFileShareSetting class, or "
             "a derived class, encoded as a string-valued "
             "embedded object parameter. If NULL or the empty "
             "string, the default configuration will be "
             "specified by the FileExportService." ), 
          EmbeddedInstance ( "SNIA_ExportedFileShareSetting" ), 
          IN]
      string Goal, 
         [Description ( 
             "This specifies the FileShare element (or its "
             "derived class) that is created by the method, if "
             "successful." ), 
          OUT]
      SNIA_FileShare REF TheShare, 
         [Description ( 
             "A reference to a concrete derived class of "
             "CIM_Identity that indicates the user id to use for "
             "default access to this share. A NULL value "
             "indicates that no user id is specified. The "
             "provider is expected to surface this access using "
             "the privilege model.\n"
             "If a default user id is not supported by the "
             "requested file sharing protocol this parameter "
             "will be ignored ." ), 
          IN]
      CIM_Identity REF DefaultUserId, 
         [Description ( 
             "An array of strings that specify the hosts that "
             "have root access to this Share, if the "
             "ExportedFileShareSetting.RootAccess property is "
             "set to \"Allow Root Access\".\n"
             "Each entry specifies a host by a URI. All entries "
             "up to thefirst empty string are allowed root "
             "access; the entries afterthe first empty string "
             "are denied root access. If thisparameter is NULL, "
             "root access will be denied to all "
             "hosts,effectively overriding the value of the "
             "propertyExportedFileShareSetting.RootAccess. If "
             "the first entry isthe empty string, root access "
             "will be allowed from all hosts,and subsequent "
             "entries will be denied root access. Theprovider is "
             "expected to surface this access using theprivilege "
             "model. This property needs to be an array of "
             "URIsbecause the remote host may not be known to "
             "the provider andtherefore a valid reference to the "
             "host may not exist. \n"
             "If Root Access is not supported by the requested "
             "file sharing protocol this parameter will be "
             "ignored." ), 
          ArrayType ( "Indexed" ), 
          ModelCorrespondence { 
             "SNIA_ExportedFileShareSetting.RootAccess" }, 
          IN]
      string RootAccessHosts[], 
         [Description ( 
             "An array of references to the ProtocolEndpoints "
             "that canconnect to this Share, if "
             "theExportedFileShareSettings.AccessPoints property "
             "is set to\"Named Ports\". If the parameter is "
             "NULL, all access points willbe denied access, "
             "effectively overriding the value of theproperty "
             "ExportedFileShareSetting.AccessPoints. If the "
             "firstentry in the array is NULL, all access points "
             "supported by theservice will be supported, and "
             "subsequent entries will bedenied access. The "
             "provider is expected to surface these accessrights "
             "(whether granted or denied) using the privilege "
             "model.Any AccessPoints granted access via this "
             "parameter will also beassociated to this share "
             "with SAPAvailableForElement. If theAccessPoint is "
             "not already enabled it will appear in a "
             "disabledstate. \n"
             "If multiple Access points or ports is not "
             "supported by the requested file sharing protocol "
             "this parameter will be ignored ." ), 
          ArrayType ( "Indexed" ), 
          ModelCorrespondence { 
             "SNIA_ExportedFileShareSetting.AccessPoints" }, 
          IN]
      string AccessPointPorts[]
);

      
   uint32 SNIA_ModifyExportedShare(
      string ElementName, 
      string Comment, 
      CIM_ConcreteJob REF Job, 
      CIM_LogicalElement REF Root, 
      string SharedElementPath, 
      string Goal, 
      SNIA_FileShare REF TheShare, 
      CIM_Identity REF DefaultUserId, 
      string RootAccessHosts[], 
      string AccessPointPorts[], 
         [Description ( 
             "An enumerated integer that specifies the action "
             "that the provider should take if the FileShare is "
             "still in use when this request is made. The "
             "WaitTime parameter indicates the \'specified time\' "
             "used for this function. \n"
             "This option is only relevant if the FileShare must "
             "be made unavailable while the request is being "
             "executed." ), 
          ValueMap { "2", "3", "4", "..", "0x1000..0xFFFF" }, 
          Values { "Do Not Execute Request", 
             "Wait for specified time, then Execute Request Immediately", 
             "Attempt Quiescence for specified time, then Execute Request Immediately", 
             "DMTF Reserved", "Vendor Defined" }, 
          IN]
      uint16 InUseOptions, 
         [Description ( 
             "An integer that indicates the time (in seconds) "
             "that the provider must wait before executing this "
             "request if it cannot be done while the FileShare "
             "is in use. If WaitTime is not zero, the method "
             "will create a job, if supported by the provider, "
             "and return immediately. If the provider does not "
             "support asynchronous jobs, there is a possibility "
             "that the client could time-out before the job is "
             "completed. \n"
             "The combination of InUseOptions = \"4\" and "
             "WaitTime =\"0\" (the default) is interpreted as "
             "\"Wait (forever) until Quiescence, then Execute "
             "Request\" and will be performed asynchronously if "
             "possible." ), 
          Units ( "seconds" ), 
          IN]
      uint32 WaitTime
);

      [Override ( "ReleaseExportedShare" ), 
       Description ( 
          "This extrinsic method, ReleaseExportedShare will start a "
          "job to removea FileShare specified by the parameter "
          "TheShare. Any associatedinstances and associations that "
          "are no longer needed will not besurfaced any more. These "
          "include associations HostedShare,ElementSettingData, and "
          "any other elements and associations created tosupport "
          "the DefaultUserId, RootAccessHosts, and "
          "AccessPointPortsparameters. In addition, the "
          "ExportedFileShareSetting will be deletedif appropriate. "
          "The elements removed will include the Directory "
          "(orLogicalFile) if one had been surfaced explicitly for "
          "this FileShare(for backward compatability with SIM-S 1.1).\n"
          "If 0 is returned, the method completed successfully and "
          "no ConcreteJob instance was required. If 0x1000 is "
          "returned, a ConcreteJob will be started to release the "
          "Share. The Job\'s reference will be returned in the OUT "
          "parameter Job. \n"
          "The input parameters InUseOptions and WaitTime provide "
          "for delaying oraborting the execution of this method if "
          "the FileShare is in use and the method requires that no "
          "operations be in progress during that execution. These "
          "parameters are supported if the "
          "ExportedFileShareCapabilities.SupportedProperties "
          "includes the \"RequireInUseOptions\" option." ), 
       ValueMap { "0", "1", "2", "3", "4", "5", "10", "..", 
          "0x1000", "0x1001..0x7FFF", "0x8000.." }, 
       Values { "Job Completed with No Error", "Not Supported", 
          "Unknown", "Timeout", "Failed", "Invalid Parameter", 
          "Share in use, Failed", "DMTF Reserved", 
          "Method Parameters Checked - Job Started", 
          "Method Reserved", "Vendor Specific" }
       ]
   uint32 ReleaseExportedShare(
         [Description ( 
             "Reference to the job (may be null if job completed)."
              ), 
          OUT, IN ( false )]
      CIM_ConcreteJob REF Job, 
         [Description ( "The Share to be released." ), 
          IN]
      SNIA_FileShare REF TheShare, 
         [Description ( 
             "An enumerated integer that specifies the action "
             "that the provider should take if the FileShare is "
             "still in use when this request is made. The "
             "WaitTime parameter indicates the \'specified time\' "
             "used for this function. \n"
             "This option is only relevant if the FileShare must "
             "be made unavailable while the request is being "
             "executed." ), 
          ValueMap { "2", "3", "4", "..", "0x1000..0xFFFF" }, 
          Values { "Do Not Execute Request", 
             "Wait for specified time, then Release Immediately", 
             "Attempt Quiescence for specified time, then Release Immediately", 
             "DMTF Reserved", "Vendor Defined" }, 
          IN]
      uint16 InUseOptions, 
         [Description ( 
             "An integer that indicates the time (in seconds) "
             "that the provider must wait before releasing this "
             "FileShare. If WaitTime is not zero, the method "
             "will create a job, if supported by the provider, "
             "and return immediately. If the provider does not "
             "support asynchronous jobs, there is a possibility "
             "that the client could time-out before the job is "
             "completed. \n"
             "The combination of InUseOptions = \'4\' and "
             "WaitTime =\'0\' (the default) is interpreted as "
             "\'Wait (forever) until Quiescence, then Release\' "
             "and will be performed asynchronously if possible." ), 
          Units ( "seconds" ), 
          IN]
      uint32 WaitTime
);

};

对于开发人员来说,这个就相当于非常详细的Programer Document了。这个class定义在MOF文件中。那么什么是MOF呢?

The Common Information Model (CIM) is described in the DMTF's Managed Object Format (MOF), a language based on IDL (the Object Management Group's Interface Definition Language). The MOF syntax is a way to describe object-oriented class and instance definitions in textual form, with the goals of human readability and parsing by a compiler.

通过MOF Compiler,这个MOF文件会生成C++或Java的class文件,开发人员只需要将需要修改的函数实现即可。

关于SMI-S的所有MOF文件可以通过下面这个衔接下载:SNIA_MOFS-16Rev4-Updated.zip。 CIM Schema可以通过下面这个衔接下载:cim_schema_v2291

4. SMI-S的实现

首先需要读懂SMI-S的官方文档:Download 1.6。然后根据实际需要,选择实现不同的Profile。对于Mandatory的class及class的Property(属性),都是需要强制实现的。下面是File Export Manipulation的Profile,需要实现的class,method还是很多的:

存储那些事儿(一):异构虚拟化一种实现SMIS

实现的SMI-S需要部署在存储系统上或者是在存储系统局域网内的Agent上。理论上来说,这个SMI-S的实现可以部署在任何地方,但是考虑到安全性,网络延时,效率,一般都是直接运行在存储系统上。

     接下来在下一节将介绍如何使用SMI-S来管理存储系统,也就是SMI-S的client。

5. 通过SMI-S管理存储系统

    通过MOF文件,和SMI-S的文档,我们可以实现SMI-S的服务器端-部署在存储系统上。通过第2小节我们知道,SMI-S是建立在一些已有的标准基础上,主要是CIM(Common Information公共Model信息模型)和WBEM(Web-Based Enterprise Management基于Web的企业管理)。介绍一个非常强大的Python库:PyWBEM: PyWBEM is a Python library for making CIM operations over HTTP using the WBEM CIM-XML protocol. It is based on the idea that a good WBEM client should be easy to use and not necessarily require a large amount of programming knowledge. PyWBEM is suitable for a large range of tasks from simply poking around to writing web and GUI applications.

   项目主页:http://sourceforge.net/apps/mediawiki/pywbem/index.php?title=Main_PageClient_Examples基本涵盖了开发客户端需要用到的所有接口。

   下面几种是我没有用过的。当然了我也不知道Microsoft具体是使用的什么。但不管怎么说,我们已经达到目的了:使用SMI-S使存储系统支持异构虚拟化。

   Open Pegasus是CIM与WBEM标准的开源实现。它由 C++ 编写,所以可以很方便的将面向对象的CIM管理对象转变成程序模块。因此他被各个操作系统平台所支撑,包括 UNIX, Linux, OpenVMS, and Microsoft Windows。
   WBEM Services是用Java编写的,适用于任何商业和非商业用途的,基于WBEM的实现。它的内容包括运用编程接口,服务器端和客户端的运用程序和工具。
   SFCB(Small Footprint CIM Broker) 是一个轻量级的CIMOM,十分适用于嵌入式环境的开发。

6. SMI-S测试

    SNIA-CTP(Conformance Testing Program)官方标准测试的工具。SNIA有自己的工作室ICTP(Interoperability Conformance Test Program)专门负责SMI-S支持度测试。如果通过了CTP测试,那么SNIA就会有官方的certificate,这应该是唯一有说服力的certificate。


上一篇:《Linux内核设计的艺术:图解Linux操作系统架构设计与实现原理》——2.15 本章小结


下一篇:css毛玻璃效果