Clean up early initialization and setup of /rw

This commit is contained in:
Manuel Amador (Rudd-O) 2016-10-22 15:43:16 +00:00
parent 3b65f98db8
commit 59aec8e5eb
44 changed files with 636 additions and 539 deletions

View File

@ -86,9 +86,15 @@ install-systemd-dropins:
install -m 0644 vm-systemd/user/$${dropin}.d/*.conf $(DESTDIR)/$(DROPIN_DIR)/user/$${dropin}.d/ ;\
done
install-systemd:
install-init:
install -d $(DESTDIR)$(LIBDIR)/qubes/init
# FIXME: do a source code move vm-systemd/*.sh to init/
# since those scripts are shared between sysvinit and systemd.
install -m 0755 init/*.sh vm-systemd/*.sh $(DESTDIR)$(LIBDIR)/qubes/init/
install -m 0644 init/functions $(DESTDIR)$(LIBDIR)/qubes/init/
install-systemd: install-init
install -d $(DESTDIR)$(SYSLIBDIR)/systemd/system{,-preset} $(DESTDIR)$(LIBDIR)/qubes/init $(DESTDIR)$(SYSLIBDIR)/modules-load.d
install -m 0755 vm-systemd/*.sh $(DESTDIR)$(LIBDIR)/qubes/init/
install -m 0644 vm-systemd/qubes-*.service $(DESTDIR)$(SYSLIBDIR)/systemd/system/
install -m 0644 vm-systemd/qubes-*.timer $(DESTDIR)$(SYSLIBDIR)/systemd/system/
install -m 0644 vm-systemd/75-qubes-vm.preset $(DESTDIR)$(SYSLIBDIR)/systemd/system-preset/
@ -98,15 +104,17 @@ install-systemd:
install -D -m 0644 vm-systemd/qubes-core-agent-linux.tmpfiles \
$(DESTDIR)/usr/lib/tmpfiles.d/qubes-core-agent-linux.conf
install-sysvinit:
install-sysvinit: install-init
install -d $(DESTDIR)/etc/init.d
install vm-init.d/qubes-sysinit $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-core-early $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-core $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-core-appvm $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-core-netvm $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-firewall $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-netwatcher $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-qrexec-agent $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-updates-proxy $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-dvm $(DESTDIR)/etc/init.d/
install -D vm-init.d/qubes-core.modules $(DESTDIR)/etc/sysconfig/modules/qubes-core.modules
install -D vm-init.d/qubes-misc.modules $(DESTDIR)/etc/sysconfig/modules/qubes-misc.modules
install network/qubes-iptables $(DESTDIR)/etc/init.d/
@ -164,13 +172,6 @@ install-common:
install -g user -m 2775 -d $(DESTDIR)/var/lib/qubes/dom0-updates
install -D -m 0644 misc/qubes-master-key.asc $(DESTDIR)/usr/share/qubes/qubes-master-key.asc
if [ -r misc/dispvm-dotfiles.$(DIST).tbz ] ; \
then \
install misc/dispvm-dotfiles.$(DIST).tbz $(DESTDIR)/etc/dispvm-dotfiles.tbz ; \
else \
install misc/dispvm-dotfiles.tbz $(DESTDIR)/etc/dispvm-dotfiles.tbz ; \
fi;
install misc/dispvm-prerun.sh $(DESTDIR)$(LIBDIR)/qubes/dispvm-prerun.sh
install misc/close-window $(DESTDIR)$(LIBDIR)/qubes/close-window

View File

@ -104,10 +104,10 @@ update_qubesconfig() {
# Location of files which contains list of protected files
mkdir -p /etc/qubes/protected-files.d
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
. /usr/lib/qubes/init/functions
# qubes-core-vm has been broken for some time - it overrides /etc/hosts; restore original content
if ! grep -rq "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/hosts ; then
if ! grep -q localhost /etc/hosts; then
cat <<EOF > /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 `hostname`
@ -118,7 +118,7 @@ EOF
# ensure that hostname resolves to 127.0.0.1 resp. ::1 and that /etc/hosts is
# in the form expected by qubes-sysinit.sh
if ! grep -rq "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/hostname ; then
for ip in '127\.0\.0\.1' '::1'; do
if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts

2
debian/control vendored
View File

@ -37,6 +37,8 @@ Depends:
ncurses-term,
net-tools,
psmisc,
procps,
util-linux,
python2.7,
python-gi,
python-xdg,

View File

@ -78,11 +78,11 @@ case "${1}" in
/usr/lib/qubes/qubes-fix-nm-conf.sh
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
. /usr/lib/qubes/init/functions
# ensure that hostname resolves to 127.0.1.1 resp. ::1 and that /etc/hosts is
# in the form expected by qubes-sysinit.sh
if ! grep -rq "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/hostname ; then
for ip in '127\.0\.1\.1' '::1'; do
if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts || true
@ -95,7 +95,7 @@ case "${1}" in
# remove hostname from 127.0.0.1 line (in debian the hostname is by default
# resolved to 127.0.1.1)
if ! grep -rq "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/hosts ; then
sed -i "/^127\.0\.0\.1\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts || true
fi

14
init/control-printer-icon.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
# Source Qubes library.
. /usr/lib/qubes/init/functions
if ! is_fully_persistent && test -f /etc/xdg/autostart/print-applet.desktop ; then
if qsvc cups ; then
# Allow also notification icon
sed -i -e '/^NotShowIn=.*QUBES/s/;QUBES//' /etc/xdg/autostart/print-applet.desktop
else
# Disable notification icon
sed -i -e '/QUBES/!s/^NotShowIn=\(.*\)/NotShowIn=QUBES;\1/' /etc/xdg/autostart/print-applet.desktop
fi
fi

117
init/functions Normal file
View File

@ -0,0 +1,117 @@
#!/bin/bash
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
qsvc() {
# Returns whether a service is enabled.
# Usage: qsvc <nameofservice>
#
# Must only be used after qubes-sysinit has started.
# See qsvc_early for more information.
local count=100
while [ ! -e /var/run/qubes-service-environment ] ; do
if [ "$count" = "0" ] ; then
echo "qsvc: Warning: qubes-sysinit has not finished executing yet" >&2
break
fi
sleep 0.1
count=$(( count - 1 ))
done
[ -e /var/run/qubes-service/"$1" ]
}
under_systemd() {
pidof systemd >/dev/null 2>&1
}
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
fi
return 1
}
possibly_run_save_script() {
ENCODED_SCRIPT=$(qubesdb-read /qubes-save-script)
if [ -z "$ENCODED_SCRIPT" ] ; then return ; fi
tmpfile=$(mktemp /tmp/qubes-save-script.XXXXXXXXX)
echo $ENCODED_SCRIPT|perl -e 'use MIME::Base64 qw(decode_base64); local($/) = undef;print decode_base64(<STDIN>)' >"$tmpfile"
chmod 755 "$tmpfile"
DISPLAY=:0 su - user -c "$tmpfile"
ret=$?
rm -f "$tmpfile"
return $ret
}
have_qubesdb() {
# Tests whether qubesdb-read exists and can be executed.
type qubesdb-read >/dev/null 2>&1
}
have_qrexec_agent() {
# Tests whether qrexec-agent exists and can be executed.
PATH=/usr/lib/qubes type qrexec-agent >/dev/null 2>&1
}
qubes_vm_type() {
qubesdb-read /qubes-vm-type
}
is_netvm() {
[ "$(qubes_vm_type)" = "NetVM" ]
}
is_appvm() {
[ "$(qubes_vm_type)" = "AppVM" ]
}
is_proxyvm() {
[ "$(qubes_vm_type)" = "ProxyVM" ]
}
is_templatevm() {
[ "$(qubes_vm_type)" = "TemplateVM" ]
}
is_dispvm() {
[ "$(qubes_vm_type)" = "DisposableVM" ]
}
is_fully_persistent() {
[ "$(qubesdb-read /qubes-vm-persistence)" = "full" ]
}
is_rwonly_persistent() {
[ "$(qubesdb-read /qubes-vm-persistence)" = "rw-only" ]
}
is_updateable() {
[ "$(qubesdb-read /qubes-vm-updateable)" = "True" ]
}
reload_random_seed() {
qubesdb-read /qubes-random-seed | base64 -d > /dev/urandom
qubesdb-rm /qubes-random-seed
}
is_protected_file() {
grep -Fxrq --exclude='*.rpmsave' --exclude='*~' --exclude='*.rpmnew' --exclude='*.rpmold' -- "${1}" "$PROTECTED_FILE_LIST" 2>/dev/null
}
umount_retry() {
local count=5
while mountpoint -q "$1" ; do
if umount "$1" ; then break ; fi
echo "Something prevents unmounting $1:" >&2
fuser -vmM "$1" >&2
if [ "$count" = "0" ] ; then
return 1
fi
sleep 5
count=$(( count - 1 ))
done
return 0
}

15
init/setup-dvm-home.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
echo "Setting up DVM home" >&2
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
fi

105
init/setup-rw.sh Executable file
View File

@ -0,0 +1,105 @@
#!/bin/sh
if mountpoint -q /rw ; then
# This means /rw is mounted now.
echo "Checking /rw" >&2
if ! [ -d /rw/config ] ; then
echo "Virgin boot of the VM: populating /rw/config" >&2
mkdir -p /rw/config
touch /rw/config/rc.local
cat > /rw/config/rc.local <<EOF
#!/bin/sh
# This script will be executed at every VM startup, you can place your own
# custom commands here. This include overriding some configuration in /etc,
# starting services etc.
#
# You need to make this script executable to have it enabled.
# Example for overriding the whole CUPS configuration:
# rm -rf /etc/cups
# ln -s /rw/config/cups /etc/cups
# systemctl --no-block restart cups
EOF
touch /rw/config/qubes-firewall-user-script
cat > /rw/config/qubes-firewall-user-script <<EOF
#!/bin/sh
# This script is called in ProxyVM after firewall every update (configuration
# change, starting some VM etc). This is good place to write own custom
# firewall rules, in addition to autogenerated one. Remember that in most cases
# you'll need to insert the rules at the beginning (iptables -I) to have it
# efective.
#
# You need to make this script executable to have it enabled.
EOF
touch /rw/config/suspend-module-blacklist
cat > /rw/config/suspend-module-blacklist <<EOF
# You can list here modules you want to be unloaded before going to sleep. This
# file is used only if the VM has any PCI device assigned. Modules will be
# automatically loaded after resume.
EOF
fi
if ! [ -d /rw/usrlocal ] ; then
if [ -d /usr/local.orig ] ; then
echo "Virgin boot of the VM: populating /rw/usrlocal from /usr/local.orig" >&2
cp -af /usr/local.orig /rw/usrlocal
else
echo "Virgin boot of the VM: creating /rw/usrlocal" >&2
mkdir -p /rw/usrlocal
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
# 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/lib/qubes/first-boot-completed ]; then
touch /var/lib/qubes/first-boot-completed
fi

25
init/setup-rwdev.sh Executable file
View File

@ -0,0 +1,25 @@
#!/bin/sh
set -e
if [ -e /dev/xvdb ] ; then
# The private /dev/xvdb device is present.
# check if private.img (xvdb) is empty - all zeros
private_size_512=`blockdev --getsz /dev/xvdb`
if dd if=/dev/zero bs=512 count=$private_size_512 2>/dev/null | diff /dev/xvdb - >/dev/null; then
# the device is empty, create filesystem
echo "Virgin boot of the VM: creating private.img filesystem" >&2
mkfs.ext4 -m 0 -q /dev/xvdb || exit 1
fi
tune2fs -m 0 /dev/xvdb
echo "Virgin boot of the VM: marking private.img as clean" >&2
fsck.ext4 -fp /dev/xvdb
echo "Virgin boot of the VM: enlarging private.img" >&2
if ! content=$(resize2fs /dev/xvdb 2>&1) ; then
echo "resize2fs /dev/xvdb failed:" >&2
echo "$content" >&2
fi
fi

Binary file not shown.

View File

@ -1,22 +1,24 @@
#!/bin/sh
# This script must be run as the `user` user.
# It is customarily launched from prepare-dvm.sh.
# At this point, the DispVM home directory customizations
# undertaken by mount-dirs.sh have taken place.
# We know this because dispvm-prerun.sh executes after
# local-fs.target, and mount-dirs.sh runs before it.
me=$( basename "$0" )
apps="/usr/libexec/evinced"
#If user have customized DispVM settings, use its home instead of default dotfiles
if [ ! -e /home/user/.qubes-dispvm-customized ]; then
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
fi
echo "$me started." >&2
for app in $apps ; do
echo "Launching: $app..."
$app >>/tmp/dispvm_prerun_errors.log 2>&1 &
echo "Launching $app" >&2
$app &
done
echo "Sleeping..."
echo "Waiting for I/O to quiesce" >&2
PREV_IO=0
while true; do
IO=`vmstat -D | awk '/read|write/ {IOs+=$1} END {print IOs}'`
@ -27,11 +29,9 @@ while true; do
sleep 2
done
ps aufwwx > /tmp/dispvm-prerun-proclist.log
echo "Closing windows..."
echo "Closing windows" >&2
/usr/lib/qubes/close-window `xwininfo -root -children|tail -n +7 |awk '{print $1}'`
sleep 1
fuser -vkm /rw
echo done.
echo "$me finished." >&2

View File

@ -1,7 +1,8 @@
#!/bin/sh
#!/bin/bash
UPDATEABLE=`qubesdb-read /qubes-vm-updateable`
# Source Qubes library.
. /usr/lib/qubes/init/functions
if [ "$UPDATEABLE" = "True" ]; then
if is_updateable ; then
/usr/lib/qubes/qrexec-client-vm dom0 qubes.SyncAppMenus /bin/sh /etc/qubes-rpc/qubes.GetAppmenus
fi

View File

@ -23,8 +23,8 @@ while true; do
TRIGGER=reload
else
# Wait for changes in qubesdb file
/usr/bin/qubesdb-watch $XENSTORE_IPTABLES
TRIGGER=$(/usr/bin/qubesdb-read $XENSTORE_IPTABLES)
qubesdb-watch $XENSTORE_IPTABLES
TRIGGER=$(qubesdb-read $XENSTORE_IPTABLES)
fi
if ! [ "$TRIGGER" = "reload" ]; then continue ; fi

View File

@ -1,9 +1,13 @@
#!/bin/sh
# Source Qubes library.
. /usr/lib/qubes/init/functions
/usr/lib/qubes/qubes-setup-dnat-to-ns
# Tinyproxy does not reload DNS servers
if [ -x /bin/systemctl ]; then
/bin/systemctl --no-block try-restart qubes-updates-proxy.service
# FIXME: Tinyproxy does not reload DNS servers.
if under_systemd ; then
systemctl --no-block try-restart qubes-updates-proxy.service
else
/usr/sbin/service qubes-updates-proxy try-restart
service qubes-updates-proxy try-restart
fi

View File

@ -1,13 +1,9 @@
#!/bin/sh
# setup-ip is potentially invoked before qubes-sysinit.sh is done, therefore
# we perform our qubesdb reads here instead of relying on qvm-service
# files under /var/run/qubes-service/
disablegw=`qubesdb-read /qubes-service/disable-default-route 2> /dev/null`
disabledns=`qubesdb-read /qubes-service/disable-dns-server 2> /dev/null`
# Source Qubes library.
. /usr/lib/qubes/init/functions
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
have_qubesdb || exit 0
ip=`/usr/bin/qubesdb-read /qubes-ip 2> /dev/null`
if [ x$ip != x ]; then
@ -18,7 +14,7 @@ if [ x$ip != x ]; then
/sbin/ethtool -K $INTERFACE sg off
/sbin/ethtool -K $INTERFACE tx off
# If NetworkManager is enabled, let it configure the network
if [ -f /var/run/qubes-service/network-manager ]; then
if qsvc network-manager ; then
nm_config=/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE
cat > $nm_config <<__EOF__
[802-3-ethernet]
@ -39,10 +35,10 @@ method=ignore
method=manual
may-fail=false
__EOF__
if [ "x$disabledns" != "x1" ]; then
if ! qsvc disable-dns-server ; then
echo "dns=$primary_dns;$secondary_dns" >> $nm_config
fi
if [ "x$disablegw" != "x1" ]; then
if ! qsvc disable-default-route ; then
echo "addresses1=$ip;32;$gateway" >> $nm_config
else
echo "addresses1=$ip;32" >> $nm_config
@ -58,7 +54,7 @@ __EOF__
if [ "x$disablegw" != "x1" ]; then
/sbin/route add default gw $gateway
fi
if ! grep -rq "^/etc/resolv[.]conf$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/resolv.conf ; then
echo > /etc/resolv.conf
if [ "x$disabledns" != "x1" ]; then
echo "nameserver $primary_dns" > /etc/resolv.conf

View File

@ -2,7 +2,9 @@
type nm-applet > /dev/null 2>&1 || exit 0
# Source Qubes library.
. /usr/lib/qubes/init/functions
# Hide nm-applet when network-manager is disabled
nm_enabled=false
[ -f /var/run/qubes-service/network-manager ] && nm_enabled=true
qsvc network-manager && nm_enabled=true || nm_enabled=false
gsettings set org.gnome.nm-applet show-applet $nm_enabled

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# The Qubes OS Project, http://www.qubes-os.org
#
@ -21,6 +21,9 @@
#
#
# Source Qubes library.
. /usr/lib/qubes/init/functions
BEGIN_MARKER="### QUBES BEGIN ###"
END_MARKER="### QUBES END ###"
@ -71,7 +74,7 @@ EOF
### helper functions end
# Determine whether the proxy should be used
if [ -f /var/run/qubes-service/yum-proxy-setup -o -f /var/run/qubes-service/updates-proxy-setup ]; then
if qsvc yum-proxy-setup || qsvc updates-proxy-setup ; then
PROXY_ADDR="http://10.137.255.254:8082/"
PROXY_CONF_ENTRY="proxy=$PROXY_ADDR"
else

View File

@ -1,4 +1,7 @@
#!/bin/sh
#!/bin/bash
# Source Qubes library.
. /usr/lib/qubes/init/functions
action=$1
[ -z "$action" ] && action=suspend
@ -12,7 +15,7 @@ if [ -r /rw/config/suspend-module-blacklist ]; then
fi
if [ x"$action" = x"suspend" ]; then
if [ -f /var/run/qubes-service/network-manager ]; then
if qsvc network-manager ; then
dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
@ -38,11 +41,11 @@ else
for mod in `cat /var/run/qubes/suspend-modules-loaded`; do
modprobe $mod
done
if [ -f /var/run/qubes-service/network-manager ]; then
if qsvc network-manager ; then
dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.Sleep boolean:false || \
{ [ -x /bin/systemctl ] && systemctl start NetworkManager.service; } || service qubes-core-netvm start
{ under_systemd && systemctl start NetworkManager.service; } || service qubes-core-netvm start
fi
fi

View File

@ -20,6 +20,8 @@
#
#
%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
%{!?version: %define version %(cat version)}
%{!?backend_vmm: %define backend_vmm %(echo $BACKEND_VMM)}
@ -49,6 +51,10 @@ Requires: net-tools
Requires: nautilus-python
Requires: qubes-utils >= 3.1.3
Requires: initscripts
Requires: gawk
# for dispvm-prerun.sh
Requires: procps-ng
Requires: util-linux
# for qubes-desktop-run
Requires: pygobject3-base
Requires: dbus-python
@ -191,10 +197,10 @@ fi
# Location of files which contains list of protected files
mkdir -p /etc/qubes/protected-files.d
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
. /usr/lib/qubes/init/functions
# qubes-core-vm has been broken for some time - it overrides /etc/hosts; restore original content
if ! grep -rq "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/hosts ; then
if ! grep -q localhost /etc/hosts; then
cat <<EOF > /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 `hostname`
@ -205,7 +211,7 @@ fi
# ensure that hostname resolves to 127.0.0.1 resp. ::1 and that /etc/hosts is
# in the form expected by qubes-sysinit.sh
if ! grep -rq "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if ! is_protected_file /etc/hostname ; then
for ip in '127\.0\.0\.1' '::1'; do
if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts
@ -324,7 +330,6 @@ rm -f %{name}-%{version}
/etc/NetworkManager/dispatcher.d/30-qubes-external-ip
/etc/NetworkManager/dispatcher.d/qubes-nmhook
%config(noreplace) /etc/X11/xorg-preload-apps.conf
/etc/dispvm-dotfiles.tbz
/etc/dhclient.d/qubes-setup-dnat-to-ns.sh
/etc/fstab
/etc/pki/rpm-gpg/RPM-GPG-KEY-qubes*
@ -425,6 +430,9 @@ rm -f %{name}-%{version}
/usr/lib/yum-plugins/yum-qubes-hooks.py*
/usr/lib/dracut/dracut.conf.d/30-qubes.conf
/usr/lib/NetworkManager/conf.d/30-qubes.conf
%dir /usr/lib/qubes/init
/usr/lib/qubes/init/*.sh
/usr/lib/qubes/init/functions
%dir /usr/lib/qubes-bind-dirs.d
/usr/lib/qubes-bind-dirs.d/30_cron.conf
/usr/lib64/python2.7/site-packages/qubes/xdg.py*
@ -464,8 +472,10 @@ Conflicts: qubes-core-vm-systemd
The Qubes core startup configuration for SysV init (or upstart).
%files sysvinit
/etc/init.d/qubes-sysinit
/etc/init.d/qubes-core-early
/etc/init.d/qubes-core
/etc/init.d/qubes-core-appvm
/etc/init.d/qubes-dvm
/etc/init.d/qubes-core-netvm
/etc/init.d/qubes-firewall
/etc/init.d/qubes-netwatcher
@ -495,22 +505,13 @@ done
chkconfig rsyslog on
chkconfig haldaemon on
chkconfig messagebus on
chkconfig --add qubes-core || echo "WARNING: Cannot add service qubes-core!"
chkconfig qubes-core on || echo "WARNING: Cannot enable service qubes-core!"
chkconfig --add qubes-core-netvm || echo "WARNING: Cannot add service qubes-core-netvm!"
chkconfig qubes-core-netvm on || echo "WARNING: Cannot enable service qubes-core-netvm!"
chkconfig --add qubes-core-appvm || echo "WARNING: Cannot add service qubes-core-appvm!"
chkconfig qubes-core-appvm on || echo "WARNING: Cannot enable service qubes-core-appvm!"
chkconfig --add qubes-firewall || echo "WARNING: Cannot add service qubes-firewall!"
chkconfig qubes-firewall on || echo "WARNING: Cannot enable service qubes-firewall!"
chkconfig --add qubes-netwatcher || echo "WARNING: Cannot add service qubes-netwatcher!"
chkconfig qubes-netwatcher on || echo "WARNING: Cannot enable service qubes-netwatcher!"
chkconfig --add qubes-iptables || echo "WARNING: Cannot add service qubes-iptables!"
chkconfig qubes-iptables on || echo "WARNING: Cannot enable service qubes-iptables!"
chkconfig --add qubes-updates-proxy || echo "WARNING: Cannot add service qubes-updates-proxy!"
chkconfig qubes-updates-proxy on || echo "WARNING: Cannot enable service qubes-updates-proxy!"
chkconfig --add qubes-qrexec-agent || echo "WARNING: Cannot add service qubes-qrexec-agent!"
chkconfig qubes-qrexec-agent on || echo "WARNING: Cannot enable service qubes-qrexec-agent!"
for svc in %qubes_services ; do
if [ "$1" = 1 ] ; then
chkconfig --add $svc || echo "WARNING: Cannot add service $svc!"
else
chkconfig $svc resetpriorities || echo "WARNING: Cannot reset priorities of service $svc!"
fi
done
# TODO: make this not display the silly message about security context...
sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
@ -518,13 +519,9 @@ sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
%preun sysvinit
if [ "$1" = 0 ] ; then
# no more packages left
chkconfig qubes-core off
chkconfig qubes-core-netvm off
chkconfig qubes-core-appvm off
chkconfig qubes-firewall off
chkconfig qubes-netwatcher off
chkconfig qubes-updates-proxy off
chkconfig qubes-qrexec-agent off
for svc in %qubes_services ; do
chkconfig --del $svc
done
fi
%package systemd
@ -559,16 +556,7 @@ The Qubes core startup configuration for SystemD init.
/lib/systemd/system-preset/75-qubes-vm.preset
/lib/modules-load.d/qubes-core.conf
/lib/modules-load.d/qubes-misc.conf
%dir /usr/lib/qubes/init
/usr/lib/qubes/init/prepare-dvm.sh
/usr/lib/qubes/init/network-proxy-setup.sh
/usr/lib/qubes/init/qubes-iptables
/usr/lib/qubes/init/misc-post.sh
/usr/lib/qubes/init/misc-post-stop.sh
/usr/lib/qubes/init/mount-dirs.sh
/usr/lib/qubes/init/qubes-random-seed.sh
/usr/lib/qubes/init/qubes-sysinit.sh
/usr/lib/qubes/init/bind-dirs.sh
/lib/systemd/system/chronyd.service.d/30_qubes.conf
/lib/systemd/system/crond.service.d/30_qubes.conf
/lib/systemd/system/cups.service.d/30_qubes.conf

View File

@ -1,154 +1,49 @@
#!/bin/bash
#
# chkconfig: 345 90 90
# description: Executes Qubes core scripts at VM boot
# description: Executes supplementary Qubes core scripts at VM boot
#
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
start()
{
echo -n $"Executing Qubes Core scripts:"
have_qubesdb || return
# Set permissions to /proc/xen/xenbus, so normal user can access xenstore
chmod 666 /proc/xen/xenbus
# Set permissions to files needed by gui-agent
chmod 666 /proc/u2mfn
mkdir -p /var/run/xen-hotplug
mkdir -p /var/run/qubes
chgrp qubes /var/run/qubes
chmod 0775 /var/run/qubes
# Load random seed from dom0
qubesdb-read /qubes-random-seed | base64 -d > /dev/urandom
qubesdb-rm /qubes-random-seed
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
# Set the hostname
if ! grep -rq "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
name=$(/usr/bin/qubesdb-read /name)
if ! [ -f /etc/this-is-dvm ] ; then
# we don't want to set hostname for DispVM
# because it makes some of the pre-created dotfiles invalid (e.g. .kde/cache-<hostname>)
# (let's be frank: nobody's gonna use xterm on DispVM)
hostname $name
sed -i "s/^\(127\.0\.0\.1[\t ].*\) \($name \)\?\(.*\)/\1\2 $name/" /etc/hosts
fi
# Start AppVM specific services
for svc in cups ntpd ; do
if qsvc $svc && test -e /etc/init.d/$svc ; then
/sbin/service $svc start
fi
done
# Set the timezone
if ! grep -rq "^/etc/timezone$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
timezone=`/usr/bin/qubesdb-read /qubes-timezone 2> /dev/null`
if [ -n "$timezone" ]; then
ln -f /usr/share/zoneinfo/$timezone /etc/localtime
echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
fi
fi
/usr/lib/qubes/update-proxy-configs
# Set IP address again (besides action in udev rules); this is needed by
# DispVM (to override DispVM-template IP) and in case when qubes-ip was
# called by udev before loading evtchn kernel module - in which case
# qubesdb-read fails
INTERFACE=eth0 /usr/lib/qubes/setup-ip
if [ -e /dev/xvdb ] ; then
# check if private.img (xvdb) is empty - all zeros
private_size_512=`blockdev --getsz /dev/xvdb`
if dd if=/dev/zero bs=512 count=$private_size_512 | diff /dev/xvdb - >/dev/null; then
# the device is empty, create filesystem
echo "--> Virgin boot of the VM: creating filesystem on private.img"
mkfs.ext4 -m 0 -q /dev/xvdb || exit 1
fi
mount /rw
resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed"
if ! [ -d /rw/home ] ; then
echo -n $"Finagling printer icon:"
/usr/lib/qubes/init/control-printer-icon.sh
success
echo
echo "--> Virgin boot of the VM: Linking /home to /rw/home"
mkdir -p /rw/config
cat > /rw/config/rc.local <<EOF
#!/bin/sh
# This script will be executed at every VM startup, you can place your own
# custom commands here. This include overriding some configuration in /etc,
# starting services etc.
#
# You need to make this script executable to have it enabled.
# Example for overriding the whole CUPS configuration:
# rm -rf /etc/cups
# ln -s /rw/config/cups /etc/cups
# systemctl --no-block restart cups
EOF
touch /rw/config/qubes-firewall-user-script
cat > /rw/config/qubes-firewall-user-script <<EOF
#!/bin/sh
# This script is called in ProxyVM after firewall every update (configuration
# change, starting some VM etc). This is good place to write own custom
# firewall rules, in addition to autogenerated one. Remember that in most cases
# you'll need to insert the rules at the beginning (iptables -I) to have it
# efective.
#
# You need to make this script executable to have it enabled.
EOF
touch /rw/config/suspend-module-blacklist
cat > /rw/config/suspend-module-blacklist <<EOF
# You can list here modules you want to be unloaded before going to sleep. This
# file is used only if the VM has any PCI device assigned. Modules will be
# automatically loaded after resume.
EOF
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
fi
if [ -L /home ]; then
rm /home
mkdir /home
fi
mount /home
if [ -n "`ls -A /usr/local/lib 2>/dev/null`" -o \
-n "`ls -A /usr/local/lib64 2>/dev/null`" ]; then
ldconfig
fi
[ -x /rw/config/rc.local ] && /rw/config/rc.local
if qsvc meminfo-writer ; then
MEM_CHANGE_THRESHOLD_KB=30000
MEMINFO_DELAY_USEC=100000
echo -n $"Starting Qubes memory information service:"
/usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC /var/run/meminfo-writer.pid
success
echo ""
start_ntpd=$(/usr/bin/qubesdb-read /qubes-service/ntpd 2> /dev/null)
if [ "$start_ntpd" == "1" ]; then
/sbin/service ntpd start
fi
return 0
echo -n $"Executing Qubes misc post scripts:"
/usr/lib/qubes/init/misc-post.sh && success || failure
echo
}
stop()
{
su -c 'mkdir -p /home_volatile/user/.local/share/applications' user
su -c 'cp -a /usr/share/applications/defaults.list /home_volatile/user/.local/share/applications/' user
if [ -r '/home/user/.local/share/applications/defaults.list' ]; then
su -c 'cat /home/user/.local/share/applications/defaults.list >> /home_volatile/user/.local/share/applications/defaults.list' user
fi
return 0
have_qubesdb || return
/usr/lib/qubes/init/misc-post-stop.sh
}
case "$1" in

View File

@ -1,104 +0,0 @@
#!/bin/bash
#
# chkconfig: 345 85 85
# description: Executes Qubes core scripts at AppVM boot
#
# Source function library.
. /etc/rc.d/init.d/functions
possibly_run_save_script()
{
ENCODED_SCRIPT=$(qubesdb-read /qubes-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(<STDIN>)' >/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
}
start()
{
type=$(/usr/bin/qubesdb-read /qubes-vm-type)
if [ "$type" != "AppVM" -a "$type" != "DisposableVM" -a "$type" != "TemplateVM" ]; then
# This script runs only on AppVMs
return 0
fi
# Start AppVM specific services
start_cups=$(/usr/bin/qubesdb-read /qubes-service/cups 2> /dev/null)
if [ "$start_cups" != "0" ]; then
/sbin/service cups start
# Allow also notification icon
sed -i -e '/^NotShowIn=.*QUBES/s/;QUBES//' /etc/xdg/autostart/print-applet.desktop
else
# Disable notification icon
sed -i -e '/QUBES/!s/^NotShowIn=\(.*\)/NotShowIn=QUBES;\1/' /etc/xdg/autostart/print-applet.desktop
fi
echo -n $"Executing Qubes Core scripts for AppVM:"
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
possibly_run_save_script
umount /rw
dmesg -c >/dev/null
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
# 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
echo Back to life.
# Reload random seed
qubesdb-read /qubes-random-seed | base64 -d > /dev/urandom
qubesdb-rm /qubes-random-seed
fi
start_meminfo_writer=$(/usr/bin/qubesdb-read /qubes-service/meminfo-writer 2>/dev/null)
if [ "$start_meminfo_writer" != "0" ]; then
MEM_CHANGE_THRESHOLD_KB=30000
MEMINFO_DELAY_USEC=100000
/usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC /var/run/meminfo-writer.pid
fi
success
echo ""
return 0
}
stop()
{
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop}"
exit 3
;;
esac
exit $RETVAL

44
vm-init.d/qubes-core-early Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
#
# chkconfig: 345 84 84
# description: Executes early necessary Qubes core scripts at VM boot
#
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
start()
{
have_qubesdb || return
echo -n $"Setting up Qubes persistent file systems:"
/usr/lib/qubes/init/mount-dirs.sh && success || failure
echo
echo -n $"Executing Qubes random seed scripts:"
/usr/lib/qubes/init/qubes-random-seed.sh && success || failure
echo
}
stop()
{
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop}"
exit 3
;;
esac
exit $RETVAL

View File

@ -6,38 +6,21 @@
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
start()
{
if ! [ -x /usr/bin/qubesdb-read ] ; then
echo "ERROR: /usr/bin/qubesdb-read not found!"
exit 1
fi
have_qubesdb || return
type=$(/usr/bin/qubesdb-read /qubes-vm-type)
if [ "$type" == "NetVM" ]; then
if is_netvm; then
/usr/lib/qubes/network-manager-prepare-conf-dir
/sbin/service NetworkManager start
fi
echo -n $"Executing Qubes Core scripts NetVM:"
# Setup gateway for all the VMs this netVM is serviceing...
network=$(/usr/bin/qubesdb-read /qubes-netvm-network 2>/dev/null)
if [ "x$network" != "x" ]; then
gateway=$(/usr/bin/qubesdb-read /qubes-netvm-gateway)
netmask=$(/usr/bin/qubesdb-read /qubes-netvm-netmask)
primary_dns=$(/usr/bin/qubesdb-read /qubes-netvm-primary-dns || echo $gateway)
secondary_dns=$(/usr/bin/qubesdb-read /qubes-netvm-secondary-dns)
modprobe netbk 2> /dev/null || modprobe xen-netback
echo "NS1=$primary_dns" > /var/run/qubes/qubes-ns
echo "NS2=$secondary_dns" >> /var/run/qubes/qubes-ns
/usr/lib/qubes/qubes-setup-dnat-to-ns
echo "1" > /proc/sys/net/ipv4/ip_forward
fi
success
echo ""
return 0
/usr/lib/qubes/init/network-proxy-setup && success || failure
echo
}
stop()

43
vm-init.d/qubes-dvm Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
#
# chkconfig: 345 91 91
# description: Executes Qubes core scripts at AppVM boot
#
# This must run after GUI agent has started. Hence 91.
#
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
start()
{
have_qubesdb || return
if qsvc qubes-dvm; then
echo -n $"Preparing Qubes DVM:"
/usr/lib/qubes/init/prepare-dvm.sh && success || failure
echo
fi
}
stop()
{
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop}"
exit 3
;;
esac
exit $RETVAL

View File

@ -1,25 +1,27 @@
#!/bin/bash
#
# chkconfig: 345 91 91
# chkconfig: 345 92 92
# description: Starts Qubes Firewall monitor
#
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
PIDFILE=/var/run/qubes/qubes-firewall.pid
start()
{
type=$(/usr/bin/qubesdb-read /qubes-vm-type)
start_firewall=$(/usr/bin/qubesdb-read /qubes-service/qubes-firewall 2> /dev/null)
if [ -z "$start_firewall" ] && [ "$type" == "ProxyVM" ] || [ "$start_firewall" == "1" ]; then
have_qubesdb || return
if qsvc qubes-firewall ; then
echo -n $"Starting Qubes Firewall monitor:"
/sbin/ethtool -K eth0 sg off
/usr/sbin/qubes-firewall &
success
echo ""
fi
return 0
}
stop()

View File

@ -1,25 +1,27 @@
#!/bin/bash
#
# chkconfig: 345 92 92
# chkconfig: 345 93 93
# description: Starts Qubes Network monitor
#
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
PIDFILE=/var/run/qubes/qubes-netwatcher.pid
start()
{
type=$(/usr/bin/qubesdb-read /qubes-vm-type)
start_netwatcher=$(/usr/bin/qubesdb-read /qubes-service/qubes-netwatcher 2>/dev/null)
if [ -z "$start_netwatcher" ] && [ "$type" == "ProxyVM" ] || [ "$start_netwatcher" == "1" ]; then
have_qubesdb || return
if qsvc qubes-netwatcher ; then
echo -n $"Starting Qubes Network monitor:"
/sbin/ethtool -K eth0 sg off
/usr/sbin/qubes-netwatcher &
success
echo ""
fi
return 0
}
stop()

View File

@ -6,20 +6,22 @@
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
start()
{
have_qrexec_agent || return
echo -n $"Starting Qubes RPC agent:"
/usr/lib/qubes/qrexec-agent 2>/var/log/qubes/qrexec-agent.log &
success
echo ""
return 0
}
stop()
{
have_qrexec_agent || return
killproc qrexec-agent
}

34
vm-init.d/qubes-sysinit Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
#
# chkconfig: 345 80 80
# description: Executes Qubes system initialization scripts at VM boot
#
# Source function library.
. /etc/rc.d/init.d/functions
start()
{
echo -n $"Executing Qubes system initialization scripts:"
/usr/lib/qubes/init/qubes-sysinit.sh && success || failure ; echo
}
stop()
{
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop}"
exit 3
;;
esac
exit $RETVAL

View File

@ -2,7 +2,7 @@
#
# tinyproxy Startup script for the tinyproxy server as Qubes updates proxy
#
# chkconfig: - 85 15
# chkconfig: 345 85 15
# description: small, efficient HTTP/SSL proxy daemon
#
# processname: tinyproxy
@ -16,6 +16,9 @@
# Source function library.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
# Source networking configuration.
. /etc/sysconfig/network
@ -32,9 +35,9 @@ pidfile="/var/run/tinyproxy-updates/tinyproxy.pid"
lockfile=/var/lock/subsys/tinyproxy-updates
start() {
type=`/usr/bin/qubesdb-read /qubes-vm-type`
start_updates_proxy=`/usr/bin/qubesdb-read /qubes-service/qubes-updates-proxy 2>/dev/null`
if [ -z "$start_updates_proxy" ] && [ "$type" != "NetVM" ] || [ "$start_updates_proxy" != "1" ]; then
have_qubesdb || return
if qsvc qubes-updates-proxy ; then
# Yum proxy disabled
exit 0
fi

View File

@ -23,21 +23,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set -x
# Source Qubes library.
. /usr/lib/qubes/init/functions
prerequisite() {
qubes_vm_persistence="$(qubesdb-read /qubes-vm-persistence)"
if [ ! "$qubes_vm_persistence" = "rw-only" ]; then
if ! is_rwonly_persistent ; then
true "No TemplateBasedVM detected. Exiting."
exit 0
fi
if [ -f "/var/run/qubes-service/qubes-dvm" ]; then
# https://github.com/QubesOS/qubes-issues/issues/1328#issuecomment-169483029
# Do none of the following in a DispVM.
# During DispVM savefile generation, 'qubesdb-read /qubes-vm-persistence'
# outputs 'rw'.
exit 0
fi
}
init() {
@ -96,7 +89,8 @@ bind_dirs() {
# Initially copy over data directories to /rw if rw directory does not exist.
if [ -d "$fso_ro" ] || [ -f "$fso_ro" ]; then
if ! [ -d "$fso_rw" -o -f "$fso_rw" ]; then
cp --verbose --archive --recursive --parents "$fso_ro" "$rw_dest_dir"
echo "Initializing $rw_dest_dir with files from $fso_ro" >&2
cp --archive --recursive --parents "$fso_ro" "$rw_dest_dir"
fi
else
true "$fso_ro is neither a directory nor a file or does not exist, skipping."
@ -104,6 +98,7 @@ bind_dirs() {
fi
# Bind the fso.
echo "Bind mounting $fso_rw onto $fso_ro" >&2
mount --bind "$fso_rw" "$fso_ro"
done
}

View File

@ -1,3 +1,6 @@
[Unit]
ConditionPathExists=/var/run/qubes-service/cups
After=qubes-sysinit.service
[Service]
ExecStartPost=/usr/lib/qubes/init/control-printer-icon.sh

View File

@ -1,5 +1,8 @@
#!/bin/sh
# Source Qubes library.
. /usr/lib/qubes/init/functions
/usr/lib/qubes/update-proxy-configs
if [ -n "`ls -A /usr/local/lib 2>/dev/null`" -o \
@ -13,14 +16,6 @@ fi
# qubesdb-read fails
INTERFACE=eth0 /usr/lib/qubes/setup-ip
[ -x /rw/config/rc.local ] && /rw/config/rc.local
# Start services which haven't own proper systemd unit:
if [ ! -f /usr/lib/systemd/system/cups.service ]; then
if [ -f /var/run/qubes-service/cups ]; then
/usr/sbin/service cups start
fi
if [ -x /rw/config/rc.local ] ; then
/rw/config/rc.local
fi
exit 0

97
vm-systemd/mount-dirs.sh Normal file → Executable file
View File

@ -1,93 +1,22 @@
#!/bin/sh
# check if private.img (xvdb) is empty - all zeros
private_size_512=`blockdev --getsz /dev/xvdb`
if dd if=/dev/zero bs=512 count=$private_size_512 2>/dev/null | diff /dev/xvdb - >/dev/null; then
# the device is empty, create filesystem
echo "--> Virgin boot of the VM: creating filesystem on private.img"
mkfs.ext4 -m 0 -q /dev/xvdb || exit 1
fi
# Source Qubes library.
. /usr/lib/qubes/init/functions
tune2fs -m 0 /dev/xvdb
mount /rw
resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed"
set -e
if ! [ -d /rw/home ] ; then
echo
echo "--> Virgin boot of the VM: Populating /rw/home"
/usr/lib/qubes/init/setup-rwdev.sh
if [ -e /dev/xvdb ] ; then mount /rw ; fi
/usr/lib/qubes/init/setup-rw.sh
mkdir -p /rw/config
touch /rw/config/rc.local
cat > /rw/config/rc.local <<EOF
#!/bin/sh
# This script will be executed at every VM startup, you can place your own
# custom commands here. This include overriding some configuration in /etc,
# starting services etc.
#
# You need to make this script executable to have it enabled.
# Example for overriding the whole CUPS configuration:
# rm -rf /etc/cups
# ln -s /rw/config/cups /etc/cups
# systemctl --no-block restart cups
EOF
touch /rw/config/qubes-firewall-user-script
cat > /rw/config/qubes-firewall-user-script <<EOF
#!/bin/sh
# This script is called in ProxyVM after firewall every update (configuration
# change, starting some VM etc). This is good place to write own custom
# firewall rules, in addition to autogenerated one. Remember that in most cases
# you'll need to insert the rules at the beginning (iptables -I) to have it
# efective.
#
# You need to make this script executable to have it enabled.
EOF
touch /rw/config/suspend-module-blacklist
cat > /rw/config/suspend-module-blacklist <<EOF
# You can list here modules you want to be unloaded before going to sleep. This
# file is used only if the VM has any PCI device assigned. Modules will be
# automatically loaded after resume.
EOF
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
if qsvc qubes-dvm; then
/usr/lib/qubes/init/setup-dvm-home.sh
echo "Mounting /home_volatile onto /home" >&2
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 /home/user/.qubes-dispvm-customized ]; then
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
fi
else
echo "Mounting /home" >&2
mount /home
# https://github.com/QubesOS/qubes-issues/issues/1328#issuecomment-169483029
# Do none of the following in a DispVM.
/usr/lib/qubes/init/bind-dirs.sh
fi
/usr/lib/qubes/init/bind-dirs.sh

View File

@ -1,24 +1,30 @@
#!/bin/bash
possibly_run_save_script()
{
ENCODED_SCRIPT=$(qubesdb-read /qubes-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(<STDIN>)' >/tmp/qubes-save-script
chmod 755 /tmp/qubes-save-script
DISPLAY=:0 su - user -c /tmp/qubes-save-script
}
# Source Qubes library.
. /usr/lib/qubes/init/functions
echo user | /bin/sh /etc/qubes-rpc/qubes.WaitForSession
set -e
echo "Waiting for user session to quiesce." >&2
echo user | /bin/sh /etc/qubes-rpc/qubes.WaitForSession || :
echo "Possibly running save script." >&2
possibly_run_save_script
umount /rw
dmesg -c >/dev/null
echo "Unmounting /rw filesystem." >&2
umount_retry /rw || echo "Giving up and proceeding. Warning: this may not work." >&2
dmesg -C
qubesdb-watch /qubes-restore-complete &
watch_pid=$!
free | grep Mem: |
(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..."
qubesdb-read /qubes-restore-complete || wait $watch_pid
echo Back to life.
systemctl restart systemd-random-seed.service
echo "Waiting for restore signal." >&2
qubesdb-read /qubes-restore-complete >/dev/null || wait $watch_pid
echo "Restore complete." >&2
# Reload random seed
echo "Reloading random seed." >&2
reload_random_seed

View File

@ -1,14 +1,14 @@
[Unit]
Description=Prepare Qubes DispVM Template
ConditionPathExists=/var/run/qubes-service/qubes-dvm
After=systemd-readahead-replay.service
After=systemd-readahead-replay.service qubes-gui-agent.service
Wants=qubes-gui-agent.service
Before=xendriverdomain.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/prepare-dvm.sh
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -5,7 +5,6 @@ After=qubes-network.service
[Service]
ExecStart=/usr/sbin/qubes-firewall
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -5,8 +5,6 @@ Description=Qubes base firewall settings
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/qubes-iptables start
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=basic.target

View File

@ -1,16 +1,19 @@
[Unit]
Description=Initialize and mount /rw and /home
After=qubes-sysinit.service
# There is a dependency on dev-xvdb.device because
# mount-dirs.sh calls setup-rwdev.sh which
# must happen only when /dev/xvdb has appeared.
After=qubes-sysinit.service dev-xvdb.device
DefaultDependencies=no
Before=local-fs.target qubes-gui-agent.service
Before=local-fs.target rw.mount home.mount qubes-gui-agent.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/mount-dirs.sh
# Fedora and Debian have different paths for fuser
ExecStop=/bin/sh -c 'fuser -kMm /home' ; /bin/umount /home
ExecStopPost=-/bin/umount /rw
# There is no need for an ExecStop because systemd
# cleans up mount units in the right order, killing
# processes as needed.
[Install]
WantedBy=multi-user.target

View File

@ -5,7 +5,6 @@ After=network-pre.target qubes-firewall.service
[Service]
ExecStart=/usr/sbin/qubes-netwatcher
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -8,7 +8,6 @@ After=network-pre.target qubes-iptables.service
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/network-proxy-setup.sh
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -5,7 +5,6 @@ After=qubes-dvm.service xendriverdomain.service
[Service]
ExecStartPre=/bin/sh -c '[ -e /dev/xen/evtchn ] || modprobe xen_evtchn'
ExecStart=/usr/lib/qubes/qrexec-agent
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -1,7 +1,9 @@
#!/bin/bash
# Source Qubes library.
. /usr/lib/qubes/init/functions
set -e
set -o pipefail
qubesdb-read /qubes-random-seed | base64 -d > /dev/urandom
qubesdb-rm /qubes-random-seed
reload_random_seed

View File

@ -8,7 +8,6 @@ After=proc-xen.mount systemd-modules-load.service qubes-db.service
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/qubes-sysinit.sh
StandardOutput=syslog
[Install]
WantedBy=sysinit.target

View File

@ -1,4 +1,7 @@
#!/bin/sh
#!/bin/bash
# Source Qubes library.
. /usr/lib/qubes/init/functions
# List of services enabled by default (in case of absence of qubesdb entry)
DEFAULT_ENABLED_NETVM="network-manager qubes-network qubes-update-check qubes-updates-proxy"
@ -7,18 +10,7 @@ DEFAULT_ENABLED_APPVM="meminfo-writer cups qubes-update-check"
DEFAULT_ENABLED_TEMPLATEVM="$DEFAULT_ENABLED_APPVM updates-proxy-setup"
DEFAULT_ENABLED="meminfo-writer"
QDB_READ=qubesdb-read
QDB_LS=qubesdb-multiread
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/etc/qubes/protected-files.d'
read_service() {
$QDB_READ /qubes-service/$1 2> /dev/null
}
systemd_pkg_version=`systemctl --version|head -n 1`
if ! dmesg | grep -q "$systemd_pkg_version running in system mode."; then
if systemd_version_changed ; then
# Ensure we're running right version of systemd (the one started by initrd may be different)
systemctl daemon-reexec
fi
@ -48,11 +40,10 @@ chgrp qubes /proc/xen/privcmd
chmod 666 /proc/u2mfn
# Set default services depending on VM type
TYPE=`$QDB_READ /qubes-vm-type 2> /dev/null`
[ "$TYPE" = "AppVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_APPVM && touch /var/run/qubes/this-is-appvm
[ "$TYPE" = "NetVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_NETVM && touch /var/run/qubes/this-is-netvm
[ "$TYPE" = "ProxyVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_PROXYVM && touch /var/run/qubes/this-is-proxyvm
[ "$TYPE" = "TemplateVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_TEMPLATEVM && touch /var/run/qubes/this-is-templatevm
is_appvm && DEFAULT_ENABLED=$DEFAULT_ENABLED_APPVM && touch /var/run/qubes/this-is-appvm
is_netvm && DEFAULT_ENABLED=$DEFAULT_ENABLED_NETVM && touch /var/run/qubes/this-is-netvm
is_proxyvm && DEFAULT_ENABLED=$DEFAULT_ENABLED_PROXYVM && touch /var/run/qubes/this-is-proxyvm
is_templatevm && DEFAULT_ENABLED=$DEFAULT_ENABLED_TEMPLATEVM && touch /var/run/qubes/this-is-templatevm
# Enable default services
for srv in $DEFAULT_ENABLED; do
@ -60,18 +51,18 @@ for srv in $DEFAULT_ENABLED; do
done
# Enable services
for srv in `$QDB_LS /qubes-service/ 2>/dev/null |grep ' = 1'|cut -f 1 -d ' '`; do
for srv in `qubesdb-multiread /qubes-service/ 2>/dev/null |grep ' = 1'|cut -f 1 -d ' '`; do
touch /var/run/qubes-service/$srv
done
# Disable services
for srv in `$QDB_LS /qubes-service/ 2>/dev/null |grep ' = 0'|cut -f 1 -d ' '`; do
for srv in `qubesdb-multiread /qubes-service/ 2>/dev/null |grep ' = 0'|cut -f 1 -d ' '`; do
rm -f /var/run/qubes-service/$srv
done
# Set the hostname
if ! grep -rq "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
name=`$QDB_READ /name`
if ! is_protected_file /etc/hostname ; then
name=`qubesdb-read /name`
if [ -n "$name" ]; then
hostname $name
if [ -e /etc/debian_version ]; then
@ -85,13 +76,13 @@ if ! grep -rq "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
fi
# Set the timezone
if ! grep -rq "^/etc/timezone$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
timezone=`$QDB_READ /qubes-timezone 2> /dev/null`
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
ln -sf ../usr/share/zoneinfo/"$timezone" /etc/localtime
if [ -e /etc/debian_version ]; then
echo "$timezone" > /etc/timezone
else
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
@ -101,7 +92,7 @@ fi
# Prepare environment for other services
echo > /var/run/qubes-service-environment
debug_mode=`$QDB_READ /qubes-debug-mode 2> /dev/null`
debug_mode=`qubesdb-read /qubes-debug-mode 2> /dev/null`
if [ -n "$debug_mode" -a "$debug_mode" -gt 0 ]; then
echo "GUI_OPTS=-vv" >> /var/run/qubes-service-environment
fi