Merge branch 'master' of git.qubes-os.org:/var/lib/qubes/git/marmarek/core
Conflicts: version_vm
This commit is contained in:
		
						commit
						b76ead2cb2
					
				
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @ -57,5 +57,6 @@ clean: | |||||||
| 	(cd dom0/restore && make clean) | 	(cd dom0/restore && make clean) | ||||||
| 	(cd dom0/qmemman && make clean) | 	(cd dom0/qmemman && make clean) | ||||||
| 	(cd common && make clean) | 	(cd common && make clean) | ||||||
|  | 	(cd u2mfn && make clean) | ||||||
| 	make -C qrexec clean | 	make -C qrexec clean | ||||||
| 	make -C vchan clean | 	make -C vchan clean | ||||||
|  | |||||||
| @ -5,9 +5,9 @@ dvm_file_editor: dvm_file_editor.o ../common/ioall.o | |||||||
| 	$(CC) -pie -g -o $@ $^ | 	$(CC) -pie -g -o $@ $^ | ||||||
| qfile-agent-dvm: qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o | qfile-agent-dvm: qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o | ||||||
| 	$(CC) -pie -g -o $@ $^ | 	$(CC) -pie -g -o $@ $^ | ||||||
| qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o copy_file.o crc32.o | qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o ../common/copy_file.o ../common/crc32.o | ||||||
| 	$(CC) -pie -g -o $@ $^ | 	$(CC) -pie -g -o $@ $^ | ||||||
| qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o copy_file.o unpack.o crc32.o | qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o ../common/copy_file.o ../common/unpack.o ../common/crc32.o | ||||||
| 	$(CC) -pie -g -o $@ $^ | 	$(CC) -pie -g -o $@ $^ | ||||||
| 
 | 
 | ||||||
| clean: | clean: | ||||||
|  | |||||||
| @ -20,15 +20,15 @@ | |||||||
| # | # | ||||||
| # | # | ||||||
| 
 | 
 | ||||||
