Skip to content
This repository has been archived by the owner on Nov 9, 2020. It is now read-only.

Add volume cloning support -o clone-from=volname #726

Merged
merged 16 commits into from
Nov 18, 2016

Conversation

brunotm
Copy link
Contributor

@brunotm brunotm commented Nov 10, 2016

This PR adds volume cloning support, including delta disks.

The use cases would be:

  • app environment/data cloning
  • app environment/data checkpointing and rollback
  • backups?

This needs #723 to correctly report the size of delta disks.


EDIT
The delta allocation format was dropped because the resulting volumes were not deltas from their parents but full sparse clones. More bellow.

@brunotm brunotm changed the title Add volume cloning support Add volume cloning support -o clone-from=volname Nov 11, 2016
src_vol_info = kv.get_vol_info(src_vmdk_path)
opts["size"] = src_vol_info["size"]
error_info, tenant_uuid, tenant_name = auth.authorize(vm_uuid, vm_datastore, "create", opts)
if error_info:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do the authorize step for "create" before doing get_vol_info(), why read the KV if the VM doesn't have create permission on the datastore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@govint
You're right. thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the implementation is correct for this.

  • In executeRequest() we fetch and validate datastore, volume and tenant info and authorize the op without the size information.
  • In cloneVMDK() we need to do the same to validate access to the src volume, then fetch its size information and _authorize again_ the create op with the correct size.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brunotm I see the create check @ line 251 but not the src check that you mention. This is a quick review and I might have missed it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kerneltime
If I understood your question correctly:

From @220, first we get tenant info again to validate accessibility with volume and datastore, and fetch its path. Then create opts[size] is updated with the src_vol_info[size] and authorize again with the correct size info @251

thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. to validate accessibility with source volume and datastore

return err(error_info)

attached, uuid, attach_as = getStatusAttached(src_vmdk_path)
if attached:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should call handle_stale_attach() in case the disk is not in use but KV says so, or disk is attached to a VM thats powered off.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. thanks!


si = get_si()
task = si.content.virtualDiskManager.CopyVirtualDisk(
sourceName=source_vol, destName=dest_vol, destSpec=vdisk_spec)
Copy link
Contributor

@govint govint Nov 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use vmkfstools -i src-disk.vmdk cloned-disk.vmdk?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the API approach is better, we could also go that path for the other ops. Also, and i might be wrong, but from the docs vmkfstools doesn't support delta disks.

Copy link
Contributor

@msterin msterin Nov 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on "API is better". Besides: #39 (remove command lines usage where API is available) is still open

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing to API calls on the *VMDK ops would be a straightforward change, if I manage to get time I can investigate it further

@@ -58,6 +58,7 @@
# The disk allocation format for vmdk
DISK_ALLOCATION_FORMAT = 'diskformat'
VALID_ALLOCATION_FORMATS = ["zeroedthick", "thin", "eagerzeroedthick"]
CLONE_ADD_ALLOCATION_FORMAT = "delta" # Additional allocation format for clones
DEFAULT_ALLOCATION_FORMAT = 'thin'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest not having delta as a format. Its an actual new disk that we get as a result of clone.

Clone could mean a full clone - a full copy of the source disk. Its not possible to get a snap of a disk that can be a delta over a base disk. And in fact we could avoid putting in ESX internal format types for a docker user.

Something like "fast", "full" clone types can be what the user specifies which sounds generic.

For now we can't support a "fast" clone as thats tied to a VM snapshot, but "full" clone can be supported, which may be slow depending on source disk size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be a source of confusion. And we already expose disk formats to the users.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also agree with @brunotm here.
In vmware speak the disks are either "delta disks" or "redo logs" . So I think "delta" in format is fine. Also, "cloning", while usually applies to VM, is also already used as a "disk cloning" (https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1028042) so we can keep using --option clone with "delta" disk IMO.

Copy link
Contributor

@govint govint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed and suggested changes,

@brunotm brunotm force-pushed the brunotm.clone-support branch 2 times, most recently from 3ee3862 to 0e5c797 Compare November 14, 2016 06:31
@brunotm
Copy link
Contributor Author

brunotm commented Nov 14, 2016

@govint @msterin
I have the tests in place. Any considerations?

Thanks!

Copy link
Contributor

@pdhamdhere pdhamdhere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice change!

What is expected behavior for 'docker volume rm source-volume' if there are clones. I assume it should fail with reasonable error.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 14, 2016

@pdhamdhere
Actually no. Diskformats other than delta are completely independent, with deltas when deleting the parent the shared data will consolidate on the next disk in the chain.

Thanks!

@msterin
Copy link
Contributor

msterin commented Nov 14, 2016

Actually no. Diskformats other than delta are completely independent, with deltas when deleting the parent the shared data will consolidate on the next disk in the chain.

That is accurate for one chain only and AFAIK is managed only in the context of VM snapshots. When you have multiple "clones" (i.e. delta disks with shared parent) I am not aware of any code that does search of all the children and consolidation into EACH of them.

So I am also wondering what happens in the current code if parent is deleted. I suspect operation will fail of the volume is currently attached, and the operation will succeed if it's detached - but all children will be rendered unusable.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 14, 2016

@msterin
This is not the behavior I have from tests. I have created diverging deep chains of deltas from deltas and removed backwards from the master and tested the clones without data loss or anything similar. I did not try while they were in use though. I'll test again and copy the logs

@brunotm
Copy link
Contributor Author

brunotm commented Nov 14, 2016

@msterin
Those tests where actually the reason why I didn't put in dependency tracking code.

Copy link
Contributor

