4.4 Setting a Complex Dependency for a Resource
Complex dependencies are supported only by protocol version 3.
The following example illustrates how a client sets a complex dependency for a resource representing a database service within a cluster. This example requires a group that contains the following resources:
A resource that represents the database service
A cluster network name resource and its dependent IP address resources
A set of storage device resources where each device contains one database
The service is traditionally structured where a client connects to it via the virtual cluster network name (whose IP addresses are registered with a name resolution service within the cluster network infrastructure) and the service stores its persistent data on the storage devices. The goal of the dependency relationship is to keep the database service hosted on this node as long as the cluster network name and at least one storage device are online.
The construction of this tiered dependency is performed in two steps:
Setting an OR dependency for the Network Name resource and its two IP address resources
Setting the AND/OR dependency for the Service and its Network Name and Disk resources
The following diagram depicts the target dependency relationship.
Figure 10: Database service with its dependent resources
The following diagram depicts the message flow for this example.
Figure 11: Message flow: Setting a complex dependency relationship for a resource
The client next obtains three HRES_RPC context handles to the Network Name and IP address resources by calling ApiOpenResource (see section 188.8.131.52.9 for protocol version 3) with the lpszResourceName parameter set to the null-terminated Unicode strings, "Name1", "IP1", and "IP2", respectively, for each call.
The client then obtains the resource IDs for the two IP address resources through use of the ApiResourceControl (see section 184.108.40.206.74 for protocol version 3). If the size of the resource ID string is well known, the client can pre-allocate a suitably sized buffer for each ID string including space for the null-termination (in this example, five buffers will eventually be needed). Otherwise, it must discover the size of the ID string for each resource by setting the nOutBufferSize parameter to zero and the lpcbRequired pointer to the address of the 32-bit integer that will receive the size, in bytes, of the ID string.
Using the allocated buffers holding the respective ID strings of the IP address resources, the client calls ApiResourceControl once for each IP address. For each IP address resource, the client sets the hResource parameter to the respective HRES_RPC context handle, the dwControlCode parameter to CLUSCTL_RESOURCE_GET_ID (0x1000039), and the lpOutBuffer parameter to a different allocated buffer each time.
Using the size of the two IP address resource strings, the client allocates another buffer to contain the dependency expression for the Network Name resource. This expression is a null-terminated Unicode string of the form "[IP1-ID] OR [IP2-ID]". If GUIDs were used for ID strings, then the expression would look like the following.
[0b8b76df-d814-4813-a7c2-37837933c157] OR [1bd68f61-3882-421f-9c31-555459f29e8a]
The client would then call ApiSetResourceDependencyExpression (see section 220.127.116.11.109; protocol version 3 only) with the hResource parameter set to the Network Name resource context handle and the lpszDependencyExpression parameter set to the expression previously shown.
The client calls ApiCloseResource (see section 18.104.22.168.12 for protocol version 3) on the two IP address context handles. The client obtains the resource IDs of the four disk resources, using the same technique described in the preceding paragraphs. After the resource IDs have been obtained, the client forms a complex dependency expression using the Network Name ID and the four Disk IDs: [NN-ID] AND ([D1] OR [D2] OR [D3] OR [D4]). If names were used for ID strings, the expression would look like the following.
[Netname] AND ([Disk1] OR [Disk2] OR [Disk3] OR [Disk4])
The client calls ApiSetResourceDependencyExpression with the hResource parameter set to the Database Service resource context handle and the lpszDependencyExpression parameter set to the expression previously shown.
The client then closes the context handles for the remaining resources using the ApiCloseResource method.