فهرست منبع

Merge remote-tracking branch 'qubesos/pr/21'

* qubesos/pr/21:
  Clean up specfile unit activation aspect.
  Fix VM settings running while / is readonly.
  Invert logic of systemd_version_changed.
Marek Marczykowski-Górecki 7 سال پیش
والد
کامیت
f47fe7cd76
6فایلهای تغییر یافته به همراه225 افزوده شده و 90 حذف شده
  1. 2 2
      init/functions
  2. 145 51
      rpm_spec/core-vm.spec
  3. 28 8
      vm-systemd/75-qubes-vm.preset
  4. 13 0
      vm-systemd/qubes-early-vm-config.service
  5. 37 0
      vm-systemd/qubes-early-vm-config.sh
  6. 0 29
      vm-systemd/qubes-sysinit.sh

+ 2 - 2
init/functions

@@ -29,9 +29,9 @@ systemd_version_changed() {
     under_systemd || return
     systemd_pkg_version=`systemctl --version|head -n 1`
     if dmesg | grep -q "$systemd_pkg_version running in system mode."; then
-        return 0
+        return 1
     fi
-    return 1
+    return 0
 }
 
 possibly_run_save_script() {

+ 145 - 51
rpm_spec/core-vm.spec

@@ -21,10 +21,88 @@
 #
 
 %define qubes_services qubes-core qubes-core-netvm qubes-core-early qubes-firewall qubes-netwatcher qubes-iptables qubes-updates-proxy qubes-qrexec-agent qubes-dvm
+%define qubes_preset_file 75-qubes-vm.preset
 
 %{!?version: %define version %(cat version)}
 %{!?backend_vmm: %define backend_vmm %(echo $BACKEND_VMM)}
 
+%define scriptletfuns is_static() { \
+    [ -f "%{_unitdir}/$1" ] && ! grep -q '^[[].nstall]' "%{_unitdir}/$1" \
+} \
+ \
+is_masked() { \
+    if [ ! -L %{_sysconfdir}/systemd/system/"$1" ] \
+    then \
+       return 1 \
+    fi \
+    target=`readlink %{_sysconfdir}/systemd/system/"$1" 2>/dev/null` || : \
+    if [ "$target" = "/dev/null" ] \
+    then \
+       return 0 \
+    fi \
+    return 1 \
+} \
+\
+mask() { \
+    ln -sf /dev/null %{_sysconfdir}/systemd/system/"$1" \
+} \
+\
+unmask() { \
+    if ! is_masked "$1" \
+    then \
+        return 0 \
+    fi \
+    rm -f %{_sysconfdir}/systemd/system/"$1" \
+} \
+\
+preset_units() { \
+    local represet= \
+    cat "$1" | while read action unit_name \
+    do \
+        if [ "$action" = "#" -a "$unit_name" = "Units below this line will be re-preset on package upgrade" ] \
+        then \
+            represet=1 \
+            continue \
+        fi \
+        echo "$action $unit_name" | grep -q '^[[:space:]]*[^#;]' || continue \
+        [ -n "$action" -a -n "$unit_name" ] || continue \
+        if [ "$2" = "initial" -o "$represet" = "1" ] \
+        then \
+            if [ "$action" = "disable" ] && is_static "$unit_name" \
+            then \
+                if ! is_masked "$unit_name" \
+                then \
+                    # We must effectively mask these units, even if they are static. \
+                    mask "$unit_name" \
+                fi \
+            elif [ "$action" = "enable" ] && is_static "$unit_name" \
+            then \
+                if is_masked "$unit_name" \
+                then \
+                    # We masked this static unit before, now we unmask it. \
+                    unmask "$unit_name" \
+                fi \
+                 systemctl --no-reload preset "$unit_name" >/dev/null 2>&1 || : \
+            else \
+                systemctl --no-reload preset "$unit_name" >/dev/null 2>&1 || : \
+            fi \
+        fi \
+    done \
+} \
+\
+restore_units() { \
+    grep '^[[:space:]]*[^#;]' "$1" | while read action unit_name \
+    do \
+        if is_static "$unit_name" && is_masked "$unit_name" \
+        then \
+            # If the unit had been masked by us, we must unmask it here. \
+            # Otherwise systemctl preset will fail badly. \
+            unmask "$unit_name" \
+        fi \
+        systemctl --no-reload preset "$unit_name" >/dev/null 2>&1 || : \
+    done \
+} \
+
 Name:		qubes-core-vm
 Version:	%{version}
 Release:	1%{dist}
@@ -549,11 +627,12 @@ The Qubes core startup configuration for SystemD init.
 /lib/systemd/system/qubes-network.service
 /lib/systemd/system/qubes-iptables.service
 /lib/systemd/system/qubes-sysinit.service
+/lib/systemd/system/qubes-early-vm-config.service
 /lib/systemd/system/qubes-update-check.service
 /lib/systemd/system/qubes-update-check.timer
 /lib/systemd/system/qubes-updates-proxy.service
 /lib/systemd/system/qubes-qrexec-agent.service
-/lib/systemd/system-preset/75-qubes-vm.preset
+/lib/systemd/system-preset/%qubes_preset_file
 /lib/modules-load.d/qubes-core.conf
 /lib/modules-load.d/qubes-misc.conf
 /usr/lib/qubes/init/qubes-iptables
@@ -581,68 +660,83 @@ The Qubes core startup configuration for SystemD init.
 
 %post systemd
 
-PRESET_FAILED=0
-if [ $1 -eq 1 ]; then
-    /bin/systemctl --no-reload preset-all > /dev/null 2>&1 && PRESET_FAILED=0 || PRESET_FAILED=1
+changed=
+
+%scriptletfuns
+
+if [ $1 -eq 1 ]
+then
+    preset_units %{_presetdir}/%qubes_preset_file initial
+    changed=true
 else
-    services="qubes-dvm qubes-misc-post qubes-firewall qubes-mount-dirs"
-    services="$services qubes-netwatcher qubes-network qubes-sysinit"
-    services="$services qubes-iptables qubes-updates-proxy qubes-qrexec-agent"
-    for srv in $services; do
-        /bin/systemctl --no-reload preset $srv.service
-    done
-    /bin/systemctl --no-reload preset qubes-update-check.timer
+    preset_units %{_presetdir}/%qubes_preset_file upgrade
+    changed=true
     # Upgrade path - now qubes-iptables is used instead
-    if [ -f /lib/systemd/system/iptables.service ]; then
-        /bin/systemctl --no-reload preset iptables.service
-    fi
-    if [ -f /lib/systemd/system/ip6tables.service ]; then
-        /bin/systemctl --no-reload preset ip6tables.service
-    fi
+    for svc in iptables ip6tables
+    do
+        if [ -f "$svc".service ]
+        then
+            systemctl --no-reload preset "$svc".service
+            changed=true
+        fi
+    done
 fi
 
-# Set default "runlevel"
-rm -f /etc/systemd/system/default.target
-ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
-
-grep '^[[:space:]]*[^#;]' /lib/systemd/system-preset/75-qubes-vm.preset | while read action unit_name; do
-    case "$action" in
-    (disable)
-        if [ -f /lib/systemd/system/$unit_name ]; then
-            if ! fgrep -q '[Install]' /lib/systemd/system/$unit_name; then
-                # forcibly disable
-                ln -sf /dev/null /etc/systemd/system/$unit_name
-            fi
-        fi
-        ;;
-    *)
-        # preset-all is not available in fc20; so preset each unit file listed in 75-qubes-vm.preset
-        if [ $1 -eq 1 -a "${PRESET_FAILED}" -eq 1 ]; then
-            systemctl --no-reload preset "${unit_name}" > /dev/null 2>&1 || true
-        fi
-        ;;
-    esac
-done
+if [ $1 -eq 1 ]
+then
+    # First install.
+    # Set default "runlevel".
+    # FIXME: this ought to be done via kernel command line.
+    # The fewer deviations of the template from the seed
+    # image, the better.
+    rm -f %{_sysconfdir}/systemd/system/default.target
+    ln -s %{_unitdir}/multi-user.target %{_sysconfdir}/systemd/system/default.target
+    changed=true
+fi
 
 # remove old symlinks
