#!/bin/bash # script to shutdown a system running buildd in a controlled way # Copyright (c) 2009 Peter Palfrader # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. set -e set -u usage() { echo "Usage: $0 [-h] " >&2 echo " -h is for halt, not for help" exit 3 } halt=0 if [ "${1:-""}" == '-h' ] ; then halt=1 shift fi if [ "$#" != 1 ]; then usage fi reason="$1" touch_stuff() { local user="$1" local home=$(getent passwd "$user" | awk -F: '{print $6}') if ! test -e "$home"/NO-DAEMON-PLEASE; then if [ -e "$home"/build/buildd.pid ] ; then echo "Touching ${home}/NO-DAEMON-PLEASE ${home}/EXIT-DAEMON-PLEASE" sudo -u "$user" touch "$home"/NO-DAEMON-PLEASE "$home"/EXIT-DAEMON-PLEASE sudo -u "$user" sh -c "echo waiting-for-clean-shutdown > '${home}/'NO-DAEMON-PLEASE" sudo chgrp -v adm "$home"/NO-DAEMON-PLEASE echo "Sending HUP to $user:buildd" sudo -u "$user" kill -HUP "$(sudo cat "${home}"/build/buildd.pid)" else echo "$user: no-daemon-please does not exist, but there is no buildd.pid file either" if pgrep -u "$user" -x buildd ; then echo "But there is a buildd running. Bad?" exit 3 fi fi else echo "no-daemon-please already exists" fi } wall_counter=0 maybe_wall() { wall_counter=$((wall_counter-1)) if [ "$wall_counter" -le 0 ]; then if [ "$halt" = 1 ]; then echo "System will halt for $reason when buildd has stopped" | wall else echo "System will reboot for $reason when buildd has stopped" | wall fi wall_counter=720 fi } buildd_wait_and_reboot() { echo -n "Waiting for buildd to shut down" while test -e ~buildd/build/buildd.pid || test -e ~buildd2/build/buildd.pid; do echo -n "." sleep 5 maybe_wall done echo if pgrep -u buildd -x buildd || pgrep -u buildd2 -x buildd; then echo "pidfile is gone, but buildd process still runs" while pgrep -u buildd -x buildd ; do echo -n "." sleep 5 maybe_wall done echo fi if grep 'waiting-for-clean-shutdown' ~buildd/NO-DAEMON-PLEASE > /dev/null; then sudo -u buildd sh -c 'echo delete-on-boot > ~buildd/NO-DAEMON-PLEASE' fi if grep 'waiting-for-clean-shutdown' ~buildd2/NO-DAEMON-PLEASE > /dev/null; then sudo -u buildd2 sh -c 'echo delete-on-boot > ~buildd2/NO-DAEMON-PLEASE' fi if [ "$halt" = 1 ]; then /sbin/shutdown -h 1 "$reason" else /sbin/shutdown -r 1 "$reason" fi } if [ "`id -u`" != 0 ]; then echo "This probably wants running as root" >&2 exit 3 fi if ! id buildd > /dev/null 2>&1; then echo "Is there a buildd user?" >&2 exit 3 fi if ! [ -d ~buildd ]; then echo "No ~buildd?" >&2 exit 3 fi touch_stuff buildd [ -d ~buildd2 ] && touch_stuff buildd2 buildd_wait_and_reboot