This mechanism is obsolete as of Qubes Beta 1!
Please see this page instead.
qfilexchgd is a dom0 daemon responsible for managing exchange of block devices (“virtual pendrives”) between VMs. It is used for
- copying files between AppVMs
- copying a single file between an AppVM and a DisposableVM
qfilexchgd is started after first qubes_guid has been started, so that it has access to X display in dom0 to present dialog messages.
qfilexchgd is event driven. The sources of events are:
- trigger of xenstore watch for the changes in
/local/domainxenstore hierarchy - to detect start/stop of VMs, and maintain vmname->vm_xid dictionary
- trigger of xenstore watch for a change in
/local/domain/domid/device/qpenkey - VMs write to this key to request service from qfilexchgd
Copying files between AppVMs
- AppVM1 user runs qvm-copy-to-vm script (accessible from Dolphin file manager by right click on a “file(s)->Actions->Send to VM” menu). It calls /usr/lib/qubes/qubes_penctl new, and it writes “new” request to its
device/qpenxenstore key. qfilexchgd creates a new 1G file, makes vfat fs on it, and does block-attach so that this file is attached as
- AppVM1 mounts
/mnt/outgoingand copies requested files there, then unmounts it.
- AppVM1 writes “send DestVM” request to its
device/qpenxenstore key (calling /usr/lib/qubes/qubes_penctl send DestVM). After getting confirmation by displaying a dialog box in dom0 display, qfilexchgd detaches
/dev/xvdgfrom AppVM1, attaches it as
- In DestVM, udev script for
/dev/xvdhnamed qubes_add_pendrive_script (see
/mnt/incoming, and then waits for
/mnt/incomingto become unmounted. A file manager running in DestVM shows a new volume, and user in DestVM may copy files from it. When user in DestVM is done, then user unmounts
/mnt/incoming. qubes_add_pendrive_script then tells qfilexchgd to detach
Copying a single file between AppVM and a DisposableVM
In order to minimize attack surface presented by necessity to process virtual pendrive metadata sent by (potentially compromised and malicious) DisposableVM, AppVM<->DisposableVM file exchange protocol does not use any filesystem.
- User in AppVM1 runs qvm-open-in-dvm (accessible from Dolphin file manager by right click on a “file->Actions->Open in DisposableVM” menu). qvm-open-in-dvm
- gets a new
/dev/xvdg(just as described in previous paragraph)
- computes a new unique transaction seq SEQ by incrementing
- writes the requested file name (say, /home/user/document.txt) to
- creates a dvm_header (see core.git/appvm/dvm.h) on
/dev/xvdg, followed by file contents
- writes the “send disposable SEQ” command to its
- gets a new
- qfilexchgd sees that “send” argument==”disposable”, and creates a new DisposableVM by calling /usr/lib/qubes/qubes_restore. It adds the new DisposableVM to qubesDB via qvm_collection.add_new_disposablevm. Then it attaches the virtual pendrive (previously attached as
/dev/xvdgat AppVM1) as
- In DisposableVM, qubes_add_pendrive_script sees non-zero
qubes_transaction_seqkey in xenstore, and instead processing the virtual pendrive as in the case of normal copy, treats it as DVM transaction (a request, because we run in DisposableVM). It retrieves the body of the file passed in
/dev/xvdh, copies to /tmp, and runs mime-open utility to open appropriate executable to edit it. When mime-open returns, if the file was modified, it is sent back to AppVM1 (by writing “send AppVM1 SEQ” to
device/qpenxenstore key). Then DisposableVM destroys itself.
- In AppVM1, a new
/dev/xvdhappears (because DisposableVM has sent it). qubes_add_pendrive_script sees non-zero
qubes_transaction_seqkey, and treats it as DVM transaction (a response, because we run in AppVM, not DisposableVM). It retrieves the filename from
/home/user/.dvm/SEQ, and copies data from