Partilhar via


Comportamento e Interação SMP

Métodos intrínsecos e APIs de infraestrutura de gerenciamento

Os desenvolvedores do SMP (Storage Management Provider) trabalham com:

  • Métodos intrínsecos gerados por Convert-MofToProvider.exe.
  • APIs de infraestrutura de gerenciamento (MI) do arquivo mi.h para fornecer a implementação de seu SMP.

Os marcadores a seguir apontam alguns métodos intrínsecos e de Inteligência de Máquina (MI) importantes.

  • EnumerateInstances e GetInstance

    EnumerateInstances é chamado quando há uma consulta para instâncias de uma classe específica. Por exemplo: O cmdlet do PowerShell 'Get-<Object>' corresponde ao método EnumerateInstances do objeto WMI correspondente. Esse método deve retornar todas as instâncias da classe via <método Object>_Post. Como o WMI chama EnumerateInstances com freqüência, ele deve ser executado rapidamente. Para fazer isso, use um bom gerenciamento de cache.

    GetInstance é chamado quando uma instância específica de uma classe é necessária, por exemplo (mas não limitado a):

    • Quando a infraestrutura WMI invoca qualquer método dessa classe
    • Quando um aplicativo baseado em WMI chama diretamente esse método
    • Quando uma instância da classe é solicitada por meio de classes de associação

    O método GetInstance só deve retornar o objeto especificado por meio do <método Object>_Post. O identificador da instância que está sendo consultada, que é a "Key" conforme definido no MOF, que geralmente é o ObjectId, é recuperado por meio do parâmetro InstanceName. Este método é chamado pelo WMI com freqüência e deve ser concluído rapidamente.

    EnumerateInstances e GetInstance são obrigatórios para classes regulares, como StorageProvider, StorageSubsystem, PhysicalDisk e assim por diante.

    Para as classes Association, EnumerateInstances, AssociatorInstances e ReferenceInstances são obrigatórios, enquanto GetInstance não é.

  • <Objeto>_Post e MI_PostResult

    Para entender a diferença entre o método MI API <Object>_Post e MI_PostResult:

    • Pense em <Object>_Post como retornando um ponteiro para um parâmetro de saída.
    • Pense em MI_PostResult como um valor de retorno de função que indica o status de execução da função.

    Você só deve chamar MI_PostResult uma vez por contexto do método WMI, o qual pode ser encontrado nos parâmetros de entrada de cada método WMI. "Contexto" é um ponteiro para retornos de chamada WMI. Chamar o MI_PostResult destruirá este ponteiro. Portanto, um método WMI nunca deve ser chamado no corpo de outro método WMI.

    <Object>_Post, por outro lado, pode ser chamado mais de uma vez dentro do contexto de um método WMI. Esse método é normalmente usado em EnumerateInstances para retornar vários objetos.

  • Definir<Propriedade> e ModificarInstância

    O método intrínseco ModifyInstance não é suportado pela API de Gerenciamento de Armazenamento do Windows. Para modificar as propriedades de um objeto, o método extrínseco set<Property> é usado.

Para obter mais informações sobre métodos intrínsecos e APIs de MI, consulte os exemplos de API de MI do SDK do Windows.

Identificação de objetos

