Переглянути джерело

Initialize home_volatile for disposable VMs.

Manuel Amador (Rudd-O) 7 роки тому
батько
коміт
6ca10b42eb
5 змінених файлів з 90 додано та 42 видалено
  1. 75 0
      init/functions
  2. 12 5
      init/setup-dvm-home.sh
  3. 0 36
      init/setup-rw.sh
  4. 1 0
      rpm_spec/core-vm.spec
  5. 2 1
      vm-systemd/mount-dirs.sh

+ 75 - 0
init/functions

@@ -115,3 +115,78 @@ umount_retry() {
     done
     return 0
 }
+
+initialize_home() {
+    local home_root
+    local mode
+    local user
+    local uid
+    local gid
+    local homedir
+    local homedirwithouthome
+    local pair
+    local homedir_uid
+    local homedir_gid
+    local waitpid
+    local waitpids
+
+    home_root="$1"
+    mode="$2"
+
+    if [ -z "$home_root" ] ; then
+        echo "initialize_home() needs a target home root directory, such as /rw/home, as first parameter" >&2
+        return 64
+    fi
+
+    if [ "$mode" != "unconditionally" -a "$mode" != "ifneeded" ] ; then
+        echo "initialize_home() second parameter must be 'unconditionally' or 'ifneeded'" >&2
+        return 64
+    fi
+
+    if ! [ -d "$home_root" ] ; then
+        echo "initialize_home: populating $home_root" >&2
+        mkdir -p "$home_root"
+    fi
+
+    # Chown home if users' UIDs have changed - can be the case on template switch.
+    for pair in $(getent passwd | awk -F : '/\/home/ { print $1":"$3":"$4":"$6 } ') ; do
+        user=$(echo "$pair" | awk -F : ' { print $1 } ')
+        uid=$(echo "$pair" | awk -F : ' { print $2 } ')
+        gid=$(echo "$pair" | awk -F : ' { print $3 } ')
+        homedir=$(echo "$pair" | awk -F : ' { print $4 } ')
+        homedirwithouthome=$(echo "$homedir" | sed 's|^/home/||')
+        if ! test -d "$home_root/$homedirwithouthome" || [ "$mode" = "unconditionally" ] ; then
+            if [ "$homedir" == "/home/user" -a -d "/home.orig/$homedirwithouthome" ] ; then
+                echo "initialize_home: populating $mode $home_root/$homedirwithouthome from /home.orig/$homedirwithouthome" >&2
+                mkdir -p "$home_root/$homedirwithouthome"
+                cp -af -T "/home.orig/$homedirwithouthome" "$home_root/$homedirwithouthome"
+            else
+                echo "initialize_home: populating $mode $home_root/$homedirwithouthome from /etc/skel" >&2
+                mkdir -p "$home_root/$homedirwithouthome"
+                cp -af -T /etc/skel "$home_root/$homedirwithouthome"
+            fi
+            echo "initialize_home: adjusting permissions $mode on $home_root/$homedirwithouthome" >&2
+            chown -R "$uid" "$home_root/$homedirwithouthome" &
+            waitpids="$!"
+            chgrp -R "$gid" "$home_root/$homedirwithouthome" &
+            waitpids="$waitpids $!"
+            chmod 700 "$home_root/$homedirwithouthome" &
+            waitpids="$waitpids $!"
+            for waitpid in $waitpids ; do wait "$waitpid" ; done ; waitpids=
+        fi
+        waitpids=
+        homedir_uid=$(ls -dn "$home_root/$homedirwithouthome" | awk '{print $3}')
+        homedir_gid=$(ls -dn "$home_root/$homedirwithouthome" | awk '{print $4}')
+        if [ "$uid" -ne "$homedir_uid" ]; then
+            echo "initialize_home: adjusting ownership on $home_root/$homedirwithouthome to $uid" >&2
+            find "$home_root/$homedirwithouthome" -uid "$homedir_uid" -print0 | xargs -0 chown "$uid" &
+            waitpids="$waitpids $!"
+        fi
+        if [ "$gid" -ne "$homedir_gid" ]; then
+            echo "initialize_home: adjusting groupship on $home_root/$homedirwithouthome to $gid" >&2
+            find "$home_root/$homedirwithouthome" -gid "$homedir_gid" -print0 | xargs -0 chgrp "$gid" &
+            waitpids="$waitpids $!"
+        fi
+        for waitpid in $waitpids ; do wait "$waitpid" ; done ; waitpids=
+    done
+}

+ 12 - 5
init/setup-dvm-home.sh

