Active IQ Unified Manager Discussions

WFA - Create CIFS Share on Destination Qtree after Replication

A_Campbell
6,178 Views

I'm going to be using WFA to create qtrees and CIFS shares in existing volumes that are using snapmirror replication. What I'd like to incorporate into my WFA workflow is creating a CIFS share on the destination qtree once it's created from replication. Has anyone done this or have ideas about the best way to go about getting it accomplished?

 

 

Thanks

1 ACCEPTED SOLUTION

mbeattie
5,961 Views

Hi,

 

I have a few ideas for you, I think it would be possible to:

 

  • Use the Read-NcDirectory CmdLet to connect the destination and periodically check if the Qtree or folder that the CIFS share was created on in production exists on the destination. If not, sleep for X seconds\minutes until it either exists or a timeout value is exceeded.
  • Have the workflow that creates your cifs share in production create an XML file then have a scheduled workflow read any XML files for processing, extract the variables from the XML and call your CIFS share creation workflow (but using the variable values for the destination cluster\vserver).
  • Wait for snapmirror to update the volume (may not be the most efficent depending on the rate of change at the time your workflow is executed and when the snapmirror schedule is configured)

I think the first option is probably the simplest. Here is some base source code for the WFA command, would just need to be modified to add in a loop\wait until success or timeout.

 

Param(
   [Parameter(Mandatory = $True, HelpMessage = "The name or IP Address of the cluster")]
   [String]$ClusterName,
   [Parameter(Mandatory = $True, HelpMessage = "The name of the vserver")]
   [String]$VserverName,
   [Parameter(Mandatory = $True, HelpMessage = "The path of the directory to read")]
   [String]$Path,
   [Parameter(Mandatory = $False, HelpMessage = "The maximum number of ZAPI retry attempts")]
   [Int]$ZapiRetryCount
)
#'------------------------------------------------------------------------------
#'Connect to the cluster
#'------------------------------------------------------------------------------
Connect-WFACluster $ClusterName
#'------------------------------------------------------------------------------
#'Create the command to read the directory.
#'------------------------------------------------------------------------------
If(-Not($Path.StartsWith("/vol/"))){
   If($Path.StartsWith("/")){
      [String]$p = $path.substring(1, ($path.length -1))
      [String]$Path = "/vol/$p"
   }Else{
      [String]$Path = "/vol/$Path"
   }
} [String]$command = "Read-NcDirectory -Path ""$Path"" " If($ZapiRetryCount){ [String]$command += "-ZapiRetryCount $ZapiRetryCount " } [String]$command += "-VserverContext $VserverName -ErrorAction Stop" #'------------------------------------------------------------------------------ #'Read the directory to ensure it exists. #'------------------------------------------------------------------------------ Try{ Invoke-Expression -Command $command -ErrorAction Stop Get-WFALogger -Info -Message "Executed Command`: $command" Get-WFALogger -Info -Message "The directory ""$Path"" exists on vserver ""$VserverName""" }Catch{ Get-WFALogger -Info -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message) Throw "The Directory ""$Path"" does not exist on vserver ""$VserverName""" } #'------------------------------------------------------------------------------

/Matt

 

 

 

 

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

View solution in original post

7 REPLIES 7

Jeff_Yao
6,078 Views

how about to start from here: (reading the guides and manuals)?

https://library.netapp.com/documentation/docweb/index.html?productID=62404&language=en-US

 

thanks

mbeattie
6,051 Views

Hi,

 

That's certainly possible to do but it depends on how you have your environment configured. Assuming you are not using onbox SVM DR, here a few ideas and thoughts to consider:

 

  • What is your cluster\vserver naming standard? Do you have a standard which enables you to easily (and accurately) predict your disaster recovery cluster\vserver name to create the CIFS share within your DR site?
  • What is the snapmirror replication schedule on your production SVM and what is the rate of data change (IE are you going to force a snapmirror update for the volume within your workflow when you create a qtree\CIFS share on your production SVM so the the Qtree is replicated to your DR SVM enabling you to connect to your DR cluster and create the CIFS share on your DR SVM?)
  • If your naming standard doesn't easily enable you to determin the DR SVM you can write a SQL filter to determine the vservers peer (but this may depend on casading\vault relationships configured in your environment)

Alternately what is also possible assuming you don't want to force a snapmirror update for the volume every time you create a CIFS share is to develop a workflow that would create your DR CIFS shares on a scheduled basis (based on your snapmirror schedule and RTO\RPO). For example you could have your WFA workflow that creates your production CIFS share also create  an XML configuration file to be read by another workflow which runs on a scheduled basis every X hours, reads the XML then connects to your DR cluster\SVM and creates the CIFS share after normal snapmirror updates as per your schedule have run. If successful then DR CIFS share is created and the XML file is archived. If not the XML file remains queued for processing (until the volume snapmirror has completed).

 

There are some ideas for you. Let me know if you think they would work in your environment.

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

A_Campbell
5,994 Views