As interfaces SMP usam os dois grupos de propriedades a seguir para identificação de objetos:

  • Para scripts e programação: ObjectId e UniqueId

    ObjectId é um identificador opaco criado e mantido para o uso dos SMPs e seus clientes para rastrear instâncias de objetos. É uma propriedade obrigatória que deve ser globalmente exclusiva. Ou seja, nenhum objeto deve ter o mesmo ObjectId, mesmo que sejam gerenciados por SMPs separados ou estejam em subsistemas de armazenamento diferentes.

    Se um objeto for visível através de dois caminhos diferentes (por exemplo: há dois SMPs separados que apontam para o mesmo subsistema de armazenamento), o mesmo objeto pode aparecer com dois ObjectIds diferentes. Para determinar se duas instâncias de objeto são o mesmo objeto, use a propriedade UniqueId.

    UniqueId é uma propriedade obrigatória usada para identificar exclusivamente uma instância de uma classe dentro de um escopo global. Esse valor deve ser o mesmo entre duas instâncias de SMPs em execução em servidores de gerenciamento diferentes. Ao contrário de ObjectId, UniqueId deve ser um valor que o subsistema de armazenamento persiste em vez do processo do provedor de gerenciamento de armazenamento.

    UniqueId pode ser qualquer valor opaco, exceto onde indicado de outra forma (por exemplo: MSFT_VirtualDisk).

  • Para exibição: FriendlyName e Name

    Os usuários finais usam essas duas propriedades para identificar um objeto. FriendlyName é uma cadeia de caracteres amigável que é configurável pelos usuários finais, se o SMP suportar tal operação. FriendlyName não precisa ser único. Dois objetos de um único subsistema de armazenamento podem compartilhar o mesmo FriendlyName, embora essa prática seja desencorajada.

    O SMP define a propriedade Name e os usuários finais não podem modificá-la. O SMP fornece informações adicionais nesta propriedade para ajudar os usuários finais a identificar um objeto. Essas informações podem abranger aspetos técnicos do objeto. Por exemplo, o Nome de um subsistema de armazenamento pode ser o IP ou WWN do subsistema. O nome geralmente é exclusivo em determinado escopo. Por exemplo, o nome de um pool de armazenamento deve ser exclusivo no subsistema de armazenamento proprietário.

Tratamento de erros

Existem três tipos de erros nas interfaces SMP: códigos de retorno da API de Gerenciamento de Armazenamento do Windows (API SM), "Erros de software" e "Erros rígidos".

Os códigos de retorno da API SM referem-se aos códigos de erro listados como valores de retorno para cada um dos métodos extrínsecos SMP. Por exemplo, "5" representa "Parâmetro inválido". Esses códigos de erro são retornados através do parâmetro de saída MIReturn, conforme definido na estrutura do método gerado por Convert-MofToProvider.exe. O valor de MIReturn pode ser definido através de <Object>_<Method>_Set_MIReturn definido no arquivo de cabeçalho do objeto correspondente.

Os métodos extrínsecos devem sempre usar códigos de erro da API SM por padrão quando possível. Quando informações adicionais são necessárias, os SMPs podem usar MSFT_ExtendedStatus classe para fornecer informações de status adicionais sobre a invocação de um método extrínseco. Esta abordagem é preferível ao uso de erros suaves para métodos extrínsecos.

Erros suaves referem-se a mensagens de erro retornadas através da classe MSFT_SoftError. Esses erros são projetados para métodos intrínsecos (EnumerateInstances, GetInstance e etc.) onde não é possível retornar códigos de erro da API SM. Para retornar erros transitórios, as instâncias das classes de erro suave derivadas de MSFT_SoftError devem ser construídas e retornadas através do parâmetro “MI_Instance error” no método MI_WriteCimError definido em mi.h. Por exemplo, para indicar "a credencial correta é necessária" durante o login da matriz de armazenamento, uma instância de "MSFT_SoftError_NotAuthenticated" pode ser retornada durante chamadas EnumerateInstances em objetos StorageSubsystem. Para erros suaves, um resultado de MI_RESULT_OK ainda deve ser enviado através de MI_PostResult.

Erros graves referem-se aos erros definidos na estrutura MI_Result do arquivo mi.h. As APIs MI retornam esses erros. O SMP deve evitar revelar diretamente esses erros aos aplicativos de gerenciamento de armazenamento, a menos que seja absolutamente necessário. Por exemplo, para "parâmetros inválidos", os SMPs devem usar MIReturn para exibir o código de erro da API SM "5" – "Parâmetro inválido" em vez de depender do aplicativo de gerenciamento de armazenamento para consumir MI_RESULT_INVALID_PARAMETER.

Piscina Primordial

Um pool primordial, também conhecido como pool de "armazenamento disponível", é de onde a capacidade de armazenamento é retirada e devolvida na criação e eliminação de pools de armazenamento concretos. Os pools primordiais não podem ser criados, excluídos ou modificados.

Os SMPs devem fornecer pelo menos um pool primordial. Quando um disco físico é adicionado a um pool de armazenamento concreto, o disco físico ainda deve ser considerado como parte do pool primordial.