-if [ -L /etc/systemd/system/sysinit.target.wants/qubes-random-seed.service ]; then
-    rm /etc/systemd/system/sysinit.target.wants/qubes-random-seed.service
+if [ -L %{_sysconfdir}/systemd/system/sysinit.target.wants/qubes-random-seed.service ]
+then
+    rm -f %{_sysconfdir}/systemd/system/sysinit.target.wants/qubes-random-seed.service
+    changed=true
 fi
-if [ -L /etc/systemd/system/multi-user.target.wants/qubes-mount-home.service ]; then
-    rm /etc/systemd/system/multi-user.target.wants/qubes-mount-home.service
+if [ -L %{_sysconfdir}/systemd/system/multi-user.target.wants/qubes-mount-home.service ]
+then
+    rm -f %{_sysconfdir}/systemd/system/multi-user.target.wants/qubes-mount-home.service
+    changed=true
 fi
 
-/bin/systemctl daemon-reload
+if [ "x$changed" != "x" ]
+then
+    systemctl daemon-reload
+fi
 
-exit 0
+%preun systemd
+
+if [ $1 -eq 0 ] ; then
+    # Run this only during uninstall.
+    # Save the preset file to later use it to re-preset services there
+    # once the Qubes OS preset file is removed.
+    mkdir -p %{_rundir}/qubes-uninstall
+    cp -f %{_presetdir}/%qubes_preset_file %{_rundir}/qubes-uninstall/
+fi
 
 %postun systemd
 