@msterin msterin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good change ! A few comments included - the major one being I am still not clear on what's the actual result of removing something that has clones.
A small requests - can you add a few examples or command line (cut-n-paste from xterm) ? I am wondering if commands like docker volume create -d vmdk --name my@datastore1 --option clone-from=old@datastore2 would work, and what happens on parent delete.

@@ -40,6 +40,9 @@
# glob expression to match end of 'delta' (aka snapshots) file names.
SNAP_SUFFIX_GLOB = "-[0-9][0-9][0-9][0-9][0-9][0-9].vmdk"

# regexp for finding datastore path "[datastore] path/to/file.vmdk" from full vmdk path
DATASTORE_PATH_REGEXP = r"^/vmfs/volumes/([a-zA-Z0-9_-]+?)/(.*)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datastores can have pretty much anything in the name. It's a symlink after all. I suspect there are interesting corner cases wich will be broken by this regexp.
Also, I think this may NOT work with the tenant since componet of the path is not limited to [a-zA-Z0-9_-] (aka w) @lipingxue

maybe something like this ^/vmfs/volumes/([^/]+)/(.*\.vmdk)$ ?

@@ -209,6 +213,91 @@ def make_create_cmd(opts, vmdk_path):
return "{0} -d {1} -c {2} {3}".format(VMDK_CREATE_CMD, disk_format, size, vmdk_path)


def cloneVMDK(vm_name, vmdk_path, opts={}, vm_uuid=None, vm_datastore=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both new params seem excessive. vm_name should be enough got find uuid, and vmdk_path should be enough to find data store. It's OK to have redundant params to save on extra search, I just want to make sure it's a deliberate choice ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. we already have them :)

@msterin
Copy link
Contributor

msterin commented Nov 14, 2016

This is not the behavior I have from tests. I have created diverging deep chains of deltas from deltas and removed backwards from the master and tested the clones without data loss or anything similar. I did not try while they were in use though. I'll test again and copy the logs

I am wondering how it is even possible to find all clones (delta disks) ? They can be on different datastores in different folders what all we know , and there is nothing in parent VMDK to track children. Something does not add up, we are missing something. Please do share the xterm logs and the vmdk_ops log and maybe 'ls -l' on the dockvols too.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 15, 2016

@msterin @pdhamdhere

I am wondering how it is even possible to find all clones (delta disks) ? They can be on different datastores in different folders what all we know , and there is nothing in parent VMDK to track children. Something does not add up, we are missing something. Please do share the xterm logs and the vmdk_ops log and maybe 'ls -l' on the dockvols too.

The test and logs are a bit long but they cover most of the concerns.
Also attached are the vmdk_ops.log and dmesg of vm dev01.
vmdk_ops.log.gz
dev01.dmesg.log.gz

_Create master volume_

root@dev01:~# docker volume create -d vmdk --name vol$$-master
vol34189-master
root@dev01:~# docker run -it -v vol$$-master:/mnt busybox
/ # cp -a /etc/* /mnt/
/ # dd if=/dev/zero of=/mnt/master.img bs=1M count=20
20+0 records in
20+0 records out
20971520 bytes (20.0MB) copied, 0.034553 seconds, 578.8MB/s
/ # ls /mnt/
group        hosts        lost+found   mtab         resolv.conf
hostname     localtime    master.img   passwd       shadow
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ #
root@dev01:~# docker rm -vf $(docker ps -qa)
ae8cef2646b0

_Create 1st delta on different datastore_

root@dev01:~# docker volume create -d vmdk --name vol$$-delta1@datastore1 -o clone-from=vol$$-master@datastore2 -o diskformat=delta
vol34189-delta1@datastore1

root@dev01:~# docker run -it -v vol$$-delta1@datastore1:/mnt busybox
/ # ls /mnt
group        hosts        lost+found   mtab         resolv.conf
hostname     localtime    master.img   passwd       shadow
/ # dd if=/dev/zero of=/mnt/delta-ds1.img bs=1M count=5
5+0 records in
5+0 records out
5242880 bytes (5.0MB) copied, 0.009949 seconds, 502.6MB/s
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta-ds1.img
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
root@dev01:~# docker rm -vf $(docker ps -qa)
6b092e964dea

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 17416
-rw-------    1 root     root      16781312 Nov 14 23:54 vol34189-delta1-delta.vmdk
-rw-------    1 root     root          4096 Nov 14 23:54 vol34189-delta1-f78c1220095c13da.vmfd
-rw-------    1 root     root           586 Nov 14 23:54 vol34189-delta1.vmdk
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 36872
-rw-------    1 root     root          4096 Nov 14 23:53 vol34189-master-84c57100deb48a6d.vmfd
-rw-------    1 root     root     104857600 Nov 14 23:53 vol34189-master-flat.vmdk
-rw-------    1 root     root           576 Nov 14 23:51 vol34189-master.vmdk

_Create 2nd delta from 1st delta on different datastore_

