Comportamiento e interacción de SMP
Los desarrolladores del proveedor de administración de almacenamiento (SMP) trabajan con:
- Métodos intrínsecos generados por Convert-MofToProvider.exe.
- API de infraestructura de administración (MI) del archivo mi.h para proporcionar la implementación de su SMP.
Las viñetas siguientes anoten algunos métodos intrínsecos clave y MI.
EnumerateInstances y GetInstance
Se llama a EnumerateInstances cuando hay una consulta para instancias de una clase determinada. Por ejemplo: el cmdlet Get-Object<> de PowerShell se asigna al método EnumerateInstances del objeto WMI correspondiente. Este método debe devolver todas las instancias de la clase a través <del método Object>_Post. Dado que WMI llama a EnumerateInstances con frecuencia, debe funcionar rápidamente. Para ello, use una buena administración de caché.
Se llama a GetInstance cuando se necesita una instancia específica de una clase, por ejemplo (pero no limitada a):
- Cuando la infraestructura de WMI invoca cualquier método de esta clase
- Cuando una aplicación basada en WMI llama directamente a este método
- Cuando se solicita una instancia de la clase a través de las clases association
El método GetInstance solo debe devolver el objeto especificado a través <del método Object>_Post. El identificador de la instancia que se consulta, que es la "clave" tal como se define en MOF, que normalmente es objectId, se recupera a través del parámetro InstanceName. WMI llama a este método con frecuencia y debe completarse rápidamente.
EnumerateInstances y GetInstance son obligatorios para clases normales como StorageProvider, StorageSubsystem, PhysicalDisk, etc.
Para las clases Association, EnumerateInstances, AssociatorInstances y ReferenceInstances son obligatorias, mientras que GetInstance no.
<Objeto>_Post y MI_PostResult
Para comprender la diferencia entre el objeto del> método <de API de MI_Post y MI_PostResult:
- Piense en <Object>_Post como devolver un puntero a un parámetro de salida.
- Piense en MI_PostResult como un valor devuelto por función que indica el estado de ejecución de la función.
Solo debe llamar a MI_PostResult una vez por método WMI "context", que se puede encontrar en los parámetros de entrada de cada método WMI. "Context" es un puntero a las devoluciones de llamada WMI. Llamar a MI_PostResult destruirá este puntero. Por lo tanto, nunca se debe llamar a un método WMI en el cuerpo de otro método WMI.
<Por otro lado, se puede llamar a object>_Post más de una vez por contexto de método WMI. Este método se usa normalmente en EnumerateInstances para devolver varios objetos.
Set<Property> y ModifyInstance
El método intrínseco ModifyInstance no se admite a través de la API de administración de almacenamiento de Windows. Para modificar las propiedades de un objeto, se usa el método extrinsic Set<Property> .
Para obtener más información sobre los métodos intrínsecos y las API de MI, consulte los ejemplos de API de MI de Windows SDK.
Las interfaces SMP usan los dos grupos de propiedades siguientes para la identificación de objetos:
Para scripting y programación: ObjectId y UniqueId
ObjectId es un identificador opaco creado y mantenido para el uso de los SMP y sus clientes para realizar un seguimiento de la instancia de objetos. Es una propiedad obligatoria que es necesaria para ser única globalmente. Es decir, ningún objeto debe tener nunca el mismo ObjectId, incluso si se administran mediante SMP independientes o se encuentran en subsistemas de almacenamiento diferentes.
Si un objeto es visible a través de dos rutas de acceso diferentes (por ejemplo: hay dos SMP independientes que apuntan al mismo subsistema de almacenamiento), el mismo objeto puede aparecer con dos ObjectId diferentes. Para determinar si dos instancias de objeto son el mismo objeto, use la propiedad UniqueId.
UniqueId es una propiedad obligatoria que se usa para identificar de forma única una instancia de una clase dentro de un ámbito global. Este valor debe ser el mismo entre dos instancias de SMP que se ejecutan en distintos servidores de administración. A diferencia de ObjectId, UniqueId debe ser un valor que el subsistema de almacenamiento conserva en lugar del proceso del proveedor de administración de almacenamiento.
UniqueId puede ser cualquier valor opaco excepto donde se indique lo contrario (por ejemplo, MSFT_VirtualDisk).
Para mostrar: FriendlyName y Name
Los usuarios finales usan estas dos propiedades para identificar un objeto. FriendlyName es una cadena fácil de usar que los usuarios finales pueden establecer si SMP admite dicha operación. FriendlyName no debe ser único. Dos objetos de un único subsistema de almacenamiento pueden compartir el mismo FriendlyName, aunque no se recomienda esta práctica.
SMP establece la propiedad Name y los usuarios finales no pueden modificarla. SMP proporciona información adicional en esta propiedad para ayudar a los usuarios finales a identificar un objeto. Dicha información podría abarcar aspectos técnicos del objeto. Por ejemplo, el nombre de un subsistema de almacenamiento puede ser la dirección IP o WWN del subsistema. El nombre suele ser único en determinados ámbitos. Por ejemplo, el nombre de un grupo de almacenamiento debe ser único en el subsistema de almacenamiento propietario.
Hay tres tipos de errores en las interfaces SMP: códigos de retorno de la API de administración de almacenamiento de Windows (SM API), "Errores suaves" y "Errores duros".
Los códigos de retorno de la API sm hacen referencia a los códigos de error enumerados como valores devueltos para cada uno de los métodos extrinsicos de SMP. Por ejemplo, "5" representa "Parámetro no válido". Estos códigos de error se devuelven a través del parámetro de salida MIReturn definido en la estructura del método generada por Convert-MofToProvider.exe. El valor de MIReturn se puede establecer a través <del objeto> _<Method>_Set_MIReturn definido en el archivo de encabezado del objeto correspondiente.
Los métodos extrinsic siempre deben usar los códigos de error de la API sm siempre que sea posible. Cuando se necesita información adicional, los SMP pueden usar MSFT_ExtendedStatus clase para proporcionar información de estado adicional sobre la invocación de un método extrinsic. Este enfoque es preferible usar errores blandos para métodos extrinsicos.
Los errores suaves hacen referencia a los mensajes de error devueltos a través de la clase MSFT_SoftError. Estos errores están diseñados para métodos intrínsecos (EnumerateInstances, GetInstance y etc.), donde no es posible devolver códigos de error de la API sm. Para devolver errores blandos, las instancias de las clases de error temporal derivadas de MSFT_SoftError deben construirse y devolverse a través del parámetro "MI_Instance error" en MI_WriteCimError método definido en mi.h. Por ejemplo, para indicar "se necesita una credencial correcta" durante el inicio de sesión de la matriz de almacenamiento, se puede devolver una instancia de "MSFT_SoftError_NotAuthenticated" durante las llamadas EnumerateInstances en objetos StorageSubsystem. En el caso de los errores de software, el resultado de MI_RESULT_OK debe publicarse a través de MI_PostResult.
Los errores duros hacen referencia a los errores definidos en MI_Result estructura del archivo mi.h . Las API de MI devuelven estos errores. SMP debe evitar mostrar directamente estos errores en las aplicaciones de administración de almacenamiento a menos que sea absolutamente necesario. Por ejemplo, para "parámetros no válidos", los SMP deben usar MIReturn para exponer el código de error de la API de SM "5" : "Parámetro no válido" en lugar de confiar en la aplicación de administración de almacenamiento para consumir MI_RESULT_INVALID_PARAMETER.
Un grupo primordial, también conocido como el grupo de almacenamiento "disponible", es donde se dibuja y devuelve la capacidad de almacenamiento en la creación y eliminación de grupos de almacenamiento concretos. Los grupos primordiales no se pueden crear, eliminar ni modificar.
Los SMP deben proporcionar al menos un grupo primordial. Cuando se agrega un disco físico a un grupo de almacenamiento concreto, el disco físico debe considerarse como parte del grupo primordial.
Hay dos casos especiales para analizar los distintos campos de tamaño de los objetos del grupo de almacenamiento: capacidad de unidades de reserva activas y capacidad de unidades con estado incorrecto.
Una vez que se designa una unidad como unidad de reserva activa, su capacidad debe incluirse en el asignadoSize del grupo primordial correspondiente. Sin embargo, la capacidad de la unidad no debe incluirse en el tamaño de ningún grupo de hormigón, aunque la matriz de almacenamiento admita la dedicación de una unidad de reserva activa a un grupo concreto de hormigón. Después de una unidad de reserva caliente se dedica a un determinado grupo de hormigón, la capacidad de la unidad no debe incluirse en el AsignadoSize de la piscina de hormigón hasta que realmente reemplaza una unidad usada. Cuando se agrega a un grupo concreto, CanPooled debe ser FALSE para el objeto Disco físico de esta unidad de reserva activa. Se debe crear una asociación entre este objeto Disco físico y el objeto Del grupo de almacenamiento del grupo de hormigón.
La capacidad de las unidades con HealthStatus de "Incorrecto" no debe incluirse en ningún campo de tamaño del grupo primordial o del grupo de hormigón.
SM API incluye clases de asociación que definen relaciones entre objetos de almacenamiento. Con estas clases de asociación, es fácil recorrer la jerarquía de objetos de almacenamiento para obtener objetos relacionados para un objeto determinado. Para el módulo de Storage PowerShell, la canalización de cmdlets se logra mediante clases de asociación. Por ejemplo, dado un objeto Disco virtual, los usuarios pueden obtener el grupo de almacenamiento que posee el objeto Disco virtual mediante el cmdlet siguiente:
PS> Get-VirtualDisk –FriendlyName MyVirtualDisk | Get-StoragePool
El resto de esta sección muestra la implementación de clases de asociación. Los métodos de las notas se generan mediante Convert-MofToProvider.exe para cada clase de asociación. Las notas usan XToY como una clase de asociación de ejemplo; el pseudocódigo usa StoragePoolToVirtualDisk como ejemplo.
- EnumerateInstances y 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
...
}
Cuando se carga el SMP, debe inicializar una memoria caché de objetos de almacenamiento. Esta inicialización garantiza un tiempo de respuesta rápido al atender las llamadas API como objetos que se pueden recuperar directamente de la memoria caché de SMP. Esta memoria caché debe mantenerse sincronizada con los cambios de objetos en banda y los cambios de objetos fuera de banda.
Los cambios de objeto en banda incluyen esos cambios realizados a través de la instancia de SMP actual. Por ejemplo, si se crea un disco virtual a través de la instancia de SMP actual:
- Se debe agregar un nuevo objeto Disco virtual a la memoria caché.
- Los objetos asociados, como el grupo de almacenamiento propietario y los objetos de puerto de destino asociados, también deben actualizarse.
Los cambios fuera de banda incluyen los cambios realizados a través de herramientas propietarias del proveedor y el hospedaje de SMP en otras máquinas. Por ejemplo, si se crea un disco virtual a través de herramientas propietarias del proveedor, se debe enviar un evento desde el subsistema de almacenamiento a los SMP para desencadenar una actualización de caché.
SMP también debe actualizar la memoria caché cuando se llama al método Discover de la clase Storage Provider. La aplicación de administración de almacenamiento llama a este método para restablecer y recompilar la memoria caché en eventos como el reinicio del servicio o el reinicio del sistema.
Si no es factible que el SMP inicialice toda la memoria caché al iniciarse (debido a demasiados objetos o porque no se puede realizar rápidamente), solo se deben cargar en caché los objetos Proveedor de almacenamiento y Subsistema de almacenamiento. Las aplicaciones examinarán la propiedad CurrentCacheLevel en el objeto Subsistema de almacenamiento para saber cuánto profundidad se ha rellenado la memoria caché. El usuario final o la aplicación cargan explícitamente el resto de la memoria caché a través del método Discover.
Cualquier operación que tarde más de 30 segundos en completarse debe devolver un objeto De trabajo de almacenamiento. Es más probable que los métodos que contienen un parámetro de salida CreatedStorageJob sean de este tipo de operación. Los SMP deben implementar todos estos métodos como operaciones asincrónicas y devolver objetos de trabajo de almacenamiento para ellos. Un objeto De trabajo de almacenamiento debe devolverse al autor de la llamada en un plazo de 30 segundos; De lo contrario, el autor de la llamada puede agotar el tiempo de espera si espera demasiado tiempo y todavía no ha recibido el objeto Trabajo de almacenamiento.
Las aplicaciones (o "cliente WMI") tienen la opción de especificar si un método debe ser "RunAsJob" o no. La API sm que usan las aplicaciones contiene este parámetro RunAsJob booleano adicional y el parámetro de salida CreatedStorageJob. Mientras tanto, los métodos correspondientes en las interfaces SMP solo tienen el parámetro CreatedStorageJob. Sin embargo, independientemente del valor de "RunAsJob", los SMP siempre deben devolver objetos de trabajo de almacenamiento para estos métodos.
En los escenarios siguientes se muestra la secuencia de llamadas de operaciones asincrónicas. CreateVirtualDisk se usa como ejemplo:
Si "RunAsJob" está establecido en TRUE
Cuando se invoca CreateVirtualDisk, los SMP deben inicializar el método, iniciar un trabajo en el subsistema de almacenamiento y devolver un objeto De trabajo de almacenamiento al autor de la llamada en un plazo de 30 segundos. Sin embargo, el subsistema de almacenamiento puede tardar cualquier cantidad de tiempo en completar la operación. El autor de la llamada sondeará el estado del trabajo durante este tiempo.
Los subprocesos de trabajo se deben usar para ejecutar los trabajos. Con fines de eficacia, los SMP pueden actualizar los atributos relacionados con el estado del trabajo (por ejemplo, PercentComplete) solo cuando el autor de la llamada sondea el estado de ese trabajo.
Si "RunAsJob" está establecido en FALSE
El autor de la llamada se bloqueará en el método CreateVirtualDisk hasta que el método devuelva. La API de SM realiza automáticamente el bloqueo y el sondeo. Este tipo de llamador suele ser un cliente no interactivo por el usuario (por ejemplo, una herramienta de scripting) que prefiere el mecanismo de bloqueo.
Dado que la única manera de obtener información sobre un objeto recién creado es a través de la asociación entre este objeto y el objeto trabajo de almacenamiento correspondiente, los SMP deben mantener un objeto de trabajo de almacenamiento durante al menos 24 horas antes de quitarlo de la memoria caché. Para otras operaciones que no devuelven un objeto recién creado (por ejemplo, una operación DeleteObject), no se necesita una asociación y el objeto Trabajo de almacenamiento solo necesita permanecer activo durante 15 minutos.
En el caso de reinicios inesperados del sistema en las consolas de administración, los SMP deben mantener una caché de objetos StorageJob en una ubicación física, por ejemplo, en la matriz de almacenamiento y volver a cargar la memoria caché tras el reinicio del sistema.
Un SMP se puede implementar como proveedor acoplado o desacoplado. Para conocer la diferencia entre estos dos tipos de proveedores, consulte la documentación de MSDN de WMI.
Un proveedor desacoplado se carga y hospeda en un proceso específico del proveedor. Este proceso suele ser un servicio siempre en ejecución.
Iniciar un proveedor puede llevar mucho tiempo, ya que implica volver a cargar la memoria caché. Si el inicio de SMP requiere más de un segundo para cargarse, se recomienda implementar un proveedor desacoplado para administrar objetos de almacenamiento a través de una caché persistente. Este enfoque ayuda a aumentar el rendimiento general y la capacidad de respuesta de las aplicaciones que usan la API de Windows SM para administrar el SMP.
El ejemplo DecoupledHost de Windows SDK proporciona más detalles sobre los proveedores desacoplados.
Los desarrolladores de aplicaciones suelen querer saber cuándo cambia el estado de un objeto a medida que cambia. Pueden hacerlo mediante la suscripción a indicaciones de WMI. Las indicaciones son un tipo diferente de clase; se exponen de forma asincrónica, a veces fuera de banda desde cualquier operación de administración y no se conservan. En lugar de implementar los métodos intrínsecos conocidos (es decir, EnumerateInstances / GetInstance), hay nuevos métodos que se deben admitir.
Hay cuatro tipos de indicaciones:
- Llegada: esta indicación se usa cuando se agrega una instancia de dispositivo o objeto al subsistema. Por ejemplo: Agregar un nuevo disco físico al subsistema o crear un disco virtual.
- Salida: esta indicación se usa cuando se quita un dispositivo o una instancia de objeto del subsistema. Por ejemplo: Quitar un disco físico del subsistema o eliminar un grupo de almacenamiento.
- Modificar: esta indicación se usa cuando cambia una propiedad importante en un objeto existente. Como mínimo, los cambios de HealthStatus y OperationalStatus deben desencadenar una indicación Modify. Se recomienda encarecidamente indicar un cambio en cualquier otra propiedad relacionada con el estado operativo de un objeto.
- Alerta: esta indicación se usa para alertar a la aplicación a un posible problema. Actualmente, la única alerta definida es notificar cuando se alcanza un umbral de aprovisionamiento fino.
Para implementar indicaciones, hay dos nuevos métodos intrínsecos que se deben implementar para cada clase de indicación:
- EnableIndication: se realizó una solicitud para suscribirse a la clase de indicación. El valor de indicationContext debe guardarse para que esté disponible para publicar en una indicación en un momento posterior.
- DisableIndication: no hay más suscriptores a la clase de indicación. La limpieza debe producirse y no se deben publicar más indicaciones para esta clase. indicationContext se destruye en este momento.
Los SMP se instalan en los "servidores de administración" seleccionados. Estos servidores se pueden agrupar en clúster para proporcionar redundancia. Otros servidores acceden al almacenamiento asignado a ellos a través de iSCSI o Canal de fibra. Todos estos equipos se pueden administrar mediante servidores que ejecutan la interfaz de usuario del servidor de archivos desde Administrador del servidor.
Sin embargo, los proveedores de almacenamiento son bienvenidos a elegir el modelo de implementación que mejor se adapte a sus requisitos.
La interfaz SMP admite el modelo de inicio de sesión único (SSO) mediante credenciales de seguridad de Windows.
En el modelo de SSO, un usuario inicia sesión en una "máquina de administración" con sus credenciales de Windows una vez y obtiene acceso automáticamente a todos los recursos de almacenamiento que tienen permiso de acceso. No es necesario tener más credenciales para el inicio de sesión del subsistema de almacenamiento.
La interfaz también permite a los administradores de almacenamiento administrar el control de acceso en recursos de almacenamiento individuales. Para cada recurso de almacenamiento, los administradores de almacenamiento pueden conceder derechos de acceso diferentes a cualquier usuario de Windows a través de los métodos GetSecurityDescriptor y SetSecurityDescriptor. Como resultado, los SMP, a diferencia del modelo de VDS, ahora pueden recibir solicitudes de cualquier tipo de cuenta de usuario.
Para implementar el modelo de SSO, un SMP debe autenticar los clientes de Windows en el subsistema de almacenamiento. El subsistema de almacenamiento debe conservar la información del descriptor de seguridad para cada recurso de almacenamiento. Para implementar la autenticación, los proveedores de almacenamiento tienen dos opciones:
- Autenticación en el subsistema (recomendado)
- Autentíquese en cada instancia de SMP.
Ambas opciones requieren que se establezca una relación de confianza entre el SMP y el subsistema de almacenamiento para que se pueda pasar de forma segura el descriptor de seguridad y la información de identidad del usuario.
Para implementar la autenticación y autorización sin problemas en el subsistema de almacenamiento, se recomienda el vínculo entre SMP y el subsistema de almacenamiento para implementar Kerberos, NTLM o SPNego. Si el subsistema de almacenamiento tiene un servidor web en su lugar, el protocolo "NTLM a través de HTTP" [MS-NLMP] podría ser más útil. Los proveedores de almacenamiento pueden optar por mantener sus protocolos propietarios para implementar el modelo de SSO. Sin embargo, este enfoque no se recomienda, ya que puede dar lugar a más trabajo o configuración que la implementación de uno de los protocolos de autenticación compatibles con Windows.
Para admitir la directiva de seguridad de Windows, el subsistema de almacenamiento tiene que obtener la "información de token" del usuario, que incluye el identificador de seguridad (SID) del usuario y los SID de cualquier grupo del que sea miembro el usuario. Si se implementa el protocolo Kerberos, NTLM o SPNego, el subsistema de almacenamiento obtendrá la información del token del usuario como parte del protocolo. Si se usa el protocolo propietario de un proveedor entre SMP y el subsistema de almacenamiento, el subsistema de almacenamiento puede consultar la información del token del usuario desde Active Directory a través del Protocolo ligero de acceso a directorios (LDAP) y examinar el atributo tokenGroupsGlobalAndUniversal o el atributo Object-Sid en el objeto de cuenta del usuario.
Con la información del token del usuario, para aplicar la directiva de seguridad de Windows, el subsistema de almacenamiento debe implementar el algoritmo de comprobación de acceso descrito en [MS-DTYP].
Si un proveedor de almacenamiento decide no admitir este modelo de SSO, se recomienda que el SMP siga el modelo de seguridad de VDS, lo que permite solo las operaciones iniciadas desde cuentas de administrador. Sin embargo, esta comprobación debe realizarse ahora por el propio SMP.