Thanks for everyone's feedback. I've actually made some progress here. After the initial qtree and share are created in the workflow, I use NetApp's 'Transfer SnapMirror' command, and then proceed to create the CIFS on the destination. I tested in our lab and it works. But I'm thinking when the snapmirror transfer takes a longer period of time, the workflow will fail on the destination share creation due to the qtree not being replicated in time. Is there a way to build in a waiting period, such as 1 hour, after 'Transfer SnapMirror' is initiated so it has time to complete before the workflow attempts to create the CIFS on the destination qtree?

A_Campbell
5,983 Views

Update -

 

I added the following to the powershell script for creating the CIFS on the destination. This will wait an hour before execution, giving the replication time to complete:

Start-Sleep -s 3600

 

It would be optimal to be able to confirm if the snapmirror transfer is complete before proceeding to the next step in the workflow, to avoid wasting further time. If anyone has thoughts on how to accomplish this, please let me know.

 

 

mbeattie
5,962 Views

Hi,

 

I have a few ideas for you, I think it would be possible to:

 

  • Use the Read-NcDirectory CmdLet to connect the destination and periodically check if the Qtree or folder that the CIFS share was created on in production exists on the destination. If not, sleep for X seconds\minutes until it either exists or a timeout value is exceeded.
  • Have the workflow that creates your cifs share in production create an XML file then have a scheduled workflow read any XML files for processing, extract the variables from the XML and call your CIFS share creation workflow (but using the variable values for the destination cluster\vserver).
  • Wait for snapmirror to update the volume (may not be the most efficent depending on the rate of change at the time your workflow is executed and when the snapmirror schedule is configured)

I think the first option is probably the simplest. Here is some base source code for the WFA command, would just need to be modified to add in a loop\wait until success or timeout.

 

Param(
   [Parameter(Mandatory = $True, HelpMessage = "The name or IP Address of the cluster")]
   [String]$ClusterName,
   [Parameter(Mandatory = $True, HelpMessage = "The name of the vserver")]
   [String]$VserverName,
   [Parameter(Mandatory = $True, HelpMessage = "The path of the directory to read")]
   [String]$Path,
   [Parameter(Mandatory = $False, HelpMessage = "The maximum number of ZAPI retry attempts")]
   [Int]$ZapiRetryCount
)
#'------------------------------------------------------------------------------
#'Connect to the cluster
#'------------------------------------------------------------------------------
Connect-WFACluster $ClusterName
#'------------------------------------------------------------------------------
#'Create the command to read the directory.
#'------------------------------------------------------------------------------
If(-Not($Path.StartsWith("/vol/"))){
   If($Path.StartsWith("/")){
      [String]$p = $path.substring(1, ($path.length -1))
      [String]$Path = "/vol/$p"
   }Else{
      [String]$Path = "/vol/$Path"
   }
} [String]$command = "Read-NcDirectory -Path ""$Path"" " If($ZapiRetryCount){ [String]$command += "-ZapiRetryCount $ZapiRetryCount " } [String]$command += "-VserverContext $VserverName -ErrorAction Stop" #'------------------------------------------------------------------------------ #'Read the directory to ensure it exists. #'------------------------------------------------------------------------------ Try{ Invoke-Expression -Command $command -ErrorAction Stop Get-WFALogger -Info -Message "Executed Command`: $command" Get-WFALogger -Info -Message "The directory ""$Path"" exists on vserver ""$VserverName""" }Catch{ Get-WFALogger -Info -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message) Throw "The Directory ""$Path"" does not exist on vserver ""$VserverName""" } #'------------------------------------------------------------------------------

/Matt

 

 

 

 

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

A_Campbell
5,941 Views

@mbeattie

 

That's fantastic information, I'm going to pursue that first option. Thank you very much.

mbeattie
5,911 Views

Hi,

 

Here is an "example" WFA command that will wait for a directory to exist (or until a timeout is exceeded). You can apply the same principle to a snapmirror update for the volume or you can just wait for the your snapmirror schedule to update the volume to the destination and use this command to wait for the Qtree you've created on production to replicate to your DR vserver. It really depends on your environment, it might be fine to invoke a snapmirror update for the entire volume (just to replicate the qtree) or your network team might disapprove of that happening more frequently than your agreed snapmirror schedule.

 

In the following example, the command will "attempt" to read a directory, if it fails, it will wait X seconds (defined by the $WaitInterval variable) until either the directory exists or the $TimeOut values is exceeded.

 

Source Code:

 