root@dev01:~# docker volume create -d vmdk --name vol$$-delta2@datastore2 -o clone-from=vol$$-delta1@datastore1 -o diskformat=delta
vol34189-delta2@datastore2
root@dev01:~# docker run -it -v vol$$-delta2@datastore2:/mnt busybox
/ # ls /mnt/
delta-ds1.img  hostname       localtime      master.img     passwd         shadow
group          hosts          lost+found     mtab           resolv.conf
/ # dd if=/dev/zero of=/mnt/delta-ds2 bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10.0MB) copied, 0.017829 seconds, 560.9MB/s
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta-ds1.img
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
/ # md5sum /mnt/delta-ds2
f1c9645dbc14efddc7d8a322685f26eb  /mnt/delta-ds2
root@dev01:~# docker rm -vf $(docker ps -qa)
4e87c20b715b
root@dev01:~# docker volume ls
DRIVER              VOLUME NAME
vmdk                vol34189-delta1@datastore1
vmdk                vol34189-delta2
vmdk                vol34189-master

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 17416
-rw-------    1 root     root      16781312 Nov 15 00:00 vol34189-delta1-delta.vmdk
-rw-------    1 root     root          4096 Nov 15 00:00 vol34189-delta1-f78c1220095c13da.vmfd
-rw-------    1 root     root           586 Nov 14 23:59 vol34189-delta1.vmdk
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 68624
-rw-------    1 root     root          4096 Nov 15 00:05 vol34189-delta2-46583f5acba16900.vmfd
-rw-------    1 root     root      33558528 Nov 15 00:05 vol34189-delta2-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:02 vol34189-delta2.vmdk
-rw-------    1 root     root          4096 Nov 14 23:53 vol34189-master-84c57100deb48a6d.vmfd
-rw-------    1 root     root     104857600 Nov 14 23:53 vol34189-master-flat.vmdk
-rw-------    1 root     root           576 Nov 14 23:51 vol34189-master.vmdk

_Create 3rd delta from 2nd on different datastore_

root@dev01:~# docker volume create -d vmdk --name vol$$-delta3@datastore1 -o clone-from=vol$$-delta2@datastore2 -o diskformat=delta
vol34189-delta3@datastore1
root@dev01:~# docker run -it -v vol$$-delta3@datastore1:/mnt busybox
/ # ls /mnt/
delta-ds1.img  group          hosts          lost+found     mtab           resolv.conf
delta-ds2      hostname       localtime      master.img     passwd         shadow
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta-ds1.img
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
/ # md5sum /mnt/delta-ds2
f1c9645dbc14efddc7d8a322685f26eb  /mnt/delta-ds2

root@dev01:~# docker rm -vf $(docker ps -qa)
91aaa793bce2

_Inspect_

