diff --git a/misc/close-window.c b/misc/close-window.c index 071527c..645cd7a 100644 --- a/misc/close-window.c +++ b/misc/close-window.c @@ -15,15 +15,26 @@ int close_window(Display *d, XID window) { return XSendEvent(ev.display, ev.window, True, 0, (XEvent *) & ev); } +int is_window_visible(Display *d, XID window) { + XWindowAttributes xwa; + + if (!XGetWindowAttributes(d, window, &xwa)) + return 0; + return xwa.map_state == IsViewable; +} + int main(int argc, char **argv) { int i; Display *d; + XID w; d = XOpenDisplay(NULL); if (!d) exit(1); for (i=1; i /tmp/dispvm-prerun-proclist.log echo "Closing windows..." /usr/lib/qubes/close-window `xwininfo -root -children|tail -n +7 |awk '{print $1}'` sleep 1 - -if [ -e /rw/home/user/.qubes-dispvm-customized ]; then - cp -af /rw/home/user /home/ -else - cat /etc/dispvm-dotfiles.tbz | tar -xjf- --overwrite -C /home/user --owner user 2>&1 >>/tmp/dispvm-dotfiles-errors.log -fi +fuser -vkm /rw echo done. diff --git a/rpm_spec/core-vm.spec b/rpm_spec/core-vm.spec index 4461d5f..2565bbf 100644 --- a/rpm_spec/core-vm.spec +++ b/rpm_spec/core-vm.spec @@ -546,6 +546,7 @@ The Qubes core startup configuration for SystemD init. /lib/systemd/system/qubes-dvm.service /lib/systemd/system/qubes-misc-post.service /lib/systemd/system/qubes-firewall.service +/lib/systemd/system/qubes-mount-home.service /lib/systemd/system/qubes-netwatcher.service /lib/systemd/system/qubes-network.service /lib/systemd/system/qubes-sysinit.service @@ -561,6 +562,7 @@ The Qubes core startup configuration for SystemD init. /usr/lib/qubes/init/network-proxy-setup.sh /usr/lib/qubes/init/misc-post.sh /usr/lib/qubes/init/misc-post-stop.sh +/usr/lib/qubes/init/mount-home.sh /usr/lib/qubes/init/qubes-sysinit.sh /usr/lib/qubes/init/ModemManager.service /usr/lib/qubes/init/NetworkManager.service @@ -580,7 +582,7 @@ The Qubes core startup configuration for SystemD init. %post systemd -for srv in qubes-dvm qubes-sysinit qubes-misc-post qubes-netwatcher qubes-network qubes-firewall qubes-updates-proxy qubes-qrexec-agent; do +for srv in qubes-dvm qubes-sysinit qubes-misc-post qubes-mount-home qubes-netwatcher qubes-network qubes-firewall qubes-updates-proxy qubes-qrexec-agent; do /bin/systemctl --no-reload enable $srv.service 2> /dev/null done @@ -648,6 +650,6 @@ if [ "$1" != 0 ] ; then exit 0 fi -for srv in qubes-dvm qubes-sysinit qubes-misc-post qubes-netwatcher qubes-network qubes-qrexec-agent; do +for srv in qubes-dvm qubes-sysinit qubes-misc-post qubes-mount-home qubes-netwatcher qubes-network qubes-qrexec-agent; do /bin/systemctl disable $srv.service do diff --git a/vm-systemd/misc-post.sh b/vm-systemd/misc-post.sh index 27b07e2..d3717d3 100755 --- a/vm-systemd/misc-post.sh +++ b/vm-systemd/misc-post.sh @@ -22,39 +22,6 @@ fi # qubesdb-read fails INTERFACE=eth0 /usr/lib/qubes/setup-ip -if [ -e /dev/xvdb -a ! -e /etc/this-is-dvm ] ; then - resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed" - tune2fs -m 0 /dev/xvdb - mount /rw - - if ! [ -d /rw/home ] ; then - echo - echo "--> Virgin boot of the VM: Linking /home to /rw/home" - - mkdir -p /rw/config - touch /rw/config/rc.local - touch /rw/config/rc.local-early - - mkdir -p /rw/home - cp -a /home.orig/user /rw/home - - mkdir -p /rw/usrlocal - cp -a /usr/local.orig/* /rw/usrlocal - - touch /var/lib/qubes/first-boot-completed - fi - # Chown home if user UID have changed - can be the case on template switch - HOME_USER_UID=`ls -dn /rw/home/user | awk '{print $3}'` - if [ "`id -u user`" -ne "$HOME_USER_UID" ]; then - find /rw/home/user -uid "$HOME_USER_UID" -print0 | xargs -0 chown user:user - fi - if [ -L /home ]; then - rm /home - mkdir /home - fi - mount /home -fi - [ -x /rw/config/rc.local ] && /rw/config/rc.local # Start services which haven't own proper systemd unit: diff --git a/vm-systemd/mount-home.sh b/vm-systemd/mount-home.sh new file mode 100644 index 0000000..3307551 --- /dev/null +++ b/vm-systemd/mount-home.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed" +tune2fs -m 0 /dev/xvdb +mount /rw + +if ! [ -d /rw/home ] ; then + echo + echo "--> Virgin boot of the VM: Populating /rw/home" + + mkdir -p /rw/config + touch /rw/config/rc.local + touch /rw/config/rc.local-early + + mkdir -p /rw/home + cp -a /home.orig/user /rw/home + + mkdir -p /rw/usrlocal + cp -a /usr/local.orig/* /rw/usrlocal + + touch /var/lib/qubes/first-boot-completed +fi + +# Chown home if user UID have changed - can be the case on template switch +HOME_USER_UID=`ls -dn /rw/home/user | awk '{print $3}'` +if [ "`id -u user`" -ne "$HOME_USER_UID" ]; then + find /rw/home/user -uid "$HOME_USER_UID" -print0 | xargs -0 chown user:user +fi + +# Old Qubes versions had symlink /home -> /rw/home; now we use mount --bind +if [ -L /home ]; then + rm /home + mkdir /home +fi + +if [ -e /var/run/qubes-service/qubes-dvm ]; then + mount --bind /home_volatile /home + touch /etc/this-is-dvm + + #If user have customized DispVM settings, use its home instead of default dotfiles + if [ -e /rw/home/user/.qubes-dispvm-customized ]; then + cp -af /rw/home/user /home/ + else + cat /etc/dispvm-dotfiles.tbz | tar -xjf- --overwrite -C /home/user --owner user 2>&1 >/tmp/dispvm-dotfiles-errors.log + fi +else + mount /home +fi diff --git a/vm-systemd/prepare-dvm.sh b/vm-systemd/prepare-dvm.sh index ffa25fe..04a9e1f 100755 --- a/vm-systemd/prepare-dvm.sh +++ b/vm-systemd/prepare-dvm.sh @@ -6,35 +6,21 @@ possibly_run_save_script() if [ -z "$ENCODED_SCRIPT" ] ; then return ; fi echo $ENCODED_SCRIPT|perl -e 'use MIME::Base64 qw(decode_base64); local($/) = undef;print decode_base64()' >/tmp/qubes-save-script chmod 755 /tmp/qubes-save-script - Xorg -config /etc/X11/xorg-preload-apps.conf :0 & - while ! [ -S /tmp/.X11-unix/X0 ]; do sleep 0.5; done DISPLAY=:0 su - user -c /tmp/qubes-save-script - killall Xorg Xorg.bin } -if qubesdb-read /qubes-save-request 2>/dev/null ; then - if [ -L /home ]; then - rm /home - mkdir /home - fi - mount --bind /home_volatile /home - touch /etc/this-is-dvm - mount /rw +if true; then + echo user | /bin/sh /etc/qubes-rpc/qubes.WaitForSession possibly_run_save_script umount /rw dmesg -c >/dev/null + qubesdb-watch /qubes-restore-complete & + watch_pid=$! free | grep Mem: | - (read a b c d ; qubesdb-write /qubes-used-mem $c) - # give dom0 time to read some entries, when done it will shutdown qubesdb, - # so wait for it - qubesdb-watch /stop-qubesdb - # just to make sure - systemctl stop qubes-db.service - + (read label total used free shared buffers cached; qubesdb-write /qubes-used-mem $[ $used + $cached ]) # we're still running in DispVM template echo "Waiting for save/restore..." - # the service will start only after successful restore - systemctl start qubes-db.service + qubesdb-read /qubes-restore-complete || wait $watch_pid echo Back to life. fi diff --git a/vm-systemd/qubes-misc-post.service b/vm-systemd/qubes-misc-post.service index 8aec208..8450a12 100644 --- a/vm-systemd/qubes-misc-post.service +++ b/vm-systemd/qubes-misc-post.service @@ -1,6 +1,6 @@ [Unit] Description=Qubes misc post-boot actions -After=qubes-dvm.service +After=qubes-dvm.service qubes-mount-home.service [Service] Type=oneshot diff --git a/vm-systemd/qubes-mount-home.service b/vm-systemd/qubes-mount-home.service new file mode 100644 index 0000000..93b3f93 --- /dev/null +++ b/vm-systemd/qubes-mount-home.service @@ -0,0 +1,13 @@ +[Unit] +Description=Mount /rw and /home, initialize them if needed +Before=qubes-gui-agent.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/lib/qubes/init/mount-home.sh +ExecStop=/sbin/fuser -kMm /home ; /bin/umount /home +ExecStopPost=-/bin/umount /rw + +[Install] +WantedBy=multi-user.target