vm/init: introduce SystemD startup scripts

This commit is contained in:
Marek Marczykowski 2012-01-10 12:10:16 +01:00
parent 11055f7162
commit cf591a4cd5
16 changed files with 359 additions and 0 deletions

View File

@ -84,6 +84,13 @@ install -D misc/fstab $RPM_BUILD_ROOT/etc/fstab
install -d $RPM_BUILD_ROOT/etc/init.d
install vm-init.d/* $RPM_BUILD_ROOT/etc/init.d/
install -d $RPM_BUILD_ROOT/lib/systemd/system $RPM_BUILD_ROOT/usr/lib/qubes/init
install -m 0755 vm-systemd/*.sh $RPM_BUILD_ROOT/usr/lib/qubes/init/
install -m 0644 vm-systemd/qubes-*.service $RPM_BUILD_ROOT/lib/systemd/system/
install -m 0644 vm-systemd/NetworkManager.service $RPM_BUILD_ROOT/usr/lib/qubes/init/
install -m 0644 vm-systemd/cups.service $RPM_BUILD_ROOT/usr/lib/qubes/init/
install -m 0644 vm-systemd/ntpd.service $RPM_BUILD_ROOT/usr/lib/qubes/init/
install -D -m 0440 misc/qubes.sudoers $RPM_BUILD_ROOT/etc/sudoers.d/qubes
install -D misc/qubes.repo $RPM_BUILD_ROOT/etc/yum.repos.d/qubes.repo
install -D misc/serial.conf $RPM_BUILD_ROOT/usr/lib/qubes/serial.conf
@ -382,6 +389,7 @@ Group: Qubes
Requires: upstart
Requires: qubes-core-vm
Provides: qubes-core-vm-init-scripts
Conflicts: qubes-core-vm-systemd
%description sysvinit
The Qubes core startup configuration for SysV init (or upstart).
@ -437,3 +445,100 @@ if [ "$1" = 0 ] ; then
chkconfig qubes_firewall off
chkconfig qubes_netwatcher off
fi
%package systemd
Summary: Qubes unit files for SystemD init style
License: GPL v2 only
Group: Qubes
Requires: systemd
Requires: qubes-core-vm
Provides: qubes-core-vm-init-scripts
Conflicts: qubes-core-vm-sysvinit
%description systemd
The Qubes core startup configuration for SystemD init.
%files systemd
%defattr(-,root,root,-)
/lib/systemd/system/qubes-dvm.service
/lib/systemd/system/qubes-meminfo-writer.service
/lib/systemd/system/qubes-qrexec-agent.service
/lib/systemd/system/qubes-misc-post.service
/lib/systemd/system/qubes-firewall.service
/lib/systemd/system/qubes-netwatcher.service
/lib/systemd/system/qubes-network.service
/lib/systemd/system/qubes-sysinit.service
%dir /usr/lib/qubes/init
/usr/lib/qubes/init/prepare-dvm.sh
/usr/lib/qubes/init/network-proxy-setup.sh
/usr/lib/qubes/init/misc-post.sh
/usr/lib/qubes/init/qubes-sysinit.sh
/usr/lib/qubes/init/NetworkManager.service
/usr/lib/qubes/init/cups.service
/usr/lib/qubes/init/ntpd.service
%ghost %attr(0644,root,root) /etc/systemd/system/NetworkManager.service
%ghost %attr(0644,root,root) /etc/systemd/system/cups.service
%post systemd
for srv in qubes-dvm qubes-meminfo-writer qubes-qrexec-agent qubes-sysinit qubes-misc-post qubes-netwatcher qubes-network; do
/bin/systemctl enable $srv.service
done
# Install overriden services only when original exists
for srv in cups NetworkManager ntpd; do
if [ -f /lib/systemd/system/$srv.service ]; then
cp /usr/lib/qubes/init/$srv.service /etc/systemd/system/$srv.service
fi
done
# Set default "runlevel"
rm -f /etc/systemd/system/default.target
ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
# Services to disable
#echo "--> Turning off unnecessary services..."
# FIXME: perhaps there is more elegant way to do this?
for f in /etc/init.d/*
do
srv=`basename $f`
[ $srv = 'functions' ] && continue
[ $srv = 'killall' ] && continue
[ $srv = 'halt' ] && continue
[ $srv = 'single' ] && continue
[ $srv = 'reboot' ] && continue
[ $srv = 'qubes_gui' ] && continue
chkconfig $srv off
done
DISABLE_SERVICES="alsa-store alsa-restore auditd backuppc cpuspeed crond dbus-org.freedesktop.Avahi"
DISABLE_SERVICES="$DISABLE_SERVICES fedora-autorelabel fedora-autorelabel-mark ipmi hwclock-load hwclock-save"
DISABLE_SERVICES="$DISABLE_SERVICES mdmonitor multipathd openct rpcbind mcelog fedora-storage-init fedora-storage-init-late"
DISABLE_SERVICES="$DISABLE_SERVICES plymouth-start plymouth-read-write plymouth-quit plymouth-quit-wait"
for srv in $DISABLE_SERVICES; do
if [ -f /lib/systemd/system/$srv.service ]; then
if fgrep -q '[Install]' /lib/systemd/system/$srv.service; then
/bin/systemctl disable $srv.service
else
# forcibly disable
ln -sf /dev/null /etc/systemd/system/$srv.service
fi
fi
done
rm -f /etc/systemd/system/getty.target.wants/getty@tty*.service
# Enable some services
/bin/systemctl enable iptables.service
/bin/systemctl enable rsyslog.service
%postun systemd
#Do not run this part on upgrades
if [ "$1" != 0 ] ; then
exit 0
fi
for srv in qubes-dvm qubes-meminfo-writer qubes-qrexec-agent qubes-sysinit qubes-misc-post qubes-netwatcher qubes-network; do
/bin/systemctl disable $srv.service
do

View File

@ -0,0 +1,3 @@
.include /lib/systemd/system/NetworkManager.service
[Unit]
ConditionPathExists=/var/run/qubes-service/network-manager

3
vm-systemd/cups.service Normal file
View File

@ -0,0 +1,3 @@
.include /lib/systemd/system/cups.service
[Unit]
ConditionPathExists=/var/run/qubes-service/cups

60
vm-systemd/misc-post.sh Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
# 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
# xenstore-read fails
INTERFACE=eth0 /usr/lib/qubes/setup_ip
if [ -e /dev/xvdb ] ; then
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
mkdir -p /rw/home
cp -a /home.orig/user /home
mkdir -p /rw/usrlocal
cp -a /usr/local.orig/* /usr/local
touch /var/lib/qubes/first_boot_completed
fi
fi
[ -x /rw/config/rc.local ] && /rw/config/rc.local
if ! [ -f /home/user/.gnome2/nautilus-scripts/.scripts_created ] ; then
echo "Creating symlinks for nautilus actions..."
su user -c 'mkdir -p /home/user/.gnome2/nautilus-scripts'
su user -c 'ln -s /usr/lib/qubes/qvm-copy-to-vm.gnome /home/user/.gnome2/nautilus-scripts/"Copy to other AppVM"'
su user -c 'ln -s /usr/bin/qvm-open-in-dvm /home/user/.gnome2/nautilus-scripts/"Open in DisposableVM"'
su user -c 'touch /home/user/.gnome2/nautilus-scripts/.scripts_created'
fi
if ! [ -f /home/user/.gnome2/nautilus-scripts/.scripts_created2 ] ; then
# as we have recently renamed tools, the symlinks would need to be fixed for older templates
su user -c 'ln -sf /usr/lib/qubes/qvm-copy-to-vm.gnome /home/user/.gnome2/nautilus-scripts/"Copy to other AppVM"'
su user -c 'ln -sf /usr/bin/qvm-open-in-dvm /home/user/.gnome2/nautilus-scripts/"Open in DisposableVM"'
su user -c 'touch /home/user/.gnome2/nautilus-scripts/.scripts_created2'
fi
# Start services which haven't own proper systemd unit:
# Start AppVM specific services
if [ ! -f /etc/systemd/system/cups.service ]; then
if [ -f /var/run/qubes-service/cups ]; 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=.*/\1QUBES;/' /etc/xdg/autostart/print-applet.desktop
fi
fi
exit 0