(reverse-i-search)`': ^C
root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol34189-delta1@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta1@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "17MB",
                "size": "16MB"
            },
            "clone-from": "vol34189-master",
            "created": "Mon Nov 14 23:54:42 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta2",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta2",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "31MB",
                "size": "32MB"
            },
            "clone-from": "vol34189-delta1",
            "created": "Tue Nov 15 00:01:36 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta3@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta3@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "31MB",
                "size": "32MB"
            },
            "clone-from": "vol34189-delta2",
            "created": "Tue Nov 15 00:08:23 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-master",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-master",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "36MB",
                "size": "100MB"
            },
            "clone-from": "None",
            "created": "Mon Nov 14 23:51:17 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "thin",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 49168
-rw-------    1 root     root      16781312 Nov 15 00:00 vol34189-delta1-delta.vmdk
-rw-------    1 root     root          4096 Nov 15 00:00 vol34189-delta1-f78c1220095c13da.vmfd
-rw-------    1 root     root           586 Nov 14 23:59 vol34189-delta1.vmdk
-rw-------    1 root     root          4096 Nov 15 00:11 vol34189-delta3-2afad75f6e1f028e.vmfd
-rw-------    1 root     root      33558528 Nov 15 00:11 vol34189-delta3-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:08 vol34189-delta3.vmdk
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 68624
-rw-------    1 root     root          4096 Nov 15 00:05 vol34189-delta2-46583f5acba16900.vmfd
-rw-------    1 root     root      33558528 Nov 15 00:05 vol34189-delta2-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:02 vol34189-delta2.vmdk
-rw-------    1 root     root          4096 Nov 14 23:53 vol34189-master-84c57100deb48a6d.vmfd
-rw-------    1 root     root     104857600 Nov 14 23:53 vol34189-master-flat.vmdk
-rw-------    1 root     root           576 Nov 14 23:51 vol34189-master.vmdk

_Remove master volume_

root@dev01:~# docker volume rm vol$$-master
vol34189-master

_Change more data on delta3_

root@dev01:~# docker run -it -v vol$$-delta3@datastore1:/mnt busybox
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta-ds1.img
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
/ # md5sum /mnt/delta-ds2
f1c9645dbc14efddc7d8a322685f26eb  /mnt/delta-ds2
/ # cat /mnt/passwd
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:99:99:nobody:/home:/bin/false
/ # vi /mnt/passwd
/ # cat /mnt/passwd
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:99:99:nobody:/home:/bin/false
i was here
/ #
root@dev01:~# docker rm -vf $(docker ps -qa)
17778a923561

_Inspect_

root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol34189-delta1@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta1@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "17MB",
                "size": "16MB"
            },
            "clone-from": "vol34189-master",
            "created": "Mon Nov 14 23:54:42 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta2",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta2",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "31MB",
                "size": "32MB"
            },
            "clone-from": "vol34189-delta1",
            "created": "Tue Nov 15 00:01:36 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta3@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta3@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "31MB",
                "size": "32MB"
            },
            "clone-from": "vol34189-delta2",
            "created": "Tue Nov 15 00:08:23 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]
root@dev01:~#

_Use delta3, for delete delta2 from another vm_

root@dev01:~# docker run -it -v vol$$-delta3@datastore1:/mnt busybox
/ #

root@vsc01:~# docker volume ls
DRIVER              VOLUME NAME
vmdk                vol34189-delta1@datastore1
vmdk                vol34189-delta2
vmdk                vol34189-delta3@datastore1
root@vsc01:~# docker volume rm vol34189-delta2
vol34189-delta2
root@vsc01:~#


/ #
/ # cat /mnt/passwd
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:99:99:nobody:/home:/bin/false
i was here
/ #
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta-ds1.img
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
/ # md5sum /mnt/delta-ds2
f1c9645dbc14efddc7d8a322685f26eb  /mnt/delta-ds2

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 49168
-rw-------    1 root     root      16781312 Nov 15 00:00 vol34189-delta1-delta.vmdk
-rw-------    1 root     root          4096 Nov 15 00:00 vol34189-delta1-f78c1220095c13da.vmfd
-rw-------    1 root     root           586 Nov 14 23:59 vol34189-delta1.vmdk
-rw-------    1 root     root          4096 Nov 15 00:16 vol34189-delta3-2afad75f6e1f028e.vmfd
-rw-------    1 root     root      33558528 Nov 15 00:19 vol34189-delta3-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:16 vol34189-delta3.vmdk
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 0
[root@esx01:~]

_Inspect_

[
    {
        "Name": "vol34189-delta1@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta1@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "17MB",
                "size": "16MB"
            },
            "clone-from": "vol34189-master",
            "created": "Mon Nov 14 23:54:42 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta3@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta3@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "31MB",
                "size": "32MB"
            },
            "clone-from": "vol34189-delta2",
            "created": "Tue Nov 15 00:08:23 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]

_Fill all available space on delta3_*

root@dev01:~# docker run -it -v vol$$-delta3@datastore1:/mnt busybox
/ # dd if=/dev/zero of=/mnt/delta3-ds1.img bs=1M count=100
dd: writing '/mnt/delta3-ds1.img': No space left on device
56+0 records in
54+1 records out
56942592 bytes (54.3MB) copied, 0.280930 seconds, 193.3MB/s
/ #
root@dev01:~# docker rm -vf $(docker ps -qa)
ff71c5550b93

_Create delta4 from delta3 on a different datastore_

root@dev01:~# docker volume ls
DRIVER              VOLUME NAME
vmdk                vol34189-delta1@datastore1
vmdk                vol34189-delta3@datastore1
root@dev01:~# docker rm -vf $(docker ps -qa)^C
root@dev01:~# docker volume create -d vmdk --name vol$$-delta4@datastore2 -o clone-from=vol$$-delta3@datastore1 -o diskformat=delta
vol34189-delta4@datastore2
root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol34189-delta1@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta1@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "17MB",
                "size": "16MB"
            },
            "clone-from": "vol34189-master",
            "created": "Mon Nov 14 23:54:42 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta3@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta3@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "79MB",
                "size": "80MB"
            },
            "clone-from": "vol34189-delta2",
            "created": "Tue Nov 15 00:08:23 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta4",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta4",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "79MB",
                "size": "80MB"
            },
            "clone-from": "vol34189-delta3",
            "created": "Tue Nov 15 00:26:33 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]

_Remove delta1_

root@dev01:~# docker volume rm vol34189-delta1@datastore1
vol34189-delta1@datastore1
root@dev01:~# docker volume ls
DRIVER              VOLUME NAME
vmdk                vol34189-delta3@datastore1
vmdk                vol34189-delta4
root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol34189-delta3@datastore1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta3@datastore1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "79MB",
                "size": "80MB"
            },
            "clone-from": "vol34189-delta2",
            "created": "Tue Nov 15 00:08:23 2016",
            "created by VM": "dev01",
            "datastore": "datastore1",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol34189-delta4",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta4",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "79MB",
                "size": "80MB"
            },
            "clone-from": "vol34189-delta3",
            "created": "Tue Nov 15 00:26:33 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 80904
-rw-------    1 root     root          4096 Nov 15 00:25 vol34189-delta3-2afad75f6e1f028e.vmfd
-rw-------    1 root     root      83890176 Nov 15 00:25 vol34189-delta3-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:24 vol34189-delta3.vmdk
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 80904
-rw-------    1 root     root          4096 Nov 15 00:30 vol34189-delta4-636a840712fd873c.vmfd
-rw-------    1 root     root      83890176 Nov 15 00:31 vol34189-delta4-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:30 vol34189-delta4.vmdk

_Use delta4 while deleting delta3 from another vm_

root@dev01:~# docker run -it -v vol$$-delta4:/mnt busybox
/ # df -hP /mnt/
Filesystem                Size      Used Available Capacity Mounted on
/dev/disk/by-path/pci-0000:03:00.0-scsi-0:0:1:0                                92.8M     90.8M         0 100% /mnt


root@vsc01:~# docker volume ls
DRIVER              VOLUME NAME
vmdk                vol34189-delta3@datastore1
vmdk                vol34189-delta4
root@vsc01:~# docker volume rm vol34189-delta3@datastore1
vol34189-delta3@datastore1


/ # md5sum /mnt/
delta-ds1.img   group           localtime       mtab            shadow
delta-ds2       hostname        lost+found/     passwd
delta3-ds1.img  hosts           master.img      resolv.conf
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta*
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
f1c9645dbc14efddc7d8a322685f26eb  /mnt/delta-ds2
5f014295b41b8cb47350efe0ae04837d  /mnt/delta3-ds1.img
/ # rm /mnt/delta*
/ # df -hP /mnt/
/ # ls /mnt/
group        hosts        lost+found   mtab         resolv.conf
hostname     localtime    master.img   passwd       shadow
/ #
root@dev01:~# docker rm -vf $(docker ps -qa)
9e790f482744

root@dev01:~# docker volume ls
DRIVER              VOLUME NAME
vmdk                vol34189-delta4
root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol34189-delta4",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol34189-delta4",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "79MB",
                "size": "80MB"
            },
            "clone-from": "vol34189-delta3",
            "created": "Tue Nov 15 00:26:33 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]
root@dev01:~#

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 0
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 80904
-rw-------    1 root     root          4096 Nov 15 00:34 vol34189-delta4-636a840712fd873c.vmfd
-rw-------    1 root     root      83890176 Nov 15 00:34 vol34189-delta4-delta.vmdk
-rw-------    1 root     root           586 Nov 15 00:30 vol34189-delta4.vmdk


_Create and use a thin clone from delta4_

root@dev01:~# docker volume create -d vmdk --name vol$$-thin -o clone-from=vol$$-delta4 -o diskformat=thin
vol34189-thin
root@dev01:~# docker volume rm vol$$-delta4
vol34189-delta4
root@dev01:~# docker run -it -v vol$$-thin:/mnt busybox
/ # md5sum /mnt/
group        hosts        lost+found/  mtab         resolv.conf
hostname     localtime    master.img   passwd       shadow
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img

_dockvols on datastores_

[root@esx01:~] ls -l /vmfs/volumes/datastore1/dockvols/
total 0
[root@esx01:~] ls -l /vmfs/volumes/datastore2/dockvols/
total 8200
-rw-------    1 root     root          4096 Nov 15 00:38 vol34189-thin-d38a098c0a97d864.vmfd
-rw-------    1 root     root     104857600 Nov 15 00:39 vol34189-thin-flat.vmdk
-rw-------    1 root     root           595 Nov 15 00:38 vol34189-thin.vmdk

@brunotm
Copy link
Contributor Author

brunotm commented Nov 15, 2016

@msterin

can you add a few examples or command line (cut-n-paste from xterm) ? I am wondering if commands like docker volume create -d vmdk --name my@datastore1 --option clone-from=old@datastore2

Thanks for the tip, i missed that one in a rebase.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 15, 2016

@govint
I just noticed that after your fix the sizes are still miscalculated

@msterin
Copy link
Contributor

msterin commented Nov 15, 2016

@brunotm - fascinating :-) ! I see all successes in the log and the actual data is obviously in place, but I still have no idea how is it possible. Evidently, either it does not really create "redo log" aka "delta" disk on on CopyDisk with target format "delta", or I am missing something. Can you share the content of vol34189-delta?.vmdk and vol34189-master.vmdk files ? Thanks.

@govint
Copy link
Contributor

govint commented Nov 15, 2016

@brunotm - can you post the contents .vmdk files of the base disk and each
of the deltas in your test. Need to see how the disks are relating together
if at all. These aren't delta disks at all. They seem to be independent
disks.

Its impossible to use a "delta" disk if the parent has been deleted.

The size calculation is based off following links in a disk chain (of
snaps/deltas) to calculate the total size.

On Tue, Nov 15, 2016 at 7:34 AM, Mark Sterin notifications@github.com
wrote:

@brunotm https://github.com/brunotm - fascinating :-) ! I see all
successes in the log and the actual data is obviously in place, but I still
have no idea how is it possible. Evidently, either it does not really
create "redo log" aka "delta" disk on on CopyDisk with target format
"delta", or I am missing something. Can you share the content of
vol34189-delta?.vmdk and vol34189-master.vmdk files ? Thanks.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#726 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/APHseABAV8C_vvS8gwGL0OTr6E5ZHLFtks5q-RMSgaJpZM4Ku9r3
.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 15, 2016

@msterin @govint
I would agree if the files size weren't different. That both block count in ls -l on dockvols folders and docker volume inspect show.
I'll reproduce part of the tests and post the vmdk files content.

Would be very disappointing if the API was lying all that time :)

@govint
Copy link
Contributor

govint commented Nov 15, 2016

Ok, from the implementation of this feature all it does is to create a new
copy of a disk.vs, a delta.

Yes, the spec doesn't call out clearly, but the fact that you can have
source on datastore and destination another one itself implies that its got
to be a full clone. Deltas are never on different datastores, like vmfs and
VSAN) or VSAN and VVOL. They have to be exactly the same datastore.

On Tue, Nov 15, 2016 at 1:17 PM, Bruno Moura notifications@github.com
wrote:

@msterin https://github.com/msterin @govint https://github.com/govint
I would agree if the files size weren't different. That both block count
in ls -l on dockvols folders and docker volume inspect show.
I'll reproduce part of the tests and post the vmdk files content.

I would be very disappointed if the API was lying all that time :)


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#726 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/APHseDpCLX1Yxe4i_D_TFqVZldI4ixKmks5q-WOAgaJpZM4Ku9r3
.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 15, 2016

All would be good, if the stored size on the datastore wasn't this.

root@dev01:~# docker volume create -d vmdk --name vol$$ -o size=1gb
vol39714
root@dev01:~# docker run -it -v vol$$:/mnt busybox
/ # dd if=/dev/zero of=/mnt/test.img bs=1M count=256
256+0 records in
256+0 records out
268435456 bytes (256.0MB) copied, 0.827847 seconds, 309.2MB/s
root@dev01:~# docker rm -vf $(docker ps -qa)
56a22cfbdb7f
root@dev01:~# docker volume create -d vmdk --name vol$$d1@datastore1 -o clone-from=vol$$ -o diskformat=delta
vol39714d1@datastore1

_Size in MB of files in datastore_

[root@esx01:~] du -sm /vmfs/volumes/datastore2/dockvols/*
0   /vmfs/volumes/datastore2/dockvols/vol39714-c903572b98b0941e.vmfd
310 /vmfs/volumes/datastore2/dockvols/vol39714-flat.vmdk
0   /vmfs/volumes/datastore2/dockvols/vol39714.vmdk
[root@esx01:~] du -sm /vmfs/volumes/datastore1/dockvols/*
0   /vmfs/volumes/datastore1/dockvols/vol39714d1-810dc9d1bb5126e3.vmfd
17  /vmfs/volumes/datastore1/dockvols/vol39714d1-delta.vmdk
0   /vmfs/volumes/datastore1/dockvols/vol39714d1.vmdk
root@dev01:~# docker run -it -v vol39714d1@datastore1:/mnt busybox
/ # dd if=/dev/zero of=/mnt/test.img bs=1M count=128
128+0 records in
128+0 records out
134217728 bytes (128.0MB) copied, 0.452270 seconds, 283.0MB/s
root@dev01:~# docker rm -vf $(docker ps -qa)
478dfb42bf84

_Size in MB of files in datastore_

[root@esx01:~] du -sm /vmfs/volumes/datastore2/dockvols/*
0   /vmfs/volumes/datastore2/dockvols/vol39714-c903572b98b0941e.vmfd
310 /vmfs/volumes/datastore2/dockvols/vol39714-flat.vmdk
0   /vmfs/volumes/datastore2/dockvols/vol39714.vmdk
[root@esx01:~] du -sm /vmfs/volumes/datastore1/dockvols/*
0   /vmfs/volumes/datastore1/dockvols/vol39714d1-810dc9d1bb5126e3.vmfd
145 /vmfs/volumes/datastore1/dockvols/vol39714d1-delta.vmdk
0   /vmfs/volumes/datastore1/dockvols/vol39714d1.vmdk
root@dev01:~# docker run -it -v vol39714d2:/mnt busybox
root@dev01:~# dd if=/dev/zero of=/mnt/test.img bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB, 512 MiB) copied, 0.916829 s, 586 MB/s

_Size in MB of files in datastore_

[root@esx01:~] du -sm /vmfs/volumes/datastore2/dockvols/*
0   /vmfs/volumes/datastore2/dockvols/vol39714-c903572b98b0941e.vmfd
310 /vmfs/volumes/datastore2/dockvols/vol39714-flat.vmdk
0   /vmfs/volumes/datastore2/dockvols/vol39714.vmdk
0   /vmfs/volumes/datastore2/dockvols/vol39714d2-30503c76abd2e5b5.vmfd
83  /vmfs/volumes/datastore2/dockvols/vol39714d2-delta.vmdk
0   /vmfs/volumes/datastore2/dockvols/vol39714d2.vmdk
[root@esx01:~] du -sm /vmfs/volumes/datastore1/dockvols/*
0   /vmfs/volumes/datastore1/dockvols/vol39714d1-810dc9d1bb5126e3.vmfd
145 /vmfs/volumes/datastore1/dockvols/vol39714d1-delta.vmdk
0   /vmfs/volumes/datastore1/dockvols/vol39714d1.vmdk

_VMDK content, the createtype differs from parent vmfs to deltas vmfsSparse_

[root@esx01:~] cat /vmfs/volumes/datastore2/dockvols/vol39714.vmdk
# Disk DescriptorFile
version=5
encoding="UTF-8"
CID=76b04425
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfs"

# Extent description
RW 2097152 VMFS "vol39714-flat.vmdk"

# The Disk Data Base
#DDB

ddb.adapterType = "lsilogic"
ddb.geometry.cylinders = "512"
ddb.geometry.heads = "128"
ddb.geometry.sectors = "32"
ddb.longContentID = "31a66a697787eef1a17389ae76b04425"
ddb.sidecars = "docker-volume-vsphere,vol39714-c903572b98b0941e.vmfd"
ddb.thinProvisioned = "1"
ddb.uuid = "60 00 C2 99 e0 1c dc 6b-05 af 91 4b f0 75 13 cd"
ddb.virtualHWVersion = "11"
[root@esx01:~] cat /vmfs/volumes/datastore1/dockvols/vol39714d1.vmdk
# Disk DescriptorFile
version=5
encoding="UTF-8"
CID=3f599999
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfsSparse"

# Extent description
RW 2097152 VMFSSPARSE "vol39714d1-delta.vmdk"

# The Disk Data Base
#DDB

ddb.adapterType = "lsilogic"
ddb.deletable = "true"
ddb.geometry.cylinders = "512"
ddb.geometry.heads = "128"
ddb.geometry.sectors = "32"
ddb.longContentID = "64df53ef91a9abc7ec7ad1413f599999"
ddb.sidecars = "docker-volume-vsphere,vol39714d1-810dc9d1bb5126e3.vmfd"
ddb.uuid = "60 00 C2 97 30 ca 02 7f-9b 82 d4 6d 08 c3 bb 56"
ddb.virtualHWVersion = "11"
[root@esx01:~] cat /vmfs/volumes/datastore2/dockvols/vol39714d2.vmdk
# Disk DescriptorFile
version=5
encoding="UTF-8"
CID=3f599999
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfsSparse"

# Extent description
RW 2097152 VMFSSPARSE "vol39714d2-delta.vmdk"

# The Disk Data Base
#DDB

ddb.adapterType = "lsilogic"
ddb.deletable = "true"
ddb.geometry.cylinders = "512"
ddb.geometry.heads = "128"
ddb.geometry.sectors = "32"
ddb.longContentID = "64df53ef91a9abc7ec7ad1413f599999"
ddb.sidecars = "docker-volume-vsphere,vol39714d2-30503c76abd2e5b5.vmfd"
ddb.uuid = "60 00 C2 9e c3 89 5f 44-b3 1a e0 68 6a 0b 0e b5"
ddb.virtualHWVersion = "11"

@msterin
Copy link
Contributor

msterin commented Nov 15, 2016

@govint writes

.... Deltas are never on different datastores, like vmfs and VSAN) or VSAN and VVOL. They have to be exactly the same datastore

This is not fully accurate. In disklib slang, "child disk" can be wherever. It will just refer to parent disk on a different DS. This is how Linked Clones VMs can be on different stores.

@brunotm writes

I would agree if the files size weren't different. That both block count in ls -l on dockvols folders and docker volume inspect show.

this is totally expected with fully cloned disks (i.e. when all "src" content is actually copied to 'target" on 'clone' operation) if the src and target have different format. Which they do. VMFSSparse allocates in smaller grains that basic VMFS thin format, and it tends to be better compacted (but slower in access) due to structure of metadata ("grain tables"). So what we see is perfectly expected - but there is NO reuse of base disk, it's content is simply copied. For real chains, child .VMDK would have non-empty parent (or parentPath, I don't recall). And, as @govint mentioneed, the child open will simply fail if the parent is not found. To see an example, take a snapshot of a VM and check the -0001.vmdk file.

The good news is that it also explains why "remove" works just fine :) so there is no issue !

So, the bottom line - the API doc is misleading, it does not create chains but creates full copy instead - at least based on .vmdks you shared. Maybe -delta?.vmdk have more about parents ?

Note that all key scenarios (backup, checkpoint) are still satisfied, albeit slower and with more space waste.

@govint
Copy link
Contributor

govint commented Nov 15, 2016

@msterin, sorry, by same datastore I meant same type, mixed types aren't
allowed as meta-data itself is different for different datastore types.
Child disk is when its a delta, copyVirtualDisk is creating a full copy.

On Tue, Nov 15, 2016 at 3:23 PM, Mark Sterin notifications@github.com
wrote:

@govint https://github.com/govint write

.... Deltas are never on different datastores, like vmfs and VSAN) or VSAN
and VVOL. They have to be exactly the same datastore

This is not accurate. In disklib slang, "child disk" can be wherever. It
will just refer to parent disk on a different DS. This is how Linked Clones
VMs can be on different stores. We even tested in for VSAN linked clones

@brunotm https://github.com/brunotm writes

I would agree if the files size weren't different. That both block count
in ls -l on dockvols folders and docker volume inspect show.

this is totally fine with fully cloned disks (i,.e. all "src" content is
actually copied to 'target" on clone)_ if th src and target have different
format. Which they do. VMFSSparse allocates in smaller grains that basic
VMFS thin format, and it tends to be better compacted (but slower in
access) due to structure of metadata ("grain tables"). So what we see is
perfectly expected - but there is NO reuse of base disk, it's content is
simply copied. For real chains, child .VMDK would have non-empty parent (or
parentPath, I don't recall). To see an example, take a snapshot of a VM and
check the -0001.vmdk file.

So, the bottom line - the API doc is misleading, it does not create chains
but creates full copy instead - at least based on .vmdks you shared. Maybe
-delta?.vmdk have more about parents ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#726 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/APHseBMpK2MKRygdRffOwL784LXr9IuBks5q-YEygaJpZM4Ku9r3
.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 15, 2016

@msterin 👍
You're right. At first i thought that the "better compaction" wouldn't be justified in this case, from 768mb down to 16mb. But the vmfs code was being very smart compacting the images filled with zeros.

A test with random data:

root@dev01:~# docker volume create -d vmdk --name vol$$ -o size=5gb
vol40781
root@dev01:~# docker run -it -v vol$$:/mnt busybox
/ # dd if=/dev/urandom of=/mnt/radom.img bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (512.0MB) copied, 62.135964 seconds, 8.2MB/s
root@dev01:~# docker rm -vf $(docker ps -qa)
6cc4efd80711
root@dev01:~#


[root@esx01:~] du -sm /vmfs/volumes/datastore*/dockvols/*
0   /vmfs/volumes/datastore2/dockvols/vol40781-16a9ea188c8218fc.vmfd
725 /vmfs/volumes/datastore2/dockvols/vol40781-flat.vmdk
0   /vmfs/volumes/datastore2/dockvols/vol40781.vmdk
[root@esx01:~]

root@dev01:~# docker volume create -d vmdk --name vol$$d1 -o clone-from=vol$$ -o diskformat=delta
vol40781d1
root@dev01:~#

root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol40781",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol40781",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "733MB",
                "size": "5GB"
            },
            "clone-from": "None",
            "created": "Tue Nov 15 10:05:03 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "thin",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    },
    {
        "Name": "vol40781d1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol40781d1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "545MB",
                "size": "544MB"
            },
            "clone-from": "vol40781",
            "created": "Tue Nov 15 10:10:01 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]
root@dev01:~#
root@dev01:~# docker volume rm vol$$
vol40781
root@dev01:~# docker volume inspect $(docker volume ls -q)
[
    {
        "Name": "vol40781d1",
        "Driver": "vmdk",
        "Mountpoint": "/mnt/vmdk/vol40781d1",
        "Status": {
            "access": "read-write",
            "attach-as": "independent_persistent",
            "capacity": {
                "allocated": "545MB",
                "size": "544MB"
            },
            "clone-from": "vol40781",
            "created": "Tue Nov 15 10:10:01 2016",
            "created by VM": "dev01",
            "datastore": "datastore2",
            "diskformat": "delta",
            "fstype": "ext4",
            "status": "detached"
        },
        "Labels": {},
        "Scope": "global"
    }
]
root@dev01:~#

Copy link
Contributor

@msterin msterin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code LGTM. The doc docs/user-guide/docker-volume-cli.md needs to be updated with a quick write up, and it's good to go,

@brunotm
Copy link
Contributor Author

brunotm commented Nov 16, 2016

@msterin @govint
Shouldn't we change the diskformat to the user to "sparse"? in this case "delta" isn't misleading?

@govint
Copy link
Contributor

govint commented Nov 16, 2016

No, the nomenclature is more like "full" or "linked". The exact filesystem
format is not used. All datastore types will support a full or linked
format but may not support a sparse (VVOL).

On Wed, Nov 16, 2016 at 12:35 PM, Bruno Moura notifications@github.com
wrote:

@msterin https://github.com/msterin @govint https://github.com/govint
Shouldn't we change the diskformat to the user to "sparse"? in this case
"delta" isn't misleading?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#726 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/APHseF-P6aMSDrdPgaHyPsWGMkvVCE_Oks5q-qtNgaJpZM4Ku9r3
.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 17, 2016

@kerneltime
Done. Thanks!

@brunotm
Copy link
Contributor Author

brunotm commented Nov 17, 2016

@msterin @govint
Pushed the proposed changes with the docs update.
Thanks!

Copy link
Contributor

@msterin msterin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only reviewed the last 2 commits (as we have discussed and reviewed the rest already). LGTM imo- ready to merge pending CI pass

@brunotm
Copy link
Contributor Author

brunotm commented Nov 17, 2016

@kerneltime
This means that something was happening with the testbed ?

Errors: 
 [LockingError]
 Another process is updating the ESX image. Please try again later.
 Please refer to the log file for more details.
make[1]: Leaving directory `/drone/src/github.com/vmware/docker-volume-vsphere/vmdk_plugin'
[info] build failed (exit code 1)

