How to move root/volatile volume of a VM?

Hi,

How can I move only the root volume of a VM to another pool?
Or root and volatile?
Or only volatile?

There’s no builtin support for moving volumes of an existing VM to another pool. You could use qvm-clone --pool=VOLUME=POOL ... and then delete the original VM. Or if you want to create a new VM, the same option can be passed to qvm-create.

But the ā€˜root’ volume of an AppVM is snap_on_start, so it is always located in the pool of its template’s ā€˜root’ volume. It’s not possible to change that.

2 Likes

@rustybird

Thanks for the quick reply.

What about the volatile? It is possible to have it in a different pool (we have that in the RAM qubes). But is it possible to have only it in a different pool?

Yes, that’s possible for ā€˜volatile’ and all other volumes that are not snap_on_start.

It can even be configured globally (instead of per VM) with qubes-prefs default_pool_volatile POOL, although this will only apply to VMs created after changing this global setting.

Could you explain how to do it? - Only volatile.

qvm-create --pool=volatile=yourpoolname --label=color newqube

or

qvm-clone --pool=volatile=yourpoolname originalqube clonedqube && qvm-remove originalqube

1 Like

There seems to be some misunderstanding.

I don’t want to move the whole VM to another pool. I want to move only it’s volatile volume.

kernel - vm-pool
private - vm-pool
root - vm-pool
volatile - another-pool

That’s sort of what --pool=volatile=yourpoolname does…

If you need to avoid cloning the VM, I guess you could also edit /var/lib/qubes/qubes.xml manually (after stopping qubesd.service!), adjusting the volume XML element’s pool and vid attributes.

Thanks.
I hope I won’t mess it up :slight_smile:

So, this seems to work! Even renaming the qube (which AFAIK works by copying it in the background) preserves the volume location which is cool.

Do you think we can use this for the RAM disposables that have their private as snap_on_start? Instead of copying them to RAM first, the private and volatile can simply be pointed to a location on a RAM drive. What do you think?

The only challenge is the need to stop/start qubesd.service. Is there a way around this?

1 Like

It’s conceptually impossible to do this with snap_on_start volumes. Those need to be snapshotted from their source volume (belonging to the template), which must happen in the source volume’s pool because that pool is what provides the mechanism for making a snapshot from a source volume to a destination volume.

I also wouldn’t recommend editing qubes.xml as part of some regular workflow. You’re bound to break something sooner or later.

No

@rustybird

It’s conceptually impossible to do this with snap_on_start volumes. Those need to be snapshotted from their source volume (belonging to the template), which must happen in the source volume’s pool because that pool is what provides the mechanism for making a snapshot from a source volume to a destination volume.

How does it work with root (rw=False) and volatile then? It is possible to have them on different pools and CoW works. Why can’t we have this mechanism between source private (DVM template) and disposable private?

ā€˜volatile’ is never snap_on_start.

ā€˜root’, if it is snap_on_start (which is the case for AppVMs and DisposableVMs), is always in the same pool as its source volume. When ā€˜root’ is rw=False, there’s in-VM support for redirecting writes to somewhere on ā€˜volatile’. (So CoW for ā€˜root’ effectively happens inside the VM.) There’s no such in-VM support for ā€˜private’ with rw=False, because sadly nobody has implemented this.

there’s in-VM support for redirecting writes to somewhere on ā€˜volatile’. (So CoW for ā€˜root’ effectively happens inside the VM.)

A-ha! Thanks for explaining.

There’s no such in-VM support for ā€˜private’ with rw=False, because sadly nobody has implemented this.

Was that done deliberately?
Or can we somehow borrow the code that does it for root/volatile and adapt it?

It’s not deliberately absent. Implementing this in-VM support for the ā€˜private’ volume is what’s missing for proper anti-forensic DisposableVMs, without any workarounds like temporary storage pools or RAM disks.

https://github.com/QubesOS/qubes-issues/issues/8704#issuecomment-1806860626

It seems we keep returning to that (it’s in my bookmarks too).

Unfortunately, I don’t quite understand everything in the script you mentioned there (xen stuff), so it is still beyond my level. Is there any good info somewhere about these things, where one can learn?

BTW, there seems to be an error in the man pages of qvm-clone/create:

--pool=POOL:VOLUME, -p POOL:VOLUME

should likely be:

--pool=POOL=VOLUME, -p POOL=VOLUME

The only Xen specific thing there is how in-VM block devices correspond to volumes (xvda = ā€˜root’, xdvb = ā€˜private’, xvdc = ā€˜volatile’, xvdd = ā€˜kernel’).

Although I’m guessing the write redirection mechanism is probably not really something that’s written down anywhere. It’s a remnant of much older storage code, which has found a new use thanks to the new ephemeral ā€˜volatile’ feature.

It’s the other way around - VOLUME=POOL:

I am also not familiar with the intricacies of dracut. Looks complicated to me as a whole.

To find what is actually changed in the PR you link to, I am looking at (in a Debian VM):

diff -wy ./qubes-linux-utils/dracut/simple/init.sh /usr/lib/dracut/modules.d/90qubes-vm-simple/init.sh

and I don’t see many differences. Are you sure that particular code is doing what we are discussing?

Although I’m guessing the write redirection mechanism is probably not really something that’s written down anywhere.

Difficult to learn without info.

You are much more familiar with all that. Have you any idea why this was not touched since 2016? And what exactly needs to be done?

@rustybird

Wrong branch checked out?