<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SIOC Archives - LucD notes</title>
	<atom:link href="https://www.lucd.info/tag/sioc/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.lucd.info/tag/sioc/</link>
	<description>My PowerShell ramblings</description>
	<lastBuildDate>Wed, 08 Apr 2020 11:01:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://www.lucd.info/wp-content/uploads/2018/12/cropped-120px-Tibetan_Dharmacakra-32x32.png</url>
	<title>SIOC Archives - LucD notes</title>
	<link>https://www.lucd.info/tag/sioc/</link>
	<width>32</width>
	<height>32</height>
</image> 
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/><atom:link rel="hub" href="https://websubhub.com/hub"/>	<item>
		<title>Test if the datastore can be unmounted</title>
		<link>https://www.lucd.info/2012/04/15/test-if-the-datastore-can-be-unmounted/</link>
					<comments>https://www.lucd.info/2012/04/15/test-if-the-datastore-can-be-unmounted/#comments</comments>
		
		<dc:creator><![CDATA[LucD]]></dc:creator>
		<pubDate>Sun, 15 Apr 2012 21:29:48 +0000</pubDate>
				<category><![CDATA[datastore]]></category>
		<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SDRS]]></category>
		<category><![CDATA[SIOC]]></category>
		<category><![CDATA[unmount]]></category>
		<guid isPermaLink="false">http://www.lucd.info/?p=3980</guid>

					<description><![CDATA[Lately I have been playing around with the new Storage related features in [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Lately I have been playing around with the new Storage related features in vSphere 5. One of the novelties is that you can now <strong>unmount</strong> a VMFS datastore and <strong>detach</strong> a SCSI LUN through the API.<br />
To be able to unmount a datastore, some <strong>conditions</strong> have to be met. In the vSphere Client you get an informative popup that tells what is prohibiting the datastore unmount. If not all conditions are met, you can not continue with the unmount.</p>
<p><a href="https://lucd.info/wp-content/uploads/2012/04/Datastore-unmount.png"><img fetchpriority="high" decoding="async" class=" wp-image-3906 alignnone" title="DS unmount" src="https://lucd.info/wp-content/uploads/2012/04/Datastore-unmount.png" alt="" width="421" height="316" /></a></p>
<p>Nice feature, but what for those of us that want to automate this ?</p>
<p><span style="background-color: #ffff00;"><strong>Update October 28th 2012</strong></span>: Take into account that the datastorecluster is not connected to a host that is part of a cluster. Skip the HA heartbeat test.</p>
<p><span style="background-color: #ffff00;"><strong>Update April 23th 2012</strong></span>: Use the <a href="https://pubs.vmware.com/vsphere-50/topic/com.vmware.wssdk.apiref.doc_50/vim.ClusterComputeResource.html#retrieveDasAdvancedRuntimeInfo" target="_blank">RetrieveDasAdvancedRuntimeInfo</a> method to find the actual datastores that are used for the heartbeat.</p>
<p><span id="more-3980"></span></p>
<h2>What to look for ?</h2>
<p>From the popup, it is quite obvious what specific feature can prohibit the unmount of a datastore.</p>
<p>But if you look at Cormac&#8217;s post called <a href="https://blogs.vmware.com/vsphere/2012/02/what-could-be-writing-to-a-vmfs-when-no-virtual-machines-are-running.html" target="_blank">What could be writing to a VMFS when no Virtual Machines are running?</a>, there are a couple of other settings that might influence the ability to unmount a datastore.</p>
<p>In Cormac&#8217;s post you&#8217;ll find that a <strong>Distributed Virtual Switch configuration file</strong> or the presence of a <strong>scratch partition</strong> might also cause IO that would prevent a datastore unmount.</p>
<p>So I decided to expand the function with a check for those 2 additional causes.</p>
<h2>The script</h2>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">function Get-DatastoreUnmountStatus{
  &lt;#
.SYNOPSIS  Check if a datastore can be unmounted.
.DESCRIPTION The function checks a number of prerequisites
  that need to be met to be able to unmount a datastore.
.NOTES  Author:  Luc Dekens
.PARAMETER Datastore
  The datastore for which you want to chekc the conditions.
  You can pass the name of the datastore or the Datastore
  object returned by Get-Datastore
.EXAMPLE
  PS&gt; Get-DatastoreUnmountStatus -Datastore DS1
.EXAMPLE
  PS&gt; Get-Datastore | Get-DatastoreUnmountStatus
#&gt;
  param(
    [CmdletBinding()]
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [PSObject[]]$Datastore
  )

  process{
    foreach($ds in $Datastore){
      if($ds.GetType().Name -eq &quot;string&quot;){
        $ds = Get-Datastore -Name $ds
      }
      $parent = Get-View $ds.ExtensionData.Parent
      New-Object PSObject -Property @{
        Datastore = $ds.Name
        # No Virtual machines
        NoVM = $ds.ExtensionData.VM.Count -eq 0
        # Not in a Datastore Cluster
        NoDastoreClusterMember = $parent -isnot [VMware.Vim.StoragePod]
        # Not managed by sDRS
        NosDRS = &amp;{
          if($parent -is [VMware.Vim.StoragePod]){
            !$parent.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Enabled
          }
          else {$true}
        }
        # SIOC disabled
        NoSIOC = !$ds.StorageIOControlEnabled
        # No HA heartbeat
        NoHAheartbeat = &amp;{
          $hbDatastores = @()
          $cls = Get-View -ViewType ClusterComputeResource -Property Host |
          where{$_.Host -contains $ds.ExtensionData.Host[0].Key}
          if($cls){
            $cls | %{
              (                $_.RetrieveDasAdvancedRuntimeInfo()).HeartbeatDatastoreInfo | %{
                $hbDatastores += $_.Datastore
              }
            }
            $hbDatastores -notcontains $ds.ExtensionData.MoRef
          }
          else{$true}
        }
        # No vdSW file
        NovdSwFile = &amp;{
          New-PSDrive -Location $ds -Name ds -PSProvider VimDatastore -Root '\' | Out-Null
          $result = Get-ChildItem -Path ds:\ -Recurse |
          where {$_.Name -match '.dvsData'}
          Remove-PSDrive -Name ds -Confirm:$false
          if($result){$false}else{$true}
        }
        # No scratch partition
        NoScratchPartition = &amp;{
          $result = $true
          $ds.ExtensionData.Host | %{Get-View $_.Key} | %{
            $diagSys = Get-View $_.ConfigManager.DiagnosticSystem
            $dsDisks = $ds.ExtensionData.Info.Vmfs.Extent | %{$_.DiskName}
            if($dsDisks -contains $diagSys.ActivePartition.Id.DiskName){
              $result = $false
            }
          }
          $result
        }
      }
    }
  }
}</pre><p></p>
<h4>Annotations</h4>
<p><strong>Line 24-26</strong>: A simple Object By Name implementation. It allows to pass the datastores by name or by object to the function.</p>
<p><strong>Line 27</strong>: The parent of the datastore is used in a couple of tests further on in the script</p>
<p><strong>Line 31</strong>: Test if there are any VMs or Templates present on the datastore</p>
<p><strong>Line 33</strong>: Test if the datastore belongs to a Storage Cluster</p>
<p><strong>Line 35-40</strong>: Test if the datastore is managed by Storage DRS. The Enabled property in the <a href="https://pubs.vmware.com/vsphere-50/topic/com.vmware.wssdk.apiref.doc_50/vim.storageDrs.PodConfigInfo.html" target="_blank">StorageDrsPodConfigInfo</a> object is used as the indicator.</p>
<p><strong>Line 42</strong>: Test if SIOC is enabled for the datastore</p>
<p><strong>Line 44-57</strong>: Test if the datastore is one of the Heartbeat Datastores. The test first gets all the clusters known in vCenter and then filters out those clusters that have hosts on which the datastore is visible.</p>
<p><strong>Line 48,56</strong>: If the host is not part of a cluster, the HA heartbeat test is considered as successful.</p>
<p><strong>Line 59-65</strong>: Test to see if the is a Distributed Virtual Switch configuration file present on the datastore.</p>
<p><strong>Line 67-77</strong>: Test if the datastore is used as a scratch partition.</p>
<h2>Sample usage</h2>
<p>The function can be used in a stand-alone or in a pipeline construct.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-DatastoreUnmountStatus -Datastore DS1</pre><p></p>
<p>The pipeline construct could look like this</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-Datastore DS* | Get-DatastoreUnmountStatus</pre><p></p>
<p>The function produces 1 object per datastore. Each of the properties in the object represents 1 test that the function executes. Something like this.</p>
<p><a href="https://lucd.info/wp-content/uploads/2012/04/dsUnmountout.png"><img decoding="async" class=" wp-image-3906 alignnone" title="DS unmount output" src="https://lucd.info/wp-content/uploads/2012/04/dsUnmountout.png" alt="" width="576" height="130" /></a></p>
<p>The output shows us that we will probably not be able to unmount datastore DS1, because:</p>
<ul>
<li>the datastore is part of a Datastore Cluster</li>
<li>the datastore is managed by Storage DRS</li>
<li>there are VMs (or Templates) on the datastore</li>
<li>the datastore is used by the Datastore Heartbeat</li>
<li>the datastore has SIOC enabled</li>
</ul>
<p>The functions to solve this and allow an unmount of the datastore will follow in some future posts.</p>
<p>Enjoy !</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.lucd.info/2012/04/15/test-if-the-datastore-can-be-unmounted/feed/</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
		<item>
		<title>SIOC statistics</title>
		<link>https://www.lucd.info/2011/01/24/sioc-statistics/</link>
					<comments>https://www.lucd.info/2011/01/24/sioc-statistics/#comments</comments>
		
		<dc:creator><![CDATA[LucD]]></dc:creator>
		<pubDate>Mon, 24 Jan 2011 21:54:44 +0000</pubDate>
				<category><![CDATA[datastore]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SIOC]]></category>
		<category><![CDATA[statistics]]></category>
		<guid isPermaLink="false">http://www.lucd.info/?p=2942</guid>

					<description><![CDATA[SIOC (Storage IO Control) is apparently a hot topic. There have been an [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>SIOC (Storage IO Control) is apparently a hot topic. There have been an important number of posts since it was made available with vSphere 4.1. On this blog, in my <a href="https://www.lucd.info/2010/10/20/automate-sioc/" target="_blank" rel="noopener noreferrer">Automate SIOC</a> post, you can find functions to verify and activate/deactivate SIOC from your PowerShell script.</p>
<p>A recent post on <a href="https://www.yellow-bricks.com/" target="_blank" rel="noopener noreferrer">Yellow-Bricks</a>, called <a href="http://www.yellow-bricks.com/2011/01/20/enable-storage-io-control-on-all-datastores/" target="_blank" rel="noopener noreferrer">Enable Storage IO Control on all Datastores!</a> got quite a few comments and Tweets.</p>
<p>I was intrigued by one of the comments on Twitter that stated that the users didn&#8217;t understand what SIOC was all about. From several posts on SIOC I came to understand that the non-VI workload event would be fired when SIOC doesn&#8217;t see any latency improvements when it throttles the storage queue. Simple enough, but is there any data available that can make this visible ?</p>
<p><span id="more-2942"></span>So I decided to try and pull some performance data from the vSphere environment to help me understand what is going on when SIOC is activated and more specifically if there is any performance data that seems to explain why the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.event.NonVIWorkloadDetectedOnDatastoreEvent.html" target="_blank" rel="noopener noreferrer">NonVIWorkloadDetectedOnDatastoreEvent</a> event is fired.</p>
<p>I started by looking at the performance metric to see if there were any that had anything to do with SIOC. The only ones I could find were 2 metrics in the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/datastore_counters.html" target="_blank" rel="noopener noreferrer">Datastore</a> group.</p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/perfMgr-SIOC.png"><img decoding="async" class="alignnone size-full wp-image-2943" title="perfMgr-SIOC" src="https://lucd.info/wp-content/uploads/2011/01/perfMgr-SIOC.png" alt="" width="798" height="110" srcset="https://www.lucd.info/wp-content/uploads/2011/01/perfMgr-SIOC.png 998w, https://www.lucd.info/wp-content/uploads/2011/01/perfMgr-SIOC-300x41.png 300w" sizes="(max-width: 798px) 100vw, 798px" /></a></p>
<p>The next preparatory step was to look at the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.event.NonVIWorkloadDetectedOnDatastoreEvent.html" target="_blank" rel="noopener noreferrer">NonVIWorkloadDetectedOnDatastoreEvent</a> event. This event extends the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.event.DatastoreEvent.html" target="_blank" rel="noopener noreferrer">DatastoreEvent</a>, which adds the <strong>datastore</strong> property to the basic <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.event.Event.html" target="_blank" rel="noopener noreferrer">Event</a> object.  From a preliminary report on this event it was clear that the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.event.NonVIWorkloadDetectedOnDatastoreEvent.html" target="_blank" rel="noopener noreferrer">NonVIWorkloadDetectedOnDatastoreEvent</a> event is fired against a Datastore. There is no specific host information present in the event.</p>
<p>I envisaged a function that would be able to return the SIOC performance data for a specific datastore on a host but also for one or more datastores in a cluster. Since this ment that the resulting array would have a variable number of columns, I decided to use the Add-Type cmdlet to create a customised object each time the function is called. See my <a href="https://www.lucd.info/2010/04/09/lun-report-datastores-rdms-and-node-visibility/" target="_blank" rel="noopener noreferrer">LUN report – datastore, RDM and node visibility</a> post for another example of this technique.</p>
<h2>The script</h2>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">#requires -version 2
#requires -pssnapin VMware.VimAutomation.Core -version 4.1

function Get-SiocStat{
&lt;#
.SYNOPSIS
	Returns SIOC related performance data for one or more
	datastores
.DESCRIPTION
	The function returns an array with SIOC performance data for
	one or more datastore over period in time.
	The data also contains all NonVIWorkloadDetectedOnDatastoreEvent
	events that occurred during the requested interval.
.NOTES
	Author:  Luc Dekens
.PARAMETER VMHostName
	The name of the ESX(i) host for which you request the data.
.PARAMETER ClusterName
	The SIOC performance data will be collected for all shared
	datastores, or for the datastore passed with DatastoreName,
	for each node in the cluster.
.PARAMETER DatastoreName
	The name of one or more datastores for which you want to retrieve
	the SIOC performance data.
	If no DatastoreName is provided, the function will return
	SIOC performance data for all the shared datastores on the
	entity.
.PARAMETER Start
	Start of the interval for which SIOC performance data will be
	collected. The default is 1 day back.
.PARAMETER Finish
	End of the interval for which SIOC performance data will be
	collected. The default is now.
.EXAMPLE
	PS&gt; $stats= Get-SiocStat -DatastoreName MyDS -Start $start
.EXAMPLE
	PS&gt; $stats = Get-SiocStat -HostName MyEsx -DatastoreName MyDS
.EXAMPLE
	PS&gt; $stats = Get-SiocStat -ClusterName MyCluster -Start $start -Finish $finish
.EXAMPLE
	PS&gt; $stats = Get-SiocStat -ClusterName MyCluster -DatastoreName MyDS
#&gt;

	[CmdletBinding(DefaultParametersetName=&quot;Host&quot;)]
	param(
	[string]$DatastoreName = &quot;*&quot;,
	[DateTime]$Start,
	[DateTime]$Finish,
	[Parameter(ParameterSetName=&quot;Host&quot;)]
	[string]$HostName,
	[Parameter(ParameterSetName=&quot;Cluster&quot;)]
	[string]$ClusterName
	)

	process{
		$dsTab = @{}
		$report = @()
		$hugeSamplesNumber = 99999

		if($psCmdlet.ParameterSetName -eq &quot;Cluster&quot;){
			$esx = Get-Cluster -Name $ClusterName | Get-VMHost
		}
		else{
			$esx = Get-VMHost -Name $HostName
		}
		if(!$Finish){
			$Finish = Get-Date
		}
		if(!$Start){
			$Start = $Finish.AddDays(-1)
		}

		Get-Datastore -Name $DatastoreName -VMHost $esx | `
		  where{$_.Type -eq &quot;VMFS&quot; -and $_.Extensiondata.Summary.MultipleHostAccess} | %{
			$dsTab[$_.Extensiondata.Info.Vmfs.Uuid] = $_.Name
		}
		$metrics = &quot;datastore.sizeNormalizedDatastoreLatency.average&quot;,&quot;datastore.datastoreIops.average&quot;

		# Create the type to hold the info
		$DSsiocDef = &quot;public string Timestamp;`n&quot;
		$rndName = &quot;DSsioc&quot; + (Get-Random -Maximum 99999)
		$DSsiocDef = &quot;public struct &quot; + $rndName + &quot;{`n&quot; + $DSsiocDef
		$dsTab.GetEnumerator() | Sort-Object -Property Value | %{
			$DSsiocDef += (&quot;`n`tpublic bool &quot; + $_.Value + &quot;_alarm&quot; + &quot;;&quot;)
		}
		foreach($esxHost in $esx){
			$shortName = $esxHost.Name.Split('.')[0]
			$dsTab.GetEnumerator() | Sort-Object -Property Value | %{
				$DSsiocDef += (&quot;`n`tpublic long &quot; + $shortName + '_' + $_.Value + &quot;_latency&quot; + &quot;;&quot;)
				$DSsiocDef += (&quot;`n`tpublic long &quot; + $shortName + '_' + $_.Value + &quot;_iops&quot; + &quot;;&quot;)
			}
		}
		$DSsiocDef += &quot;`n}&quot;

		Add-Type -Language CsharpVersion3 -TypeDefinition $DSsiocDef

		$events = Get-VIEvent -Start $start -Finish $Finish -MaxSamples $hugeSamplesNumber | `
		  where {$_.GetType().Name -eq 'NonVIWorkloadDetectedOnDatastoreEvent'}
		$stats = Get-Stat -Entity $esx -Stat $metrics -Start $start -Finish $Finish -Instance @($dsTab.Keys)
		$groups = $stats | Sort-Object -Property Timestamp | Group-Object -Property Timestamp
		$groups | %{
			$row = New-Object $rndName
			$row.Timestamp = $_.Group[0].Timestamp
			$_.Group | %{
				$shortName = $_.Entity.Name.Split('.')[0]
				$property = $shortName + &quot;_&quot; + $dsTab[$_.Instance] + &quot;_&quot; + $_.MetricId.Split('.')[1]
				$property = $property.Replace('sizenormalizeddatastorelatency','latency')
				$property = $property.Replace('datastoreiops','iops')
				$row.$property = $_.Value
			}
			foreach($nonVIevent in $events){
				if($dsTab.Values -contains $nonVIevent.Datastore.Name -and `
				   $_.Group[0].Timestamp -le $nonVIevent.CreatedTime -and `
					 ($_.Group[0].Timestamp.AddSeconds($_.Group[0].IntervalSecs)) -gt $nonVIevent.CreatedTime){
					$property = $nonVIevent.Datastore.Name + &quot;_alarm&quot;
					$row.$property = $true
				}
			}
			$report += $row
		}
		$report
	}
}</pre><p></p>
<h4>Annotations</h4>
<p><strong>Line 49,51</strong>: The function has 2 parameter sets, one called Host and the other called Cluster. This avoids incorrect calls where you pass a Hostname and a Clustername</p>
<p><strong>Line 60-62</strong>: When the function is called with the Cluster parameter set, the script will get all the ESX(i) hosts that are present in the cluster.</p>
<p><strong>Line 66-71</strong>: The default start and/or finish for the interval are calculated when these values are not provided in the call to the function.</p>
<p><strong>Line 73-76</strong>: A hash table is created to translate the datastore UUID to a datastorename. This translation is needed because the Instance returned by the <a href="https://www.vmware.com/support/developer/PowerCLI/PowerCLI41U1/html/Get-Stat.html" target="_blank" rel="noopener noreferrer">Get-Stat</a> cmdlet uses the datastore UUID.</p>
<p><strong>Line 79-95</strong>: Define a custom object to hold all the data. Each datastore  will have the following properties: &lt;datastorename&gt;_alarm, &lt;hostname&gt;_&lt;datastorename&gt;_latecy and &lt;hostname&gt;_&lt;datastorename&gt;_iops. Notice that the script adds a random number to the name of the new object to avoid errors on multiple runs of the script. There is currently no way that I know of to remove a type that was created by Add-Type besides stopping/starting the PowerShell session.</p>
<p><strong>Line 97-98</strong>: Collects all the non-VI-workload events for the interval.</p>
<p><strong>Line 99-100</strong>: Collects all the statistical data for the SIOC-related metrics.</p>
<p><strong>Line 101-118</strong>: Creates and populates an object for each interval that was returned by the Get-Stat cmdlet.</p>
<p><strong>Line 121</strong>: The function returns an array with customised objects.</p>
<h2>Sample runs</h2>
<p>As I already mentioned the function has two parameter sets.</p>
<p>The &#8216;<strong>Host</strong>&#8216; parameter set can be used like this</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">$esxName = &quot;esx41.test.local&quot;
$start = [DateTime]&quot;1/23/2011 14:00&quot;
$finish = $start.AddHours(2)
Get-SiocStat -HostName $esxName -Start $start -Finish $finish | `
Export-Csv &quot;C:\sioc-report.csv&quot; -NoTypeInformation -UseCulture</pre><p></p>
<p>This will produce a CSV file that looks something like this</p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/SIOC-host.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2945" title="SIOC-host" src="https://lucd.info/wp-content/uploads/2011/01/SIOC-host.png" alt="" width="1034" height="104" srcset="https://www.lucd.info/wp-content/uploads/2011/01/SIOC-host.png 1477w, https://www.lucd.info/wp-content/uploads/2011/01/SIOC-host-300x30.png 300w, https://www.lucd.info/wp-content/uploads/2011/01/SIOC-host-1024x102.png 1024w" sizes="auto, (max-width: 1034px) 100vw, 1034px" /></a></p>
<p>You can see that the host has 4 datastores. Needless to say that a report on latency and IOPS over 30 minute intervals is of no real use for looking at SIOC.</p>
<p>The &#8216;<strong>Cluster</strong>&#8216; parameter set will include by default performance data for all datastores for each node in the cluster.</p>
<p>Watch out, this can produce huge CSV file. For example a 5-node cluster with 8 shared datastores will produce a CSV file with 89 columns.  When you use the Cluster parameter set it is advised to look at 1 or more specific datastores. This can be done like this.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">$clusterName = &quot;CLUS1&quot;
$dsName = &quot;ds1&quot;

$start = (Get-Date).AddHours(-1)
Get-SiocStat -ClusterName $clusterName -DatastoreName $dsName -Start $start | `
Export-Csv &quot;C:\ds1-sioc-report.csv&quot; -NoTypeInformation -UseCulture</pre><p></p>
<p>This produces a report like that will look something like this. The sample comes from a 3-node cluster.</p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/SIOC-cluster.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2946" title="SIOC-cluster" src="https://lucd.info/wp-content/uploads/2011/01/SIOC-cluster.png" alt="" width="695" height="280" srcset="https://www.lucd.info/wp-content/uploads/2011/01/SIOC-cluster.png 993w, https://www.lucd.info/wp-content/uploads/2011/01/SIOC-cluster-300x120.png 300w" sizes="auto, (max-width: 695px) 100vw, 695px" /></a></p>
<h2>Interpretation of the data</h2>
<p>Now that I had an easy way to produce these reports I decided to do some testing.</p>
<p>To force some non-VI workload I started a VCB backup for a guest.</p>
<p>As expected this produced the Alarm for the non-VI workload. But I&#8217;m somewhat confused by the data I see in the report.</p>
<p>The VCB backup released the disk lease at 21:24:01.</p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/SIOC-VCB-job.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2947" title="SIOC-VCB-job" src="https://lucd.info/wp-content/uploads/2011/01/SIOC-VCB-job.png" alt="" width="1017" height="63" srcset="https://www.lucd.info/wp-content/uploads/2011/01/SIOC-VCB-job.png 1017w, https://www.lucd.info/wp-content/uploads/2011/01/SIOC-VCB-job-300x18.png 300w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /></a></p>
<p>In the report that I produced with the Get-SiocStat function, I see the Alarm being fired nearly 1 minute later. I could understand that SIOC uses a safety margin to decide if the latency decreased after SIOC throttled the storage queue depth.</p>
<p>But I don&#8217;t understand why I see an enormous increase in latency after the VCB disk lease is released.</p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/SIOC-perfdata.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2948" title="SIOC-perfdata" src="https://lucd.info/wp-content/uploads/2011/01/SIOC-perfdata.png" alt="" width="977" height="349" srcset="https://www.lucd.info/wp-content/uploads/2011/01/SIOC-perfdata.png 1396w, https://www.lucd.info/wp-content/uploads/2011/01/SIOC-perfdata-300x107.png 300w, https://www.lucd.info/wp-content/uploads/2011/01/SIOC-perfdata-1024x365.png 1024w" sizes="auto, (max-width: 977px) 100vw, 977px" /></a></p>
<p>And it&#8217;s not the Get-SiocStat function that makes an error, because the performance graphs for the datastore in the vSphere client seem to indicate the same thing.</p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/VC-iops.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2949" title="VC-iops" src="https://lucd.info/wp-content/uploads/2011/01/VC-iops.png" alt="" width="506" height="311" srcset="https://www.lucd.info/wp-content/uploads/2011/01/VC-iops.png 506w, https://www.lucd.info/wp-content/uploads/2011/01/VC-iops-300x184.png 300w" sizes="auto, (max-width: 506px) 100vw, 506px" /></a></p>
<p><a href="https://lucd.info/wp-content/uploads/2011/01/VC-latency.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2950" title="VC-latency" src="https://lucd.info/wp-content/uploads/2011/01/VC-latency.png" alt="" width="497" height="312" srcset="https://www.lucd.info/wp-content/uploads/2011/01/VC-latency.png 497w, https://www.lucd.info/wp-content/uploads/2011/01/VC-latency-300x188.png 300w" sizes="auto, (max-width: 497px) 100vw, 497px" /></a></p>
<p>Can anyone shed some light on what I see here ?</p>
<p>On a side note, I think it would be useful if SIOC provided a bit more information about what it is doing. Just an Alarm is a bit sparse. A metric that returns the <strong>queue depth</strong> would be a good start.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.lucd.info/2011/01/24/sioc-statistics/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Automate SIOC</title>
		<link>https://www.lucd.info/2010/10/20/automate-sioc/</link>
					<comments>https://www.lucd.info/2010/10/20/automate-sioc/#comments</comments>
		
		<dc:creator><![CDATA[LucD]]></dc:creator>
		<pubDate>Wed, 20 Oct 2010 16:37:19 +0000</pubDate>
				<category><![CDATA[datastore]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SIOC]]></category>
		<category><![CDATA[vSphere]]></category>
		<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[SDK]]></category>
		<guid isPermaLink="false">http://www.lucd.info/?p=2721</guid>

					<description><![CDATA[With vSphere 4.1 came 150+ new features. One of these is called Storage [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>With vSphere 4.1 came 150+ new features. One of these is called Storage IO Control or SIOC.And it has been a very popular subject in the last weeks. Just a small selection of blog posts on the subject:</p>
<ul>
<li><a href="http://blog.vkernel.com/2010/09/what-to-expect-when-you-enable-storage.html" target="_blank" rel="noopener noreferrer">What to Expect When You Enable Storage I/O Controls in ESX 4.1</a> by Alex Bakman</li>
<li><a href="http://www.yellow-bricks.com/2010/09/29/storage-io-fairness/">Storage I/O Fairness</a>, <a href="http://www.yellow-bricks.com/2010/10/08/sioc-tying-up-some-loose-ends/" target="_blank" rel="noopener noreferrer">SIOC, tying up some loose ends</a> and <a href="http://www.yellow-bricks.com/2010/10/19/storage-io-control-best-practices/" target="_blank" rel="noopener noreferrer">Storage IO Control Best Practices</a> all by Duncan Epping</li>
</ul>
<p>The only thing missing was a way to automate everything surrounding SIOC. And so I decided to write a couple of functions to fill that gap.</p>
<h2><span id="more-2721"></span>The script</h2>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">#requires -pssnapin VMware.VimAutomation.Core -version 4.1
function Get-Sioc{
&lt;#
.SYNOPSIS
	Get the Storage IO Control settings for a host or a datastore
.DESCRIPTION
	When called against a VMHost, the cmdlet will return the SIOC
	settings on the host
	When called against a Datastore, the cmdlet will return the SIOC
	settings for all hosts on which the datastore is accessible
.NOTES
	Authors:      Luc Dekens
.PARAMETER VMHost
	On or more hosts
.PARAMETER Datastore
	On or more datastores
.EXAMPLE
	PS&gt; Get-Sioc -VMHost (Get-VMHost)
.EXAMPLE
	PS&gt; Get-VMHost -Name &quot;esx41&quot; | Get-Sioc
.EXAMPLE
	PS&gt; Get-Sioc -Datastore (Get-Datastore)
.EXAMPLE
	PS&gt; Get-Datastore -Name &quot;DS1&quot; | Get-Sioc
#&gt;
	param(
		[parameter(ParameterSetName = &quot;VMHost&quot;,
			valuefrompipeline = $true,position = 0,
			HelpMessage = &quot;Enter a host&quot;)]
			[VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost,
		[parameter(ParameterSetName = &quot;Datastore&quot;,
			valuefrompipeline = $true, position = 0,
			HelpMessage = &quot;Enter a datastore&quot;)]
			[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl[]]$Datastore
	)
	begin{
		switch($PsCmdlet.ParameterSetName){
			&quot;VMHost&quot;{
				$si = Get-View ServiceInstance
			}
			&quot;Datastore&quot;{}
		}
	}
	process{
		switch($PsCmdlet.ParameterSetName){
			&quot;VMHost&quot;{
				$VMHost | %{
					$result = $si.Client.VimService.QueryIORMConfigOption(
						[VMWare.Vim.VIConvert]::ToVim41($si.Content.StorageResourceManager),
						[VMWare.Vim.VIConvert]::ToVim41( $_.Extensiondata.MoRef))
					$row = &quot;&quot; | Select Name,SIOCSupported,SIOCStateDefault,
										SIOCThresholdMinimum,SIOCThresholdMaximum,SIOCThresholdDefault
					$row.Name = $_.Name
					$row.SIOCSupported = $result.enabledOption.supported
					$row.SIOCStateDefault = $result.enabledOption.defaultValue
					$row.SIOCThresholdMinimum = $result.congestionThresholdOption.min
					$row.SIOCThresholdMaximum = $result.congestionThresholdOption.max
					$row.SIOCThresholdDefault = $result.congestionThresholdOption.defaultValue
					$row
				}
			}
			&quot;Datastore&quot;{
				$Datastore | %{
					$row = &quot;&quot; | Select Name,SIOCEnabled,SIOCThreshold
					$row.Name = $_.Name
					$row.SIOCEnabled = $_.Extensiondata.iormConfiguration.enabled
					$row.SIOCThreshold = $_.Extensiondata.iormConfiguration.congestionThreshold
					$row
				}
			}
		}
	}
}

function Set-Sioc{
&lt;#
.SYNOPSIS
	Enables/disables Storage IO Control for a a datastore
.DESCRIPTION
	The function enables or disables SIOC for a datastore.
.NOTES
	Authors:      Luc Dekens
.PARAMETER Datastore
	On or more datastores
.PARAMETER Enabled
	A switch that defines if SIOC will be enabled or disabled
.PARAMETER Threshold
	Specify the threshold
.EXAMPLE
	PS&gt; Set-Sioc -Datastore (Get-Datastore -Name &quot;DS1&quot;) -Enabled:$true
.EXAMPLE
	PS&gt; Get-Datastore | Set-SIOC -Enabled:$true -Threshold 30
.EXAMPLE
	PS&gt; Get-Datastore | Set-SIOC -Enabled:$false
#&gt;
	param(
		[parameter(
		valuefrompipeline = $true,position = 0,
		HelpMessage = &quot;Enter a datastore&quot;)]
		[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl[]]$Datastore,
		[switch]$Enabled,
		[int]$Threshold = 30
	)
	begin{
	$si = Get-View ServiceInstance
	$spec = New-Object VMware.Vim.StorageIORMConfigSpec
	$spec.congestionThreshold = $Threshold
	$spec.enabled = $Enabled
	}

	process{
		$Datastore | %{
			$taskMoRef = $si.Client.VimService.ConfigureDatastoreIORM_Task(
				[VMWare.Vim.VIConvert]::ToVim41($si.Content.StorageResourceManager),
				[VMWare.Vim.VIConvert]::ToVim41($_.Extensiondata.MoRef),
				[VMWare.Vim.VIConvert]::ToVim41($spec))
			$task = Get-View ([VMWare.Vim.VIConvert]::ToVim($taskMoRef))
			while (&quot;running&quot;,&quot;queued&quot; -contains $task.Info.State){
				$task.UpdateViewData(&quot;Info.State&quot;)
			}
		}
	}
}</pre><p></p>
<h4>Annotations</h4>
<p><strong>Line 27-34</strong>: Since you have SIOC settings on a Datastore and on a VMHost, I use 2 parameter sets.</p>
<p><strong>Line 37</strong>: Via the $PsCmdlet.ParameterSetName the script can find out with which parameter set the function was called.</p>
<p><strong>Line 39</strong>: When the function was called with the <strong>VMHost</strong> parameter set, we need the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ServiceInstance.html" target="_blank" rel="noopener noreferrer">ServiceInstance</a> object to get to the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.StorageResourceManager.html" target="_blank" rel="noopener noreferrer">StorageResourceManager</a>.</p>
<p><strong>Line 48-50</strong>: The <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.StorageResourceManager.html" target="_blank" rel="noopener noreferrer">StorageResourceManager</a> object is not included in the <strong>PowerCLI 4.1</strong> framework. The script uses the method, I also used in <a href="https://www.lucd.info/2010/07/25/script-vsphere-4-1-ad-authentication/" target="_blank" rel="noopener noreferrer">Script vSphere 4.1 AD Authentication</a> to get to the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.StorageResourceManager.html" target="_blank" rel="noopener noreferrer">StorageResourceManager</a> object and use the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.StorageResourceManager.html#QueryIORMConfigOption" target="_blank" rel="noopener noreferrer">QueryIORMConfigOption</a> method. Thanks again to <strong>Yasen</strong> for providing us with this method.</p>
<p><strong>Line 62</strong>: If the function is called with the Datastore parameter set, the SIOC properties can be found in the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.StorageResourceManager.IORMConfigInfo.html" target="_blank" rel="noopener noreferrer">StorageIORMInfo</a> object.</p>
<p><strong>Line 102</strong>: Notice that the script uses a default threshold of 30 ms, which is apparently the default except for SSD storage.</p>
<p><strong>Line 113-116</strong>: Again, to call the <a href="https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.StorageResourceManager.html#ConfigureDatastoreIORM" target="_blank" rel="noopener noreferrer">ConfigureDatastoreIORM_Task</a> method, the script uses the method provided by Yasen.</p>
<h2>Samples</h2>
<p>The Get-SIOC function can be used with two parameter sets. First the VMHost parameter set will retrieve the SIOC settings on a specific host.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-SIOC (Get-VMHost esx41)</pre><p></p>
<p>This will return the SIOC settings for that specific host. Your output will look something like this.</p>
<p><a href="https://lucd.info/wp-content/uploads/2010/10/Get-SIOC-1.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2724" title="Get-SIOC-1" src="https://lucd.info/wp-content/uploads/2010/10/Get-SIOC-1.png" alt="" width="329" height="68" srcset="https://www.lucd.info/wp-content/uploads/2010/10/Get-SIOC-1.png 411w, https://www.lucd.info/wp-content/uploads/2010/10/Get-SIOC-1-300x62.png 300w" sizes="auto, (max-width: 329px) 100vw, 329px" /></a></p>
<p>You can of course use the Get-SIOC function a pipeline as well.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-VMHost | Get-SIOC | ft -Autosize</pre><p></p>
<p>This will give a nice tabular overview<br />
<a href="https://lucd.info/wp-content/uploads/2010/10/Get-SIOC-2.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2725" title="Get-SIOC-2" src="https://lucd.info/wp-content/uploads/2010/10/Get-SIOC-2.png" alt="" width="810" height="80" srcset="https://www.lucd.info/wp-content/uploads/2010/10/Get-SIOC-2.png 1012w, https://www.lucd.info/wp-content/uploads/2010/10/Get-SIOC-2-300x29.png 300w" sizes="auto, (max-width: 810px) 100vw, 810px" /></a></p>
<p>With the Datastore parameter set you get the SIOC settings for a specific datastore</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-SIOC -Datastore DS1</pre><p></p>
<p>And again this can be used in a pipeline</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-Datastore | Get-SIOC</pre><p></p>
<p><a href="https://lucd.info/wp-content/uploads/2010/10/Get-SIOC-3.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2726" title="Get-SIOC-3" src="https://lucd.info/wp-content/uploads/2010/10/Get-SIOC-3.png" alt="" width="250" height="68" srcset="https://www.lucd.info/wp-content/uploads/2010/10/Get-SIOC-3.png 313w, https://www.lucd.info/wp-content/uploads/2010/10/Get-SIOC-3-300x81.png 300w" sizes="auto, (max-width: 250px) 100vw, 250px" /></a></p>
<p>To change your SIOC settings on a datastore you can do</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Set-SIOC  -Datastore (Get-Datastore DS1) -Enabled:$true -Threshold 30</pre><p></p>
<p>Or in a pipeline</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-Datastore -Name &quot;DS*&quot; | Set-SIOC -Enabled:$true -Threshold 30</pre><p></p>
<p>Notice that the Set-SIOC function doesn&#8217;t return anything !</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.lucd.info/2010/10/20/automate-sioc/feed/</wfw:commentRss>
			<slash:comments>31</slash:comments>
		
		
			</item>
	</channel>
</rss>