@kerneltime
Copy link
Contributor

@brunotm Yes, but the latest push from you has passed. The good news is that CI will a lot more robust here on.. but it did need everyone pushing to rebase and pull latest from master.

@brunotm
Copy link
Contributor Author

brunotm commented Nov 17, 2016

@kerneltime
Thanks! The last push was just an amend to restart the build.

if vm_uuid and vm_datastore:
src_vol_info = kv.get_vol_info(src_vmdk_path)
opts["size"] = src_vol_info["size"]
error_info, tenant_uuid, tenant_name = auth.authorize(vm_uuid, vm_datastore, "create", opts)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be src_datastore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this @kerneltime, i understand that we're missing a explicit auth on the src_datastore. But its not only that, we're also missing a check of the src_volume file existence and a lock on it for the clone operation.

Thanks!

@brunotm
Copy link
Contributor Author

brunotm commented Nov 18, 2016

@kerneltime @msterin
This last push address all considerations, plus locking, verifications and unecessary literals usage.
From my part is good to go.

Thanks.

error_info, tenant_uuid, tenant_name = auth.authorize(vm_uuid,
src_datastore, auth.CMD_ATTACH, {})
if error_info:
return err(error_info)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could log if the user is not authorized. May be not in this change as the change is more or less final and looking good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@govint
Pushed the last commit again with the suggested changes.
Thanks!

