VMware {code} Community
ldg0x21
Contributor
Contributor
Jump to solution

identify VM's running on local storage

I'm trying to identify vm's that are on local drives on specific esx hosts, but can't seem to find the correct combination or references that map them.  I'm willing to use any means available to aid in identifiening them, console, vcli linux commands etc.  Any help or pointers appriciated.

thanks

0 Kudos
1 Solution

Accepted Solutions
stumpr
Virtuoso
Virtuoso
Jump to solution

Right now I don't think there is a way to get the BIOS boot drive setting with the SDK.  The other issue is do you want the Boot Disk or the OS Partition/Disk?  For the OS Partition/Disk, you will have to query the GuestOS through VIX or other interface and then correlate that to the SCSI Disk Device in your Virtual Inventory.

If you just need the boot drive, you can make the assumption that it is SCSI 0:0.  This would only be changed by manual user intervention through the VM BIOS (F2 at startup).  While this assumption isn't guaranteed, it's likely to be accurate most of time.  I vaguely recall some talk around adding features to control the device boot order of the VM's BIOS through automation.  If this gets added it would be possible to detect and modify the boot order through a script or program.

Something like the following would let you determine the device node and vmdk file location:


use strict;
use warnings;
use VMware::VIRuntime;
Opts::parse();
Opts::validate();
Util::connect();
my $vm_views = Vim::find_entity_views( view_type => "VirtualMachine",
     properties => [ 'name', 'config.hardware.device' ] );
foreach my $vm ( @{$vm_views} ) {
     my $vmname = $vm->name;
     my $vm_devices = $vm->{'config.hardware.device'};
     foreach my $vm_disk ( grep $_->isa('VirtualDisk'), @{$vm_devices} ) {
          my $controller_key = eval { $vm_disk->controllerKey };
          my $unit_number = eval { $vm_disk->unitNumber };
          my $controller_bus_number = get_controller_bus_number( controller_key => $controller_key,
                              vm_devices => $vm_devices );
          my $vm_disk_file_name = eval { $vm_disk->backing->fileName };
          my $vm_disk_label = eval { $vm_disk->deviceInfo->label };
          my $vm_device_node = sprintf("SCSI (%s:%s) %s", $controller_bus_number,
                              $unit_number, $vm_disk_label );
          printf("%s: %s, %s\n", $vmname, $vm_device_node, $vm_disk_file_name);
     }
}
sub get_controller_bus_number {
     my (%args) = @_;
     my $controller_key = delete($args{controller_key});
     my $vm_devices = delete($args{vm_devices});
     my @controllers = grep $_->key eq $controller_key, @{$vm_devices};
     # Should only be one controller since it is a key value in the VI SDK
     my $bus_number = eval { $controllers[0]->busNumber };
     return $bus_number;
}

perl vm-scsinode.pl --username=administrator  --server=172.16.110.10
Test: SCSI (0:0) Hard disk 1, [datastore1] Test/Test.vmdk
Test: SCSI (1:0) Hard disk 2, [datastore1] Test/Test_1.vmdk

In my test output, I'd make the assumption that Hard disk 1 is the boot disk based on the SCSI Bus and Logical Unit (0:0).  If you had to correlate that back to the GuestOS's view of the disks, it would be the same SCSI Bus and Logical Unit values. 

You'll notice this basically recreates the same string you'd see in "Edit Settings" on a VM when looking at its disk labels through vCenter's UI.

Reuben Stump | http://www.virtuin.com | @ReubenStump

View solution in original post

0 Kudos
11 Replies
lamw
Community Manager
Community Manager
Jump to solution

There are a number of ways to accomplish this, what tool/CLI are you trying to utilize?

0 Kudos
ldg0x21
Contributor
Contributor
Jump to solution

I've been all over the board with this.

apps vicfg-scsidevs -m  (Is nice, however)

vmhba1:0:11:1   /vmfs/devices/disks/vml.02000b00006006016013321c0096d2decb790ce011524149442035:1   4d10093a-fa211bd4-3a31-00145ea7f15e   0  FC_VMFS_11
vmhba3:0:0:1    /vmfs/devices/disks/vml.02000000005000cca0002d66c4434252424130:1                   4d114c9f-84e8d33a-c95d-00145ea7f15e   0  Local_esx03a
vmhba1:0:10:1   /vmfs/devices/disks/vml.02000a00006006016013321c0090d2decb790ce011524149442035:1   4d10092a-8f658011-a4d4-00145ea7f15e   0  FC_VMFS_10
vmhba1:1:0:6    /vmfs/devices/disks/vml.02000000006006016013321c0096bb44c1c4ebdf11524149442035:6   4d10091d-0d4d2b17-ebc6-00145ea7f15e   0  Boot_esx03a

output of :

   vmhbaA:B:C:D

       A-Adapter#

       B-Lun

       C-Disk

       D-Part

Doesn't line up with much

cat /proc/scsi/scsi

[root@esx03a scsi]# cat scsi
Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: IBM-ESXS Model: CBRBA073C3ETS0 N Rev: C331
  Type:   Direct-Access                    ANSI SCSI revision: 05

*Can't match that

--- I know this is my device from dmesg ----- but I really need to relate it to the vicfg-devs

   * Named local to help find..

vmhba3:0:0:1    /vmfs/devices/disks/vml.02000000005000cca0002d66c4434252424130:1                   4d114c9f-84e8d33a-c95d-00145ea7f15e   0  Local_esx03a

*From dmesg

VMWARE: Unique Device attached as scsi disk sda at scsi1, channel 0, id 0, lun 0
Attached scsi disk sda at scsi1, channel 0, id 0, lun 0
SCSI device sda: 143374000 512-byte hdwr sectors (73407 MB)

* I can match that to the /rpoc/scsi/scsi but no relation (from what I see to the vicfg-devs

The end result I was hoping to achieve ....

If I take the vicfg-devs /id   and look under it's volumes, I find my vm's

ls -tlr /vmfs/volumes/4d114c9f-84e8d33a-c95d-00145ea7f15e

[root@esx03a 4d114c9f-84e8d33a-c95d-00145ea7f15e]# ls -tlr
total 320
drwxr-xr-x    1 root     root         1820 Feb 16 13:07 ld-03a-xp03f
drwxr-xr-x    1 root     root         1260 Mar  6 16:55 test_vm_1
drwxr-xr-x    1 root     root         2520 Mar  6 18:50 another_local_vm
drwxr-xr-x    1 root     root          420 Mar  6 19:08 test_vm_2
drwxr-xr-x    1 root     root         2520 Mar  7 16:11 unbuntu_10

maybe I'm over complicating this, or just missing the connection.

Thanks

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

There's actually a simple flag you can use to quickly assess if a Datastore is local (or more specifically if it is only seen by one host, which ultimately is the same issue in terms of your environment's health).

The boolean property multipleHostAccess in Datastore.Summary: http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datastore.Summary.html

A simple perl SDK script would be something like the following:

use strict;
use warnings;
use VMware::VIRuntime;
Opts::parse();
Opts::validate();
Util::connect();
my $datastore_views = Vim::find_entity_views( view_type => "Datastore",
     filter => { 'summary.multipleHostAccess' => 'false' },
     properties => [ 'vm', 'summary' ] );
foreach my $datastore ( @{$datastore_views} ) {
     foreach my $entity_ref ( eval { @{$datastore->vm} } ) {
          my $vm_view = Vim::get_view( mo_ref => $entity_ref, properties => [ 'name' ] );
          printf("%s, %s\n", $vm_view->name, $datastore->summary->name);
     }
}

I didn't test this, so let me know if there are any errors.

In your case of going by specific host, you could create a script to find a HostSystem by name, then get the Datastore objects connected to it, check the multipleHostAccess flag and print out any VMs that are on Datastore objects that don't have multiple hosts connected.

The example above will inspect all Datastore objects in your vSphere inventory and may be enough to accomplish your task.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
ldg0x21
Contributor
Contributor
Jump to solution

GREAT! Thanks I'll give it a go and get back to you asap.

0 Kudos
ldg0x21
Contributor
Contributor
Jump to solution

Thank you very much!! , made a few changes but working great so far !!!  You can close this unless of course you have another trick to identify the "boot" disk uuid, so I can further limit the output.

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Do you mean the VM UUID or the UUID that the GuestOS assigns to the disk?

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
ldg0x21
Contributor
Contributor
Jump to solution

Of the disk..

For instance:  I now get back

Boot_esx03d sanfs://vmfs_uuid:4d100997-16f1d4cc-20aa-00145ea7f14a/
  local-03d-xp03e-flat.vmdk

   ..

   ...

Local_esx03b sanfs://vmfs_uuid:4d114cb4-b5b5bac2-eee0-00145ea7f15a/
  ld-03b-xp03g.vmdk

  ..

  ..

Without Naming them "Boot_" & "Local_" I need to know which is actual  Boot.

Thanks again

0 Kudos
ldg0x21
Contributor
Contributor
Jump to solution

I should have pointed out that was from the ref

DB<3> x $_->summary
0  DatastoreSummary=HASH(0x9afa1b0)
   'accessible' => 1
   'capacity' => 12884901888
   'datastore' => ManagedObjectReference=HASH(0x9b050a8)
      'type' => 'Datastore'
      'value' => 'datastore-81'
   'freeSpace' => 7937720320
   'multipleHostAccess' => 0
   'name' => 'Boot_esx03d'
   'type' => 'VMFS'
   'url' => 'sanfs://vmfs_uuid:4d100997-16f1d4cc-20aa-00145ea7f14a/'

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Right now I don't think there is a way to get the BIOS boot drive setting with the SDK.  The other issue is do you want the Boot Disk or the OS Partition/Disk?  For the OS Partition/Disk, you will have to query the GuestOS through VIX or other interface and then correlate that to the SCSI Disk Device in your Virtual Inventory.

If you just need the boot drive, you can make the assumption that it is SCSI 0:0.  This would only be changed by manual user intervention through the VM BIOS (F2 at startup).  While this assumption isn't guaranteed, it's likely to be accurate most of time.  I vaguely recall some talk around adding features to control the device boot order of the VM's BIOS through automation.  If this gets added it would be possible to detect and modify the boot order through a script or program.

Something like the following would let you determine the device node and vmdk file location:


use strict;
use warnings;
use VMware::VIRuntime;
Opts::parse();
Opts::validate();
Util::connect();
my $vm_views = Vim::find_entity_views( view_type => "VirtualMachine",
     properties => [ 'name', 'config.hardware.device' ] );
foreach my $vm ( @{$vm_views} ) {
     my $vmname = $vm->name;
     my $vm_devices = $vm->{'config.hardware.device'};
     foreach my $vm_disk ( grep $_->isa('VirtualDisk'), @{$vm_devices} ) {
          my $controller_key = eval { $vm_disk->controllerKey };
          my $unit_number = eval { $vm_disk->unitNumber };
          my $controller_bus_number = get_controller_bus_number( controller_key => $controller_key,
                              vm_devices => $vm_devices );
          my $vm_disk_file_name = eval { $vm_disk->backing->fileName };
          my $vm_disk_label = eval { $vm_disk->deviceInfo->label };
          my $vm_device_node = sprintf("SCSI (%s:%s) %s", $controller_bus_number,
                              $unit_number, $vm_disk_label );
          printf("%s: %s, %s\n", $vmname, $vm_device_node, $vm_disk_file_name);
     }
}
sub get_controller_bus_number {
     my (%args) = @_;
     my $controller_key = delete($args{controller_key});
     my $vm_devices = delete($args{vm_devices});
     my @controllers = grep $_->key eq $controller_key, @{$vm_devices};
     # Should only be one controller since it is a key value in the VI SDK
     my $bus_number = eval { $controllers[0]->busNumber };
     return $bus_number;
}

perl vm-scsinode.pl --username=administrator  --server=172.16.110.10
Test: SCSI (0:0) Hard disk 1, [datastore1] Test/Test.vmdk
Test: SCSI (1:0) Hard disk 2, [datastore1] Test/Test_1.vmdk

In my test output, I'd make the assumption that Hard disk 1 is the boot disk based on the SCSI Bus and Logical Unit (0:0).  If you had to correlate that back to the GuestOS's view of the disks, it would be the same SCSI Bus and Logical Unit values. 

You'll notice this basically recreates the same string you'd see in "Edit Settings" on a VM when looking at its disk labels through vCenter's UI.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
ldg0x21
Contributor
Contributor
Jump to solution

Thank you ! this is perfect....

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Glad to help!  I do recall someone posting that those SCSI Bus:LU numbers don't always consistently match inside the GuestOS.  If that's the case and you need to correlate the GuestOS disk to VMDK in some way, then you'll likely need to get the Disk UUID value and compare between what the GuestOS sees and the VI SDK provides.

Reuben Stump | http://www.virtuin.com | @ReubenStump