| if [ x"$1" = "x--with-progress" ] ; then | if [ x"$1" = "x--without-progress" ] ; then | ||||||
| 	DO_PROGRESS=1 | 	DO_PROGRESS=0 | ||||||
| 	shift | 	shift | ||||||
| else | else | ||||||
| 	DO_PROGRESS=0 | 	DO_PROGRESS=1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if [ $# -lt 2 ] ; then | if [ $# -lt 2 ] ; then | ||||||
| 	echo usage: $0 '[--with-progress] dest_vmname file [file]+' | 	echo usage: $0 '[--without-progress] dest_vmname file [file]+' | ||||||
| 	exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,4 +6,4 @@ meminfo-writer: meminfo-writer.o | |||||||
| xenstore-watch: xenstore-watch.o | xenstore-watch: xenstore-watch.o | ||||||
| 	$(CC) -o xenstore-watch xenstore-watch.o -lxenstore | 	$(CC) -o xenstore-watch xenstore-watch.o -lxenstore | ||||||
| clean: | clean: | ||||||
| 	rm -f meminfo-writer *.o *~ | 	rm -f meminfo-writer xenstore-watch *.o *~ | ||||||
|  | |||||||
| @ -5,7 +5,16 @@ | |||||||
| # This creates dm-snapshot device on given arguments | # This creates dm-snapshot device on given arguments | ||||||
| 
 | 
 | ||||||
| dir=$(dirname "$0") | dir=$(dirname "$0") | ||||||
| . "$dir/block-common.sh" | if [ "$1" = "prepare" ] || [ "$1" = "cleanup" ]; then | ||||||
|  |   . "$dir/xen-hotplug-common.sh" | ||||||
|  |   command=$1 | ||||||
|  | else | ||||||
|  |   . "$dir/block-common.sh" | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | shopt -s nullglob | ||||||
|  | 
 | ||||||
|  | HOTPLUG_STORE="/var/run/xen-hotplug/${XENBUS_PATH//\//-}" | ||||||
| 
 | 
 | ||||||
| get_dev() { | get_dev() { | ||||||
|   dev=$1 |   dev=$1 | ||||||
| @ -89,7 +98,6 @@ create_dm_snapshot_origin() { | |||||||
| 
 | 
 | ||||||
| t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING') | t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING') | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| case "$command" in | case "$command" in | ||||||
|   add) |   add) | ||||||
|     case $t in |     case $t in | ||||||
| @ -117,24 +125,81 @@ case "$command" in | |||||||
|         if [ "$t" == "snapshot" ]; then |         if [ "$t" == "snapshot" ]; then | ||||||
|           #that's all for snapshot, store name of prepared device |           #that's all for snapshot, store name of prepared device | ||||||
|           xenstore_write "$XENBUS_PATH/node" "/dev/mapper/$dm_devname" |           xenstore_write "$XENBUS_PATH/node" "/dev/mapper/$dm_devname" | ||||||
|  |           echo "/dev/mapper/$dm_devname" > "$HOTPLUG_STORE-node" | ||||||
|           write_dev /dev/mapper/$dm_devname |           write_dev /dev/mapper/$dm_devname | ||||||
|         elif [ "$t" == "origin" ]; then |         elif [ "$t" == "origin" ]; then | ||||||
|           # for origin - prepare snapshot-origin device and store its name |           # for origin - prepare snapshot-origin device and store its name | ||||||
|           dm_devname=origin-$(stat -c '%D:%i' "$base") |           dm_devname=origin-$(stat -c '%D:%i' "$base") | ||||||
|           create_dm_snapshot_origin $dm_devname "$base" |           create_dm_snapshot_origin $dm_devname "$base" | ||||||
|           xenstore_write "$XENBUS_PATH/node" "/dev/mapper/$dm_devname" |           xenstore_write "$XENBUS_PATH/node" "/dev/mapper/$dm_devname" | ||||||
|  |           echo "/dev/mapper/$dm_devname" > "$HOTPLUG_STORE-node" | ||||||
|           write_dev /dev/mapper/$dm_devname |           write_dev /dev/mapper/$dm_devname | ||||||
|         fi |         fi | ||||||
|  |         # Save domain name for template commit on device remove | ||||||
|  |         domain=$(xenstore_read_default "$XENBUS_PATH/domain" '') | ||||||
|  |         if [ -z "$domain" ]; then | ||||||
|  |           domid=$(xenstore_read "$XENBUS_PATH/frontend-id") | ||||||
|  |           domain=$(xl domname $domid) | ||||||
|  |         fi | ||||||
|  |         echo $domain > "$HOTPLUG_STORE-domain" | ||||||
|  | 
 | ||||||
|  |         release_lock "block" | ||||||
|  |         exit 0 | ||||||
|  |         ;; | ||||||
|  |     esac | ||||||
|  |     ;; | ||||||
|  |   prepare) | ||||||
|  |     t=$2 | ||||||
|  |     case $t in | ||||||
|  |       snapshot|origin) | ||||||
|  |         p=$3 | ||||||
|  |         base=${p/:*/} | ||||||
|  |         cow=${p/*:/} | ||||||
|  | 
 | ||||||
|  |         if [ -L "$base" ]; then | ||||||
|  |           base=$(readlink -f "$base") || fatal "$base link does not exist." | ||||||
|  |         fi | ||||||
|  | 
 | ||||||
|  |         if [ -L "$cow" ]; then | ||||||
|  |           cow=$(readlink -f "$cow") || fatal "$cow link does not exist." | ||||||
|  |         fi | ||||||
|  | 
 | ||||||
|  |         # first ensure that snapshot device exists (to write somewhere changes from snapshot-origin) | ||||||
|  |         dm_devname=$(get_dm_snapshot_name "$base" "$cow") | ||||||
|  | 
 | ||||||
|  |         claim_lock "block" | ||||||
|  | 
 | ||||||
|  |         # prepare snapshot device | ||||||
|  |         create_dm_snapshot $dm_devname "$base" "$cow" | ||||||
|  | 
 | ||||||
|  |         if [ "$t" == "snapshot" ]; then | ||||||
|  |           #that's all for snapshot, store name of prepared device | ||||||
|  |           echo "/dev/mapper/$dm_devname" | ||||||
|  |         elif [ "$t" == "origin" ]; then | ||||||
|  |           # for origin - prepare snapshot-origin device and store its name | ||||||
|  |           dm_devname=origin-$(stat -c '%D:%i' "$base") | ||||||
|  |           create_dm_snapshot_origin $dm_devname "$base" | ||||||
|  |           echo "/dev/mapper/$dm_devname" | ||||||
|  |         fi | ||||||
| 
 | 
 | ||||||
|         release_lock "block" |         release_lock "block" | ||||||
|         exit 0 |         exit 0 | ||||||
|         ;; |         ;; | ||||||
|     esac |     esac | ||||||
|     ;; |     ;; | ||||||
|   remove) |   remove|cleanup) | ||||||
|  |     if [ "$command" = "cleanup" ]; then | ||||||
|  |       t=$2 | ||||||
|  |     else | ||||||
|  |       t=$(cat $HOTPLUG_STORE-type) | ||||||
|  |     fi | ||||||
|     case $t in |     case $t in | ||||||
|       snapshot|origin) |       snapshot|origin) | ||||||
|         node=$(xenstore_read "$XENBUS_PATH/node") |         if [ "$command" = "cleanup" ]; then | ||||||
|  |           node=$3 | ||||||
|  |         else | ||||||
|  |           node=$(cat "$HOTPLUG_STORE-node") | ||||||
|  |         fi | ||||||
| 
 | 
 | ||||||
|         if [ -z "$node" ]; then |         if [ -z "$node" ]; then | ||||||
|           fatal "No device node to remove" |           fatal "No device node to remove" | ||||||
| @ -174,13 +239,15 @@ case "$command" in | |||||||
|               dmsetup remove $snap |               dmsetup remove $snap | ||||||
|             fi |             fi | ||||||
|           done |           done | ||||||
|  |           if [ "$command" = "remove" ]; then | ||||||
|             # Commit template changes |             # Commit template changes | ||||||
|           domain=$(xenstore_read "$XENBUS_PATH/domain") |             domain=$(cat "$HOTPLUG_STORE-domain") | ||||||
|             if [ "$domain" ]; then |             if [ "$domain" ]; then | ||||||
|               # Dont stop on errors |               # Dont stop on errors | ||||||
|               /usr/bin/qvm-template-commit "$domain" || true |               /usr/bin/qvm-template-commit "$domain" || true | ||||||
|             fi |             fi | ||||||
|           fi |           fi | ||||||
|  |         fi | ||||||
| 
 | 
 | ||||||
|         if [ -e $node ]; then |         if [ -e $node ]; then | ||||||
|           log debug "Removing $node" |           log debug "Removing $node" | ||||||
|  | |||||||
							
								
								
									
										51
									
								
								common/qubes_download_dom0_updates.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										51
									
								
								common/qubes_download_dom0_updates.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | DOM0_UPDATES_DIR=/var/lib/qubes/dom0-updates | ||||||
|  | 
 | ||||||
|  | DOIT=0 | ||||||
|  | GUI=1 | ||||||
|  | while [ -n "$1" ]; do | ||||||
|  |     if [ "x--doit" = "x$1" ]; then | ||||||
|  |         DOIT=1 | ||||||
|  |     elif [ "x--nogui" = "x$1" ]; then | ||||||
|  |         GUI=0 | ||||||
|  |     fi | ||||||
|  |     shift | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | if ! [ -d "$DOM0_UPDATES_DIR" ]; then | ||||||
|  |     echo "Dom0 updates dir does not exists: $DOM0_UPDATES_DIR" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | mkdir -p $DOM0_UPDATES_DIR/etc | ||||||
|  | cp /etc/yum.conf $DOM0_UPDATES_DIR/etc/ | ||||||
|  | 
 | ||||||
|  | echo "Checking for updates..." | ||||||
|  | PKGLIST=`yum --installroot $DOM0_UPDATES_DIR check-update -q | cut -f 1 -d ' '` | ||||||
|  | 
 | ||||||
|  | if [ -z $PKGLIST ]; then | ||||||
|  |     # No new updates | ||||||
|  |     exit 0 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | if [ "$DOIT" != "1" ]; then | ||||||
|  |     zenity --question --title="Qubes Dom0 updates" \ | ||||||
|  |       --text="Updates for dom0 available. Do you want to download its now?" || exit 0 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | mkdir -p "$DOM0_UPDATES_DIR/packages" | ||||||
|  | 
 | ||||||
|  | set -e | ||||||
|  | 
 | ||||||
|  | if [ "$GUI" = 1 ]; then | ||||||
|  |     ( echo "1" | ||||||
|  |     yumdownloader --destdir "$DOM0_UPDATES_DIR/packages" --installroot "$DOM0_UPDATES_DIR" $PKGLIST | ||||||
|  |     echo 100 ) | zenity --progress --pulsate --auto-close --auto-kill \ | ||||||
|  |          --text="Downloading updates for Dom0, please wait..." --title="Qubes Dom0 updates" | ||||||
|  | else | ||||||
|  |     yumdownloader --destdir "$DOM0_UPDATES_DIR/packages" --installroot "$DOM0_UPDATES_DIR" $PKGLIST | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # qvm-copy-to-vm works only from user | ||||||
|  | su -c "qvm-copy-to-vm @dom0updates $DOM0_UPDATES_DIR/packages/*.rpm" user | ||||||
							
								
								
									
										2
									
								
								common/qubes_network.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								common/qubes_network.rules
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | 
 | ||||||
|  | SUBSYSTEMS=="xen", KERNEL=="eth*", ACTION=="add", RUN+="/usr/lib/qubes/setup_ip" | ||||||
							
								
								
									
										1
									
								
								common/qubes_trigger_sync_appmenus.action
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								common/qubes_trigger_sync_appmenus.action
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | *:any:/usr/lib/qubes/qubes_trigger_sync_appmenus.sh | ||||||
							
								
								
									
										7
									
								
								common/qubes_trigger_sync_appmenus.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								common/qubes_trigger_sync_appmenus.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | 
 | ||||||
|  | UPDATEABLE=`/usr/bin/xenstore-read qubes_vm_updateable` | ||||||
|  | 
 | ||||||
|  | if [ "$UPDATEABLE" = "True" ]; then | ||||||
|  |     echo -n SYNC > /var/run/qubes/qrexec_agent | ||||||
|  | fi | ||||||
							
								
								
									
										13
									
								
								common/setup_ip
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								common/setup_ip
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | 
 | ||||||
|  | ip=`/usr/bin/xenstore-read qubes_ip` | ||||||
|  | netmask=`/usr/bin/xenstore-read qubes_netmask` | ||||||
|  | gateway=`/usr/bin/xenstore-read qubes_gateway` | ||||||
|  | secondary_dns=`/usr/bin/xenstore-read qubes_secondary_dns` | ||||||
|  | if [ x$ip != x ]; then | ||||||
|  |     /sbin/ifconfig $INTERFACE $ip netmask 255.255.255.255 | ||||||
|  |     /sbin/ifconfig $INTERFACE up | ||||||
|  |     /sbin/route add default dev $INTERFACE | ||||||
|  |     echo "nameserver $gateway" > /etc/resolv.conf | ||||||
|  |     echo "nameserver $secondary_dns" >> /etc/resolv.conf | ||||||
|  | fi | ||||||
| @ -1,3 +1,4 @@ | |||||||
|  | #define _GNU_SOURCE /* For O_NOFOLLOW. */ | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <ioall.h> | #include <ioall.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
							
								
								
									
										1
									
								
								dom0/aux-tools/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dom0/aux-tools/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | qfile-dom0-unpacker | ||||||
							
								
								
									
										4
									
								
								dom0/aux-tools/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								dom0/aux-tools/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | CC=gcc | ||||||
|  | CFLAGS=-g -Wall -I../../common -fPIC -pie | ||||||
|  | qfile-dom0-unpacker: qfile-dom0-unpacker.o ../../common/ioall.o ../../common/gui-fatal.o ../../common/copy_file.o ../../common/unpack.o ../../common/crc32.o | ||||||
|  | 	$(CC) -pie -g -o $@ $^ | ||||||
| @ -22,20 +22,29 @@ | |||||||
| 
 | 
 | ||||||
| SRCDIR=$1 | SRCDIR=$1 | ||||||
| VMNAME=$2 | VMNAME=$2 | ||||||
| VMDIR=/var/lib/qubes/appvms/$VMNAME | VMTYPE=$3 | ||||||
|  | if [ -z "$VMTYPE" ]; then | ||||||
|  |     VMTYPE=appvms | ||||||
|  | fi | ||||||
|  | VMDIR=/var/lib/qubes/$VMTYPE/$VMNAME | ||||||
| APPSDIR=$VMDIR/apps | APPSDIR=$VMDIR/apps | ||||||
| 
 | 
 | ||||||
| if [ $# != 2 ]; then | if [ $# -lt 2 ]; then | ||||||
|     echo "usage: $0 <apps_templates_dir> <vmname>" |     echo "usage: $0 <apps_templates_dir> <vmname> [appvms|vm-templates|servicevms]" | ||||||
|     exit |     exit | ||||||
| fi | fi | ||||||
| mkdir -p $APPSDIR | mkdir -p $APPSDIR | ||||||
| 
 | 
 | ||||||
| if [ "$SRCDIR" != "none" ]; then | if [ "$SRCDIR" != "none" ]; then | ||||||
|     echo "--> Converting Appmenu Templates..." |     echo "--> Converting Appmenu Templates..." | ||||||
|     find $SRCDIR -name "*.desktop" -exec /usr/lib/qubes/convert_apptemplate2vm.sh {} $APPSDIR $VMNAME $VMDIR \; |     if [ -r "$VMDIR/whitelisted-appmenus.list" ]; then | ||||||
|  |         cat $VMDIR/whitelisted-appmenus.list | xargs -I{} /usr/lib/qubes/convert_apptemplate2vm.sh $SRCDIR/{} $APPSDIR $VMNAME $VMDIR | ||||||
|  |     else | ||||||
|  |         find $SRCDIR -name "*.desktop" $CHECK_WHITELISTED -exec /usr/lib/qubes/convert_apptemplate2vm.sh {} $APPSDIR $VMNAME $VMDIR \; | ||||||
|  |     fi | ||||||
|  |     /usr/lib/qubes/convert_apptemplate2vm.sh /usr/share/qubes/qubes-appmenu-select.template $APPSDIR $VMNAME $VMDIR | ||||||
| 
 | 
 | ||||||
|     /usr/lib/qubes/convert_dirtemplate2vm.sh $SRCDIR/qubes-vm.directory.template $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR |     /usr/lib/qubes/convert_dirtemplate2vm.sh $SRCDIR/qubes-*.directory.template $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "--> Adding Apps to the Menu..." | echo "--> Adding Apps to the Menu..." | ||||||
|  | |||||||
							
								
								
									
										86
									
								
								dom0/aux-tools/qfile-dom0-unpacker.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								dom0/aux-tools/qfile-dom0-unpacker.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | |||||||
|  | #define _GNU_SOURCE | ||||||
|  | #include <ioall.h> | ||||||
|  | #include <grp.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <pwd.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <sys/fsuid.h> | ||||||
|  | #include <gui-fatal.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include "filecopy.h" | ||||||
|  | int prepare_creds_return_uid(char *username) | ||||||
|  | { | ||||||
|  | 	struct passwd *pwd; | ||||||
|  | 	pwd = getpwnam(username); | ||||||
|  | 	if (!pwd) { | ||||||
|  | 		perror("getpwnam"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	setenv("HOME", pwd->pw_dir, 1); | ||||||
|  | 	setenv("USER", username, 1); | ||||||
|  | 	setgid(pwd->pw_gid); | ||||||
|  | 	initgroups(username, pwd->pw_gid); | ||||||
|  | 	setfsuid(pwd->pw_uid); | ||||||
|  | 	return pwd->pw_uid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wait_for_child(int statusfd) | ||||||
|  | { | ||||||
|  | 	int status; | ||||||
|  | 	if (read(statusfd, &status, sizeof status)!=sizeof status) | ||||||
|  | 		gui_fatal("File copy error: Internal error reading status from unpacker"); | ||||||
|  | 	errno = status; | ||||||
|  | 	switch (status) { | ||||||
|  | 	case LEGAL_EOF: break; | ||||||
|  | 	case 0: gui_fatal("File copy: Connection terminated unexpectedly"); break; | ||||||
|  | 	case EINVAL: gui_fatal("File copy: Corrupted data from packer"); break; | ||||||
|  | 	case EEXIST: gui_fatal("File copy: not overwriting existing file. Clean ~/incoming, and retry copy"); break; | ||||||
|  | 	default: gui_fatal("File copy");  | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | extern void do_unpack(int); | ||||||
|  | 
 | ||||||
|  | int main(int argc, char ** argv) | ||||||
|  | { | ||||||
|  | 	char *incoming_dir; | ||||||
|  | 	int pipefds[2]; | ||||||
|  | 	int uid; | ||||||
|  | 
 | ||||||
|  | 	if (argc < 3) { | ||||||
|  | 		fprintf(stderr, "Invalid parameters, usage: %s user dir\n", argv[0]); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pipe(pipefds); | ||||||
|  | 
 | ||||||
|  | 	uid = prepare_creds_return_uid(argv[1]); | ||||||
|  | 
 | ||||||
|  | 	incoming_dir = argv[2]; | ||||||
|  | 	mkdir(incoming_dir, 0700); | ||||||
|  | 	if (chdir(incoming_dir)) | ||||||
|  | 		gui_fatal("Error chdir to %s", incoming_dir);  | ||||||
|  | 	switch (fork()) { | ||||||
|  | 	case -1: | ||||||
|  | 		perror("fork"); | ||||||
|  | 		exit(1); | ||||||
|  | 	case 0: | ||||||
|  | 		if (chroot(incoming_dir)) //impossible
 | ||||||
|  | 			gui_fatal("Error chroot to %s", incoming_dir); | ||||||
|  | 		setuid(uid); | ||||||
|  | 		close(pipefds[0]); | ||||||
|  | 		do_unpack(pipefds[1]); | ||||||
|  | 		exit(0); | ||||||
|  | 	default:; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	setuid(uid); | ||||||
|  | 	close(pipefds[1]); | ||||||
|  | 	wait_for_child(pipefds[0]); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| @ -1,14 +1,19 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
| VMNAME=$1 | VMNAME=$1 | ||||||
| VMDIR=/var/lib/qubes/appvms/$VMNAME | VMTYPE=$2 | ||||||
|  | if [ -z "$VMTYPE" ]; then | ||||||
|  |     VMTYPE=appvms | ||||||
|  | fi | ||||||
|  | VMDIR=/var/lib/qubes/$VMTYPE/$VMNAME | ||||||
| APPSDIR=$VMDIR/apps | APPSDIR=$VMDIR/apps | ||||||
| 
 | 
 | ||||||
| if [ $# != 1 ]; then | if [ $# -lt 1 ]; then | ||||||
|     echo "usage: $0 <vmname>" |     echo "usage: $0 <vmname> [appvms|vm-templates|servicevms]" | ||||||
|     exit |     exit | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if ls $APPSDIR/*.directory $APPSDIR/*.desktop > /dev/null 2>&1; then | if ls $APPSDIR/*.directory $APPSDIR/*.desktop > /dev/null 2>&1; then | ||||||
|     xdg-desktop-menu uninstall $APPSDIR/*.directory $APPSDIR/*.desktop |     xdg-desktop-menu uninstall $APPSDIR/*.directory $APPSDIR/*.desktop | ||||||
|  |     rm -f $APPSDIR/*.desktop $APPSDIR/*.directory | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								dom0/aux-tools/sync_rpmdb_updatevm.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								dom0/aux-tools/sync_rpmdb_updatevm.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | 
 | ||||||
|  | UPDATEVM=`qvm-get-updatevm` | ||||||
|  | 
 | ||||||
|  | if [ -n "$UPDATEVM" ]; then | ||||||
|  |     qvm-run -u root --pass_io --localcmd='tar c /var/lib/rpm /etc/yum.repos.d' "$UPDATEVM" 'tar x -C /var/lib/qubes/dom0-updates' | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # Ignore errors (eg VM not running) | ||||||
|  | exit 0 | ||||||
| @ -20,6 +20,7 @@ | |||||||
| start() | start() | ||||||
| { | { | ||||||
|     echo -n $"Executing Qubes Core scripts:" |     echo -n $"Executing Qubes Core scripts:" | ||||||
|  |     modprobe evtchn | ||||||
|     chgrp qubes /etc/xen |     chgrp qubes /etc/xen | ||||||
|     chmod 710 /etc/xen |     chmod 710 /etc/xen | ||||||
|     chgrp qubes /var/run/xend |     chgrp qubes /var/run/xend | ||||||
| @ -28,7 +29,21 @@ start() | |||||||
|     chmod 660 /var/run/xend/xen-api.sock /var/run/xend/xmlrpc.sock |     chmod 660 /var/run/xend/xen-api.sock /var/run/xend/xmlrpc.sock | ||||||
|     chgrp qubes /var/run/xenstored/* |     chgrp qubes /var/run/xenstored/* | ||||||
|     chmod 660 /var/run/xenstored/* |     chmod 660 /var/run/xenstored/* | ||||||
|     xm sched-credit -d 0 -w 65535 |     chgrp qubes /var/lib/xen | ||||||
|  |     chmod 770 /var/lib/xen | ||||||
|  |     chgrp qubes /var/log/xen | ||||||
|  |     chmod 770 /var/log/xen | ||||||
|  |     chgrp qubes /proc/xen/privcmd | ||||||
|  |     chmod 660 /proc/xen/privcmd | ||||||
|  |     chgrp qubes /dev/xen/evtchn | ||||||
|  |     chmod 660 /dev/xen/evtchn | ||||||
|  |     touch /var/run/qubes/xl-lock | ||||||
|  |     chgrp qubes /var/run/qubes/xl-lock | ||||||
|  |     chmod 660 /var/run/qubes/xl-lock | ||||||
|  | 
 | ||||||
|  |     xenstore-write /local/domain/0/name Domain-0 | ||||||
|  |      | ||||||
|  |     xl sched-credit -d 0 -w 512 | ||||||
|     cp /var/lib/qubes/qubes.xml /var/lib/qubes/backup/qubes-$(date +%F-%T).xml |     cp /var/lib/qubes/qubes.xml /var/lib/qubes/backup/qubes-$(date +%F-%T).xml | ||||||
| 
 | 
 | ||||||
|     /usr/lib/qubes/qmemman_daemon.py >/var/log/qubes/qmemman.log 2>/var/log/qubes/qmemman.errs &  |     /usr/lib/qubes/qmemman_daemon.py >/var/log/qubes/qmemman.log 2>/var/log/qubes/qmemman.errs &  | ||||||
|  | |||||||
| @ -22,10 +22,10 @@ NETVM=$(qvm-get-default-netvm) | |||||||
| 
 | 
 | ||||||
| get_running_netvms() { | get_running_netvms() { | ||||||
|     # Actually get running VMs with PCI devices attached |     # Actually get running VMs with PCI devices attached | ||||||
|     RUNNING_VMS=`xm list --state=Running | tail -n +3 | cut -f 1 -d " "` |     RUNNING_VMS=`xl list | tail -n +3 | cut -f 1 -d " "` | ||||||
|     RUNNING_NETVMS="" |     RUNNING_NETVMS="" | ||||||
|     for VM in $RUNNING_VMS; do |     for VM in $RUNNING_VMS; do | ||||||
|         if [ -n "`xm pci-list $VM`" ]; then |         if [ -n "`xl pci-list $VM`" ]; then | ||||||
|             echo "$VM" |             echo "$VM" | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								dom0/misc/limits-qubes.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dom0/misc/limits-qubes.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | # xl create needs to allocate and mlock all VM memory | ||||||
|  | @qubes  soft    memlock unlimited | ||||||
|  | @qubes  hard    memlock unlimited | ||||||
							
								
								
									
										10
									
								
								dom0/misc/qubes-appmenu-select.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								dom0/misc/qubes-appmenu-select.template
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | [Desktop Entry] | ||||||
|  | Version=1.0 | ||||||
|  | Type=Application | ||||||
|  | Exec=qubes-appmenu-select %VMNAME% | ||||||
|  | Icon=/usr/share/qubes/icons/qubes.png | ||||||
|  | Terminal=false | ||||||
|  | Name=%VMNAME%: Add more shortcuts... | ||||||
|  | GenericName=%VMNAME%: Add more shortcuts... | ||||||
|  | StartupNotify=false | ||||||
|  | Categories=System; | ||||||
							
								
								
									
										5
									
								
								dom0/misc/qubes-templatevm.directory.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								dom0/misc/qubes-templatevm.directory.template
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | [Desktop Entry] | ||||||
|  | Encoding=UTF-8 | ||||||
|  | Type=Directory | ||||||
|  | Name=Template: %VMNAME% | ||||||
|  | Icon=/usr/share/qubes/icons/template.png | ||||||
							
								
								
									
										5
									
								
								dom0/misc/qubes-vm.directory.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								dom0/misc/qubes-vm.directory.template
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | [Desktop Entry] | ||||||
|  | Encoding=UTF-8 | ||||||
|  | Type=Directory | ||||||
|  | Name=Domain: %VMNAME% | ||||||
|  | Icon=%VMDIR%/icon.png | ||||||
							
								
								
									
										1
									
								
								dom0/misc/qubes_sync_rpmdb_updatevm.action
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dom0/misc/qubes_sync_rpmdb_updatevm.action
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | *:any:/usr/lib/qubes/sync_rpmdb_updatevm.sh | ||||||
							
								
								
									
										28
									
								
								dom0/misc/vm-template.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								dom0/misc/vm-template.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | # | ||||||
|  | # This is a Xen VM config file for Qubes VM | ||||||
|  | # DO NOT EDIT - autogenerated by qubes tools | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | kernel="{kerneldir}/vmlinuz" | ||||||
|  | ramdisk="{kerneldir}/initramfs" | ||||||
|  | extra="ro nomodeset xencons=hvc rd_NO_PLYMOUTH 3 {kernelopts}" | ||||||
|  | root="/dev/mapper/dmroot" | ||||||
|  | 
 | ||||||
|  | memory = {mem} | ||||||
|  | maxmem = {maxmem} | ||||||
|  | name = "{name}" | ||||||
|  | 
 | ||||||
|  | disk = [ {rootdev} | ||||||
|  |          {privatedev} | ||||||
|  |          {volatiledev} | ||||||
|  |        ] | ||||||
|  | 
 | ||||||
|  | vif = [ {netdev} ] | ||||||
|  | 
 | ||||||
|  | pci = [ {pcidev} ] | ||||||
|  | 
 | ||||||
|  | vcpus = {vcpus} | ||||||
|  | 
 | ||||||
|  | on_poweroff = 'destroy' | ||||||
|  | on_reboot   = 'destroy' | ||||||
|  | on_crash    = 'destroy' | ||||||
| @ -4,10 +4,10 @@ | |||||||
| 
 | 
 | ||||||
| get_running_netvms() { | get_running_netvms() { | ||||||
|     # Actually get running VMs with PCI devices attached |     # Actually get running VMs with PCI devices attached | ||||||
|     RUNNING_VMS=`xm list --state=Running | tail -n +3 | cut -f 1 -d " "` |     RUNNING_VMS=`xl list | tail -n +3 | cut -f 1 -d " "` | ||||||
|     RUNNING_NETVMS="" |     RUNNING_NETVMS="" | ||||||
|     for VM in $RUNNING_VMS; do |     for VM in $RUNNING_VMS; do | ||||||
|         if [ -n "`xm pci-list $VM`" ]; then |         if [ -n "`xl pci-list $VM|tail -n +2`" ]; then | ||||||
|             echo "$VM" |             echo "$VM" | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ class DomainState: | |||||||
|     def __init__(self, id): |     def __init__(self, id): | ||||||
|         self.meminfo = None		#dictionary of memory info read from client |         self.meminfo = None		#dictionary of memory info read from client | ||||||
|         self.memory_actual = None	#the current memory size |         self.memory_actual = None	#the current memory size | ||||||
|  |         self.memory_maximum = None	#the maximum memory size | ||||||
|         self.mem_used = None		#used memory, computed based on meminfo |         self.mem_used = None		#used memory, computed based on meminfo | ||||||
|         self.id = id			#domain id |         self.id = id			#domain id | ||||||
|         self.last_target = 0		#the last memset target |         self.last_target = 0		#the last memset target | ||||||
| @ -27,6 +28,7 @@ class SystemState: | |||||||
| 
 | 
 | ||||||
|     def del_domain(self, id): |     def del_domain(self, id): | ||||||
|         self.domdict.pop(id) |         self.domdict.pop(id) | ||||||
|  |         self.do_balance() | ||||||
| 
 | 
 | ||||||
|     def get_free_xen_memory(self): |     def get_free_xen_memory(self): | ||||||
|         return self.xc.physinfo()['free_memory']*1024 |         return self.xc.physinfo()['free_memory']*1024 | ||||||
| @ -42,6 +44,9 @@ class SystemState: | |||||||
|             id = str(domain['domid']) |             id = str(domain['domid']) | ||||||
|             if self.domdict.has_key(id): |             if self.domdict.has_key(id): | ||||||
|                 self.domdict[id].memory_actual = domain['mem_kb']*1024 |                 self.domdict[id].memory_actual = domain['mem_kb']*1024 | ||||||
|  |                 self.domdict[id].memory_maximum = self.xs.read('', '/local/domain/%s/memory/static-max' % str(id)) | ||||||
|  |                 if not self.domdict[id].memory_maximum: | ||||||
|  |                     self.domdict[id].memory_maximum = domain['maxmem_kb']*1024 | ||||||
| 
 | 
 | ||||||
| #the below works (and is fast), but then 'xm list' shows unchanged memory value | #the below works (and is fast), but then 'xm list' shows unchanged memory value | ||||||
|     def mem_set(self, id, val): |     def mem_set(self, id, val): | ||||||
| @ -51,6 +56,7 @@ class SystemState: | |||||||
| #can happen in the middle of domain shutdown | #can happen in the middle of domain shutdown | ||||||
| #apparently xc.lowlevel throws exceptions too | #apparently xc.lowlevel throws exceptions too | ||||||
|         try: |         try: | ||||||
|  |             self.xc.domain_setmaxmem(int(id), val/1024 + 1024) # LIBXL_MAXMEM_CONSTANT=1024 | ||||||
|             self.xc.domain_set_target_mem(int(id), val/1024) |             self.xc.domain_set_target_mem(int(id), val/1024) | ||||||
|         except: |         except: | ||||||
|             pass |             pass | ||||||
|  | |||||||
| @ -60,8 +60,8 @@ def prefmem(domain): | |||||||
|     CACHE_FACTOR = 1.3 |     CACHE_FACTOR = 1.3 | ||||||
| #dom0 is special, as it must have large cache, for vbds. Thus, give it a special boost | #dom0 is special, as it must have large cache, for vbds. Thus, give it a special boost | ||||||
|     if domain.id == '0': |     if domain.id == '0': | ||||||
|         return domain.mem_used*CACHE_FACTOR + 350*1024*1024 |         return min(domain.mem_used*CACHE_FACTOR + 350*1024*1024, domain.memory_maximum) | ||||||
|     return domain.mem_used*CACHE_FACTOR |     return min(domain.mem_used*CACHE_FACTOR, domain.memory_maximum) | ||||||
| 
 | 
 | ||||||
| def memory_needed(domain): | def memory_needed(domain): | ||||||
| #do not change | #do not change | ||||||
| @ -104,8 +104,11 @@ def balloon(memsize, domain_dictionary): | |||||||
| 
 | 
 | ||||||
| #redistribute positive "total_available_memory" of memory between domains, proportionally to prefmem | #redistribute positive "total_available_memory" of memory between domains, proportionally to prefmem | ||||||
| def balance_when_enough_memory(domain_dictionary, xen_free_memory, total_mem_pref, total_available_memory): | def balance_when_enough_memory(domain_dictionary, xen_free_memory, total_mem_pref, total_available_memory): | ||||||
|     donors_rq = list() |     print 'balance_when_enough_memory(', xen_free_memory, total_mem_pref, total_available_memory, ')' | ||||||
|     acceptors_rq = list() |     target_memory = {} | ||||||
|  |     # memory not assigned because of static max | ||||||
|  |     left_memory = 0 | ||||||
|  |     acceptors_count = 0 | ||||||
|     for i in domain_dictionary.keys(): |     for i in domain_dictionary.keys(): | ||||||
|         if domain_dictionary[i].meminfo is None: |         if domain_dictionary[i].meminfo is None: | ||||||
|             continue |             continue | ||||||
| @ -114,10 +117,43 @@ def balance_when_enough_memory(domain_dictionary, xen_free_memory, total_mem_pre | |||||||
|         target_nonint = prefmem(domain_dictionary[i]) + scale*total_available_memory |         target_nonint = prefmem(domain_dictionary[i]) + scale*total_available_memory | ||||||
| #prevent rounding errors | #prevent rounding errors | ||||||
|         target = int(0.999*target_nonint) |         target = int(0.999*target_nonint) | ||||||
|  | #do not try to give more memory than static max | ||||||
|  |         if target > domain_dictionary[i].memory_maximum: | ||||||
|  |             left_memory += target-domain_dictionary[i].memory_maximum | ||||||
|  |             target = domain_dictionary[i].memory_maximum | ||||||
|  |         else: | ||||||
|  | # count domains which can accept more memory | ||||||
|  |             acceptors_count += 1 | ||||||
|  |         target_memory[i] = target | ||||||
|  | # distribute left memory across all acceptors | ||||||
|  |     while left_memory > 0 and acceptors_count > 0: | ||||||
|  |         print '  left_memory:', left_memory, 'acceptors_count:', acceptors_count | ||||||
|  |         new_left_memory = 0 | ||||||
|  |         new_acceptors_count = acceptors_count | ||||||
|  |         for i in target_memory.keys(): | ||||||
|  |             target = target_memory[i] | ||||||
|  |             if target < domain_dictionary[i].memory_maximum: | ||||||
|  |                 memory_bonus = int(0.999*(left_memory/acceptors_count)) | ||||||
|  |                 if target+memory_bonus >= domain_dictionary[i].memory_maximum: | ||||||
|  |                     new_left_memory += target+memory_bonus - domain_dictionary[i].memory_maximum | ||||||
|  |                     target = domain_dictionary[i].memory_maximum | ||||||
|  |                     new_acceptors_count -= 1 | ||||||
|  |                 else: | ||||||
|  |                     target += memory_bonus | ||||||
|  |             target_memory[i] = target | ||||||
|  |         left_memory = new_left_memory | ||||||
|  |         acceptors_count = new_acceptors_count | ||||||
|  | # split target_memory dictionary to donors and acceptors | ||||||
|  | #  this is needed to first get memory from donors and only then give it to acceptors | ||||||
|  |     donors_rq = list() | ||||||
|  |     acceptors_rq = list() | ||||||
|  |     for i in target_memory.keys(): | ||||||
|  |         target = target_memory[i] | ||||||
|         if (target < domain_dictionary[i].memory_actual): |         if (target < domain_dictionary[i].memory_actual): | ||||||
|             donors_rq.append((i, target)) |             donors_rq.append((i, target)) | ||||||
|         else: |         else: | ||||||
|             acceptors_rq.append((i, target)) |             acceptors_rq.append((i, target)) | ||||||
|  | 
 | ||||||
| #    print 'balance(enough): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq | #    print 'balance(enough): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq | ||||||
|     return donors_rq + acceptors_rq |     return donors_rq + acceptors_rq | ||||||
| 
 | 
 | ||||||
| @ -140,7 +176,9 @@ def balance_when_low_on_memory(domain_dictionary, xen_free_memory, total_mem_pre | |||||||
|     for i in acceptors: |     for i in acceptors: | ||||||
|         scale = 1.0*prefmem(domain_dictionary[i])/total_mem_pref_acceptors |         scale = 1.0*prefmem(domain_dictionary[i])/total_mem_pref_acceptors | ||||||
|         target_nonint = domain_dictionary[i].memory_actual + scale*squeezed_mem |         target_nonint = domain_dictionary[i].memory_actual + scale*squeezed_mem | ||||||
|         acceptors_rq.append((i, int(target_nonint)))        | #do not try to give more memory than static max | ||||||
|  |         target = min(int(0.999*target_nonint), domain_dictionary[i].memory_maximum) | ||||||
|  |         acceptors_rq.append((i, target)) | ||||||
| #    print 'balance(low): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq | #    print 'balance(low): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq | ||||||
|     return donors_rq + acceptors_rq |     return donors_rq + acceptors_rq | ||||||
| 
 | 
 | ||||||
| @ -171,7 +209,7 @@ def balance(xen_free_memory, domain_dictionary): | |||||||
|             continue |             continue | ||||||
|         need = memory_needed(domain_dictionary[i]) |         need = memory_needed(domain_dictionary[i]) | ||||||
| #        print 'domain' , i, 'act/pref', domain_dictionary[i].memory_actual, prefmem(domain_dictionary[i]), 'need=', need | #        print 'domain' , i, 'act/pref', domain_dictionary[i].memory_actual, prefmem(domain_dictionary[i]), 'need=', need | ||||||
|         if need < 0: |         if need < 0 or domain_dictionary[i].memory_actual >= domain_dictionary[i].memory_maximum: | ||||||
|             donors.append(i) |             donors.append(i) | ||||||
|         else: |         else: | ||||||
|             acceptors.append(i) |             acceptors.append(i) | ||||||
|  | |||||||
| @ -29,10 +29,11 @@ class WatchType: | |||||||
| class XS_Watcher: | class XS_Watcher: | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         self.handle = xen.lowlevel.xs.xs() |         self.handle = xen.lowlevel.xs.xs() | ||||||
|         self.handle.watch('/vm', WatchType(XS_Watcher.domain_list_changed, None)) |         self.handle.watch('/local/domain', WatchType(XS_Watcher.domain_list_changed, None)) | ||||||
|         self.watch_token_dict = {} |         self.watch_token_dict = {} | ||||||
| 
 | 
 | ||||||
|     def domain_list_changed(self, param): |     def domain_list_changed(self, param): | ||||||
|  |         time.sleep(0.05) | ||||||
|         curr = self.handle.ls('', '/local/domain') |         curr = self.handle.ls('', '/local/domain') | ||||||
|         if curr == None: |         if curr == None: | ||||||
|             return |             return | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								dom0/qubes-cached.repo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								dom0/qubes-cached.repo
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | [qubes-dom0-cached] | ||||||
|  | name = Qubes OS Repository for Dom0 | ||||||
|  | baseurl = file:///var/lib/qubes/updates | ||||||
|  | gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-1-primary | ||||||
|  | gpgcheck = 1 | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -64,14 +64,6 @@ def main(): | |||||||
|         qvm_collection.pop(vm.qid) |         qvm_collection.pop(vm.qid) | ||||||
|         exit (1) |         exit (1) | ||||||
| 
 | 
 | ||||||
|     try: |  | ||||||
|         vm.add_to_xen_storage() |  | ||||||
| 
 |  | ||||||
|     except (IOError, OSError) as err: |  | ||||||
|         print "ERROR: {0}".format(err) |  | ||||||
|         qvm_collection.pop(vm.qid) |  | ||||||
|         exit (1) |  | ||||||
| 
 |  | ||||||
|     qvm_collection.save() |     qvm_collection.save() | ||||||
|     qvm_collection.unlock_db() |     qvm_collection.unlock_db() | ||||||
|      |      | ||||||
|  | |||||||
| @ -164,7 +164,6 @@ def main(): | |||||||
| 
 | 
 | ||||||
|     try: |     try: | ||||||
|         vm.create_on_disk(verbose=options.verbose, source_template=template_vm) |         vm.create_on_disk(verbose=options.verbose, source_template=template_vm) | ||||||
|         vm.add_to_xen_storage() |  | ||||||
| 
 | 
 | ||||||
|     except (IOError, OSError) as err: |     except (IOError, OSError) as err: | ||||||
|         print "ERROR: {0}".format(err) |         print "ERROR: {0}".format(err) | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								dom0/qvm-tools/qvm-dom0-upgrade
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								dom0/qvm-tools/qvm-dom0-upgrade
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | UPDATEVM=`qvm-get-updatevm` | ||||||
|  | if [ -z "$UPDATEVM" ]; then | ||||||
|  |     echo "UpdateVM not set, exiting" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | echo "Checking for dom0 updates" | ||||||
|  | 
 | ||||||
|  | # Start VM if not running already | ||||||
|  | qvm-run -a $UPDATEVM true || exit 1 | ||||||
|  | /usr/lib/qubes/sync_rpmdb_updatevm.sh || exit 1 | ||||||
|  | qvm-run -u root --pass_io $UPDATEVM "/usr/lib/qubes/qubes_download_dom0_updates.sh --doit $@" || exit 1 | ||||||
|  | yum check-update | ||||||
|  | if [ $? -ne 100 ]; then | ||||||
|  |     exit 0 | ||||||
|  | fi | ||||||
|  | gpk-update-viewer | ||||||
|  | 
 | ||||||
							
								
								
									
										39
									
								
								dom0/qvm-tools/qvm-get-updatevm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								dom0/qvm-tools/qvm-get-updatevm
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #!/usr/bin/python2.6 | ||||||
|  | # | ||||||
|  | # The Qubes OS Project, http://www.qubes-os.org | ||||||
|  | # | ||||||
|  | # Copyright (C) 2010  Joanna Rutkowska <joanna@invisiblethingslab.com> | ||||||
|  | # | ||||||
|  | # This program is free software; you can redistribute it and/or | ||||||
|  | # modify it under the terms of the GNU General Public License | ||||||
|  | # as published by the Free Software Foundation; either version 2 | ||||||
|  | # of the License, or (at your option) any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | from qubes.qubes import QubesVmCollection | ||||||
|  | from optparse import OptionParser; | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |     qvm_collection = QubesVmCollection() | ||||||
|  |     qvm_collection.lock_db_for_reading() | ||||||
|  |     qvm_collection.load() | ||||||
|  |     qvm_collection.unlock_db() | ||||||
|  |     updatevm = qvm_collection.get_updatevm_vm() | ||||||
|  |     if updatevm is None: | ||||||
|  |         print "" | ||||||
|  |     else: | ||||||
|  |         print updatevm.name | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | main() | ||||||
| @ -21,6 +21,7 @@ | |||||||
| # | # | ||||||
| 
 | 
 | ||||||
| from qubes.qubes import QubesVmCollection | from qubes.qubes import QubesVmCollection | ||||||
|  | from qubes.qubes import QubesHost | ||||||
| from qubes.qubes import QubesException | from qubes.qubes import QubesException | ||||||
| from optparse import OptionParser | from optparse import OptionParser | ||||||
| 
 | 
 | ||||||
| @ -59,8 +60,8 @@ fields = { | |||||||
| 
 | 
 | ||||||
|     "xid" : {"func" : "vm.get_xid() if vm.is_running() else '-'"}, |     "xid" : {"func" : "vm.get_xid() if vm.is_running() else '-'"}, | ||||||
| 
 | 
 | ||||||
|     "mem" : {"func" : "(str(vm.get_mem()/1024/1024) + ' MB') if vm.is_running() else '-'"}, |     "mem" : {"func" : "(str(vm.get_mem()/1024) + ' MB') if vm.is_running() else '-'"}, | ||||||
|     "cpu" : {"func" : "round (vm.get_cpu_total_load(), 1) if vm.is_running() else '-'"}, |     "cpu" : {"func" : "round (cpu_usages[vm.get_xid()]['cpu_usage'], 1) if vm.is_running() else '-'"}, | ||||||
|     "disk": {"func" : "str(vm.get_disk_utilization()/(1024*1024)) + ' MB'"},  |     "disk": {"func" : "str(vm.get_disk_utilization()/(1024*1024)) + ' MB'"},  | ||||||
|     "state": {"func" : "vm.get_power_state()"}, |     "state": {"func" : "vm.get_power_state()"}, | ||||||
| 
 | 
 | ||||||
| @ -114,10 +115,14 @@ def main(): | |||||||
| 
 | 
 | ||||||
|     fields_to_display = ["name", "on", "state", "updbl", "type", "template", "netvm", "label" ] |     fields_to_display = ["name", "on", "state", "updbl", "type", "template", "netvm", "label" ] | ||||||
| 
 | 
 | ||||||
|  |     cpu_usages = None | ||||||
|  | 
 | ||||||
|     if (options.ids): |     if (options.ids): | ||||||
|         fields_to_display += ["qid", "xid"] |         fields_to_display += ["qid", "xid"] | ||||||
| 
 | 
 | ||||||
|     if (options.cpu): |     if (options.cpu): | ||||||
|  |         qhost = QubesHost() | ||||||
|  |         (measure_time, cpu_usages) = qhost.measure_cpu_usage() | ||||||
|         fields_to_display += ["cpu"] |         fields_to_display += ["cpu"] | ||||||
| 
 | 
 | ||||||
|     if (options.mem): |     if (options.mem): | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ def do_list(vm): | |||||||
|     print fmt.format ("name", vm.name) |     print fmt.format ("name", vm.name) | ||||||
|     print fmt.format ("label", vm.label.name) |     print fmt.format ("label", vm.label.name) | ||||||
|     print fmt.format ("type", vm.type) |     print fmt.format ("type", vm.type) | ||||||
|     if vm.is_appvm(): |     if vm.template_vm is not None: | ||||||
|         print fmt.format ("template", vm.template_vm.name) |         print fmt.format ("template", vm.template_vm.name) | ||||||
|     if vm.netvm_vm is not None: |     if vm.netvm_vm is not None: | ||||||
|         print fmt.format ("netvm", vm.netvm_vm.name) |         print fmt.format ("netvm", vm.netvm_vm.name) | ||||||
| @ -40,15 +40,18 @@ def do_list(vm): | |||||||
|     print fmt.format ("installed by RPM?", vm.installed_by_rpm) |     print fmt.format ("installed by RPM?", vm.installed_by_rpm) | ||||||
|     print fmt.format ("dir", vm.dir_path) |     print fmt.format ("dir", vm.dir_path) | ||||||
|     print fmt.format ("config", vm.conf_file) |     print fmt.format ("config", vm.conf_file) | ||||||
|  |     print fmt.format ("pcidevs", vm.pcidevs) | ||||||
|     if not vm.is_appvm(): |     if not vm.is_appvm(): | ||||||
|         print fmt.format ("root img", vm.root_img) |         print fmt.format ("root img", vm.root_img) | ||||||
|     if vm.is_template(): |     if vm.is_template(): | ||||||
|         print fmt.format ("root COW img", vm.rootcow_img) |         print fmt.format ("root COW img", vm.rootcow_img) | ||||||
|     if vm.is_appvm(): |     if vm.template_vm is not None: | ||||||
|         print fmt.format ("root img", vm.template_vm.root_img) |         print fmt.format ("root img", vm.template_vm.root_img) | ||||||
|     print fmt.format ("root volatile img", vm.volatile_img) |     print fmt.format ("root volatile img", vm.volatile_img) | ||||||
| 
 | 
 | ||||||
|     print fmt.format ("private img", vm.private_img) |     print fmt.format ("private img", vm.private_img) | ||||||
|  |     print fmt.format ("memory", vm.memory) | ||||||
|  |     print fmt.format ("maxmem", vm.maxmem) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def set_label(vms, vm, args): | def set_label(vms, vm, args): | ||||||
| @ -65,6 +68,23 @@ def set_label(vms, vm, args): | |||||||
|     vm.label = QubesVmLabels[label] |     vm.label = QubesVmLabels[label] | ||||||
|     subprocess.check_call (["ln", "-sf", vm.label.icon_path, vm.icon_path]) |     subprocess.check_call (["ln", "-sf", vm.label.icon_path, vm.icon_path]) | ||||||
| 
 | 
 | ||||||
|  | def set_memory(vms, vm, args): | ||||||
|  |     if len (args) != 1: | ||||||
|  |         print "Missing memory argument!" | ||||||
|  | 
 | ||||||
|  |     vm.memory = int(args[0]) | ||||||
|  | 
 | ||||||
|  | def set_maxmem(vms, vm, args): | ||||||
|  |     if len (args) != 1: | ||||||
|  |         print "Missing maxmem argument!" | ||||||
|  | 
 | ||||||
|  |     vm.maxmem = int(args[0]) | ||||||
|  | 
 | ||||||
|  | def set_pcidevs(vms, vm, args): | ||||||
|  |     if len (args) != 1: | ||||||
|  |         print "Missing memory argument!" | ||||||
|  | 
 | ||||||
|  |     vm.pcidevs = args[0] | ||||||
| 
 | 
 | ||||||
| def set_netvm(vms, vm, args): | def set_netvm(vms, vm, args): | ||||||
|     if len (args) != 1: |     if len (args) != 1: | ||||||
| @ -151,8 +171,11 @@ def set_nonupdateable(vms, vm, args): | |||||||
| properties = { | properties = { | ||||||
|     "updateable": set_updateable, |     "updateable": set_updateable, | ||||||
|     "nonupdateable": set_nonupdateable, |     "nonupdateable": set_nonupdateable, | ||||||
|  |     "pcidevs": set_pcidevs, | ||||||
|     "label" : set_label, |     "label" : set_label, | ||||||
|     "netvm" : set_netvm, |     "netvm" : set_netvm, | ||||||
|  |     "maxmem" : set_maxmem, | ||||||
|  |     "memory" : set_memory, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										140
									
								
								dom0/qvm-tools/qvm-revert-template-changes
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										140
									
								
								dom0/qvm-tools/qvm-revert-template-changes
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,140 @@ | |||||||
|  | #!/usr/bin/python2.6 | ||||||
|  | # | ||||||
|  | # The Qubes OS Project, http://www.qubes-os.org | ||||||
|  | # | ||||||
|  | # Copyright (C) 2011  Marek Marczykowski <marmarek@mimuw.edu.pl> | ||||||
|  | # | ||||||
|  | # This program is free software; you can redistribute it and/or | ||||||
|  | # modify it under the terms of the GNU General Public License | ||||||
|  | # as published by the Free Software Foundation; either version 2 | ||||||
|  | # of the License, or (at your option) any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | from qubes.qubes import QubesVmCollection | ||||||
|  | from qubes.qubes import QubesException | ||||||
|  | from optparse import OptionParser | ||||||
|  | import subprocess | ||||||
|  | import os | ||||||
|  | import time | ||||||
|  | import glob | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |     usage = "usage: %prog [options] <template-name>" | ||||||
|  |     parser = OptionParser (usage) | ||||||
|  |     parser.add_option ("--force", action="store_true", dest="force", default=False, | ||||||
|  |             help="Do not prompt for comfirmation") | ||||||
|  | 
 | ||||||
|  |     (options, args) = parser.parse_args () | ||||||
|  |     if (len (args) != 1): | ||||||
|  |         parser.error ("You must specify TemplateVM name!") | ||||||
|  |     vmname = args[0] | ||||||
|  | 
 | ||||||
|  |     if os.geteuid() != 0: | ||||||
|  |         print "ERROR: This tool must be run as root!" | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     qvm_collection = QubesVmCollection() | ||||||
|  |     qvm_collection.lock_db_for_reading() | ||||||
|  |     qvm_collection.load() | ||||||
|  |     qvm_collection.unlock_db() | ||||||
|  | 
 | ||||||
|  |     vm = qvm_collection.get_vm_by_name(vmname) | ||||||
|  |     if vm is None: | ||||||
|  |         print "A VM with the name '{0}' does not exist in the system.".format(vmname) | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     if not vm.is_template(): | ||||||
|  |         print "A VM '{0}' is not template.".format(vmname) | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     if vm.is_running(): | ||||||
|  |         print "You must stop VM first." | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     oldcow_img = vm.rootcow_img + '.old' | ||||||
|  |     oldcow_stat = os.stat(oldcow_img) | ||||||
|  |     oldcow_time_str = time.strftime("%F %T", time.gmtime(oldcow_stat.st_mtime)) | ||||||
|  | 
 | ||||||
|  |     root_stat = os.stat(vm.root_img) | ||||||
|  |     old_dmdev = "/dev/mapper/snapshot-{0:x}:{1}-{2:x}:{3}".format( | ||||||
|  |         root_stat[2], root_stat[1], | ||||||
|  |         oldcow_stat[2], oldcow_stat[1]) | ||||||
|  | 
 | ||||||
|  |     snapshots = glob.glob('/dev/mapper/snapshot-{0:x}:{1}-*'.format(root_stat[2], root_stat[1])) | ||||||
|  |     snapshot_present = False | ||||||
|  |     for dev in snapshots: | ||||||
|  |         if dev == old_dmdev: | ||||||
|  |             snapshot_present = True | ||||||
|  |         else: | ||||||
|  |             print "ERROR: You must shutdown all VMs running system older/newer than last good one." | ||||||
|  |             exit(1) | ||||||
|  | 
 | ||||||
|  |     root_blocks = os.path.getsize(vm.root_img)/512 | ||||||
|  |     if not snapshot_present: | ||||||
|  |         p = subprocess.Popen (["/etc/xen/scripts/block-snapshot", "prepare", | ||||||
|  |             "snapshot", "{0}:{1}".format(vm.root_img, oldcow_img)], | ||||||
|  |             stdout=subprocess.PIPE) | ||||||
|  |         result = p.communicate() | ||||||
|  |         if result[0].strip() != old_dmdev: | ||||||
|  |             print "ERROR: Cannot create snapshot device ({0} != {1})".format( | ||||||
|  |                     result[0].strip(), old_dmdev) | ||||||
|  |             exit(1) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     print "INFO: Reverting template changes done at {0}".format(oldcow_time_str) | ||||||
|  |     if not options.force: | ||||||
|  |         prompt = raw_input ("Do you want to proceed? [y/N] ") | ||||||
|  |         if not (prompt == "y" or prompt == "Y"): | ||||||
|  |             exit (0) | ||||||
|  |      | ||||||
|  |     p = subprocess.Popen(["/sbin/dmsetup", "table", old_dmdev], stdout=subprocess.PIPE) | ||||||
|  |     result = p.communicate() | ||||||
|  |     dm_table = result[0] | ||||||
|  |     dm_table_elements = dm_table.split(' ') | ||||||
|  |     if dm_table_elements[2] != 'snapshot': | ||||||
|  |         print "ERROR: Unexpected device-mapper type ({0}). Template changes reverting already running".format(dm_table_elements[2]) | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     dm_table_elements[2] = 'snapshot-merge' | ||||||
|  |     dm_table = ' '.join(dm_table_elements) | ||||||
|  |     subprocess.check_call(["/sbin/dmsetup", "reload", old_dmdev, "--table", dm_table]) | ||||||
|  |     # Reload new table into LIVE slot | ||||||
|  |     subprocess.check_call(["/sbin/dmsetup", "suspend", old_dmdev]) | ||||||
|  |     subprocess.check_call(["/sbin/dmsetup", "resume", old_dmdev]) | ||||||
|  |     # Wait to snapshot merge completed | ||||||
|  |     while True: | ||||||
|  |         p = subprocess.Popen(["/sbin/dmsetup", "status", old_dmdev], stdout=subprocess.PIPE) | ||||||
|  |         result = p.communicate() | ||||||
|  |         status_details = result[0].split(' ') | ||||||
|  |         blocks_used = status_details[3].split('/')[0] | ||||||
|  |         if int(blocks_used) == int(status_details[4]): | ||||||
|  |             break | ||||||
|  |         print "\r-> Reverting template changes: {0} of {1} left".format(blocks_used, root_blocks), | ||||||
|  |         time.sleep(1) | ||||||
|  |     print "\r-> Reverting template changes: done                  ".format(blocks_used, root_blocks) | ||||||
|  | 
 | ||||||
|  |     dm_table_elements[2] = 'snapshot' | ||||||
|  |     dm_table = ' '.join(dm_table_elements) | ||||||
|  |     subprocess.check_call(["/sbin/dmsetup", "reload", old_dmdev, "--table", dm_table]) | ||||||
|  |     # Reload new table into LIVE slot | ||||||
|  |     subprocess.check_call(["/sbin/dmsetup", "suspend", old_dmdev]) | ||||||
|  |     subprocess.check_call(["/sbin/dmsetup", "resume", old_dmdev]) | ||||||
|  | 
 | ||||||
|  |     subprocess.check_call(["/etc/xen/scripts/block-snapshot", "cleanup", | ||||||
|  |             "snapshot", old_dmdev]) | ||||||
|  | 
 | ||||||
|  |     os.rename(oldcow_img, vm.rootcow_img) | ||||||
|  |     exit(0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | main() | ||||||
| @ -79,19 +79,19 @@ def vm_run_cmd(vm, cmd, options): | |||||||
|     if options.shutdown: |     if options.shutdown: | ||||||
|         if options.verbose: |         if options.verbose: | ||||||
|             print "Shutting down VM: '{0}'...".format(vm.name) |             print "Shutting down VM: '{0}'...".format(vm.name) | ||||||
|         subprocess.call (["/usr/sbin/xm", "shutdown", vm.name]) |         subprocess.call (["/usr/sbin/xl", "shutdown", vm.name]) | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|     if options.pause: |     if options.pause: | ||||||
|         if options.verbose: |         if options.verbose: | ||||||
|             print "Pausing VM: '{0}'...".format(vm.name) |             print "Pausing VM: '{0}'...".format(vm.name) | ||||||
|         subprocess.call (["/usr/sbin/xm", "pause", vm.name]) |         subprocess.call (["/usr/sbin/xl", "pause", vm.name]) | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|     if options.unpause: |     if options.unpause: | ||||||
|         if options.verbose: |         if options.verbose: | ||||||
|             print "UnPausing VM: '{0}'...".format(vm.name) |             print "UnPausing VM: '{0}'...".format(vm.name) | ||||||
|         subprocess.call (["/usr/sbin/xm", "unpause", vm.name]) |         subprocess.call (["/usr/sbin/xl", "unpause", vm.name]) | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|     if options.verbose: |     if options.verbose: | ||||||
| @ -152,13 +152,13 @@ def main(): | |||||||
|                       help="Wait for the VM(s) to shutdown") |                       help="Wait for the VM(s) to shutdown") | ||||||
| 
 | 
 | ||||||
|     parser.add_option ("--shutdown", action="store_true", dest="shutdown", default=False, |     parser.add_option ("--shutdown", action="store_true", dest="shutdown", default=False, | ||||||
|                       help="Do 'xm shutdown' for the VM(s) (can be combined this with --all and --wait)") |                       help="Do 'xl shutdown' for the VM(s) (can be combined this with --all and --wait)") | ||||||
| 
 | 
 | ||||||
|     parser.add_option ("--pause", action="store_true", dest="pause", default=False, |     parser.add_option ("--pause", action="store_true", dest="pause", default=False, | ||||||
|                       help="Do 'xm pause' for the VM(s) (can be combined this with --all and --wait)") |                       help="Do 'xl pause' for the VM(s) (can be combined this with --all and --wait)") | ||||||
| 
 | 
 | ||||||
|     parser.add_option ("--unpause", action="store_true", dest="unpause", default=False, |     parser.add_option ("--unpause", action="store_true", dest="unpause", default=False, | ||||||
|                       help="Do 'xm unpause' for the VM(s) (can be combined this with --all and --wait)") |                       help="Do 'xl unpause' for the VM(s) (can be combined this with --all and --wait)") | ||||||
| 
 | 
 | ||||||
|     parser.add_option ("--pass_io", action="store_true", dest="passio", default=False, |     parser.add_option ("--pass_io", action="store_true", dest="passio", default=False, | ||||||
|                       help="Pass stdin/stdout/stderr from remote program") |                       help="Pass stdin/stdout/stderr from remote program") | ||||||
| @ -166,6 +166,9 @@ def main(): | |||||||
|     parser.add_option ("--localcmd", action="store", dest="localcmd", default=None, |     parser.add_option ("--localcmd", action="store", dest="localcmd", default=None, | ||||||
|                       help="With --pass_io, pass stdin/stdout/stderr to the given program") |                       help="With --pass_io, pass stdin/stdout/stderr to the given program") | ||||||
| 
 | 
 | ||||||
|  |     parser.add_option ("--force", action="store_true", dest="force", default=False, | ||||||
|  |                       help="Force operation, even if may damage other VMs (eg shutdown of NetVM)") | ||||||
|  | 
 | ||||||
|     (options, args) = parser.parse_args () |     (options, args) = parser.parse_args () | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -218,8 +221,12 @@ def main(): | |||||||
|      |      | ||||||
|         # If stopping NetVM - stop connected VMs too |         # If stopping NetVM - stop connected VMs too | ||||||
|         if options.shutdown and vm.is_netvm(): |         if options.shutdown and vm.is_netvm(): | ||||||
|             vms_list += [vm for vm in qvm_collection.get_vms_connected_to(vm.qid) if vm.is_running()] |             connected_vms =  [vm for vm in qvm_collection.get_vms_connected_to(vm.qid) if vm.is_running()] | ||||||
|             vms_list.reverse() |             if connected_vms and not options.force: | ||||||
|  |                 print "ERROR: There are other VMs connected to this VM, " | ||||||
|  |                 print "       shutdown them first or use --force option" | ||||||
|  |                 print "VMs list: " + str([vm.name for vm in connected_vms]) | ||||||
|  |                 exit(1) | ||||||
| 
 | 
 | ||||||
|     if takes_cmd_argument: |     if takes_cmd_argument: | ||||||
|         cmd = "{user}:{cmd}".format(user=options.user, cmd=cmdstr) |         cmd = "{user}:{cmd}".format(user=options.user, cmd=cmdstr) | ||||||
|  | |||||||
							
								
								
									
										46
									
								
								dom0/qvm-tools/qvm-set-updatevm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								dom0/qvm-tools/qvm-set-updatevm
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | #!/usr/bin/python2.6 | ||||||
|  | # | ||||||
|  | # The Qubes OS Project, http://www.qubes-os.org | ||||||
|  | # | ||||||
|  | # Copyright (C) 2010  Joanna Rutkowska <joanna@invisiblethingslab.com> | ||||||
|  | # | ||||||
|  | # This program is free software; you can redistribute it and/or | ||||||
|  | # modify it under the terms of the GNU General Public License | ||||||
|  | # as published by the Free Software Foundation; either version 2 | ||||||
|  | # of the License, or (at your option) any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | from qubes.qubes import QubesVmCollection | ||||||
|  | from optparse import OptionParser; | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |     usage = "usage: %prog <vm-name>" | ||||||
|  |     parser = OptionParser (usage) | ||||||
|  |     (options, args) = parser.parse_args () | ||||||
|  |     if (len (args) != 1): | ||||||
|  |         parser.error ("Missing argument!") | ||||||
|  |     vmname = args[0] | ||||||
|  | 
 | ||||||
|  |     qvm_collection = QubesVmCollection() | ||||||
|  |     qvm_collection.lock_db_for_writing() | ||||||
|  |     qvm_collection.load() | ||||||
|  |     vm = qvm_collection.get_vm_by_name(vmname) | ||||||
|  |     if vm is None or vm.qid not in qvm_collection: | ||||||
|  |         print "A VM with the name '{0}' does not exist in the system.".format(vmname) | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     qvm_collection.set_updatevm_vm(vm) | ||||||
|  |     qvm_collection.save() | ||||||
|  |     qvm_collection.unlock_db() | ||||||
|  | 
 | ||||||
|  | main() | ||||||
							
								
								
									
										199
									
								
								dom0/qvm-tools/qvm-sync-appmenus
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										199
									
								
								dom0/qvm-tools/qvm-sync-appmenus
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,199 @@ | |||||||
|  | #!/usr/bin/python | ||||||
|  | # | ||||||
|  | # The Qubes OS Project, http://www.qubes-os.org | ||||||
|  | # | ||||||
|  | # Copyright (C) 2011  Marek Marczykowski <marmarek@mimuw.edu.pl> | ||||||
|  | # | ||||||
|  | # This program is free software; you can redistribute it and/or | ||||||
|  | # modify it under the terms of the GNU General Public License | ||||||
|  | # as published by the Free Software Foundation; either version 2 | ||||||
|  | # of the License, or (at your option) any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | import subprocess | ||||||
|  | import re | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import fnmatch | ||||||
|  | import shutil | ||||||
|  | from optparse import OptionParser | ||||||
|  | from qubes.qubes import QubesVmCollection,QubesException | ||||||
|  | from qubes.qubes import qrexec_client_path | ||||||
|  | 
 | ||||||
|  | # fields required to be present (and verified) in retrieved desktop file | ||||||
|  | required_fields = [ "Name", "Exec" ] | ||||||
|  | 
 | ||||||
|  | # regexps for sanitization of retrieved values | ||||||
|  | std_re = re.compile(r"^[/a-zA-Z0-9.,&() -]*$") | ||||||
|  | fields_regexp = { | ||||||
|  |     "Name": std_re, | ||||||
|  |     "GenericName": std_re, | ||||||
|  |     "Comment": std_re, | ||||||
|  |     "Categories": re.compile(r"^[a-zA-Z0-9/.; -]*$"), | ||||||
|  |     "Exec": re.compile(r"^[a-zA-Z0-9%>/:.= -]*$"), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | def get_appmenus(xid): | ||||||
|  |     untrusted_appmenulist = [] | ||||||
|  |     if xid == -1: | ||||||
|  |         untrusted_appmenulist = sys.stdin.readlines() | ||||||
|  |     else: | ||||||
|  |         p = subprocess.Popen ([qrexec_client_path, '-d', str(xid), | ||||||
|  |                 'user:grep -H = /usr/share/applications/*.desktop'], stdout=subprocess.PIPE) | ||||||
|  |         untrusted_appmenulist = p.communicate()[0].split('\n') | ||||||
|  |         if p.returncode != 0: | ||||||
|  |             raise QubesException("Error getting application list") | ||||||
|  | 
 | ||||||
|  |     row_no = 0 | ||||||
|  |     appmenus = {} | ||||||
|  |     line_rx = re.compile(r"([a-zA-Z0-9-.]+.desktop):([a-zA-Z0-9-]+(?:\[[a-zA-Z@_]+\])?)=(.*)") | ||||||
|  |     ignore_rx = re.compile(r".*([a-zA-Z0-9-.]+.desktop):(#.*|\s+)$") | ||||||
|  |     for untrusted_line in untrusted_appmenulist: | ||||||
|  |         # Ignore blank lines and comments | ||||||
|  |         if len(untrusted_line) == 0 or ignore_rx.match(untrusted_line): | ||||||
|  |             continue  | ||||||
|  |         # use search instead of match to skip file path | ||||||
|  |         untrusted_m = line_rx.search(untrusted_line) | ||||||
|  |         if untrusted_m: | ||||||
|  |             untrusted_key = untrusted_m.group(2) | ||||||
|  |             untrusted_value = untrusted_m.group(3) | ||||||
|  |             if fields_regexp.has_key(untrusted_key): | ||||||
|  |                 if fields_regexp[untrusted_key].match(untrusted_value): | ||||||
|  |                     # now values are sanitized | ||||||
|  |                     key = untrusted_key | ||||||
|  |                     value = untrusted_value | ||||||
|  |                     filename = untrusted_m.group(1) | ||||||
|  | 
 | ||||||
|  |                     if not appmenus.has_key(filename): | ||||||
|  |                         appmenus[filename] = {} | ||||||
|  | 
 | ||||||
|  |                     appmenus[filename][key]=value | ||||||
|  |                 else: | ||||||
|  |                     print >>sys.stderr, "Warning: ignoring key %s: %s" % (untrusted_key, untrusted_value) | ||||||
|  |             # else: ignore this key | ||||||
|  |         else: | ||||||
|  |             print >>sys.stderr, "Warning: ignoring line: %s" % (untrusted_line); | ||||||
|  | 
 | ||||||
|  |     return appmenus | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def create_template(path, values): | ||||||
|  | 
 | ||||||
|  |     # check if all required fields are present | ||||||
|  |     for key in required_fields: | ||||||
|  |         if not values.has_key(key): | ||||||
|  |             print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key) | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |     desktop_file = open(path, "w") | ||||||
|  |     desktop_file.write("[Desktop Entry]\n") | ||||||
|  |     desktop_file.write("Version=1.0\n") | ||||||
|  |     desktop_file.write("Type=Application\n") | ||||||
|  |     desktop_file.write("Terminal=false\n") | ||||||
|  |     desktop_file.write("X-Qubes-VmName=%VMNAME%\n") | ||||||
|  |     desktop_file.write("Icon=%VMDIR%/icon.png\n") | ||||||
|  |     for key in ["Name", "GenericName" ]: | ||||||
|  |         if values.has_key(key): | ||||||
|  |             desktop_file.write("{0}=%VMNAME%: {1}\n".format(key, values[key])) | ||||||
|  |      | ||||||
|  |     for key in [ "Comment", "Categories" ]: | ||||||
|  |         if values.has_key(key): | ||||||
|  |             desktop_file.write("{0}={1}\n".format(key, values[key])) | ||||||
|  | 
 | ||||||
|  |     desktop_file.write("Exec=qvm-run -q --tray -a %VMNAME% '{0}'\n".format(values['Exec'])) | ||||||
|  |     desktop_file.close() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  | 
 | ||||||
|  |     env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN") | ||||||
|  |     usage = "usage: %prog [options] <vm-name>\n"\ | ||||||
|  |             "Updates desktop file templates for given StandaloneVM or TemplateVM" | ||||||
|  | 
 | ||||||
|  |     parser = OptionParser (usage) | ||||||
|  |     parser.add_option ("-v", "--verbose", action="store_true", dest="verbose", default=False) | ||||||
|  | 
 | ||||||
|  |     (options, args) = parser.parse_args () | ||||||
|  |     if (len (args) != 1) and env_vmname is None: | ||||||
|  |         parser.error ("You must specify at least the VM name!") | ||||||
|  | 
 | ||||||
|  |     if env_vmname: | ||||||
|  |         vmname=env_vmname | ||||||
|  |     else: | ||||||
|  |         vmname=args[0] | ||||||
|  | 
 | ||||||
|  |     qvm_collection = QubesVmCollection() | ||||||
|  |     qvm_collection.lock_db_for_reading() | ||||||
|  |     qvm_collection.load() | ||||||
|  |     qvm_collection.unlock_db() | ||||||
|  | 
 | ||||||
|  |     vm = qvm_collection.get_vm_by_name(vmname) | ||||||
|  | 
 | ||||||
|  |     if vm is None: | ||||||
|  |         print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname) | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     if not vm.is_updateable(): | ||||||
|  |         print >>sys.stderr, "ERROR: To sync appmenus for non-updateable VM, do it on template instead" | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     if not vm.is_running(): | ||||||
|  |         print >>sys.stderr, "ERROR: Appmenus can be retrieved only from running VM - start it first" | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     new_appmenus = {} | ||||||
|  |     if env_vmname is None: | ||||||
|  |         # Get appmenus from VM | ||||||
|  |         xid = vm.get_xid() | ||||||
|  |         assert xid > 0 | ||||||
|  | 
 | ||||||
|  |         new_appmenus = get_appmenus(xid) | ||||||
|  |     else: | ||||||
|  |         options.verbose = False | ||||||
|  |         new_appmenus = get_appmenus(-1) | ||||||
|  | 
 | ||||||
|  |     if len(new_appmenus) == 0: | ||||||
|  |         print >>sys.stderr, "ERROR: No appmenus received, terminating" | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     if not os.path.exists(vm.appmenus_templates_dir): | ||||||
|  |         os.mkdir(vm.appmenus_templates_dir) | ||||||
|  |         if vm.is_template(): | ||||||
|  |             shutil.copy('/usr/share/qubes/qubes-templatevm.directory.template', vm.appmenus_templates_dir) | ||||||
|  |         else: | ||||||
|  |             shutil.copy('/usr/share/qubes/qubes-vm.directory.template', vm.appmenus_templates_dir) | ||||||
|  | 
 | ||||||
|  |     # Create new/update existing templates | ||||||
|  |     if options.verbose: | ||||||
|  |         print "--> Got {0} appmenus, storing to disk".format(str(len(new_appmenus))) | ||||||
|  |     for appmenu_file in new_appmenus.keys(): | ||||||
|  |         if options.verbose: | ||||||
|  |             if os.path.exists(vm.appmenus_templates_dir + '/' + appmenu_file): | ||||||
|  |                 print "---> Updating {0}".format(appmenu_file) | ||||||
|  |             else: | ||||||
|  |                 print "---> Creating {0}".format(appmenu_file) | ||||||
|  |         create_template(vm.appmenus_templates_dir + '/' + appmenu_file, new_appmenus[appmenu_file]) | ||||||
|  | 
 | ||||||
|  |     # Delete appmenus of remove applications | ||||||
|  |     if options.verbose: | ||||||
|  |         print "--> Cleaning old files" | ||||||
|  |     for appmenu_file in os.listdir(vm.appmenus_templates_dir): | ||||||
|  |         if not fnmatch.fnmatch(appmenu_file, '*.desktop'): | ||||||
|  |             continue | ||||||
|  | 
 | ||||||
|  |         if not new_appmenus.has_key(appmenu_file): | ||||||
|  |             if options.verbose: | ||||||
|  |                 print "---> Removing {0}".format(appmenu_file) | ||||||
|  |             os.unlink(vm.appmenus_templates_dir + '/' + appmenu_file) | ||||||
|  | 
 | ||||||
|  | main() | ||||||
| @ -1,5 +1,7 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
| 
 | 
 | ||||||
|  | HOTPLUG_STORE="/var/run/xen-hotplug/${XENBUS_PATH//\//-}" | ||||||
|  | 
 | ||||||
| hd_arr[10]=a | hd_arr[10]=a | ||||||
| hd_arr[11]=b | hd_arr[11]=b | ||||||
| hd_arr[12]=c | hd_arr[12]=c | ||||||
| @ -38,6 +40,8 @@ process() | |||||||
| 	xenstore-write "$XENBUS_PATH/node" "$dev" \ | 	xenstore-write "$XENBUS_PATH/node" "$dev" \ | ||||||
| 		"$XENBUS_PATH/physical-device" "7:"$HEXNUMBER \ | 		"$XENBUS_PATH/physical-device" "7:"$HEXNUMBER \ | ||||||
|  		"$XENBUS_PATH/hotplug-status" connected |  		"$XENBUS_PATH/hotplug-status" connected | ||||||
|  | 	echo "$dev" > "$HOTPLUG_STORE-node" | ||||||
|  | 	echo "file" > "$HOTPLUG_STORE-type" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #exec 2>>/tmp/block.$$ | #exec 2>>/tmp/block.$$ | ||||||
|  | |||||||
| @ -22,8 +22,13 @@ | |||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
| import subprocess | import subprocess | ||||||
|  | import shutil | ||||||
|  | import glob | ||||||
| from qubes.qubes import QubesVmCollection | from qubes.qubes import QubesVmCollection | ||||||
| 
 | 
 | ||||||
|  | updates_dir = "/var/lib/qubes/updates" | ||||||
|  | updates_rpm_dir = updates_dir + "/rpm" | ||||||
|  | 
 | ||||||
| def is_copy_allowed(vm): | def is_copy_allowed(vm): | ||||||
| #    if vm.copy_allowed: | #    if vm.copy_allowed: | ||||||
| #        return True | #        return True | ||||||
| @ -33,6 +38,36 @@ def is_copy_allowed(vm): | |||||||
|     retcode = subprocess.call(['/usr/bin/kdialog', '--yesno', q, '--title', 'File transfer confirmation']) |     retcode = subprocess.call(['/usr/bin/kdialog', '--yesno', q, '--title', 'File transfer confirmation']) | ||||||
|     return retcode == 0 |     return retcode == 0 | ||||||
| 
 | 
 | ||||||
|  | def dom0updates_fatal(msg): | ||||||
|  |     print >> sys.stderr, msg | ||||||
|  |     shutil.rmtree(updates_rpm_dir) | ||||||
|  |     exit(1) | ||||||
|  | 
 | ||||||
|  | def handle_dom0updates(updatevm): | ||||||
|  |     source=os.getenv("QREXEC_REMOTE_DOMAIN") | ||||||
|  |     if source != updatevm.name: | ||||||
|  |         print >> sys.stderr, 'Domain ' + source + ' not allowed to send dom0 updates' | ||||||
|  |         exit(1) | ||||||
|  |     # Clean old packages | ||||||
|  |     if os.path.exists(updates_rpm_dir): | ||||||
|  |         shutil.rmtree(updates_rpm_dir) | ||||||
|  |     subprocess.check_call(["/usr/lib/qubes/qfile-dom0-unpacker", os.getlogin(), updates_rpm_dir]) | ||||||
|  |     # Verify received files | ||||||
|  |     for f in os.listdir(updates_rpm_dir): | ||||||
|  |         if glob.fnmatch.fnmatch(f, "*.rpm"): | ||||||
|  |             p = subprocess.Popen (["/bin/rpm", "-K", updates_rpm_dir + "/" + f], | ||||||
|  |                     stdout=subprocess.PIPE) | ||||||
|  |             output = p.communicate()[0] | ||||||
|  |             if p.returncode != 0: | ||||||
|  |                 dom0updates_fatal('Error while verifing %s signature: %s' % (f, output)) | ||||||
|  |             if output.find("pgp") < 0: | ||||||
|  |                 dom0updates_fatal('Domain ' + source + ' sent not signed rpm: ' + f) | ||||||
|  |         else: | ||||||
|  |             dom0updates_fatal('Domain ' + source + ' sent unexpected file: ' + f) | ||||||
|  |     # After updates received - create repo metadata | ||||||
|  |     subprocess.check_call(["/usr/bin/createrepo", "-q", "/var/lib/qubes/updates"]) | ||||||
|  |     exit(0) | ||||||
|  | 
 | ||||||
| def main(): | def main(): | ||||||
|     FILECOPY_VMNAME_SIZE = 32 |     FILECOPY_VMNAME_SIZE = 32 | ||||||
|     blob=os.read(0, FILECOPY_VMNAME_SIZE) |     blob=os.read(0, FILECOPY_VMNAME_SIZE) | ||||||
| @ -43,6 +78,11 @@ def main(): | |||||||
|     qvm_collection.load() |     qvm_collection.load() | ||||||
|     qvm_collection.unlock_db() |     qvm_collection.unlock_db() | ||||||
|      |      | ||||||
|  |     if vmname == '@dom0updates': | ||||||
|  |         updatevm = qvm_collection.get_updatevm_vm() | ||||||
|  |         handle_dom0updates(updatevm) | ||||||
|  |         # handle_dom0updates never returns | ||||||
|  | 
 | ||||||
|     vm = qvm_collection.get_vm_by_name(vmname) |     vm = qvm_collection.get_vm_by_name(vmname) | ||||||
| # we do not want to flood dom0 with error windows; so just log to stderr | # we do not want to flood dom0 with error windows; so just log to stderr | ||||||
|     if vm is None: |     if vm is None: | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ from qubes.qubes import QubesDaemonPidfile | |||||||
| from qubes.qmemman_client import QMemmanClient | from qubes.qmemman_client import QMemmanClient | ||||||
| 
 | 
 | ||||||
| current_savefile = '/var/run/qubes/current_savefile' | current_savefile = '/var/run/qubes/current_savefile' | ||||||
|  | current_dvm_conf = '/var/run/qubes/current_dvm.conf' | ||||||
| notify_object = None | notify_object = None | ||||||
| 
 | 
 | ||||||
| class QfileDaemonDvm: | class QfileDaemonDvm: | ||||||
| @ -58,6 +59,7 @@ class QfileDaemonDvm: | |||||||
|             return None |             return None | ||||||
|         retcode = subprocess.call(['/usr/lib/qubes/qubes_restore', |         retcode = subprocess.call(['/usr/lib/qubes/qubes_restore', | ||||||
|             current_savefile, |             current_savefile, | ||||||
|  |             current_dvm_conf, | ||||||
|             '-c', vm.label.color, |             '-c', vm.label.color, | ||||||
|             '-i', vm.label.icon, |             '-i', vm.label.icon, | ||||||
|             '-l', str(vm.label.index)]) |             '-l', str(vm.label.index)]) | ||||||
| @ -130,7 +132,7 @@ def main(): | |||||||
|     lockf.close() |     lockf.close() | ||||||
|     if dispname is not None: |     if dispname is not None: | ||||||
|         subprocess.call(['/usr/lib/qubes/qrexec_client', '-d', dispname, 'directly:user:/usr/lib/qubes/dvm_file_editor']) |         subprocess.call(['/usr/lib/qubes/qrexec_client', '-d', dispname, 'directly:user:/usr/lib/qubes/dvm_file_editor']) | ||||||
|         subprocess.call(['/usr/sbin/xm', 'destroy', dispname]) |         subprocess.call(['/usr/sbin/xl', 'destroy', dispname]) | ||||||
|         qfile.remove_disposable_from_qdb(dispname) |         qfile.remove_disposable_from_qdb(dispname) | ||||||
| 
 | 
 | ||||||
| main() | main() | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| #!/bin/sh | #!/bin/bash | ||||||
| get_encoded_script() | get_encoded_script() | ||||||
| { | { | ||||||
| 	if ! [ -f "$1" ] ; then | 	if ! [ -f "$1" ] ; then | ||||||
| @ -42,22 +42,24 @@ if [ -n "$ENCODED_SCRIPT" ] ; then | |||||||
| fi | fi | ||||||
| #set -x | #set -x | ||||||
| xenstore-write /local/domain/$ID/qubes_save_request 1  | xenstore-write /local/domain/$ID/qubes_save_request 1  | ||||||
| xenstore-watch /local/domain/$ID/device/qubes_used_mem | xenstore-watch-qubes /local/domain/$ID/device/qubes_used_mem | ||||||
| xenstore-read /local/domain/$ID/qubes_gateway | \ | xenstore-read /local/domain/$ID/qubes_gateway | \ | ||||||
| 	cut -d . -f 2 | tr -d "\n" > $VMDIR/netvm_id.txt | 	cut -d . -f 3 | tr -d "\n" > $VMDIR/netvm_id.txt | ||||||
| xm block-detach $1 /dev/xvdb | xl block-detach $1 xvdb | ||||||
| MEM=$(xenstore-read /local/domain/$ID/device/qubes_used_mem) | MEM=$(xenstore-read /local/domain/$ID/device/qubes_used_mem) | ||||||
| echo "DVM boot complete, memory used=$MEM. Saving image..." | echo "DVM boot complete, memory used=$MEM. Saving image..." | ||||||
| QMEMMAN_STOP=/var/run/qubes/do-not-membalance | QMEMMAN_STOP=/var/run/qubes/do-not-membalance | ||||||
| touch $QMEMMAN_STOP | touch $QMEMMAN_STOP | ||||||
| xm mem-set $1 $(($MEM/1000)) | xl mem-set $1 $(($MEM/1000)) | ||||||
| sleep 1 | sleep 1 | ||||||
| touch $2 | touch $2 | ||||||
| if ! xm save $1 $2 ; then  | if ! xl save $1 $2 ; then  | ||||||
| 	rm -f $QMEMMAN_STOP | 	rm -f $QMEMMAN_STOP | ||||||
| 	exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| rm -f $QMEMMAN_STOP | rm -f $QMEMMAN_STOP | ||||||
| cd $VMDIR | cd $VMDIR | ||||||
|  | # Fix start memory | ||||||
|  | sed -i -e "s/^memory.*/memory = $((MEM/1000))/" dvm.conf | ||||||
| tar -Scvf saved_cows.tar volatile.img | tar -Scvf saved_cows.tar volatile.img | ||||||
| echo "DVM savefile created successfully." | echo "DVM savefile created successfully." | ||||||
|  | |||||||
| @ -12,95 +12,73 @@ | |||||||
| #include <syslog.h> | #include <syslog.h> | ||||||
| #include <xs.h> | #include <xs.h> | ||||||
| 
 | 
 | ||||||
| char xmlrpc_header[] = | int restore_domain(char *restore_file, char *conf_file, char *name) { | ||||||
|     "POST /RPC2 HTTP/1.0\r\n" | 	int pid, status, domid; | ||||||
|     "Host: \r\n" | 	int pipe_fd[2]; | ||||||
|     "User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)\r\n" | 	char buf[256]; | ||||||
|     "Content-Type: text/xml\r\n" "Content-Length: %d\r\n" "\r\n"; | 	char *endptr; | ||||||
| char xmlrpc_body_restore[] = | 	switch (pid = fork()) { | ||||||
|     "<?xml version='1.0'?>\n" | 	case -1: | ||||||
|     "<methodCall>\n" | 		perror("fork"); | ||||||
|     "<methodName>xend.domain.restore</methodName>\n" | 		exit(1); | ||||||
|     "<params>\n" | 	case 0: | ||||||
|     "<param>\n" | 		close(1); | ||||||
|     "<value><string>%s</string></value>\n" | 		if (dup2(open("/dev/null", O_RDWR), 1)==-1) { | ||||||
|     "</param>\n" | 			perror("dup2 or open"); | ||||||
|     "<param>\n" |  | ||||||
|     "<value><boolean>0</boolean></value>\n" |  | ||||||
|     "</param>\n" "</params>\n" "</methodCall>\n"; |  | ||||||
| 
 |  | ||||||
| char xmlrpc_body_setmem[] = |  | ||||||
|     "<?xml version='1.0'?>\n<methodCall>\n<methodName>xend.domain.setMemoryTarget</methodName>\n<params>\n<param>\n<value><string>%d</string></value>\n</param>\n<param>\n<value><int>%d</int></value>\n</param>\n</params>\n</methodCall>\n"; |  | ||||||
| 
 |  | ||||||
| void send_raw(int fd, char *body) |  | ||||||
| { |  | ||||||
| 	char *header; |  | ||||||
| 	asprintf(&header, xmlrpc_header, strlen(body)); |  | ||||||
| 	if (write(fd, header, strlen(header)) != strlen(header)) { |  | ||||||
| 		perror("write xend"); |  | ||||||
| 			exit(1); | 			exit(1); | ||||||
| 		} | 		} | ||||||
| 	if (write(fd, body, strlen(body)) != strlen(body)) { | 		execl("/usr/sbin/xl", "xl", "restore", conf_file, restore_file, NULL); | ||||||
| 		perror("write xend"); | 		perror("execl"); | ||||||
|  | 		exit(1); | ||||||
|  | 	default:; | ||||||
|  | 	} | ||||||
|  | 	if (waitpid(pid, &status, 0) < 0) { | ||||||
|  | 		perror("waitpid"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 	shutdown(fd, SHUT_WR); | 	if (status != 0) { | ||||||
| } | 		fprintf(stderr, "Error starting VM\n"); | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void send_req_restore(int fd, char *name) |  | ||||||
| { |  | ||||||
| 	char *body; |  | ||||||
| 	asprintf(&body, xmlrpc_body_restore, name); |  | ||||||
| 	send_raw(fd, body); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void send_req_setmem(int fd, int domid, int mem) |  | ||||||
| { |  | ||||||
| 	char *body; |  | ||||||
| 	asprintf(&body, xmlrpc_body_setmem, domid, mem); |  | ||||||
| 	send_raw(fd, body); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| char *recv_resp(int fd) |  | ||||||
| { |  | ||||||
| #define RESPSIZE 65536 |  | ||||||
| 	static char buf[RESPSIZE]; |  | ||||||
| 	int total = 0; |  | ||||||
| 	int n; |  | ||||||
| 	for (;;) { |  | ||||||
| 		n = read(fd, buf + total, RESPSIZE - total); |  | ||||||
| 		if (n == 0) { |  | ||||||
| 			buf[total] = 0; |  | ||||||
| 			close(fd); |  | ||||||
| 			return buf; |  | ||||||
| 		} |  | ||||||
| 		if (n < 0) { |  | ||||||
| 			perror("xend read"); |  | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 		total += n; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void bad_resp(char *resp) | 	// read domid
 | ||||||
| { | 	if (pipe(pipe_fd)==-1) { | ||||||
| 	fprintf(stderr, "Error; Xend response:\n%s\n", resp); | 		perror("pipe"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	switch (pid = fork()) { | ||||||
|  | 	case -1: | ||||||
|  | 		perror("fork"); | ||||||
|  | 		exit(1); | ||||||
|  | 	case 0: | ||||||
|  | 		close(1); | ||||||
|  | 		if (dup2(pipe_fd[1], 1) == -1) { | ||||||
|  | 			perror("dup2"); | ||||||
|  | 			exit(1); | ||||||
|  | 		} | ||||||
|  | 		execl("/usr/sbin/xl", "xl", "domid", name, NULL); | ||||||
|  | 		perror("execl"); | ||||||
|  | 		exit(1); | ||||||
|  | 	default:; | ||||||
|  | 	} | ||||||
|  | 	read(pipe_fd[0], buf, sizeof(buf)-1); | ||||||
|  | 	buf[sizeof(buf)-1] = 0; | ||||||
|  | 	domid = strtoul(buf, &endptr, 10); | ||||||
|  | 	if (domid <= 0 || *endptr != '\n') { | ||||||
|  | 		fprintf(stderr, "Cannot get DispVM xid\n"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	if (waitpid(pid, &status, 0) < 0) { | ||||||
|  | 		perror("waitpid"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	if (status != 0) { | ||||||
|  | 		fprintf(stderr, "Error getting DispVM xid\n"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	return domid; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int parse_resp(char *resp) |  | ||||||
| { |  | ||||||
| 	char *domid; |  | ||||||
| 	if (strstr(resp, "<fault>")) |  | ||||||
| 		bad_resp(resp); |  | ||||||
| 	if (!strstr(resp, "domid")) |  | ||||||
| 		bad_resp(resp); |  | ||||||
| 	domid = strstr(resp, "<int>"); |  | ||||||
| 	if (!domid) |  | ||||||
| 		bad_resp(resp); |  | ||||||
| 	return strtoul(domid + 5, NULL, 0); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| char *gettime() | char *gettime() | ||||||
| { | { | ||||||
| @ -161,27 +139,6 @@ void preload_cache(int fd) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int xend_connect() |  | ||||||
| { |  | ||||||
| 	struct sockaddr_un server; |  | ||||||
| 	int s; |  | ||||||
| 
 |  | ||||||
| 	s = socket(AF_UNIX, SOCK_STREAM, 0); |  | ||||||
| 	if (s < 0) { |  | ||||||
| 		perror("socket af_unix"); |  | ||||||
| 		exit(1); |  | ||||||
| 	} |  | ||||||
| 	server.sun_family = AF_UNIX; |  | ||||||
| 	strcpy(server.sun_path, "/var/run/xend/xmlrpc.sock"); |  | ||||||
| 	if (connect |  | ||||||
| 	    (s, (struct sockaddr *) &server, |  | ||||||
| 	     strlen(server.sun_path) + sizeof(server.sun_family))) { |  | ||||||
| 		perror("connext xend"); |  | ||||||
| 		exit(1); |  | ||||||
| 	} |  | ||||||
| 	return s; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void start_rexec(int domid) | void start_rexec(int domid) | ||||||
| { | { | ||||||
| 	int pid, status; | 	int pid, status; | ||||||
| @ -214,40 +171,13 @@ void start_guid(int domid, int argc, char **argv) | |||||||
| 	guid_args[0] = "qubes_guid"; | 	guid_args[0] = "qubes_guid"; | ||||||
| 	guid_args[1] = "-d"; | 	guid_args[1] = "-d"; | ||||||
| 	guid_args[2] = dstr; | 	guid_args[2] = dstr; | ||||||
| 	for (i = 2; i < argc; i++) | 	for (i = 3; i < argc; i++) | ||||||
| 		guid_args[i + 1] = argv[i]; | 		guid_args[i + 1] = argv[i]; | ||||||
| 	guid_args[argc + 1] = NULL; | 	guid_args[argc + 1] = NULL; | ||||||
| 	execv("/usr/bin/qubes_guid", guid_args); | 	execv("/usr/bin/qubes_guid", guid_args); | ||||||
| 	perror("execv"); | 	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; |  | ||||||
| 	char *bracket; |  | ||||||
| 	char *loc = strstr(buf + 20, pattern) + strlen(pattern); |  | ||||||
| 	if (!loc) |  | ||||||
| 		return; |  | ||||||
| 	bracket = index(loc, ')'); |  | ||||||
| 	if (!bracket) |  | ||||||
| 		return; |  | ||||||
| 	origlen = (long) bracket - (long) loc; |  | ||||||
| 	if (origlen < len) { |  | ||||||
| 		fprintf(stderr, "too long string %s\n", val); |  | ||||||
| 		exit(1); |  | ||||||
| 	} |  | ||||||
| 	for (i = 0; i < origlen - len; i++) |  | ||||||
| 		loc[i] = ' '; |  | ||||||
| 	memcpy(loc + i, val, strlen(val)); |  | ||||||
| 	lseek(fd, (long) loc - (long) buf, SEEK_SET); |  | ||||||
| 	write(fd, loc, origlen); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| char *dispname_by_dispid(int dispid) | char *dispname_by_dispid(int dispid) | ||||||
| { | { | ||||||
| 	static char retbuf[16]; | 	static char retbuf[16]; | ||||||
| @ -258,8 +188,7 @@ char *dispname_by_dispid(int dispid) | |||||||
| char *build_dvm_ip(int netvm, int id) | char *build_dvm_ip(int netvm, int id) | ||||||
| { | { | ||||||
| 	static char buf[256]; | 	static char buf[256]; | ||||||
| 	snprintf(buf, sizeof(buf), "10.%d.%d.%d", netvm, id / 254 + 200, | 	snprintf(buf, sizeof(buf), "10.138.%d.%d", netvm, (id % 254) + 1); | ||||||
| 		 (id % 254) + 1); |  | ||||||
| 	return buf; | 	return buf; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -270,15 +199,17 @@ char *build_dvm_ip(int netvm, int id) | |||||||
| // normally, it should be "templatename-dvm"
 | // normally, it should be "templatename-dvm"
 | ||||||
| char *get_vmname_from_savefile(int fd) | char *get_vmname_from_savefile(int fd) | ||||||
| { | { | ||||||
|  | 	int buflen; | ||||||
| 	static char buf[4096]; | 	static char buf[4096]; | ||||||
| 	char *name; | 	char *name; | ||||||
| 	char *slash; | 	char *slash; | ||||||
| 	lseek(fd, 0, SEEK_SET); | 	lseek(fd, 0, SEEK_SET); | ||||||
| 	if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { | 	buflen = read(fd, buf, sizeof(buf) - 1); | ||||||
| 		perror("read savefile"); | 	if (buflen < 0) { | ||||||
|  | 		perror("read vm conf"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 	buf[sizeof(buf) - 1] = 0; | 	buf[buflen] = 0; | ||||||
| 	name = strstr(buf + 20, NAME_PATTERN); | 	name = strstr(buf + 20, NAME_PATTERN); | ||||||
| 	if (!name) { | 	if (!name) { | ||||||
| 		fprintf(stderr, | 		fprintf(stderr, | ||||||
| @ -296,25 +227,69 @@ char *get_vmname_from_savefile(int fd) | |||||||
| 	return slash + 1; | 	return slash + 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void fix_savefile_all(int fd, int dispid, int netvm_id) | void fill_field(FILE *conf, char *field, int dispid, int netvm_id) | ||||||
| { | { | ||||||
| 	char val[256]; | 	if (!strcmp(field, "NAME")) { | ||||||
| 	char buf[4096]; | 		fprintf(conf, "%s", dispname_by_dispid(dispid)); | ||||||
| 	lseek(fd, 0, SEEK_SET); | 	} else if (!strcmp(field, "MAC")) { | ||||||
| 	if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { | 		fprintf(conf, "00:16:3e:7c:8b:%02x", dispid); | ||||||
| 		perror("read savefile"); | 	} else if (!strcmp(field, "IP")) { | ||||||
|  | 		fprintf(conf, "%s", build_dvm_ip(netvm_id, dispid)); | ||||||
|  | 	} else if (!strcmp(field, "UUID")) { | ||||||
|  | 		// currently not present in conf file
 | ||||||
|  | 		fprintf(conf, "064cd14c-95ad-4fc2-a4c9-cf9f522e5b%02x", dispid); | ||||||
|  | 	} else { | ||||||
|  | 		fprintf(stderr, "unknown field in vm conf: %s\n", field); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 	buf[sizeof(buf) - 1] = 0; |  | ||||||
| 	snprintf(val, sizeof(val), |  | ||||||
| 		 "064cd14c-95ad-4fc2-a4c9-cf9f522e5b%02x", dispid); |  | ||||||
| 	fix_savefile(fd, buf, "(uuid ", val); |  | ||||||
| 	fix_savefile(fd, buf, "(name ", dispname_by_dispid(dispid)); |  | ||||||
| 	snprintf(val, sizeof(val), "00:16:3e:7c:8b:%02x", dispid); |  | ||||||
| 	fix_savefile(fd, buf, "(mac ", val); |  | ||||||
| 	fix_savefile(fd, buf, "(ip ", build_dvm_ip(netvm_id, dispid)); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // modify the config file. conf = FILE of the new config,
 | ||||||
|  | // conf_templ - fd of config template
 | ||||||
|  | // pattern - pattern to search for
 | ||||||
|  | // val - string to replace pattern with
 | ||||||
|  | void fix_conffile(FILE *conf, int conf_templ, int dispid, int netvm_id) | ||||||
|  | { | ||||||
|  | 	int buflen, cur_len = 0; | ||||||
|  | 	char buf[4096]; | ||||||
|  | 	char *bufpos = buf; | ||||||
|  | 	char *pattern, *patternend; | ||||||
|  | 
 | ||||||
|  | 	/* read config template */ | ||||||
|  | 	lseek(conf_templ, 0, SEEK_SET); | ||||||
|  | 	while ((cur_len = read(conf_templ, buf+cur_len, sizeof(buf)-cur_len)) > 0) { | ||||||
|  | 		buflen+=cur_len; | ||||||
|  | 	} | ||||||
|  | 	if (cur_len < 0) { | ||||||
|  | 		perror("read vm conf"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	while ((pattern = index(bufpos, '%'))) { | ||||||
|  | 		fwrite(bufpos, 1, pattern-bufpos, conf); | ||||||
|  | 		if (ferror(conf)) { | ||||||
|  | 			perror("write vm conf"); | ||||||
|  | 			exit(1); | ||||||
|  | 		} | ||||||
|  | 		patternend = index(pattern+1, '%'); | ||||||
|  | 		if (!patternend) { | ||||||
|  | 			fprintf(stderr, "Unmatched '%%' in VM config\n"); | ||||||
|  | 			exit(1); | ||||||
|  | 		} | ||||||
|  | 		*patternend = '\0'; | ||||||
|  | 		fill_field(conf, pattern+1, dispid, netvm_id); | ||||||
|  | 		bufpos = patternend+1; | ||||||
|  | 	} | ||||||
|  | 	while ((cur_len = fwrite(bufpos, 1, buflen-(bufpos-buf), conf)) > 0) { | ||||||
|  | 		bufpos+=cur_len; | ||||||
|  | 	} | ||||||
|  | 	if (ferror(conf)) { | ||||||
|  | 		perror("write vm conf"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| void unpack_cows(char *name) | void unpack_cows(char *name) | ||||||
| { | { | ||||||
| 	char vmdir[4096]; | 	char vmdir[4096]; | ||||||
| @ -355,6 +330,17 @@ void write_xs_single(struct xs_handle *xs, int domid, char *name, | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void perm_xs_single(struct xs_handle *xs, int domid, char *name, | ||||||
|  | 		     struct xs_permissions *perms, int nperms) | ||||||
|  | { | ||||||
|  | 	char key[256]; | ||||||
|  | 	snprintf(key, sizeof(key), "/local/domain/%d/%s", domid, name); | ||||||
|  | 	if (!xs_set_permissions(xs, XBT_NULL, key, perms, nperms)) { | ||||||
|  | 		fprintf(stderr, "xs_set_permissions"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int get_netvm_id_from_name(char *name) | int get_netvm_id_from_name(char *name) | ||||||
| { | { | ||||||
| 	int fd, n; | 	int fd, n; | ||||||
| @ -377,6 +363,7 @@ void setup_xenstore(int netvm_id, int domid, int dvmid, char *name) | |||||||
| { | { | ||||||
| 	char val[256]; | 	char val[256]; | ||||||
| 	struct xs_handle *xs = xs_daemon_open(); | 	struct xs_handle *xs = xs_daemon_open(); | ||||||
|  | 	struct xs_permissions perm[1]; | ||||||
| 	if (!xs) { | 	if (!xs) { | ||||||
| 		perror("xs_daemon_open"); | 		perror("xs_daemon_open"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| @ -385,12 +372,18 @@ void setup_xenstore(int netvm_id, int domid, int dvmid, char *name) | |||||||
| 	write_xs_single(xs, domid, "qubes_ip", | 	write_xs_single(xs, domid, "qubes_ip", | ||||||
| 			build_dvm_ip(netvm_id, dvmid)); | 			build_dvm_ip(netvm_id, dvmid)); | ||||||
| 	write_xs_single(xs, domid, "qubes_netmask", "255.255.0.0"); | 	write_xs_single(xs, domid, "qubes_netmask", "255.255.0.0"); | ||||||
| 	snprintf(val, sizeof(val), "10.%d.0.1", netvm_id); | 	snprintf(val, sizeof(val), "10.137.%d.1", netvm_id); | ||||||
| 	write_xs_single(xs, domid, "qubes_gateway", val); | 	write_xs_single(xs, domid, "qubes_gateway", val); | ||||||
| 	snprintf(val, sizeof(val), "10.%d.255.254", netvm_id); | 	snprintf(val, sizeof(val), "10.137.%d.254", netvm_id); | ||||||
| 	write_xs_single(xs, domid, "qubes_secondary_dns", val); | 	write_xs_single(xs, domid, "qubes_secondary_dns", val); | ||||||
| 	write_xs_single(xs, domid, "qubes_vm_type", "AppVM"); | 	write_xs_single(xs, domid, "qubes_vm_type", "AppVM"); | ||||||
| 	write_xs_single(xs, domid, "qubes_restore_complete", "True"); | 	write_xs_single(xs, domid, "qubes_restore_complete", "True"); | ||||||
|  | 
 | ||||||
|  | 	perm[0].id = domid; | ||||||
|  | 	perm[0].perms = XS_PERM_NONE; | ||||||
|  | 	perm_xs_single(xs, domid, "device", perm, 1); | ||||||
|  | 	perm_xs_single(xs, domid, "memory", perm, 1); | ||||||
|  | 
 | ||||||
| 	xs_daemon_close(xs); | 	xs_daemon_close(xs); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @ -437,46 +430,45 @@ void redirect_stderr() | |||||||
| 
 | 
 | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| { | { | ||||||
| 	int fd, domid, dispid, netvm_id; | 	int conf_templ, domid, dispid, netvm_id; | ||||||
| 	char *resp; | 	FILE *conf; | ||||||
| 	char *name; | 	char *name; | ||||||
| 	if (argc < 2) { | 	char confname[256]; | ||||||
|  | 	if (argc < 3) { | ||||||
| 		fprintf(stderr, | 		fprintf(stderr, | ||||||
| 			"usage: %s savefile [guid args] \n", argv[0]); | 			"usage: %s savefile conf_templ [guid args] \n", argv[0]); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 	redirect_stderr(); | 	redirect_stderr(); | ||||||
| 	fprintf(stderr, "time=%s, starting\n", gettime()); | 	fprintf(stderr, "time=%s, starting\n", gettime()); | ||||||
| 	set_fast_flag(); | 	set_fast_flag(); | ||||||
| 	atexit(rm_fast_flag); | 	atexit(rm_fast_flag); | ||||||
| 	fd = open(argv[1], O_RDWR); | 	conf_templ = open(argv[2], O_RDONLY); | ||||||
| 	if (fd < 0) { | 	if (conf_templ < 0) { | ||||||
| 		perror("open savefile"); | 		perror("fopen vm conf"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 	dispid = get_next_disposable_id(); | 	dispid = get_next_disposable_id(); | ||||||
| 	name = get_vmname_from_savefile(fd); | 	name = get_vmname_from_savefile(conf_templ); | ||||||
| 	netvm_id = get_netvm_id_from_name(name); | 	netvm_id = get_netvm_id_from_name(name); | ||||||
| 	fix_savefile_all(fd, dispid, netvm_id); | 	snprintf(confname, sizeof(confname), "/tmp/qubes-dvm-%d.xl", dispid); | ||||||
|  | 	conf = fopen(confname, "w"); | ||||||
|  | 	if (!conf) { | ||||||
|  | 		perror("fopen new vm conf"); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	fix_conffile(conf, conf_templ, dispid, netvm_id); | ||||||
|  | 	close(conf_templ); | ||||||
|  | 	fclose(conf); | ||||||
| //      printf("name=%s\n", name);
 | //      printf("name=%s\n", name);
 | ||||||
| 	unpack_cows(name); | 	unpack_cows(name); | ||||||
| //      no preloading for now, assume savefile in shm
 | //      no preloading for now, assume savefile in shm
 | ||||||
| //      preload_cache(fd);
 | //      preload_cache(fd);
 | ||||||
| 	fd = xend_connect(); | 	domid=restore_domain(argv[1], confname, dispname_by_dispid(dispid)); | ||||||
| 	send_req_restore(fd, argv[1]); |  | ||||||
| 	resp = recv_resp(fd); |  | ||||||
| 	domid = parse_resp(resp); |  | ||||||
| 	write_varrun_domid(domid, dispname_by_dispid(dispid), name); | 	write_varrun_domid(domid, dispname_by_dispid(dispid), name); | ||||||
| 	fprintf(stderr, | 	fprintf(stderr, | ||||||
| 		"time=%s, created domid=%d, creating xenstore entries\n", | 		"time=%s, created domid=%d, creating xenstore entries\n", | ||||||
| 		gettime(), domid); | 		gettime(), domid); | ||||||
| #if 0 |  | ||||||
| 	fd = xend_connect(); |  | ||||||
| 	send_req_setmem(fd, domid, 400); |  | ||||||
| 	resp = recv_resp(fd); |  | ||||||
| //      printf("%s\n", resp);
 |  | ||||||
| 	fprintf(stderr, "time=%s, creating xenstore entries\n", gettime()); |  | ||||||
| #endif |  | ||||||
| 	setup_xenstore(netvm_id, domid, dispid, name); | 	setup_xenstore(netvm_id, domid, dispid, name); | ||||||
| 	fprintf(stderr, "time=%s, starting qubes_guid\n", gettime()); | 	fprintf(stderr, "time=%s, starting qubes_guid\n", gettime()); | ||||||
| 	rm_fast_flag(); | 	rm_fast_flag(); | ||||||
|  | |||||||
| @ -40,12 +40,16 @@ if ! /usr/lib/qubes/qubes_prepare_saved_domain.sh \ | |||||||
| fi | fi | ||||||
| ROOT=/var/lib/qubes/dvmdata/savefile_root | ROOT=/var/lib/qubes/dvmdata/savefile_root | ||||||
| DEFAULT=/var/lib/qubes/dvmdata/default_savefile | DEFAULT=/var/lib/qubes/dvmdata/default_savefile | ||||||
|  | DEFAULTCONF=/var/lib/qubes/dvmdata/default_dvm.conf | ||||||
| CURRENT=/var/run/qubes/current_savefile | CURRENT=/var/run/qubes/current_savefile | ||||||
|  | CURRENTCONF=/var/run/qubes/current_dvm.conf | ||||||
| SHMDIR=/dev/shm/qubes | SHMDIR=/dev/shm/qubes | ||||||
| SHMCOPY=$SHMDIR/current_savefile | SHMCOPY=$SHMDIR/current_savefile | ||||||
| rm -f $ROOT $DEFAULT $CURRENT | rm -f $ROOT $DEFAULT $CURRENT $DEFAULTCONF $CURRENTCONF | ||||||
| ln -s "/var/lib/qubes/appvms/$DVMTMPL/dvm-savefile" $DEFAULT | ln -s "/var/lib/qubes/appvms/$DVMTMPL/dvm-savefile" $DEFAULT | ||||||
| ln -s "/var/lib/qubes/vm-templates/$TEMPLATENAME/root.img" $ROOT | ln -s "/var/lib/qubes/vm-templates/$TEMPLATENAME/root.img" $ROOT | ||||||
|  | ln -s $DVMTMPLDIR/dvm.conf $DEFAULTCONF | ||||||
|  | ln -s $DVMTMPLDIR/dvm.conf $CURRENTCONF | ||||||
| if [ -f /var/lib/qubes/dvmdata/dont_use_shm ] ; then | if [ -f /var/lib/qubes/dvmdata/dont_use_shm ] ; then | ||||||
|             ln -s $DEFAULT $CURRENT |             ln -s $DEFAULT $CURRENT | ||||||
| else | else | ||||||
|  | |||||||
| @ -4,8 +4,13 @@ | |||||||
| struct xen_sysctl_physinfo xphysinfo; | struct xen_sysctl_physinfo xphysinfo; | ||||||
| main() | main() | ||||||
| { | { | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  | 	xc_interface *handle = xc_interface_open(NULL, NULL, 0); | ||||||
|  | 	if (!handle) { | ||||||
|  | #else | ||||||
| 	int handle = xc_interface_open(); | 	int handle = xc_interface_open(); | ||||||
| 	if (handle == -1) { | 	if (handle == -1) { | ||||||
|  | #endif | ||||||
| 		perror("xc_interface_open"); | 		perror("xc_interface_open"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -1,42 +0,0 @@ | |||||||
| <!DOCTYPE busconfig PUBLIC |  | ||||||
|  "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" |  | ||||||
|  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> |  | ||||||
| <busconfig> |  | ||||||
| 	<!-- |  | ||||||
| 	     WARNING: if running any D-Bus version prior to 1.2.6, you may be |  | ||||||
| 	     vulnerable to information leakage via the NM D-Bus interface. |  | ||||||
| 	     Previous D-Bus versions did not deny-by-default, and this permissions |  | ||||||
| 	     config file assumes that D-Bus will deny rules by default unless |  | ||||||
| 	     explicitly over-ridden with an <allow /> tag. |  | ||||||
| 	 --> |  | ||||||
| 
 |  | ||||||
|         <policy user="root"> |  | ||||||
|                 <allow own="org.freedesktop.NetworkManagerUserSettings"/> |  | ||||||
| 
 |  | ||||||
|                 <allow send_destination="org.freedesktop.NetworkManagerUserSettings" |  | ||||||
|                        send_interface="org.freedesktop.NetworkManagerSettings"/> |  | ||||||
| 
 |  | ||||||
|                 <allow send_destination="org.freedesktop.NetworkManagerUserSettings" |  | ||||||
|                        send_interface="org.freedesktop.NetworkManagerSettings.Connection"/> |  | ||||||
| 
 |  | ||||||
|                 <!-- Only root can get secrets --> |  | ||||||
|                 <allow send_destination="org.freedesktop.NetworkManagerUserSettings" |  | ||||||
|                        send_interface="org.freedesktop.NetworkManagerSettings.Connection.Secrets"/> |  | ||||||
|         </policy> |  | ||||||
|         <policy user="user"> |  | ||||||
|                 <allow own="org.freedesktop.NetworkManagerUserSettings"/> |  | ||||||
| 
 |  | ||||||
|                 <allow send_destination="org.freedesktop.NetworkManagerUserSettings" |  | ||||||
|                        send_interface="org.freedesktop.NetworkManagerSettings"/> |  | ||||||
| 
 |  | ||||||
|                 <allow send_destination="org.freedesktop.NetworkManagerUserSettings" |  | ||||||
|                        send_interface="org.freedesktop.NetworkManagerSettings.Connection"/> |  | ||||||
|         </policy> |  | ||||||
|         <policy context="default"> |  | ||||||
|                 <allow send_destination="org.freedesktop.NetworkManagerUserSettings" |  | ||||||
|                        send_interface="org.freedesktop.DBus.Introspectable"/> |  | ||||||
|         </policy> |  | ||||||
| 
 |  | ||||||
|         <limit name="max_replies_per_connection">512</limit> |  | ||||||
| </busconfig> |  | ||||||
| 
 |  | ||||||
| @ -19,6 +19,9 @@ while true; do | |||||||
| 		IPTABLES_SAVE=$(/sbin/iptables-save | sed '/^\*filter/,/^COMMIT/d') | 		IPTABLES_SAVE=$(/sbin/iptables-save | sed '/^\*filter/,/^COMMIT/d') | ||||||
| 		OUT=`echo -e "$RULES\n$IPTABLES_SAVE" | /sbin/iptables-restore 2>&1 || :` | 		OUT=`echo -e "$RULES\n$IPTABLES_SAVE" | /sbin/iptables-restore 2>&1 || :` | ||||||
| 		/usr/bin/xenstore-write $XENSTORE_ERROR "$OUT" | 		/usr/bin/xenstore-write $XENSTORE_ERROR "$OUT" | ||||||
|  | 		if [ "$OUT" ]; then | ||||||
|  | 			DISPLAY=:0 /usr/bin/notify-send -t 3000 "Firewall loading error ($HOSTNAME)" "$OUT" || : | ||||||
|  | 		fi | ||||||
| 
 | 
 | ||||||
| 		if [[ -z "$OUT" ]]; then | 		if [[ -z "$OUT" ]]; then | ||||||
| 			# If OK save it for later | 			# If OK save it for later | ||||||
| @ -29,5 +32,5 @@ while true; do | |||||||
| 	fi | 	fi | ||||||
| 
 | 
 | ||||||
| 	# Wait for changes in xenstore file | 	# Wait for changes in xenstore file | ||||||
| 	/usr/bin/xenstore-watch $XENSTORE_IPTABLES | 	/usr/bin/xenstore-watch-qubes $XENSTORE_IPTABLES | ||||||
| done | done | ||||||
|  | |||||||
| @ -24,8 +24,8 @@ while true; do | |||||||
| 			/usr/bin/xenstore-write qubes_netvm_external_ip "$CURR_NETCFG" | 			/usr/bin/xenstore-write qubes_netvm_external_ip "$CURR_NETCFG" | ||||||
| 		fi | 		fi | ||||||
| 
 | 
 | ||||||
| 		/usr/bin/xenstore-watch /local/domain/$NET_DOMID/qubes_netvm_external_ip | 		/usr/bin/xenstore-watch-qubes /local/domain/$NET_DOMID/qubes_netvm_external_ip | ||||||
| 	else | 	else | ||||||
| 		/usr/bin/xenstore-watch qubes_netvm_domid | 		/usr/bin/xenstore-watch-qubes qubes_netvm_domid | ||||||
| 	fi | 	fi | ||||||
| done | done | ||||||
|  | |||||||
| @ -51,7 +51,8 @@ enum { | |||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
| 	QREXEC_EXECUTE_FILE_COPY=0x700, | 	QREXEC_EXECUTE_FILE_COPY=0x700, | ||||||
| 	QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM | 	QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM, | ||||||
|  | 	QREXEC_EXECUTE_APPMENUS_SYNC | ||||||
| }; | }; | ||||||
| 	 | 	 | ||||||
| struct server_header { | struct server_header { | ||||||
|  | |||||||
| @ -482,6 +482,9 @@ void handle_trigger_io() | |||||||
| 		else if (!strcmp(buf, "DVMR")) | 		else if (!strcmp(buf, "DVMR")) | ||||||
| 			s_hdr.client_id = | 			s_hdr.client_id = | ||||||
| 			    QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM; | 			    QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM; | ||||||
|  | 		else if (!strcmp(buf, "SYNC")) | ||||||
|  | 			s_hdr.client_id = | ||||||
|  | 			    QREXEC_EXECUTE_APPMENUS_SYNC; | ||||||
| 		if (s_hdr.client_id) { | 		if (s_hdr.client_id) { | ||||||
| 			s_hdr.type = MSG_AGENT_TO_SERVER_TRIGGER_EXEC; | 			s_hdr.type = MSG_AGENT_TO_SERVER_TRIGGER_EXEC; | ||||||
| 			write_all_vchan_ext(&s_hdr, sizeof s_hdr); | 			write_all_vchan_ext(&s_hdr, sizeof s_hdr); | ||||||
|  | |||||||
| @ -361,6 +361,10 @@ void handle_execute_predefined_command(int req) | |||||||
| 		rcmd = "directly:user:/usr/lib/qubes/qfile-agent-dvm"; | 		rcmd = "directly:user:/usr/lib/qubes/qfile-agent-dvm"; | ||||||
| 		lcmd = "/usr/lib/qubes/qfile-daemon-dvm"; | 		lcmd = "/usr/lib/qubes/qfile-daemon-dvm"; | ||||||
| 		break; | 		break; | ||||||
|  | 	case QREXEC_EXECUTE_APPMENUS_SYNC: | ||||||
|  | 		rcmd = "user:grep -H = /usr/share/applications/*.desktop"; | ||||||
|  | 		lcmd = "/usr/bin/qvm-sync-appmenus"; | ||||||
|  | 		break; | ||||||
| 	default:		/* cannot happen, already sanitized */ | 	default:		/* cannot happen, already sanitized */ | ||||||
| 		fprintf(stderr, "got trigger exec no %d\n", req); | 		fprintf(stderr, "got trigger exec no %d\n", req); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| @ -402,7 +406,8 @@ void sanitize_message_from_agent(struct server_header *untrusted_header) | |||||||
| 	case MSG_AGENT_TO_SERVER_TRIGGER_EXEC: | 	case MSG_AGENT_TO_SERVER_TRIGGER_EXEC: | ||||||
| 		untrusted_cmd = untrusted_header->client_id; | 		untrusted_cmd = untrusted_header->client_id; | ||||||
| 		if (untrusted_cmd != QREXEC_EXECUTE_FILE_COPY && | 		if (untrusted_cmd != QREXEC_EXECUTE_FILE_COPY && | ||||||
| 		    untrusted_cmd != QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM) { | 		    untrusted_cmd != QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM && | ||||||
|  | 		    untrusted_cmd != QREXEC_EXECUTE_APPMENUS_SYNC) { | ||||||
| 			fprintf(stderr, | 			fprintf(stderr, | ||||||
| 				"received MSG_AGENT_TO_SERVER_TRIGGER_EXEC cmd %d ?\n", | 				"received MSG_AGENT_TO_SERVER_TRIGGER_EXEC cmd %d ?\n", | ||||||
| 				untrusted_cmd); | 				untrusted_cmd); | ||||||
|  | |||||||
| @ -83,7 +83,11 @@ int buffer_space_vchan_ext() | |||||||
| // if the remote domain is destroyed, we get no notification
 | // if the remote domain is destroyed, we get no notification
 | ||||||
| // thus, we check for the status periodically
 | // thus, we check for the status periodically
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  | static xc_interface *xc_handle = NULL; | ||||||
|  | #else | ||||||
| static int xc_handle = -1; | static int xc_handle = -1; | ||||||
|  | #endif | ||||||
| void slow_check_for_libvchan_is_eof(struct libvchan *ctrl) | void slow_check_for_libvchan_is_eof(struct libvchan *ctrl) | ||||||
| { | { | ||||||
| 	struct evtchn_status evst; | 	struct evtchn_status evst; | ||||||
| @ -198,8 +202,13 @@ char *peer_client_init(int dom, int port) | |||||||
| 	// now client init should succeed; "while" is redundant
 | 	// now client init should succeed; "while" is redundant
 | ||||||
| 	while (!(ctrl = libvchan_client_init(dom, port))); | 	while (!(ctrl = libvchan_client_init(dom, port))); | ||||||
| 
 | 
 | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  | 	xc_handle = xc_interface_open(NULL, 0, 0); | ||||||
|  | 	if (!xc_handle) { | ||||||
|  | #else | ||||||
| 	xc_handle = xc_interface_open(); | 	xc_handle = xc_interface_open(); | ||||||
| 	if (xc_handle < 0) { | 	if (xc_handle < 0) { | ||||||
|  | #endif | ||||||
| 		perror("xc_interface_open"); | 		perror("xc_interface_open"); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -33,6 +33,7 @@ License:	GPL | |||||||
| URL:		http://www.qubes-os.org | URL:		http://www.qubes-os.org | ||||||
| Requires:	/usr/bin/xenstore-read | Requires:	/usr/bin/xenstore-read | ||||||
| Requires:   fedora-release | Requires:   fedora-release | ||||||
|  | Requires:   yum-plugin-post-transaction-actions | ||||||
| BuildRequires: xen-devel | BuildRequires: xen-devel | ||||||
| 
 | 
 | ||||||
| %define _builddir %(pwd)/common | %define _builddir %(pwd)/common | ||||||
| @ -71,24 +72,76 @@ install -m 644 RPM-GPG-KEY-qubes* $RPM_BUILD_ROOT/etc/pki/rpm-gpg/ | |||||||
| mkdir -p $RPM_BUILD_ROOT/sbin | mkdir -p $RPM_BUILD_ROOT/sbin | ||||||
| cp qubes_serial_login $RPM_BUILD_ROOT/sbin | cp qubes_serial_login $RPM_BUILD_ROOT/sbin | ||||||
| mkdir -p $RPM_BUILD_ROOT/usr/bin | mkdir -p $RPM_BUILD_ROOT/usr/bin | ||||||
| cp xenstore-watch $RPM_BUILD_ROOT/usr/bin | cp xenstore-watch $RPM_BUILD_ROOT/usr/bin/xenstore-watch-qubes | ||||||
| mkdir -p $RPM_BUILD_ROOT/etc | mkdir -p $RPM_BUILD_ROOT/etc | ||||||
| cp serial.conf $RPM_BUILD_ROOT/var/lib/qubes/ | cp serial.conf $RPM_BUILD_ROOT/var/lib/qubes/ | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d | ||||||
|  | cp qubes_network.rules $RPM_BUILD_ROOT/etc/udev/rules.d/ | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
|  | cp setup_ip $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
|  | cp qubes_download_dom0_updates.sh $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/etc/yum/post-actions | ||||||
|  | cp qubes_trigger_sync_appmenus.action $RPM_BUILD_ROOT/etc/yum/post-actions/ | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
|  | cp qubes_trigger_sync_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/dom0-updates | ||||||
| 
 | 
 | ||||||
| %triggerin -- initscripts | %triggerin -- initscripts | ||||||
| cp /var/lib/qubes/serial.conf /etc/init/serial.conf | cp /var/lib/qubes/serial.conf /etc/init/serial.conf | ||||||
| 
 | 
 | ||||||
| %post | %post | ||||||
| 
 | 
 | ||||||
| # Disable gpk-update-icon | # disable some Upstart services | ||||||
| sed 's/^NotShowIn=KDE;$/\0QUBES;/' -i /etc/xdg/autostart/gpk-update-icon.desktop | for F in plymouth-shutdown prefdm splash-manager start-ttys tty ; do | ||||||
|  | 	if [ -e /etc/init/$F.conf ]; then | ||||||
|  | 		mv -f /etc/init/$F.conf /etc/init/$F.conf.disabled | ||||||
|  | 	fi | ||||||
|  | done | ||||||
| 
 | 
 | ||||||
|  | remove_ShowIn () { | ||||||
|  | 	if [ -e /etc/xdg/autostart/$1.desktop ]; then | ||||||
|  | 		sed -i '/^\(Not\|Only\)ShowIn/d' /etc/xdg/autostart/$1.desktop | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # don't want it at all | ||||||
|  | for F in abrt-applet deja-dup-monitor imsettings-start krb5-auth-dialog pulseaudio restorecond sealertauto ; do | ||||||
|  | 	if [ -e /etc/xdg/autostart/$F.desktop ]; then | ||||||
|  | 		remove_ShowIn $F | ||||||
|  | 		echo 'NotShowIn=QUBES' >> /etc/xdg/autostart/$F.desktop | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | # don't want it in DisposableVM | ||||||
|  | for F in gcm-apply ; do | ||||||
|  | 	if [ -e /etc/xdg/autostart/$F.desktop ]; then | ||||||
|  | 		remove_ShowIn $F | ||||||
|  | 		echo 'NotShowIn=DisposableVM' >> /etc/xdg/autostart/$F.desktop | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | # want it in AppVM only | ||||||
|  | for F in gnome-keyring-gpg gnome-keyring-pkcs11 gnome-keyring-secrets gnome-keyring-ssh gnome-settings-daemon user-dirs-update-gtk gsettings-data-convert ; do | ||||||
|  | 	if [ -e /etc/xdg/autostart/$F.desktop ]; then | ||||||
|  | 		remove_ShowIn $F | ||||||
|  | 		echo 'OnlyShowIn=GNOME;AppVM;' >> /etc/xdg/autostart/$F.desktop | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | # remove existing rule to add own later | ||||||
|  | for F in gpk-update-icon nm-applet ; do | ||||||
|  | 	remove_ShowIn $F | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | echo 'OnlyShowIn=GNOME;UpdateableVM;' >> /etc/xdg/autostart/gpk-update-icon.desktop || : | ||||||
|  | echo 'OnlyShowIn=GNOME;NetVM;' >> /etc/xdg/autostart/nm-applet.desktop || : | ||||||
|  | 
 | ||||||
|  | usermod -p '' root | ||||||
| if [ "$1" !=  1 ] ; then | if [ "$1" !=  1 ] ; then | ||||||
| # do this whole %post thing only when updating for the first time... | # do this whole %post thing only when updating for the first time... | ||||||
| exit 0 | exit 0 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| usermod -L root |  | ||||||
| if ! [ -f /var/lib/qubes/serial.orig ] ; then | if ! [ -f /var/lib/qubes/serial.orig ] ; then | ||||||
| 	cp /etc/init/serial.conf /var/lib/qubes/serial.orig | 	cp /etc/init/serial.conf /var/lib/qubes/serial.orig | ||||||
| fi | fi | ||||||
| @ -177,4 +230,9 @@ rm -rf $RPM_BUILD_ROOT | |||||||
| /etc/yum.repos.d/qubes%{dist}.repo | /etc/yum.repos.d/qubes%{dist}.repo | ||||||
| /etc/pki/rpm-gpg/RPM-GPG-KEY-qubes* | /etc/pki/rpm-gpg/RPM-GPG-KEY-qubes* | ||||||
| /sbin/qubes_serial_login | /sbin/qubes_serial_login | ||||||
| /usr/bin/xenstore-watch | /usr/bin/xenstore-watch-qubes | ||||||
|  | /etc/udev/rules.d/qubes_network.rules | ||||||
|  | /usr/lib/qubes/setup_ip | ||||||
|  | /etc/yum/post-actions/qubes_trigger_sync_appmenus.action | ||||||
|  | /usr/lib/qubes/qubes_trigger_sync_appmenus.sh | ||||||
|  | /usr/lib/qubes/qubes_download_dom0_updates.sh | ||||||
|  | |||||||
| @ -39,8 +39,9 @@ URL:		http://www.qubes-os.org | |||||||
| BuildRequires:  xen-devel | BuildRequires:  xen-devel | ||||||
| Requires:	python, xen-runtime, pciutils, python-inotify, python-daemon, kernel-qubes-dom0 | Requires:	python, xen-runtime, pciutils, python-inotify, python-daemon, kernel-qubes-dom0 | ||||||
| Conflicts:      qubes-gui-dom0 < 1.1.13 | Conflicts:      qubes-gui-dom0 < 1.1.13 | ||||||
|  | Requires:       yum-plugin-post-transaction-actions | ||||||
| Requires:       NetworkManager >= 0.8.1-1 | Requires:       NetworkManager >= 0.8.1-1 | ||||||
| Requires:       xen >= 3.4.3-6 | Requires:       xen >= 4.1.0-2 | ||||||
| %define _builddir %(pwd)/dom0 | %define _builddir %(pwd)/dom0 | ||||||
| 
 | 
 | ||||||
| %description | %description | ||||||
| @ -50,6 +51,7 @@ The Qubes core files for installation on Dom0. | |||||||
| python -m compileall qvm-core qmemman | python -m compileall qvm-core qmemman | ||||||
| python -O -m compileall qvm-core qmemman | python -O -m compileall qvm-core qmemman | ||||||
| make -C restore | make -C restore | ||||||
|  | make -C aux-tools | ||||||
| make -C ../common | make -C ../common | ||||||
| make -C ../vchan | make -C ../vchan | ||||||
| make -C ../u2mfn | make -C ../u2mfn | ||||||
| @ -89,17 +91,26 @@ cp aux-tools/convert_dirtemplate2vm.sh $RPM_BUILD_ROOT/usr/lib/qubes | |||||||
| cp aux-tools/create_apps_for_appvm.sh $RPM_BUILD_ROOT/usr/lib/qubes | cp aux-tools/create_apps_for_appvm.sh $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| cp aux-tools/remove_appvm_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes | cp aux-tools/remove_appvm_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| cp aux-tools/reset_vm_configs.py  $RPM_BUILD_ROOT/usr/lib/qubes | cp aux-tools/reset_vm_configs.py  $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
|  | cp aux-tools/sync_rpmdb_updatevm.sh $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
| cp qmemman/server.py $RPM_BUILD_ROOT/usr/lib/qubes/qmemman_daemon.py | cp qmemman/server.py $RPM_BUILD_ROOT/usr/lib/qubes/qmemman_daemon.py | ||||||
| cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes/ | cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
| cp ../qrexec/qrexec_daemon $RPM_BUILD_ROOT/usr/lib/qubes/ | cp ../qrexec/qrexec_daemon $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
| cp ../qrexec/qrexec_client $RPM_BUILD_ROOT/usr/lib/qubes/ | cp ../qrexec/qrexec_client $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
|  | cp aux-tools/qfile-dom0-unpacker $RPM_BUILD_ROOT/usr/lib/qubes/ | ||||||
| 
 | 
 | ||||||
| cp restore/xenstore-watch restore/qvm-create-default-dvm $RPM_BUILD_ROOT/usr/bin | cp restore/qvm-create-default-dvm $RPM_BUILD_ROOT/usr/bin | ||||||
|  | cp restore/xenstore-watch $RPM_BUILD_ROOT/usr/bin/xenstore-watch-qubes | ||||||
| cp restore/qubes_restore restore/xenfreepages $RPM_BUILD_ROOT/usr/lib/qubes | cp restore/qubes_restore restore/xenfreepages $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| cp restore/qubes_prepare_saved_domain.sh  $RPM_BUILD_ROOT/usr/lib/qubes | cp restore/qubes_prepare_saved_domain.sh  $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| cp restore/qfile-daemon-dvm $RPM_BUILD_ROOT/usr/lib/qubes | cp restore/qfile-daemon-dvm $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| cp restore/qfile-daemon $RPM_BUILD_ROOT/usr/lib/qubes | cp restore/qfile-daemon $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| 
 | 
 | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/etc/yum.real.repos.d | ||||||
|  | cp qubes-cached.repo $RPM_BUILD_ROOT/etc/yum.real.repos.d/ | ||||||
|  | 
 | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/etc/yum/post-actions | ||||||
|  | cp misc/qubes_sync_rpmdb_updatevm.action $RPM_BUILD_ROOT/etc/yum/post-actions/ | ||||||
|  | 
 | ||||||
| mkdir -p $RPM_BUILD_ROOT/var/lib/qubes | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes | ||||||
| mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/vm-templates | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/vm-templates | ||||||
| mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/appvms | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/appvms | ||||||
| @ -108,8 +119,14 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/servicevms | |||||||
| mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/backup | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/backup | ||||||
| mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/dvmdata | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/dvmdata | ||||||
| 
 | 
 | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/updates | ||||||
|  | 
 | ||||||
| mkdir -p $RPM_BUILD_ROOT/usr/share/qubes/icons | mkdir -p $RPM_BUILD_ROOT/usr/share/qubes/icons | ||||||
| cp icons/*.png $RPM_BUILD_ROOT/usr/share/qubes/icons | cp icons/*.png $RPM_BUILD_ROOT/usr/share/qubes/icons | ||||||
|  | cp misc/qubes-vm.directory.template $RPM_BUILD_ROOT/usr/share/qubes/ | ||||||
|  | cp misc/qubes-templatevm.directory.template $RPM_BUILD_ROOT/usr/share/qubes/ | ||||||
|  | cp misc/qubes-appmenu-select.template $RPM_BUILD_ROOT/usr/share/qubes/ | ||||||
|  | cp misc/vm-template.conf $RPM_BUILD_ROOT/usr/share/qubes/ | ||||||
| 
 | 
 | ||||||
| mkdir -p $RPM_BUILD_ROOT/usr/bin | mkdir -p $RPM_BUILD_ROOT/usr/bin | ||||||
| cp ../common/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/usr/lib/qubes | cp ../common/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/usr/lib/qubes | ||||||
| @ -120,6 +137,8 @@ mkdir -p $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/ | |||||||
| cp ../common/qubes_nmhook $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/ | cp ../common/qubes_nmhook $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/ | ||||||
| mkdir -p $RPM_BUILD_ROOT/etc/sysconfig | mkdir -p $RPM_BUILD_ROOT/etc/sysconfig | ||||||
| cp ../common/iptables $RPM_BUILD_ROOT/etc/sysconfig | cp ../common/iptables $RPM_BUILD_ROOT/etc/sysconfig | ||||||
|  | mkdir -p $RPM_BUILD_ROOT/etc/security/limits.d | ||||||
|  | cp misc/limits-qubes.conf $RPM_BUILD_ROOT/etc/security/limits.d/99-qubes.conf | ||||||
| 
 | 
 | ||||||
| mkdir -p $RPM_BUILD_ROOT/usr/lib64/pm-utils/sleep.d | mkdir -p $RPM_BUILD_ROOT/usr/lib64/pm-utils/sleep.d | ||||||
| cp pm-utils/01qubes-sync-vms-clock $RPM_BUILD_ROOT/usr/lib64/pm-utils/sleep.d/ | cp pm-utils/01qubes-sync-vms-clock $RPM_BUILD_ROOT/usr/lib64/pm-utils/sleep.d/ | ||||||
| @ -150,6 +169,13 @@ fi | |||||||
| 
 | 
 | ||||||
| sed 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/'  -i /etc/sysctl.conf | sed 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/'  -i /etc/sysctl.conf | ||||||
| 
 | 
 | ||||||
|  | sed '/^autoballoon=/d;/^lockfile=/d' -i /etc/xen/xl.conf | ||||||
|  | echo 'autoballoon=0' >> /etc/xen/xl.conf | ||||||
|  | echo 'lockfile="/var/run/qubes/xl-lock"' >> /etc/xen/xl.conf | ||||||
|  | 
 | ||||||
|  | sed '/^reposdir=/d' -i /etc/yum.conf | ||||||
|  | echo reposdir=/etc/yum.real.repos.d >> /etc/yum.conf | ||||||
|  | 
 | ||||||
| chkconfig --add qubes_core || echo "WARNING: Cannot add service qubes_core!" | chkconfig --add qubes_core || echo "WARNING: Cannot add service qubes_core!" | ||||||
| chkconfig --add qubes_netvm || echo "WARNING: Cannot add service qubes_netvm!" | chkconfig --add qubes_netvm || echo "WARNING: Cannot add service qubes_netvm!" | ||||||
| chkconfig --add qubes_setupdvm || echo "WARNING: Cannot add service qubes_setupdvm!" | chkconfig --add qubes_setupdvm || echo "WARNING: Cannot add service qubes_setupdvm!" | ||||||
| @ -158,6 +184,10 @@ chkconfig --level 5 qubes_core on || echo "WARNING: Cannot enable service qubes_ | |||||||
| chkconfig --level 5 qubes_netvm on || echo "WARNING: Cannot enable service qubes_netvm!" | chkconfig --level 5 qubes_netvm on || echo "WARNING: Cannot enable service qubes_netvm!" | ||||||
| chkconfig --level 5 qubes_setupdvm on || echo "WARNING: Cannot enable service qubes_setupdvm!" | chkconfig --level 5 qubes_setupdvm on || echo "WARNING: Cannot enable service qubes_setupdvm!" | ||||||
| 
 | 
 | ||||||
|  | # Conflicts with libxl stack, so disable it | ||||||
|  | service xend stop | ||||||
|  | chkconfig --level 5 xend off | ||||||
|  | 
 | ||||||
| HAD_SYSCONFIG_NETWORK=yes | HAD_SYSCONFIG_NETWORK=yes | ||||||
| if ! [ -e /etc/sysconfig/network ]; then | if ! [ -e /etc/sysconfig/network ]; then | ||||||
|     HAD_SYSCONFIG_NETWORK=no |     HAD_SYSCONFIG_NETWORK=no | ||||||
| @ -167,10 +197,7 @@ fi | |||||||
| 
 | 
 | ||||||
| # Load evtchn module - xenstored needs it | # Load evtchn module - xenstored needs it | ||||||
| modprobe evtchn | modprobe evtchn | ||||||
| 
 |  | ||||||
| # Now launch xend - we will need it for subsequent steps |  | ||||||
| service xenstored start | service xenstored start | ||||||
| service xend start |  | ||||||
| 
 | 
 | ||||||
| if ! [ -e /var/lib/qubes/qubes.xml ]; then | if ! [ -e /var/lib/qubes/qubes.xml ]; then | ||||||
| #    echo "Initializing Qubes DB..." | #    echo "Initializing Qubes DB..." | ||||||
| @ -259,13 +286,20 @@ fi | |||||||
| /usr/lib/qubes/meminfo-writer | /usr/lib/qubes/meminfo-writer | ||||||
| /usr/lib/qubes/qfile-daemon-dvm* | /usr/lib/qubes/qfile-daemon-dvm* | ||||||
| /usr/lib/qubes/qfile-daemon | /usr/lib/qubes/qfile-daemon | ||||||
|  | /usr/lib/qubes/sync_rpmdb_updatevm.sh | ||||||
|  | %attr(4750,root,qubes) /usr/lib/qubes/qfile-dom0-unpacker | ||||||
| %attr(770,root,qubes) %dir /var/lib/qubes | %attr(770,root,qubes) %dir /var/lib/qubes | ||||||
| %attr(770,root,qubes) %dir /var/lib/qubes/vm-templates | %attr(770,root,qubes) %dir /var/lib/qubes/vm-templates | ||||||
| %attr(770,root,qubes) %dir /var/lib/qubes/appvms | %attr(770,root,qubes) %dir /var/lib/qubes/appvms | ||||||
| %attr(770,root,qubes) %dir /var/lib/qubes/servicevms | %attr(770,root,qubes) %dir /var/lib/qubes/servicevms | ||||||
| %attr(770,root,qubes) %dir /var/lib/qubes/backup | %attr(770,root,qubes) %dir /var/lib/qubes/backup | ||||||
| %attr(770,root,qubes) %dir /var/lib/qubes/dvmdata | %attr(770,root,qubes) %dir /var/lib/qubes/dvmdata | ||||||
|  | %attr(770,root,qubes) %dir /var/lib/qubes/updates | ||||||
| %dir /usr/share/qubes/icons/*.png | %dir /usr/share/qubes/icons/*.png | ||||||
|  | /usr/share/qubes/qubes-vm.directory.template | ||||||
|  | /usr/share/qubes/qubes-templatevm.directory.template | ||||||
|  | /usr/share/qubes/qubes-appmenu-select.template | ||||||
|  | /usr/share/qubes/vm-template.conf | ||||||
| /usr/lib/qubes/qubes_setup_dnat_to_ns | /usr/lib/qubes/qubes_setup_dnat_to_ns | ||||||
| /usr/lib/qubes/qubes_fix_nm_conf.sh | /usr/lib/qubes/qubes_fix_nm_conf.sh | ||||||
| /etc/dhclient.d/qubes_setup_dnat_to_ns.sh | /etc/dhclient.d/qubes_setup_dnat_to_ns.sh | ||||||
| @ -274,7 +308,7 @@ fi | |||||||
| /usr/lib64/pm-utils/sleep.d/01qubes-sync-vms-clock | /usr/lib64/pm-utils/sleep.d/01qubes-sync-vms-clock | ||||||
| /usr/lib64/pm-utils/sleep.d/01qubes-suspend-netvm | /usr/lib64/pm-utils/sleep.d/01qubes-suspend-netvm | ||||||
| /usr/lib64/pm-utils/sleep.d/02qubes-pause-vms | /usr/lib64/pm-utils/sleep.d/02qubes-pause-vms | ||||||
| /usr/bin/xenstore-watch | /usr/bin/xenstore-watch-qubes | ||||||
| /usr/lib/qubes/qubes_restore | /usr/lib/qubes/qubes_restore | ||||||
| /usr/lib/qubes/qubes_prepare_saved_domain.sh | /usr/lib/qubes/qubes_prepare_saved_domain.sh | ||||||
| /etc/xen/scripts/block.qubes | /etc/xen/scripts/block.qubes | ||||||
| @ -288,5 +322,8 @@ fi | |||||||
| %attr(770,root,qubes) %dir /var/run/qubes | %attr(770,root,qubes) %dir /var/run/qubes | ||||||
| %{_libdir}/libvchan.so | %{_libdir}/libvchan.so | ||||||
| %{_libdir}/libu2mfn.so | %{_libdir}/libu2mfn.so | ||||||
|  | /etc/yum.real.repos.d/qubes-cached.repo | ||||||
| /etc/sudoers.d/qubes | /etc/sudoers.d/qubes | ||||||
| /etc/xdg/autostart/qubes-guid.desktop | /etc/xdg/autostart/qubes-guid.desktop | ||||||
|  | /etc/security/limits.d/99-qubes.conf | ||||||
|  | /etc/yum/post-actions/qubes_sync_rpmdb_updatevm.action | ||||||
|  | |||||||
| @ -66,9 +66,6 @@ mkdir -p $RPM_BUILD_ROOT/var/run/qubes | |||||||
| mkdir -p $RPM_BUILD_ROOT/etc/xen/scripts | mkdir -p $RPM_BUILD_ROOT/etc/xen/scripts | ||||||
| cp ../common/vif-route-qubes $RPM_BUILD_ROOT/etc/xen/scripts | cp ../common/vif-route-qubes $RPM_BUILD_ROOT/etc/xen/scripts | ||||||
| 
 | 
 | ||||||
| mkdir -p $RPM_BUILD_ROOT/etc/dbus-1/system.d |  | ||||||
| cp ../netvm/dbus-nm-applet.conf $RPM_BUILD_ROOT/etc/dbus-1/system.d/qubes-nm-applet.conf |  | ||||||
| 
 |  | ||||||
| %post | %post | ||||||
| 
 | 
 | ||||||
| # Create NetworkManager configuration if we do not have it | # Create NetworkManager configuration if we do not have it | ||||||
| @ -91,11 +88,6 @@ if [ "$1" = 0 ] ; then | |||||||
|     chkconfig qubes_core_netvm off |     chkconfig qubes_core_netvm off | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| %triggerin -- NetworkManager |  | ||||||
| # Fix PolicyKit settings to allow run as normal user not visible to ConsoleKit |  | ||||||
| sed 's#<defaults>$#\0<allow_any>yes</allow_any>#' -i /usr/share/polkit-1/actions/org.freedesktop.NetworkManager.policy |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| %clean | %clean | ||||||
| rm -rf $RPM_BUILD_ROOT | rm -rf $RPM_BUILD_ROOT | ||||||
| 
 | 
 | ||||||
| @ -108,4 +100,3 @@ rm -rf $RPM_BUILD_ROOT | |||||||
| /etc/NetworkManager/dispatcher.d/qubes_nmhook | /etc/NetworkManager/dispatcher.d/qubes_nmhook | ||||||
| /etc/NetworkManager/dispatcher.d/30-qubes_external_ip | /etc/NetworkManager/dispatcher.d/30-qubes_external_ip | ||||||
| /etc/xen/scripts/vif-route-qubes | /etc/xen/scripts/vif-route-qubes | ||||||
| /etc/dbus-1/system.d/qubes-nm-applet.conf |  | ||||||
|  | |||||||
							
								
								
									
										42
									
								
								vchan/init.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								vchan/init.c
									
									
									
									
									
								
							| @ -65,15 +65,25 @@ static int server_interface_init(struct libvchan *ctrl, int devno) | |||||||
| 	struct xs_handle *xs; | 	struct xs_handle *xs; | ||||||
| 	char buf[64]; | 	char buf[64]; | ||||||
| 	char ref[16]; | 	char ref[16]; | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |     xc_evtchn *evfd; | ||||||
|  | #else | ||||||
| 	int evfd; | 	int evfd; | ||||||
|  | #endif | ||||||
| 	evtchn_port_or_error_t port; | 	evtchn_port_or_error_t port; | ||||||
| 	xs = xs_domain_open(); | 	xs = xs_domain_open(); | ||||||
| 	if (!xs) { | 	if (!xs) { | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  | 	evfd = xc_evtchn_open(NULL, 0); | ||||||
|  | 	if (!evfd) | ||||||
|  | 		goto fail; | ||||||
|  | #else | ||||||
| 	evfd = xc_evtchn_open(); | 	evfd = xc_evtchn_open(); | ||||||
| 	if (evfd < 0) | 	if (evfd < 0) | ||||||
| 		goto fail; | 		goto fail; | ||||||
|  | #endif | ||||||
| 	ctrl->evfd = evfd; | 	ctrl->evfd = evfd; | ||||||
| 	// the following hardcoded 0 is the peer domain id
 | 	// the following hardcoded 0 is the peer domain id
 | ||||||
| 	port = xc_evtchn_bind_unbound_port(evfd, 0);	 | 	port = xc_evtchn_bind_unbound_port(evfd, 0);	 | ||||||
| @ -98,7 +108,11 @@ static int server_interface_init(struct libvchan *ctrl, int devno) | |||||||
| 	ret = 0; | 	ret = 0; | ||||||
|       fail2: |       fail2: | ||||||
| 	if (ret) | 	if (ret) | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |         xc_evtchn_close(evfd); | ||||||
|  | #else | ||||||
| 		close(evfd); | 		close(evfd); | ||||||
|  | #endif | ||||||
|       fail: |       fail: | ||||||
| 	xs_daemon_close(xs); | 	xs_daemon_close(xs); | ||||||
| 	return ret; | 	return ret; | ||||||
| @ -152,10 +166,18 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) | |||||||
| 	int ret = -1; | 	int ret = -1; | ||||||
| 	unsigned int len; | 	unsigned int len; | ||||||
| 	struct xs_handle *xs; | 	struct xs_handle *xs; | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |     xc_interface *xcfd; | ||||||
|  | #else | ||||||
| 	int xcfd; | 	int xcfd; | ||||||
|  | #endif | ||||||
| 	char buf[64]; | 	char buf[64]; | ||||||
| 	char *ref; | 	char *ref; | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |     xc_evtchn *evfd; | ||||||
|  | #else | ||||||
| 	int evfd; | 	int evfd; | ||||||
|  | #endif | ||||||
| 	int remote_port; | 	int remote_port; | ||||||
| 	xs = xs_daemon_open(); | 	xs = xs_daemon_open(); | ||||||
| 	if (!xs) { | 	if (!xs) { | ||||||
| @ -181,23 +203,43 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) | |||||||
| 	if (!remote_port) | 	if (!remote_port) | ||||||
| 		goto fail; | 		goto fail; | ||||||
| 	free(ref); | 	free(ref); | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  | 	xcfd = xc_interface_open(NULL, NULL, 0); | ||||||
|  | 	if (!xcfd) | ||||||
|  | 		goto fail; | ||||||
|  | #else | ||||||
| 	xcfd = xc_interface_open(); | 	xcfd = xc_interface_open(); | ||||||
| 	if (xcfd < 0) | 	if (xcfd < 0) | ||||||
| 		goto fail; | 		goto fail; | ||||||
|  | #endif | ||||||
| 	ctrl->ring = (struct vchan_interface *) | 	ctrl->ring = (struct vchan_interface *) | ||||||
| 	    xc_map_foreign_range(xcfd, domain, 4096, | 	    xc_map_foreign_range(xcfd, domain, 4096, | ||||||
| 				 PROT_READ | PROT_WRITE, ctrl->ring_ref); | 				 PROT_READ | PROT_WRITE, ctrl->ring_ref); | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |     xc_interface_close(xcfd); | ||||||
|  | #else | ||||||
| 	close(xcfd); | 	close(xcfd); | ||||||
|  | #endif | ||||||
| 	if (ctrl->ring == 0 || ctrl->ring == MAP_FAILED) | 	if (ctrl->ring == 0 || ctrl->ring == MAP_FAILED) | ||||||
| 		goto fail; | 		goto fail; | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  | 	evfd = xc_evtchn_open(NULL, 0); | ||||||
|  | 	if (!evfd) | ||||||
|  | 		goto fail; | ||||||
|  | #else | ||||||
| 	evfd = xc_evtchn_open(); | 	evfd = xc_evtchn_open(); | ||||||
| 	if (evfd < 0) | 	if (evfd < 0) | ||||||
| 		goto fail; | 		goto fail; | ||||||
|  | #endif | ||||||
| 	ctrl->evfd = evfd; | 	ctrl->evfd = evfd; | ||||||
| 	ctrl->evport = | 	ctrl->evport = | ||||||
| 	    xc_evtchn_bind_interdomain(evfd, domain, remote_port); | 	    xc_evtchn_bind_interdomain(evfd, domain, remote_port); | ||||||
| 	if (ctrl->evport < 0 || xc_evtchn_notify(evfd, ctrl->evport)) | 	if (ctrl->evport < 0 || xc_evtchn_notify(evfd, ctrl->evport)) | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |         xc_evtchn_close(evfd); | ||||||
|  | #else | ||||||
| 		close(evfd); | 		close(evfd); | ||||||
|  | #endif | ||||||
| 	else | 	else | ||||||
| 		ret = 0; | 		ret = 0; | ||||||
|       fail: |       fail: | ||||||
|  | |||||||
| @ -149,7 +149,7 @@ int libvchan_close(struct libvchan *ctrl) | |||||||
| /// The fd to use for select() set
 | /// The fd to use for select() set
 | ||||||
| int libvchan_fd_for_select(struct libvchan *ctrl) | int libvchan_fd_for_select(struct libvchan *ctrl) | ||||||
| { | { | ||||||
| 	return ctrl->evfd; | 	return xc_evtchn_fd(ctrl->evfd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Unmasks event channel; must be called before calling select(), and only then
 | /// Unmasks event channel; must be called before calling select(), and only then
 | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  | #include <xenctrl.h> | ||||||
| typedef uint32_t VCHAN_RING_IDX; | typedef uint32_t VCHAN_RING_IDX; | ||||||
| 
 | 
 | ||||||
| /// struct vchan_interface is placed in memory shared between domains
 | /// struct vchan_interface is placed in memory shared between domains
 | ||||||
| @ -37,7 +38,11 @@ struct libvchan { | |||||||
| 	struct vchan_interface *ring; | 	struct vchan_interface *ring; | ||||||
| 	uint32_t ring_ref; | 	uint32_t ring_ref; | ||||||
| 	/// descriptor to event channel interface
 | 	/// descriptor to event channel interface
 | ||||||
|  | #ifdef XENCTRL_HAS_XC_INTERFACE | ||||||
|  |     xc_evtchn *evfd; | ||||||
|  | #else | ||||||
| 	int evfd; | 	int evfd; | ||||||
|  | #endif | ||||||
| 	int evport; | 	int evport; | ||||||
| 	VCHAN_RING_IDX *wr_cons, *wr_prod, *rd_cons, *rd_prod; | 	VCHAN_RING_IDX *wr_cons, *wr_prod, *rd_cons, *rd_prod; | ||||||
| 	char *rd_ring, *wr_ring; | 	char *rd_ring, *wr_ring; | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 1.5.26 | 1.6.1 | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 1.5.28 | 1.6.1 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Joanna Rutkowska
						Joanna Rutkowska