-#Do not run this part on upgrades
-if [ "$1" != 0 ] ; then
-    exit 0
+changed=
+
+%scriptletfuns
+
+if [ -d %{_rundir}/qubes-uninstall ]
+then
+    # We have a saved preset file (or more).
+    # Re-preset the units mentioned there.
+    restore_units %{_rundir}/qubes-uninstall/%qubes_preset_file
+    rm -rf %{_rundir}/qubes-uninstall
+    changed=true
 fi
 
-for srv in qubes-dvm qubes-sysinit qubes-misc-post qubes-mount-dirs qubes-netwatcher qubes-network qubes-qrexec-agent; do
-    /bin/systemctl disable $srv.service
-do
+if [ "x$changed" != "x" ]
+then
+    systemctl daemon-reload
+fi

+ 28 - 8
vm-systemd/75-qubes-vm.preset

@@ -14,13 +14,38 @@
 # Qubes currently does not provide a way to permanently prevent such units from
 # being masked.
 #
+# Maintainer information:
+#
+# * All units listed here are preset during first install of the *-systemd RPM.
+#   For those units which are disabled here, but don't have an install section
+#   (static units), we mask them during that install.
+# * All units listed here that find themselves below the comment titled
+#   "# Units below this line will be re-preset on package upgrade"
+#   are preset both during install and during upgrade.  This allows you to add
+#   new units here and have them become active when the user's machine upgrades
+#   their *-systemd RPM built by this project.
+#
+# Hi, Matt!  I see you did great with this conversion to systemd presets!
+# Thank you!  Skyler sends you her regards from Europe!
+#   - Rudd-O
+#
 # https://groups.google.com/d/topic/qubes-users/dpM_GHfmEOk/discussion
 
-disable alsa-store.service
-disable alsa-restore.service
 disable avahi.service
 disable avahi-daemon.service
 disable avahi-daemon.socket