Relatório de Dimensões

Há dois casos especiais a serem discutidos para campos de vários tamanhos de objetos do Pool de Armazenamento: capacidade de unidades hot-spare e capacidade de unidades não íntegras.

Uma vez que uma unidade é designada como hot-spare, a sua capacidade deve ser incluída no AllocatedSize do pool primordial correspondente. No entanto, a capacidade da unidade não deve ser incluída no tamanho de qualquer pool de armazenamento, mesmo que a matriz de armazenamento suporte dedicar uma unidade hot-spare a um pool de armazenamento específico. Depois que uma unidade hot-spare é dedicada a uma piscina de concreto específica, a capacidade da unidade não deve ser incluída no AllocatedSize da piscina de concreto até que ela realmente substitua uma unidade usada. Quando adicionado a um pool específico, CanPooled deve estar definido como FALSE para o objeto Disco Físico desta drive hot-spare. Uma associação deve ser criada entre este objeto de Disco Físico e o objeto de Pool de Armazenamento do pool específico.

A capacidade de unidades com o estado de saúde "Não Saudável" não deve ser incluída em quaisquer campos de tamanho de piscinas primordiais ou piscinas concretas.

Associações

A API SM inclui classes de associação que definem relações entre objetos de armazenamento. Com essas classes de associação, é fácil percorrer a hierarquia de objetos de armazenamento para obter objetos relacionados para um determinado objeto. Para o módulo Storage PowerShell, a tubulação do cmdlet é obtida por meio de classes de associação. Por exemplo, dado um objeto de Disco Virtual, os usuários podem obter o Pool de Armazenamento que possui o objeto de Disco Virtual por meio do seguinte cmdlet:

    PS> Get-VirtualDisk –FriendlyName MyVirtualDisk | Get-StoragePool

O restante desta seção ilustra a implementação de classes de associação. Os métodos nas notas são gerados por Convert-MofToProvider.exe para cada classe de associação. As notas usam XToY como uma classe de associação de exemplo; o pseudocódigo usa StoragePoolToVirtualDisk como exemplo.

  • EnumerateInstances e GetInstance
      - XToY\_EnumerateInstances returns association objects (XToY objects) for ALL X objects
    
    <!-- end list -->
    
        void MI_CALL SAMPLE_StoragePoolToVirtualDisk_EnumerateInstances( ... )
        {
            ...
        
        /** This method should return association objects for ALL Storage Pools. **/
        
            // for each storage pool
        
                // for each virtual disk that's associated with this storage pool
        
                    // create the StoragePoolToVirtualDisk association object
                    // set the storage pool object and virtual disk object to this association object
                    // post the association object
                
                // end for
        
            // end for
        
            ...
        }
  • AssociatorInstances
      - AssociatorInstances method returns regular objects instead of association objects
      - XToY\_AssociatorInstancesX should return all associated Y object(s) for the X specified
      - XToY\_AssociatorInstancesY should return all associated X object(s) for the Y specified
    
    <!-- end list -->
    
        void MI_CALL SAMPLE_StoragePoolToVirtualDisk_AssociatorInstancesStoragePool(...)
        {
            ...
        
        /** This method should return VIRTUAL DISK object(s) for the 
        STORAGE POOL specified. **/
        
            // for each virtual disk that's associated with this storage pool
        
                // create the virtual disk object
                // post the virtual disk object
                
            // end for
        
            ...
        }
        
        void MI_CALL SAMPLE_StoragePoolToVirtualDisk_AssociatorInstancesVirtualDisk(...)
        {
            ...
        
        /** This method should return STORAGE POOL object(s) for the 
        VIRTUAL DISK specified. **/
        
            // for each storage pool that's associated with this virtual disk
        
                // create the storage pool object
                // post the storage pool object
                
            // end for
        
            ...
        }
  • ReferenceInstances
      - ReferenceInstances is similar to AssociatorInstances except that these methods return association (XToY) objects instead of regular objects
      - XToY\_ReferenceInstancesX should return XToY object(s) for X specified
      - XToY\_ReferenceInstancesY should return YToX object(s) for Y specified
    
    <!-- end list -->
    
        void MI_CALL SAMPLE_StoragePoolToVirtualDisk_ReferenceInstancesStoragePool(...)
        {
            ...
        
        /** This method should return StoragePoolToVirtualDisk 
        ASSOCIATION object(s) for the STORAGE POOL specified. **/
        
            // for each virtual disk that's associated with this storage pool
        
                // create the StoragePoolToVirtualDisk association object
                // set the storage pool and virtual disk to this association object
                // post the association object
                
            // end for
        
        
            ...
        }
        
        void MI_CALL SAMPLE_StoragePoolToVirtualDisk_ReferenceInstancesVirtualDisk(...)
        {
            ...
        
        /** This method should return StoragePoolToVirtualDisk 
        ASSOCIATION object(s) for the VIRTUAL DISK specified. **/
        
            // for each storage pool that's associated with this virtual disk
        
                // create the StoragePoolToVirtualDisk association object
                // set the storage pool and virtual disk to this association object
                // post the association object
                
            // end for
        
            ...
        }