Param(
   [Parameter(Mandatory=$true, HelpMessage="The Cluster name or IP Address")]
   [String]$ClusterName,
   [Parameter(Mandatory=$true, HelpMessage="The Vserver name")]
   [String]$VserverName,
   [Parameter(Mandatory=$True, HelpMessage="The junction path of the directory to read")]
   [String]$Path,
   [Parameter(Mandatory=$True, HelpMessage="The total Number of seconds to wait")]
   [Long]$TimeOut,
   [Parameter(Mandatory=$True, HelpMessage="The number of seconds to wait in between checks")]
   [Long]$WaitInterval
)
#'------------------------------------------------------------------------------
Function Wait-ReadDirectory{
  <#
   .SYNOPSIS
   This function verifies a directory exist or waits for it to be created within a specified timeout.
   .DESCRIPTION
   Checks if a directory exists or waits for it to be created and returns a boolean.
   .PARAMETER
   ClusterName Accepts a string containing the destination clusters name or IP Address.
   .PARAMETER
   VserverName Accepts a string containing the destination vserver hostname.
   .PARAMETER
   Path Accepts a string containing the junction path of the directory to check it exists.
   .PARAMETER
   TimeOut Accepts an integer containing the maximum number of seconds to wait for snapmirror operations.
   .PARAMETER
   WaitInterval Accepts an integer containing the maximum number of seconds to wait in between attempting to read the directory.
   .EXAMPLE
   Wait-ReadDirectory -VserverName vserver1 -Path "/vol/vol1/qtree1" -TimeOut 3600 -WaitInterval 30
   #>
   #---------------------------------------------------------------------------
   [CmdletBinding()]
  Param(
      [Parameter(Position=0,
         Mandatory=$True,
         ValueFromPipeLine=$True,
         ValueFromPipeLineByPropertyName=$True)]
      [String]$VserverName,
      [Parameter(Position=1,
         Mandatory=$True,
         ValueFromPipeLine=$True,
         ValueFromPipeLineByPropertyName=$True)]
      [String]$Path,  
      [Parameter(Position=2,
         Mandatory=$True,
         ValueFromPipeLine=$True,
         ValueFromPipeLineByPropertyName=$True)]
      [Long]$TimeOut,
      [Parameter(Position=3,
        Mandatory=$True,
         ValueFromPipeLine=$True,
         ValueFromPipeLineByPropertyName=$True)]
      [Long]$WaitInterval
   )
   #'---------------------------------------------------------------------------
   #'Wait for the directory to be created or until the timeout is exceeded.
   #'---------------------------------------------------------------------------
   [Long]$waited     = 0
   [Long]$timeWaited = $waited
   [Bool]$exists     = $False
   Do{
      #'------------------------------------------------------------------------
      #'Read the directory to ensure it exists.
      #'------------------------------------------------------------------------
      [Long]$timeWaited += [Long]($waited + $waitInterval)
      [String]$command   = "Read-NcDirectory -Path ""$Path"" -VserverContext $VserverName -ErrorAction Stop"
      Try{
         Invoke-Expression -Command $command -ErrorAction Stop
         Get-WFALogger -Info -Message "Executed Command`: $command"
         Get-WFALogger -Info -Message "The junction path ""$Path"" exists on vserver ""$VserverName"""
         [Bool]$exists = $True
      }Catch{
         [Bool]$exists = $False
         Get-WFALogger -Info -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message + ". Waiting ""$WaitInterval"" seconds before retrying.")
      }
      If(($exists) -And ($timeWaited -le $timeOut) -And $timeOut -gt 0){
         Break;
      }
      Start-Sleep -Seconds $waitInterval      
   }Until(($exists) -Or (($timeWaited -ge $timeOut) -And $timeOut -gt 0))
   #'------------------------------------------------------------------------
   #'Log the total time waited for the directory to be created.
   #'------------------------------------------------------------------------  
   If(($exists) -And ($timeWaited -lt $timeOut)){
      Get-WFALogger -Info -Message "Waited a total of ""$timeWaited"" seconds for the junction path ""$Path"" to exist on vserver ""$VserverName"""
   }
   #'---------------------------------------------------------------------------
   #'Raise an error if the timeout is exceeded.
   #'---------------------------------------------------------------------------
   If(($timeWaited -ge $timeOut) -And ($timeOut -gt 0) -And ($exists -eq $False)){
      Get-WFALogger -Error -Message "The junction path ""$Path"" does not exist on the destination vserver ""$VserverName"" within the timeout of ""$timeOut"" seconds"
   }
   Return $exists;
}#End Function
#'------------------------------------------------------------------------------
#'Connect to the cluster.
#'------------------------------------------------------------------------------
Connect-WfaCluster $ClusterName
#'------------------------------------------------------------------------------
#'Create the command to read the directory.
#'------------------------------------------------------------------------------
If(-Not($Path.StartsWith("/vol/"))){
   If($Path.StartsWith("/")){
      [String]$p = $path.substring(1, ($path.length -1))
      [String]$Path = "/vol/$p"
   }Else{
      [String]$Path = "/vol/$Path"
   }
}
#'------------------------------------------------------------------------------
#'Wait for the directory to exist on the destination vserver.
#'------------------------------------------------------------------------------
If(Wait-ReadDirectory -VserverName $VserverName -Path $Path -TimeOut $TimeOut -WaitInterval $WaitInterval){
   Get-WFALogger -Info -Message "The junction path ""$Path"" on vserver ""$VserverName` exists."
}Else{
   Throw "The path ""$Path"" on vserver ""$VserverName"" does not exist or reached the wait timeout of ""$TimeOut"" seconds"
}
#'------------------------------------------------------------------------------

When testing it, i connected to a CIFS share at the root of a volume, wait for a while then created the test directory folder (in your instance that will be a qtree that is created on the destination vserver via snapmirror replication)

 

Example output:

 

wfa1.png

 

Hope this helps.

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.
Public