Package: vmdb2
Version: 0.22-1
Severity: important

Hi,

I'm trying to replace vmdebootstrap with vmdb2, but this tool still doesn't
work for me with a pretty basic use case based on the manual:

% head -15 myvm.vmdb2.yml
steps:
  - lvcreate: "vg0"
    name: "myvm-root"
    size: 4G
  - mklabel: msdos
    device: "{{ image }}"
  - mkpart: primary
    device: "{{ image }}"
    start: 0%
    end: 100%
    tag: /
  - kpartx: "{{ image }}"
  - mkfs: ext4
    partition: /
  - mount: /

% sudo vmdb2 myvm.vmdb2.yml --image /dev/vg0/myvm-root --verbose --log 
myvm.vmdb2.log
Load spec file myvm.vmdb2.yml
Exec: ['dpkg', '--print-architecture']
Exec: ['lvcreate', '--name', 'myvm-root', '--size', '4G', 'vg0']
Exec: ['parted', '-s', '/dev/vg0/myvm-root', 'mklabel', 'msdos']
Exec: ['parted', '-m', '/dev/dm-0', 'print']
Exec: ['parted', '-s', '/dev/dm-0', '--', 'mkpart', 'primary', 'ext2', '0%', 
'100%']
Exec: ['parted', '-m', '/dev/dm-0', 'print']

And then it just sits there. Attaching a strace shows a loop:

% sudo strace -p 77503
strace: Process 77503 attached
select(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=751734}) = 0 (Timeout)
stat("/dev/dm-01", 0x7fff8d70a7f0)      = -1 ENOENT (No such file or directory)
select(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
stat("/dev/dm-01", 0x7fff8d70a7f0)      = -1 ENOENT (No such file or directory)
select(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
stat("/dev/dm-01", 0x7fff8d70a7f0)      = -1 ENOENT (No such file or directory)
select(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
stat("/dev/dm-01", 0x7fff8d70a7f0)      = -1 ENOENT (No such file or directory)
select(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
stat("/dev/dm-01", 0x7fff8d70a7f0)      = -1 ENOENT (No such file or directory)
select(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
stat("/dev/dm-01", 0x7fff8d70a7f0)      = -1 ENOENT (No such file or directory)

So I looked into the code to find the culprit, and found it in
/usr/lib/python3/dist-packages/vmdb/plugins/mkpart_plugin.py

It passes the device parameter through os.path.realpath() which results in
/dev/dm-0, which in turn is actively bad for the rest of the partitioning
logic as you can't simply tack on the partition numbers onto a device path
like that.

I tried passing in /dev/mapper/vg0-myvm--root as that device parameter, but
realpath() destroys that as well by resolving it into /dev/dm-0 again.

That doesn't happen for parted, though, that one could work:

% sudo parted -m /dev/mapper/vg0-myvm--root print
BYT;
/dev/mapper/vg0-myvm--root:4295MB:dm:512:4096:msdos:Linux device-mapper 
(linear):;
1:1049kB:4295MB:4294MB:::;

>From this output, the diff logic could actually generate
/dev/mapper/vg0-myvm--root1 which would indeed work, but, again, realpath()
is unyielding.

So, maybe detect the use of device mapper paths? If realpath resolves into 
/dev/dm*, abort with an error message saying use /dev/mapper/ as the device?
And then have an exception for /dev/mapper paths so that it doesn't even
try to run realpath on those?

Otherwise I'm going to have to work around this by doing lvcreate and
losetup outside of vmdb2, I guess.

Please fix this. TIA.

-- 
Josip Rodin

Reply via email to