+
+# Fedora only services
+disable rpcbind.service
+disable sendmail.service
+disable sm-client.service
+disable sshd.service
+disable backuppc.service
+
+# Units below this line will be re-preset on package upgrade
+
+disable alsa-store.service
+disable alsa-restore.service
 disable hwclock-save.service
 disable mdmonitor.service
 disable plymouth-start.service
@@ -33,7 +58,6 @@ disable colord.service
 disable systemd-timesyncd.service
 
 # Fedora only services
-disable backuppc.service
 disable cpuspeed.service
 disable dnf-makecache.timer
 disable fedora-autorelabel.service
@@ -50,17 +74,13 @@ disable mdmonitor-takeover.service
 disable multipathd.service
 disable openct.service
 disable rngd.service
-disable rpcbind.service
-disable sendmail.service
-disable sm-client.service
-disable sshd.service
 disable tcsd.service
 
 enable qubes-sysinit.service
+enable qubes-early-vm-config.service
 enable qubes-db.service
 enable qubes-gui-agent.service
 enable qubes-update-check.timer
-enable qubes-update-check.timer
 enable qubes-misc-post.service
 enable qubes-updates-proxy.service
 enable qubes-dvm.service

+ 13 - 0
vm-systemd/qubes-early-vm-config.service

@@ -0,0 +1,13 @@
+[Unit]
+Description=Early Qubes VM settings
+DefaultDependencies=no
+Before=sysinit.target
+After=local-fs.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/qubes/init/qubes-early-vm-config.sh
+
+[Install]
+WantedBy=sysinit.target

+ 37 - 0
vm-systemd/qubes-early-vm-config.sh

@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# This is invoked by qubes-early-vm-config.service.
+# It happens after local-fs.target is reached
+# but before sysinit.target is reached.
+
+# Source Qubes library.
+. /usr/lib/qubes/init/functions
+
+# Set the hostname
+if ! is_protected_file /etc/hostname ; then
+    name=`qubesdb-read /name`
+    if [ -n "$name" ]; then
+        hostname $name
+        if [ -e /etc/debian_version ]; then
+            ipv4_localhost_re="127\.0\.1\.1"
+        else
+            ipv4_localhost_re="127\.0\.0\.1"
+        fi
+        sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
+        sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
+    fi
+fi
+
+# Set the timezone
+if ! is_protected_file /etc/timezone ; then
+    timezone=`qubesdb-read /qubes-timezone 2> /dev/null`
+    if [ -n "$timezone" ]; then
+        ln -sf ../usr/share/zoneinfo/"$timezone" /etc/localtime
+        if [ -e /etc/debian_version ]; then
+            echo "$timezone" > /etc/timezone
+        elif test -d /etc/sysconfig ; then
+            echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
+            echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
+        fi
+    fi
+fi

+ 0 - 29
vm-systemd/qubes-sysinit.sh

@@ -60,35 +60,6 @@ for srv in `qubesdb-multiread /qubes-service/ 2>/dev/null |grep ' = 0'|cut -f 1
     rm -f /var/run/qubes-service/$srv
 done
 
-# Set the hostname
-if ! is_protected_file /etc/hostname ; then
-    name=`qubesdb-read /name`
-    if [ -n "$name" ]; then
-        hostname $name
-        if [ -e /etc/debian_version ]; then
-            ipv4_localhost_re="127\.0\.1\.1"
-        else
-            ipv4_localhost_re="127\.0\.0\.1"
-        fi
-        sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
-        sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
-    fi
-fi
-
-# Set the timezone
-if ! is_protected_file /etc/timezone ; then
-    timezone=`qubesdb-read /qubes-timezone 2> /dev/null`
-    if [ -n "$timezone" ]; then
-        ln -sf ../usr/share/zoneinfo/"$timezone" /etc/localtime
-        if [ -e /etc/debian_version ]; then
-            echo "$timezone" > /etc/timezone
-        elif test -d /etc/sysconfig ; then
-            echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
-            echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
-        fi
-    fi
-fi
-
 # Prepare environment for other services
 echo > /var/run/qubes-service-environment