View File

@ -0,0 +1,14 @@
#!/bin/sh
# Setup gateway for all the VMs this netVM is serviceing...
network=$(/usr/bin/xenstore-read qubes_netvm_network 2>/dev/null)
if [ "x$network" != "x" ]; then
gateway=$(/usr/bin/xenstore-read qubes_netvm_gateway)
netmask=$(/usr/bin/xenstore-read qubes_netvm_netmask)
secondary_dns=$(/usr/bin/xenstore-read qubes_netvm_secondary_dns)
modprobe netbk 2> /dev/null || modprobe xen-netback
echo "NS1=$gateway" > /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

3
vm-systemd/ntpd.service Normal file
View File

@ -0,0 +1,3 @@
.include /lib/systemd/system/ntpd.service
[Unit]
ConditionPathExists=/var/run/qubes-service/ntpd

30
vm-systemd/prepare-dvm.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh
possibly_run_save_script()
{
ENCODED_SCRIPT=$(xenstore-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 &
sleep 2
DISPLAY=:0 su - user -c /tmp/qubes_save_script
killall Xorg
}
if xenstore-read qubes_save_request 2>/dev/null ; then
ln -sf /home_volatile /home
possibly_run_save_script
touch /etc/this_is_dvm
dmesg -c >/dev/null
free | grep Mem: |
(read a b c d ; xenstore-write device/qubes_used_mem $c)
# we're still running in DispVM template
echo "Waiting for save/restore..."
# ... wait until qubes_restore.c (in Dom0) recreates VM-specific keys
while ! xenstore-read qubes_restore_complete 2>/dev/null ; do
usleep 10
done
echo Back to life.
fi

View File

@ -0,0 +1,12 @@
[Unit]
Description=Prepare Qubes DispVM Template
ConditionPathExists=/var/run/qubes-service/qubes-dvm
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/prepare-dvm.sh
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,10 @@
[Unit]
Description=Qubes firewall updater
ConditionPathExists=/var/run/qubes-service/qubes-firewall
[Service]
ExecStart=/usr/sbin/qubes_firewall
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,12 @@
[Unit]
Description=Qubes memory information reporter
ConditionPathExists=/var/run/qubes-service/meminfo-writer
[Service]
Type=forking
ExecStart=/usr/lib/qubes/meminfo-writer 30000 100000 /var/run/meminfo-writer.pid
PIDFile=/var/run/meminfo-writer.pid
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=Qubes misc post-boot actions
After=qubes-dvm.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/misc-post.sh
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=Qubes network monitor
ConditionPathExists=/var/run/qubes-service/qubes-netwatcher
After=qubes-firewall.service
[Service]
ExecStart=/usr/sbin/qubes_netwatcher
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,14 @@
[Unit]
Names=qubes_firewall.service
Description=Qubes network forwarding setup
ConditionPathExists=/var/run/qubes-service/qubes-network
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/sbin/ethtool -K eth0 sg off
ExecStart=/usr/lib/qubes/init/network-proxy-setup.sh
StandardOutput=syslog
[Install]
WantedBy=network.target

View File

@ -0,0 +1,10 @@
[Unit]
Description=Qubes remote exec agent
After=qubes-dvm.service
[Service]
ExecStart=/usr/lib/qubes/qrexec_agent
StandardOutput=syslog
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=Init Qubes Services settings
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/qubes/init/qubes-sysinit.sh
StandardOutput=syslog
[Install]
WantedBy=sysinit.target

50
vm-systemd/qubes-sysinit.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
# List of services enabled by default (in case of absence of xenstore entry)
DEFAULT_ENABLED_NETVM="network-manager qubes-network"
DEFAULT_ENABLED_PROXYVM="meminfo-writer qubes-network qubes-firewall qubes-netwatcher"
DEFAULT_ENABLED_APPVM="meminfo-writer"
DEFAULT_ENABLED="meminfo-writer"
XS_READ=/usr/bin/xenstore-read
XS_LS=/usr/bin/xenstore-ls
read_service() {
$XS_READ qubes-service/$1 2> /dev/null
}
mkdir -p /var/run/qubes
mkdir -p /var/run/qubes-service
mkdir -p /var/run/xen-hotplug
# Set permissions to /proc/xen/xenbus, so normal user can use xenstore-read
chmod 666 /proc/xen/xenbus
# Set default services depending on VM type
TYPE=`$XS_READ qubes_vm_type 2> /dev/null`
[ "$TYPE" == "AppVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_APPVM
[ "$TYPE" == "NetVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_NETVM
[ "$TYPE" == "ProxyVM" ] && DEFAULT_ENABLED=$DEFAULT_ENABLED_PROXYVM
# Enable default services
for srv in $DEFAULT_ENABLED; do
touch /var/run/qubes-service/$srv
done
# Enable services
for srv in `$XS_LS qubes-service 2>/dev/null |grep ' = "1"'|cut -f 1 -d ' '`; do
touch /var/run/qubes-service/$srv
done
# Disable services
for srv in `$XS_LS qubes-service 2>/dev/null |grep ' = "0"'|cut -f 1 -d ' '`; do
rm -f /var/run/qubes-service/$srv
done
# Set the hostname
name=`$XS_READ name`
if [ -n "$name" ]; then
hostname $name
(grep -v "\<$name\>" /etc/hosts; echo "127.0.0.1 $name") > /etc/hosts
fi