Gerenciamento de cache

Quando o SMP é carregado, ele deve inicializar um cache de objetos de armazenamento. Essa inicialização garante um tempo de resposta rápido ao atender chamadas de API, pois os objetos podem ser recuperados diretamente do cache do SMP. Esse cache deve ser mantido em sincronia com alterações em objetos dentro da banda e alterações em objetos fora da banda.

As alterações de objeto em banda incluem as alterações feitas através da instância SMP atual. Por exemplo, se um disco virtual for criado por meio da instância SMP atual:

  • Um novo objeto de disco virtual deve ser adicionado ao cache.
  • Os objetos associados, como o Pool de Armazenamento proprietário e os objetos Porta de Destino associados, também devem ser atualizados.

As alterações fora de banda incluem as alterações feitas por meio de ferramentas proprietárias do fornecedor e SMPs hospedados em outras máquinas. Por exemplo, se um disco virtual for criado por meio de ferramentas proprietárias do fornecedor, um evento deverá ser enviado do subsistema de armazenamento para o(s) SMP(s) para disparar uma atualização de cache.

O SMP também deve atualizar o cache quando o método Discover da classe Storage Provider for chamado. O aplicativo de gerenciamento de armazenamento chama esse método para redefinir e reconstruir o cache em eventos como reinicialização do serviço ou reinicialização do sistema.

Se não for viável para o SMP inicializar todo o cache na inicialização (devido ao excesso de objetos ou porque isso não pode ser feito rapidamente), somente os objetos do Provedor de Armazenamento e do Subsistema de Armazenamento deverão ser carregados no cache. Os aplicativos examinarão a propriedade CurrentCacheLevel no objeto do Subsistema de Armazenamento para saber a profundidade do cache que foi preenchido. O usuário final ou aplicativo carrega explicitamente o restante do cache por meio do método Discover.

Operações assíncronas

Qualquer operação que demore mais de 30 segundos para ser concluída deve retornar um objeto de Trabalho de Armazenamento. Os métodos que contêm um parâmetro de saída CreatedStorageJob são mais prováveis de ser desse tipo de operação. Os SMPs devem implementar todos esses métodos como operações assíncronas e retornar objetos de trabalho de armazenamento para eles. Um objeto de trabalho de armazenamento deve ser retornado ao chamador dentro de 30 segundos; caso contrário, o chamador poderá atingir o tempo limite se a espera for demasiado longa e ainda não tiver recebido o objeto de trabalho de armazenamento.

Os aplicativos (ou "Cliente WMI") têm a opção de especificar se um método deve ser "RunAsJob" ou não. A API SM que os aplicativos usam contém esse parâmetro Boolean RunAsJob extra e o parâmetro de saída CreatedStorageJob. Enquanto isso, os métodos correspondentes nas interfaces SMP têm apenas o parâmetro CreatedStorageJob. No entanto, independentemente do valor de "RunAsJob", os SMPs sempre devem retornar objetos de trabalho de armazenamento para esses métodos.