vmdk_ops.cloneVMDK: add auth on src_datastore @kerneltime
vmdk_ops.cloneVMDK: check if source volume file exists
vmdk_ops.cloneVMDK: fix logging on invalid datastores
vmdk_ops.cloneVMDK: use kv.CLONE_FROM instead of literals
vmdk_ops.cloneVMDK: Log errors in tenant authorisation for src_datastore @govint
vmdk_utils: add get_datastore_from_vmdk_path()
@@ -71,3 +71,11 @@ docker volume create --driver=vmdk --name=MyVolume -o size=10gb -o fstype=ext4 (

Specifies which filesystem will be created on the new volume. vSphere Docker Volume Service will search for a existing /sbin/mkfs.**fstype** on the docker host to create the filesystem, and if not found it will return a list of filesystems for which it has found a corresponding mkfs. The specified filesystem must be supported by the running kernel and support labels (-L flag for mkfs). Defaults to ext4 if not specified.

### clone-from
```
docker volume create --driver=vmdk --name=CloneVolume -o clone-from=MyVolume -o access=read-only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you have multi-datstore setup. Did you test following;

docker volume create --driver=vmdk --name=CloneVolume@DS2 -o clone-from=MyVolume@DS3

Copy link
Contributor Author

@brunotm brunotm Nov 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, on the examples above in the thread:

Create 3rd delta from 2nd on different datastore

root@dev01:~# docker volume create -d vmdk --name vol$$-delta3@datastore1 -o clone-from=vol$$-delta2@datastore2 -o diskformat=delta
vol34189-delta3@datastore1
root@dev01:~# docker run -it -v vol$$-delta3@datastore1:/mnt busybox
/ # ls /mnt/
delta-ds1.img  group          hosts          lost+found     mtab           resolv.conf
delta-ds2      hostname       localtime      master.img     passwd         shadow
/ # md5sum /mnt/master.img
8f4e33f3dc3e414ff94e5fb6905cba8c  /mnt/master.img
/ # md5sum /mnt/delta-ds1.img
5f363e0e58a95f06cbe9bbc662c5dfb6  /mnt/delta-ds1.img
/ # md5sum /mnt/delta-ds2
f1c9645dbc14efddc7d8a322685f26eb  /mnt/delta-ds2

root@dev01:~# docker rm -vf $(docker ps -qa)
91aaa793bce2

Copy link
Contributor

@pdhamdhere pdhamdhere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@pdhamdhere
Copy link
Contributor

Awesome! Thanks again @brunotm for your contribution. With required approvals and green CI, I am merging this PR.

@pdhamdhere pdhamdhere merged commit a3b38f5 into vmware-archive:master Nov 18, 2016
@brunotm
Copy link
Contributor Author

brunotm commented Nov 18, 2016

@pdhamdhere
I'll push a patch right away after rebasing for the pylint changes.

@kerneltime
Copy link
Contributor

Fixes #462

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants