VMware {code} Community
blackcomb84
Contributor
Contributor

VixDiskLib_Shrink does not reclaim any zero blocks

I use the VDDK library(version 6.7) API VixDiskLib_Write() to write zeros to the unused blocks of a vmdk (a thin provisioned disk). Then issue VixDiskLib_Shrink() to reclaim the blocks which has only zero's, the call returns immediately with success but no blocks are reclaimed. The VM is in shutdown state during the whole process.

But, if I use the command vmkfstools --punchzero <vmdk path> (the same vmdk where VixDiskLib_Shrink() did not reclaim), the blocks with zeros are reclaimed and only non-zero blocks are consumed.

Isn't VixDiskLib_Shrink() supposed to work the same as --punchzero?

0 Kudos
11 Replies
bluefirestorm
Champion
Champion

From the documentation

https://developer.vmware.com/docs/14686/virtual-disk-development-kit-programming-guide--7-0-3--/GUID...


In the API, use VixDiskLib_Write() to zero out unused blocks, and VixDiskLib_Shrink() to reclaim space.

 


 

 

0 Kudos
blackcomb84
Contributor
Contributor

Yes, the API documentation do say that. But I did not see the desired result.

0 Kudos
bluefirestorm
Champion
Champion

Somehow the first paragraph in your first post didn't enter my brain. Sorry about that.

It is possible that
(1) the write of zeroes through API is not working properly
(2) something wrong with the shrink call
(3) both (1) or (2)

I suppose the way you are testing this is create a large file in a sparse disk (e.g. create 2GB file in an 8GB sparse VMDK and then delete the 2GB file).

To test for (1)
You could create a large file with a fixed hexadecimal recognisable pattern (such as 0xDEADBEEF) and delete that file. After you done with the write of zeroes through API, check to see whether that obvious pattern still exists in the VMDK with a hexadecimal dump

To test for (2)
You create a large file with all zeroes (such using dd input from /dev/zero) and delete that file (to mimic the punching of zeroes) and see whether the shrink API call works.

Did you try to close the virtual disk set after the writing of zeroes (to flush it to storage) and then re-open to shrink?

 

0 Kudos
blackcomb84
Contributor
Contributor

Thanks for your response!

Here's what I have tried now but still unsuccessful,

  1. Filled the entire disk(a 4GB VMDK) with zeros. From within the guest OS, did "dd if=/dev/zero of=/dev/sdd bs=1048576 count=4096"
  2. Shutdown the VM and verified the disk has only zeros.

 

# du -sh ubun-vm1-restore_2-flat.vmdk
4.0G ubun-vm1-restore_2-flat.vmdk

# od -x ubun-vm1-restore_2-flat.vmdk
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
40000000000

 

  1. Used the shrink API call to reclaim the blocks, ideally when shrink API returns all the blocks should have been reclaimed and usage should be 0. But it still shows 4GB used,

 

# du -sh ubun-vm1-restore_2-flat.vmdk
4.0G ubun-vm1-restore_2-flat.vmdk

 

The API call sequence used,

 

1. VixDiskLib_ConnectEx()
2. VixDiskLib_Open() with flags 0. Tried using flag VIXDISKLIB_FLAG_OPEN_SINGLE_LINK as well.
3. VixDiskLib_Shrink(vDiskHandle, shrinkProgressFunc, NULL) -> Call returned success
4. VixDiskLib_Close()
5. VixDiskLib_Disconnect()

 

 

Snippet from vixDiskLib.log,

 

