#!/bin/sh set -e test_started() { # ensure the *old* logind from before the upgrade isn't running echo " * try-restarting systemd-logind" systemctl try-restart systemd-logind echo " * daemon is started" # should start at boot, not with D-BUS activation LOGINDPID=$(pidof systemd-logind) # loginctl should succeed echo " * loginctl succeeds" LOGINCTL_OUT=`loginctl` } test_properties() { # Default KillUserProcesses should be off for debian/ubuntu builds r=$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses) [ "$r" = "b false" ] } # args: wait_suspend() { timeout=$1 while [ $timeout -gt 0 ] && [ ! -e /run/suspend.flag ]; do sleep 1 timeout=$((timeout - 1)) [ $(($timeout % 5)) -ne 0 ] || echo " waiting for suspend, ${timeout}s remaining..." done if [ ! -e /run/suspend.flag ]; then echo "closing lid did not cause suspend" >&2 exit 1 fi rm /run/suspend.flag echo " * closing lid caused suspend" } test_suspend_on_lid() { if systemd-detect-virt --quiet --container; then echo " * Skipping suspend test in container" return fi if ! grep -s -q mem /sys/power/state; then echo " * suspend not supported on this testbed, skipping" return fi # cleanup handler trap 'rm -f /run/udev/rules.d/70-logindtest-*.rules; udevadm control --reload; kill $KILL_PID; rm /run/systemd/system/systemd-suspend.service; if [ -d /sys/module/scsi_debug ]; then rmmod scsi_debug 2>/dev/null || (sleep 2; rmmod scsi_debug ) || true; fi' \ EXIT INT QUIT TERM PIPE # watch what's going on journalctl -f -u systemd-logind.service & KILL_PID="$KILL_PID $!" # create fake suspend UNIT=$(systemctl show -pFragmentPath --value systemd-suspend.service) sed '/^ExecStart=/ s_=.*$_=/bin/touch /run/suspend.flag_' $UNIT > /run/systemd/system/systemd-suspend.service sync systemctl daemon-reload # create fake lid switch mkdir -p /run/udev/rules.d echo 'SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="Fake Lid Switch", TAG+="power-switch"' \ > /run/udev/rules.d/70-logindtest-lid.rules sync udevadm control --reload evemu-device $(dirname $0)/lidswitch.evemu & KILL_PID="$KILL_PID $!" while [ -z "$O" ]; do sleep 0.1 O=$(grep -l '^Fake Lid Switch' /sys/class/input/*/device/name) done O=${O%/device/name} LID_DEV=/dev/${O#/sys/class/} # close lid evemu-event $LID_DEV --sync --type 5 --code 0 --value 1 # need to wait for 30s suspend inhibition after boot wait_suspend 31 # open lid again evemu-event $LID_DEV --sync --type 5 --code 0 --value 0 echo " * waiting for 30s inhibition time between suspends" sleep 30 # now closing lid should cause instant suspend evemu-event $LID_DEV --sync --type 5 --code 0 --value 1 wait_suspend 2 evemu-event $LID_DEV --sync --type 5 --code 0 --value 0 P=$(pidof systemd-logind) [ "$P" = "$LOGINDPID" ] || { echo "logind crashed" >&2; exit 1; } } test_shutdown() { echo " * scheduled shutdown with wall message" shutdown 2>&1 sleep 5 shutdown -c || true # logind should still be running P=$(pidof systemd-logind) [ "$P" = "$LOGINDPID" ] || { echo "logind crashed" >&2; exit 1; } echo " * scheduled shutdown without wall message" shutdown --no-wall 2>&1 sleep 5 shutdown -c --no-wall || true P=$(pidof systemd-logind) [ "$P" = "$LOGINDPID" ] || { echo "logind crashed" >&2; exit 1; } } test_in_logind_session() { echo " * XDG_SESSION_ID=$XDG_SESSION_ID" # cgroup v1: "1:name=systemd:/user.slice/..."; unified hierarchy: "0::/user.slice" if grep -E '(name=systemd|^0:):.*session.*scope' /proc/self/cgroup; then echo " * process is in session cgroup" else echo "FAIL: process is not in session cgroup" echo "/proc/self/cgroup:" cat /proc/self/cgroup loginctl loginctl show-session "$XDG_SESSION_ID" exit 1 fi } test_acl() { # ACL tests if ! echo "$LOGINCTL_OUT" | grep -q "seat0"; then echo " * Skipping ACL tests, as there is no seat" return fi if systemd-detect-virt --quiet --container; then echo " * Skipping ACL tests in container" return fi # determine user USER=`echo "$OUT" | grep seat0 | awk '{print $3}'` echo "seat user: $USER" # scsi_debug should not be loaded yet ! test -d /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block # we use scsi_debug to create new devices which we can put ACLs on # tell udev about the tagging, so that logind can pick it up cat < /run/udev/rules.d/70-logindtest-scsi_debug-user.rules SUBSYSTEM=="block", ATTRS{model}=="scsi_debug*", TAG+="uaccess" EOF sync udevadm control --reload echo " * coldplug: logind started with existing device" killall systemd-logind modprobe scsi_debug while ! dev=/dev/`ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null`; do sleep 0.1; done test -b $dev echo "got block device $dev" udevadm settle # trigger logind loginctl > /dev/null sleep 1 if getfacl -p $dev | grep -q "user:$USER:rw-"; then echo "$dev has ACL for user $USER" else echo "$dev has no ACL for user $USER:" >&2 getfacl -p $dev >&2 exit 1 fi rmmod scsi_debug echo " * hotplug: new device appears while logind is running" modprobe scsi_debug while ! dev=/dev/`ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block`; do sleep 0.1; done test -b $dev echo "got block device $dev" udevadm settle sleep 1 if getfacl -p $dev | grep -q "user:$USER:rw-"; then echo "$dev has ACL for user $USER" else echo "$dev has no ACL for user $USER:" >&2 getfacl -p $dev >&2 exit 1 fi } # # main # test_started test_properties test_in_logind_session test_suspend_on_lid test_shutdown test_acl