docs: def get_datastores(service_instance, reference, datastore_names=None,
                     backing_disk_ids=None, get_all_datastores=False):
      '''
      Returns a list of vim.Datastore objects representing the datastores visible
      from a VMware object, filtered by their names, or the backing disk
      cannonical name or scsi_addresses
  
      service_instance
          The Service Instance Object from which to obtain datastores.
  
      reference
          The VMware object from which the datastores are visible.
  
      datastore_names
          The list of datastore names to be retrieved. Default value is None.
  
      backing_disk_ids
          The list of canonical names of the disks backing the datastores
          to be retrieved. Only supported if reference is a vim.HostSystem.
          Default value is None
  
      get_all_datastores
          Specifies whether to retrieve all disks in the host.
          Default value is False.
      '''
      obj_name = get_managed_object_name(reference)
      if get_all_datastores:
          log.trace('Retrieving all datastores visible to \'%s\'', obj_name)
      else:
          log.trace('Retrieving datastores visible to \'%s\': names = (%s); '
                    'backing disk ids = (%s)',
                    obj_name, datastore_names, backing_disk_ids)
          if backing_disk_ids and not isinstance(reference, vim.HostSystem):
  
              raise salt.exceptions.ArgumentValueError(
                  'Unsupported reference type \'{0}\' when backing disk filter '
                  'is set'.format(reference.__class__.__name__))
      if (not get_all_datastores) and backing_disk_ids:
          # At this point we know the reference is a vim.HostSystem
          log.trace('Filtering datastores with backing disk ids: %s',
                    backing_disk_ids)
          storage_system = get_storage_system(service_instance, reference,
                                              obj_name)
          props = salt.utils.vmware.get_properties_of_managed_object(
              storage_system, ['fileSystemVolumeInfo.mountInfo'])
          mount_infos = props.get('fileSystemVolumeInfo.mountInfo', [])
          disk_datastores = []
          # Non vmfs volumes aren't backed by a disk
          for vol in [i.volume for i in mount_infos if
                      isinstance(i.volume, vim.HostVmfsVolume)]:
  
              if not [e for e in vol.extent if e.diskName in backing_disk_ids]:
                  # Skip volume if it doesn't contain an extent with a
                  # canonical name of interest
                  continue
              log.trace('Found datastore \'%s\' for disk id(s) \'%s\'',
                        vol.name, [e.diskName for e in vol.extent])
              disk_datastores.append(vol.name)
          log.trace('Datastore found for disk filter: %s', disk_datastores)
          if datastore_names:
              datastore_names.extend(disk_datastores)
          else:
              datastore_names = disk_datastores
  
      if (not get_all_datastores) and (not datastore_names):
          log.trace('No datastore to be filtered after retrieving the datastores '
                    'backed by the disk id(s) \'%s\'', backing_disk_ids)
          return []
  
      log.trace('datastore_names = %s', datastore_names)
  
      # Use the default traversal spec
      if isinstance(reference, vim.HostSystem):
          # Create a different traversal spec for hosts because it looks like the
          # default doesn't retrieve the datastores
          traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
              name='host_datastore_traversal',
              path='datastore',
              skip=False,
              type=vim.HostSystem)
      elif isinstance(reference, vim.ClusterComputeResource):
          # Traversal spec for clusters
          traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
              name='cluster_datastore_traversal',
              path='datastore',
              skip=False,
              type=vim.ClusterComputeResource)
      elif isinstance(reference, vim.Datacenter):
          # Traversal spec for datacenter
          traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
              name='datacenter_datastore_traversal',
              path='datastore',
              skip=False,
              type=vim.Datacenter)
      elif isinstance(reference, vim.StoragePod):
          # Traversal spec for datastore clusters
          traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
              name='datastore_cluster_traversal',
              path='childEntity',
              skip=False,
              type=vim.StoragePod)
      elif isinstance(reference, vim.Folder) and \
              get_managed_object_name(reference) == 'Datacenters':
          # Traversal of root folder (doesn't support multiple levels of Folders)
          traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
              path='childEntity',
              selectSet=[
                  vmodl.query.PropertyCollector.TraversalSpec(
                      path='datastore',
                      skip=False,
                      type=vim.Datacenter)],
              skip=False,
              type=vim.Folder)
      else:
          raise salt.exceptions.ArgumentValueError(
              'Unsupported reference type \'{0}\''
              ''.format(reference.__class__.__name__))
  
      items = get_mors_with_properties(service_instance,
                                       object_type=vim.Datastore,
                                       property_list=['name'],
                                       container_ref=reference,
                                       traversal_spec=traversal_spec)
      log.trace('Retrieved %s datastores', len(items))
      items = [i for i in items if get_all_datastores or i['name'] in
               datastore_names]
      log.trace('Filtered datastores: %s', [i['name'] for i in items])
      return [i['object'] for i in items]