2022-01-07T07:44:59.714Z| host-5243| I125: Opening file [datastore-2M282402Q0] ubun-vm1-restore/ubun-vm1-restore_2.vmdk (vpxa-nfc://[datastore-2M282402Q0] ubun-vm1-restore/ubun-vm1-restore_2.vmdk@10.1.20.108:902)
2022-01-07T07:44:59.796Z| host-5243| I125: DISKLIB-LINK : Opened 'vpxa-nfc://[datastore-2M282402Q0] ubun-vm1-restore/ubun-vm1-restore_2.vmdk@10.1.20.108:902' (0x8): custom, 8388608 sectors / 4 GB. 
2022-01-07T07:44:59.798Z| host-5243| I125: DISKLIB-LIB : Opened "vpxa-nfc://[datastore-2M282402Q0] ubun-vm1-restore/ubun-vm1-restore_2.vmdk@10.1.20.108:902" (flags 0x8, type custom). 
2022-01-07T07:44:59.798Z| host-5243| I125: VixDiskLib: VixDiskLib_Shrink: Shrink an existing local disk.
2022-01-07T07:44:59.798Z| host-5243| I125: DISKLIB-LIB : Shrink (Synchronous) chain 7FFFD84C10C8.
2022-01-07T07:44:59.798Z| host-5243| I125: VixDiskLib: VixDiskLib_Close: Close disk.

 

  1. Tried the vmkfstools -K to reclaim the blocks on the same vmdk

 

# du -sh ubun-vm1-restore_2-flat.vmdk
4.0G ubun-vm1-restore_2-flat.vmdk

# vmkfstools -K ubun-vm1-restore_2.vmdk
vmfsDisk: 1, rdmDisk: 0, blockSize: 1048576
Hole Punching: 100% done.

# du -sh ubun-vm1-restore_2-flat.vmdk
0 ubun-vm1-restore_2-flat.vmdk

 

 

What could possibly be going wrong here that VixDiskLib_Shrink() is unable to reclaim the zeroed blocks which "vmkfstools -K" is able to reclaim?

0 Kudos
bluefirestorm
Champion
Champion

The possible difference is that vmkfstools open as a local disk while your API is opening as remote disk. Notice both the documentation and the log snippet indicate "shrink an existing local disk".

 

0 Kudos
blackcomb84
Contributor
Contributor

"vmkfstools open as a local disk while your API is opening as remote disk"

Sorry I fail to understand this. Its the same vmdk I used for both API and vmkfstools. The vmdk is hosted on a local VMFS datastore which is created out of HDD attached to the ESXi host.

I connect to the Vcenter(VixDiskLib_ConnectEx) for establishing the connection before opening the disk for Shrink. Does it make a difference?

Could you kindly elaborate on the differences of remote disk vs local disk? By remote you meant managed disks and local for hosted disks?

 

0 Kudos
bluefirestorm
Champion
Champion

From the PDF doc, there are two ways to open a disk. One as local and another as remote. Open as remote the VxDiskLib_Connect would have credentials passed while open as local disk have NULLs.

If you look at the documentation PDF TOC, some functions are explicit as local, "Grow an Existing Local Disk", "Shrink an Existing Local Disk" while other calls are "Read Sector from a disk" while another "Open a Local or Remote Disk". Apart from that, Shrink Disk documentation indicates it won't work for "Managed disks", which seems like another term for "remote disks".

blackcomb84
Contributor
Contributor

Correct if my understanding is wrong,

If the connection is made without any host IP address(like the code snippet below) then Shrink API should reclaim the blocks. This means the program must be run on the ESXi node itself where the disk is hosted.

VixDiskLibConnectParams cnxParams = {0};
vixError = VixDiskLib_ConnectEx(&cnxParams, 0, ssMoRef, transportModes, &connection);

Whereas if the connection is made from a remote node to a ESX host by providing host IP, credentials and Shrink API is called, it does not reclaim the blocks.

So, for a shrink API to work the program should execute on the ESXi host directly like how a vmkfstools command is run?

0 Kudos
bluefirestorm
Champion
Champion

That seems to be the only difference for one to be local or remote disk (absence/presence of server credentials).

The most explicit statement is in page 67 with the walk-through of the sample program.


A call to VixDiskLib_Connect() creates a connection to disk. If host cnxParams.serverName is
null, as it is without the -host argument, a connection is made to hosted disk on the local host.
Otherwise a connection is made to managed disk on the remote host. With -ssmoref argument,
advanced transport is used.
blackcomb84
Contributor
Contributor

Thanks @bluefirestorm!!

I was trying to mimic an unmap behavior by writing zeros and then issuing Shrink API from a backup-restore app. I tried to use the Shrink API as I could not find a direct unmap API in the VDDK documentation. Given that Shrink API does not work if issued from a remote node, is there any other way we can unmap/punch hole a certain region of vmdk?

0 Kudos
bluefirestorm
Champion
Champion

There is no obvious API in the documentation to get the unallocated sectors. There is the QueryAllocatedBlocks call but the inverse call (QueryUnallocatedBlocks) is not there. I also don't see the relationship of blocks to sectors written out anywhere. I have no idea how the writing of zeroes would be done with just purely VDDK API.

0 Kudos