Os cenários a seguir ilustram a sequência de chamada de operações assíncronas. CreateVirtualDisk é usado como exemplo:

  • Se "RunAsJob" estiver definido como TRUE

    Quando CreateVirtualDisk é invocado, os SMPs devem fazer a inicialização do método, iniciar um trabalho no subsistema de armazenamento e retornar um objeto de trabalho de armazenamento para o chamador em 30 segundos. No entanto, o subsistema de armazenamento pode levar qualquer período de tempo para concluir a operação. O chamador verificará o status da tarefa durante esse período.

    Os threads de trabalhadores devem ser usados para executar as tarefas. Para fins de eficiência, os SMPs podem atualizar atributos relacionados ao estado do trabalho (por exemplo, percentual de conclusão) somente quando o chamador verifica o estado desse trabalho.

  • Se "RunAsJob" estiver definido como FALSE

    O chamador será bloqueado no método CreateVirtualDisk até que o método retorne. A API SM faz automaticamente o bloqueio e a sondagem em si. Esse tipo de chamador geralmente é um cliente não interativo do usuário (por exemplo, uma ferramenta de script) que prefere o mecanismo de bloqueio.

    Como a única maneira de obter informações sobre um objeto recém-criado é por meio da associação entre esse objeto e o objeto de Trabalho de Armazenamento correspondente, os SMPs devem manter um objeto de Trabalho de Armazenamento por pelo menos 24 horas antes de removê-lo do cache. Para outras operações que não retornam um objeto recém-criado (por exemplo, uma operação DeleteObject), uma associação não é necessária e o objeto Trabalho de Armazenamento só precisa permanecer ativo por 15 minutos.

Para reinicializações inesperadas do sistema em consoles de gerenciamento, os SMPs devem manter um cache de objetos StorageJob em um local físico, por exemplo, na matriz de armazenamento, e recarregar o cache após a reinicialização do sistema.

Controlo do Tempo de Vida do Fornecedor

Um SMP pode ser implementado como um provedor acoplado ou dissociado. Para obter a diferença entre esses dois tipos de provedores, consulte a documentação do WMI MSDN.

Um provedor dissociado é carregado e hospedado em um processo específico do fornecedor. Esse processo normalmente é um serviço em execução constante.

Iniciar um provedor pode ser demorado, pois envolve o recarregamento do cache. Se a inicialização do SMP exigir mais de um segundo para carregar, recomendamos que você implemente um provedor dissociado para gerenciar objetos de armazenamento por meio de um cache persistente. Essa abordagem ajuda a aumentar o desempenho geral e a capacidade de resposta de aplicativos que usam a API do Windows SM para gerenciar seu SMP.

O exemplo DecoupledHost do SDK do Windows fornece mais detalhes sobre provedores dissociados.

Indicações

Os desenvolvedores de aplicativos geralmente querem saber quando o estado de um objeto muda à medida que ele muda. Podem fazê-lo subscrevendo as indicações do WMI. As indicações são um tipo diferente de classe; as indicações são expostas de forma assíncrona, às vezes fora de banda de qualquer operação de gerenciamento, e não persistem. Em vez de implementar os métodos intrínsecos familiares (ou seja, EnumerateInstances / GetInstance), há novos métodos que devem ser suportados.

Existem quatro tipos de indicações:

  • Chegada – Esta indicação é usada quando uma instância de dispositivo ou objeto é adicionada ao subsistema. Por exemplo: Adicionar um novo disco físico ao subsistema ou criar um disco virtual.
  • Partida – Esta indicação é usada quando uma instância de dispositivo ou objeto é removida do subsistema. Por exemplo: remover um disco físico do subsistema ou excluir um pool de armazenamento.
  • Modificar – Esta indicação é usada quando uma propriedade importante é alterada em um objeto existente. No mínimo, as alterações HealthStatus e OperationalStatus devem acionar uma indicação Modificar. A indicação de uma alteração em qualquer outra propriedade relacionada ao status operacional de um objeto é fortemente encorajada.
  • Alerta – Esta indicação é usada para alertar o aplicativo sobre um possível problema. Atualmente, o único alerta definido é para notificar quando um limite de provisionamento thin é atingido.

