Merge branch 'comment1' of git://qubes-os.org/rafal/core
Conflicts: dom0/restore/qubes_restore.c
This commit is contained in:
commit
0f1700ef3d
@ -143,6 +143,8 @@ void suicide(struct xs_handle *xs)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// we are DVM, AppVM sends us a document to work on
|
||||
// /dev/xvdh contains the dvm_header and document data
|
||||
void dvm_transaction_request(char *seq, struct xs_handle *xs)
|
||||
{
|
||||
char filename[1024], cmdbuf[1024];
|
||||
@ -189,12 +191,16 @@ void dvm_transaction_request(char *seq, struct xs_handle *xs)
|
||||
if (stat_pre.st_mtime == stat_post.st_mtime)
|
||||
suicide(xs);
|
||||
xs_daemon_close(xs);
|
||||
// if the modify timestamp of the document file has changed, write back the
|
||||
// modified content to the requestor AppVM
|
||||
execl("/usr/lib/qubes/qvm-dvm-transfer", "qvm-dvm-transfer", src_vm,
|
||||
filename, seq, NULL);
|
||||
syslog(LOG_DAEMON | LOG_ERR, "execl qvm-dvm-transfer");
|
||||
suicide(xs);
|
||||
}
|
||||
|
||||
// we are AppVM, DVM sends us a modified document
|
||||
// /dev/xvdh contains the dvm_header and document data
|
||||
void dvm_transaction_return(char *seq_string, struct xs_handle *xs)
|
||||
{
|
||||
int seq = strtoul(seq_string, 0, 10);
|
||||
@ -213,6 +219,7 @@ void dvm_transaction_return(char *seq_string, struct xs_handle *xs)
|
||||
goto out_err;
|
||||
}
|
||||
drop_to_user();
|
||||
// read the file name for which the open-in-dvm with transaction=="seq" was started
|
||||
snprintf(db_name, sizeof(db_name), DBDIR "/%d", seq);
|
||||
db_fd = open(db_name, O_RDONLY);
|
||||
if (!db_fd) {
|
||||
|
@ -39,6 +39,13 @@ void check_name(unsigned char *s)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
A tool to request action from qfileexchgd by writing to device/qpen xenstore key.
|
||||
new - please attach a vfat-formatted block device at /dev/xvdg; I will either write some files to it and
|
||||
then request sending it to other AppVM, or I will place dvm_header+some file on it and send it to DVM
|
||||
send vmname - detach my /dev/xvdg and attach it to vmname at /dev/xvdh
|
||||
umount - I am done with my /dev/xvdh, please detach it
|
||||
*/
|
||||
|
||||
void usage(char *argv0)
|
||||
{
|
||||
|
@ -62,7 +62,12 @@ int get_and_set_seq()
|
||||
close(seq_fd);
|
||||
return seq;
|
||||
}
|
||||
|
||||
/*
|
||||
Write the filename we are sending to DVM to DBDIR/transaction_seq
|
||||
When DVM sends us a modified document via transaction with transaction_seq,
|
||||
we will know that we are supposed to update the document with the
|
||||
filename at DBDIR/transaction_seq
|
||||
*/
|
||||
void write_db(char *name, int seq)
|
||||
{
|
||||
int db_fd;
|
||||
@ -137,6 +142,7 @@ int main(int argc, char **argv)
|
||||
perror("xs_domain_open");
|
||||
exit(1);
|
||||
}
|
||||
// request a new block device at /dev/xvdg from qfileexchgd
|
||||
if (!xs_write(xs, 0, "device/qpen", "new", 3)) {
|
||||
perror("xs_write");
|
||||
exit(1);
|
||||
@ -150,8 +156,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
setuid(getuid());
|
||||
if (argc == 3)
|
||||
// we are AppVM; get new seq
|
||||
seq = get_and_set_seq();
|
||||
else
|
||||
// we are DVM; use the cmdline transaction_seq
|
||||
seq = strtoul(argv[3], 0, 0);
|
||||
file_fd = open(abs_filename, O_RDONLY);
|
||||
if (file_fd < 0) {
|
||||
@ -165,6 +173,9 @@ int main(int argc, char **argv)
|
||||
copy_file(xvdg_fd, file_fd);
|
||||
close(file_fd);
|
||||
close(xvdg_fd);
|
||||
// request qfileexchgd to send our /dev/xvdg to its destination
|
||||
// either "disposable", which means "create DVM for me"
|
||||
// or vmname, meaning this is a reply to originator AppVM
|
||||
snprintf(buf, sizeof(buf), "send %s %d", argv[1], seq);
|
||||
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
|
||||
perror("xs_write");
|
||||
|
62
dom0/pendrive_swapper/README
Normal file
62
dom0/pendrive_swapper/README
Normal file
@ -0,0 +1,62 @@
|
||||
qfilexchgd is a daemon responsible for managing exchange of block
|
||||
devices ("virtual pendrives") between VMs. It is used for
|
||||
a) copying files between AppVMs
|
||||
b) copying a single file between an AppVM and a DVM
|
||||
|
||||
qfilexchgd is event driven. The sources of events are:
|
||||
a) trigger of xenstore watch for the changes in /local/domain xenstore hierarchy -
|
||||
to detect start/stop of VMs, and maintain vmname->vm_xid dictionary
|
||||
b) triger of xenstore watch for a change in /local/domain/domid/device/qpen
|
||||
key - VMs write to this key to request service from qfilexchgd
|
||||
|
||||
Copying files between AppVMs is implemented as follows:
|
||||
1) 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/qpen
|
||||
key. qfilexchgd creates a new 1G file, makes vfat fs on it, and does block-attach
|
||||
so that this file is attached as /dev/xvdg in AppVM1.
|
||||
2) AppVM1 mounts /dev/xvdg on /mnt/outgoing and copies some files there,
|
||||
then unmounts it.
|
||||
3) AppVM1 writes "send DestVM" request to its device/qpen key (calling
|
||||
"/usr/lib/qubes/qubes_penctl send DestVM"). After getting confirmation by
|
||||
displaying a dialog box in dom0 display, qfilexchgd detaches /dev/xvdg
|
||||
from AppVM1, attaches it as /dev/xvdh to DestVM.
|
||||
4) In DestVM, udev script for /dev/xvdh named qubes_add_pendrive_script (see
|
||||
/etc/udev/rules.d/qubes.rules) mounts /dev/xvdh on /mnt/incoming, and then
|
||||
waits for /mnt/incoming to 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 /dev/xvdh.
|
||||
qubes_add_pendrive_script then tells qfilexchgd to detach /dev/xvdh and
|
||||
terminates.
|
||||
|
||||
Copying a single file between AppVM and a DVM is implemented as
|
||||
follows:
|
||||
1) User in AppVM1 runs qvm-open-in-dvm (accessible from Dolphin file manager
|
||||
by "right click on a file->Actions->Open in DVM" menu). qvm-open-in-dvm
|
||||
a) gets a new /dev/xvdg (just as described in previous paragraph)
|
||||
b) computes a new unique transaction seq SEQ,
|
||||
c) writes the requested file name (say, /home/user/document.txt) to
|
||||
/home/user/.dvm/SEQ.
|
||||
d) creates a dvm_header (see core.git/appvm/dvm.h) on /dev/xvdg, followed by
|
||||
file contents
|
||||
e) writes the "send disposable SEQ" to its device/qpen xenstore key.
|
||||
2) qfilexchgd sees that "send" argument=="disposable", and creates the new
|
||||
DVM by calling /usr/lib/qubes/qubes_restore. It adds new DVM to qubesDB via
|
||||
qvm_collection.add_new_appvm. Then it attaches /dev/xvdg from AppVM1 as
|
||||
/dev/xvdh in DVM.
|
||||
3) In DVM, qubes_add_pendrive_script sees non-zero "qubes_transaction_seq"
|
||||
key in xenstore, and instead processing it as in the case of normal copy,
|
||||
treats it as a request to DVM (because we run in DVM). It retrieves the
|
||||
body of the file passed in
|
||||
/dev/xvdh, copies to /tmp, and runs "mime-open" 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/qpen).
|
||||
Then DVM destroys itself.
|
||||
4) In AppVM1, a new /dev/xvdh appears (because DVM sent it).
|
||||
qubes_add_pendrive_script sees non-zero "qubes_transaction_seq" key, and
|
||||
treats it as response from DVM (because we run in AppVM, not DVM). It
|
||||
retrieves the filename from
|
||||
/home/user/.dvm/SEQ, and copies data from /dev/xvdh to it.
|
||||
|
||||
qfilexchgd is started after first qubes_guid is started, so that it
|
||||
has access to X display in dom0 to present dialog messages.
|
@ -197,7 +197,10 @@ void start_guid(int domid, int argc, char **argv)
|
||||
execv("/usr/bin/qubes_guid", guid_args);
|
||||
perror("execv");
|
||||
}
|
||||
|
||||
// modify the savefile. fd = fd to the open savefile,
|
||||
// buf - already read 1st page of the savefile
|
||||
// pattern - pattern to search for
|
||||
// val - string to replace pattern with
|
||||
void fix_savefile(int fd, char *buf, char *pattern, char *val)
|
||||
{
|
||||
int i, len = strlen(val), origlen;
|
||||
@ -237,6 +240,10 @@ char *build_dvm_ip(int netvm, int id)
|
||||
}
|
||||
|
||||
#define NAME_PATTERN "/root-cow.img"
|
||||
// replaces the unique portions of the savefile with per-dvm values
|
||||
// returns the name of VM the savefile was taken for
|
||||
// by looking for /.../vmname/root-cow.img
|
||||
// normally, it should be "templatename-dvm"
|
||||
char *get_vmname_from_savefile(int fd)
|
||||
{
|
||||
static char buf[4096];
|
||||
|
Loading…
Reference in New Issue
Block a user