@@ -1,5 +1,8 @@
 #!/bin/sh
 
+# Source Qubes library.
+. /usr/lib/qubes/init/functions
+
 echo "Setting up DVM home" >&2
 
 touch /etc/this-is-dvm
@@ -7,9 +10,13 @@ touch /etc/this-is-dvm
 # If the user has customized DispVM settings, use its home instead of default skel
 [ -e /home_volatile/user/.qubes-dispvm-customized ] && already_customized=yes || already_customized=no
 [ -e /rw/home/user/.qubes-dispvm-customized ] && wants_customization=yes || wants_customization=no
-if [ "$wants_customization" = "yes" -a "$already_customized" = "no" ] ; then
-    echo "Customizing /home from /rw/home/user" >&2
-    rm -rf /home_volatile/user
-    cp -af /rw/home/user /home_volatile/user
-    chown -R user.user /home_volatile/user
+if [ "$wants_customization" = "yes" ] ; then
+    if [ "$already_customized" = "no" ] ; then
+        echo "Customizing /home from /rw/home/user" >&2
+        rm -rf /home_volatile/user
+        cp -af /rw/home/user /home_volatile/user
+        chown -R user.user /home_volatile/user
+    fi
+else
+    initialize_home "/home_volatile" unconditionally
 fi

+ 0 - 36
init/setup-rw.sh

@@ -55,42 +55,6 @@ EOF
         fi
     fi
 
-    if ! [ -d /rw/home ] ; then
-        echo "Virgin boot of the VM: populating /rw/home" >&2
-        mkdir -p /rw/home
-    fi
-
-    # Chown home if users' UIDs have changed - can be the case on template switch.
-    for pair in $(getent passwd | awk -F : '/\/home/ { print $1":"$3":"$4":"$6 } ') ; do
-        user=$(echo "$pair" | awk -F : ' { print $1 } ')
-        uid=$(echo "$pair" | awk -F : ' { print $2 } ')
-        gid=$(echo "$pair" | awk -F : ' { print $3 } ')
-        homedir=$(echo "$pair" | awk -F : ' { print $4 } ')
-        if ! test -d /rw"$homedir" ; then
-            if [ "$homedir" == "/home/user" -a -d /home.orig/"$user" ] ; then
-                echo "Virgin boot of the VM: populating /rw$homedir from /home.orig/$user" >&2
-                cp -af /home.orig/"$user" /rw"$homedir"
-            else
-                echo "Virgin boot of the VM: populating /rw$homedir from /etc/skel" >&2
-                cp -af /etc/skel /rw"$homedir"
-            fi
-            chown -R "$uid"  /rw"$homedir" &
-            chgrp -R "$gid"  /rw"$homedir" &
-            chmod 700 /rw"$homedir" &
-            wait
-        fi
-        homedir_uid=$(ls -dn /rw"$homedir" | awk '{print $3}')
-        homedir_gid=$(ls -dn /rw"$homedir" | awk '{print $4}')
-        if [ "$uid" -ne "$homedir_uid" ]; then
-            echo "Virgin boot of the VM: adjusting ownership on /rw$homedir to $uid" >&2
-            find /rw/"$homedir" -uid "$homedir_uid" -print0 | xargs -0 echo chown "$uid"
-        fi
-        if [ "$gid" -ne "$homedir_gid" ]; then
-            echo "Virgin boot of the VM: adjusting groupship on /rw$homedir to $gid" >&2
-            find /rw/"$homedir" -gid "$homedir_gid" -print0 | xargs -0 echo chgrp "$gid"
-        fi
-    done
-
     echo "Finished checking /rw" >&2
 fi
 

+ 1 - 0
rpm_spec/core-vm.spec

@@ -130,6 +130,7 @@ Requires:   nautilus-python
 Requires:   qubes-utils >= 3.1.3
 Requires:   initscripts
 Requires:   gawk
+Requires:   sed
 # for dispvm-prerun.sh
 Requires:   procps-ng
 Requires:   util-linux

+ 2 - 1
vm-systemd/mount-dirs.sh

@@ -14,7 +14,8 @@ if qsvc qubes-dvm; then
     echo "Mounting /home_volatile onto /home" >&2
     mount --bind /home_volatile /home
 else
-    echo "Mounting /home" >&2
+    initialize_home "/rw/home" ifneeded
+    echo "Mounting /rw/home onto /home" >&2
     mount /home
     # https://github.com/QubesOS/qubes-issues/issues/1328#issuecomment-169483029
     # Do none of the following in a DispVM.