Para implementar indicações, existem dois novos métodos intrínsecos que devem ser implementados para cada classe de indicação:

  • EnableIndication – Foi feito um pedido para subscrever a classe de indicação. A indicationContext deve ser guardada para ficar disponível para publicar numa indicação num momento posterior.
  • DisableIndication – Não há mais assinantes para a classe de notificação. A limpeza deve ocorrer e não devem ser publicadas mais indicações para esta classe. indicaçãoO contexto é destruído neste momento.

Implantação

Os SMPs são instalados em "servidores de gerenciamento" selecionados. Esses servidores podem ser agrupados para fornecer redundância. Outros servidores acessam o armazenamento alocado a eles via iSCSI ou Fiber Channel. Todas essas máquinas podem ser gerenciadas por servidores que executam a Interface do Usuário do Servidor de Arquivos a partir do Gerenciador do Servidor.

Os fornecedores de armazenamento, no entanto, podem escolher o modelo de implantação que melhor atenda às suas necessidades.

Modelo de Segurança

A interface SMP suporta o modelo de logon único (SSO) usando credenciais de segurança do Windows.

No modelo SSO, um usuário efetua login em uma "máquina de gerenciamento" com suas credenciais do Windows uma vez e obtém automaticamente acesso a todos os ativos de armazenamento que ele tem permissão de acesso. Não é necessário ter mais credenciais para entrar no subsistema de armazenamento.

A interface também permite que os administradores de armazenamento gerenciem o controle de acesso em ativos de armazenamento individuais. Para cada ativo de armazenamento, os administradores de armazenamento podem conceder diferentes direitos de acesso a qualquer usuário do Windows por meio dos métodos GetSecurityDescriptor e SetSecurityDescriptor. Como resultado, os SMPs, ao contrário do modelo VDS, agora podem receber solicitações de qualquer tipo de conta de usuário.

Para implementar o modelo SSO, um SMP deve autenticar os clientes Windows no subsistema de armazenamento. O subsistema de armazenamento deve manter as informações do descritor de segurança para cada ativo de armazenamento. Para implementar a autenticação, os fornecedores de armazenamento têm duas opções:

  • Autenticar no subsistema (recomendado)
  • Autentique-se em cada instância do SMP.

Ambas as opções exigem que uma relação de confiança seja estabelecida entre o SMP e o subsistema de armazenamento para que o descritor de segurança e as informações de identidade do usuário possam ser transmitidas com segurança.

Para implementar autenticação e autorização contínuas no subsistema de armazenamento, recomendamos o link entre o SMP e o subsistema de armazenamento para implementar Kerberos, NTLM ou SPNego. Se o subsistema de armazenamento tiver um servidor Web instalado, o protocolo "NTLM sobre HTTP" [MS-NLMP] pode ser mais útil. Os fornecedores de armazenamento podem optar por manter seus protocolos proprietários para implementar o modelo SSO. No entanto, essa abordagem não é recomendada, pois pode resultar em mais trabalho ou configuração do que implementar um dos protocolos de autenticação suportados pelo Windows.

Para dar suporte à política de segurança do Windows, o subsistema de armazenamento precisa obter as "informações de token" do usuário, que incluem o SID (Identificador de Segurança) do usuário e os SIDs de quaisquer grupos dos quais o usuário seja membro. Se o protocolo Kerberos, NTLM ou SPNego for implementado, o subsistema de armazenamento obterá as informações de token do usuário como parte do protocolo. Se o protocolo proprietário de um fornecedor for usado entre o SMP e o subsistema de armazenamento, o subsistema de armazenamento poderá consultar as informações de token do usuário do Ative Directory por meio do protocolo LDAP (Lightweight Directory Access Protocol) e examinar o atributo tokenGroupsGlobalAndUniversal ou o atributo Object-Sid no objeto de conta do usuário.

Com as informações de token do usuário, para impor a política de segurança do Windows, o subsistema de armazenamento precisa implementar o algoritmo de verificação de acesso descrito em [MS-DTYP].

Se um fornecedor de armazenamento optar por não oferecer suporte a esse modelo de SSO, recomendamos que o SMP siga o modelo de segurança do VDS, permitindo apenas operações iniciadas a partir de contas de administrador. Esta verificação, no entanto, deve agora ser realizada pelo próprio SMP.