use 'findObject -e' instead of 'findFile' to find /dev/null also
[util-vserver.git] / util-vserver / scripts / vshelper
1 #! /bin/bash
2
3 # Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 #  
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
8 #  
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #  
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 ## Usage: vshelper <xid> <action> <args>
19
20 : ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars}
21 test -e "$UTIL_VSERVER_VARS" || {
22     echo "Can not find util-vserver installation; aborting..." >&2
23     exit 1
24 }
25 . "$UTIL_VSERVER_VARS"
26 . "$_LIB_FUNCTIONS"
27
28 function showHelp
29 {
30     echo $"\
31 Usage: vshelper <xid> <event> <args>*
32
33 Report bugs to <$PACKAGE_BUGREPORT>."
34     exit 0
35 }
36
37 function showVersion
38 {
39     echo $"\
40 vshelper $PACKAGE_VERSION -- userspace reboot helper
41 This program is part of $PACKAGE_STRING
42
43 Copyright (C) 2004 Enrico Scholz
44 This program is free software; you may redistribute it under the terms of
45 the GNU General Public License.  This program has absolutely no warranty."
46     exit 0
47 }
48
49 function doInternalMethod
50 {
51     local method=$1
52     case "$method" in
53         (restart)
54             case "$ACTION" in
55                 (restart)
56                     logging $"Restarting vserver '$VSERVER'"
57                     execute $_VSERVER "$VSERVER" restart
58                     ;;
59                 (halt|poweroff)
60                     logging $"Stopping vserver '$VSERVER'"
61                     execute $_VSERVER "$VSERVER" stop
62                     ;;
63                 (swsusp)
64                     ## TODO: any senseful action here? Perhaps shutdown scheduler for it?
65                     exit 0
66                     ;;
67                 (restart2)      ;;
68                 (*)
69                     warning $"Unknown action '$ACTION' for vserver '$VSERVER'"
70                     exit 1
71             esac
72             ;;
73             
74         (sync)
75             local f=${METHOD_ARGS[0]}
76             test "$f" ||
77                 panic $"Insufficent arguments for method '$method' and vserver '$VSERVER'"
78
79             test -p "$f" ||
80                 panic $"File '$f' which is required for synchronisation of vserver '$VSERVER' is not a pipe"
81
82             echo "$ACTION" >"$f"
83             ;;
84
85         (*)
86             local script
87             findObject -x script "$CONFDIR"/.defaults/apps/vshelper-methods/"$method" "$PKGLIBDIR"/vshelper-methods/"$method" ''
88             
89             test '$script' || {
90                 warning $"No handler for internal method '$method' found"
91                 exit 1
92             }
93
94             export VSERVER
95             execute "$script" "${ARGS[@]}"
96     esac
97 }
98     
99 function doDefaultMethod
100 {
101     local handler
102
103     vshelper.getHandler handler "$VSERVER" "$ACTION" || {
104         warning $"No handler configured for action '$ACTION' on vserver '$VSERVER'"
105         exit 1
106     }
107
108     case "$handler" in
109         (/*)    execute "$handler" "${ARGS[@]}";;
110         (:*)    doInternalMethod "${handler##:}" "$@";;
111     esac
112 }
113
114 #===========
115
116 if ! tty -s; then
117     findObject -e _VS_LOGFILE "$CONFDIR"/.defaults/apps/vshelper/logfile /dev/null
118     findObject -e _VS_ERRFILE "$CONFDIR"/.defaults/apps/vshelper/logfile /dev/null
119
120     exec  >>$_VS_LOGFILE
121     exec 2>>$_VS_ERRFILE
122 fi
123     
124 logging "$(date): vshelper $*"
125
126 test "$1" != '--version' || showVersion
127 test "$1" != '--help'    || showHelp
128 test "$#" -ge 2 ||
129     panic $"vshelper called with missing arguments; try '--help' for more information"
130
131 vshelper.isEnabled || exit 0
132     
133 set -eu
134
135 declare -r XID=$1
136 declare -r ACTION=$2
137
138
139 this_xid=$($_VSERVER_INFO - XID)
140 pxid=
141 while true; do
142     pxid=$($_VSERVER_INFO "$XID" PXID) || break
143     test "$pxid" -ne "$this_xid"       || break
144     xid=$pxid
145 done
146
147 vserver_id=$($_VSERVER_INFO "$XID" ID) ||
148     panic $"No responsible vserver found for xid '$1' ($XID); aborting..."
149     
150 test "$1" = "$XID" || {
151     logging "Giving 'vshelper' task for '$1' to parent vserver '$vserver_id' ($XID)"
152     execute $_VSERVER "$vserver_id" exec $_VSHELPER "$@"
153 }
154
155 #===========
156
157 ARGS=( "$@" )
158
159 declare -a state
160 getFileArray state "$VSHELPERSTATEDIR/$XID" && test ${#state[@]} -ge 2 || {
161     logging "'vshelper' not configured for xid '$XID'"
162     exit 0
163 }
164
165 declare -r VSERVER=${state[0]}
166
167 cfg_xid=$($_VSERVER_INFO "${state[0]}" CONTEXT false) ||
168     panic $"Configured vserver '$VSERVER' does not seem to run; aborting..."
169
170 test "$cfg_xid" = "$XID" ||
171     panic $"Configured ($cfg_xid) and actual ($XID) xid for vserver '$VSERVER' are mismatching; aborting..."
172
173 cur_xid=$($_VSERVER_INFO "$VSERVER" CONTEXT false) ||
174     panic $"Vserver '$VSERVER' with '$XID' does not seem to run; strange..."
175
176 test "$cur_xid" = "$XID" ||
177     panic $"Expected ($XID) and actual ($cur_xid) xid for vserver '$VSERVER' are mismatching; strange..."
178
179
180 method=${state[1]}
181 if test "${#state[@]}" -gt 2; then
182     unset state[0] state[1]
183     declare -ra METHOD_ARGS=( "${state[@]}" )
184 else
185     declare -ra METHOD_ARGS=()
186 fi
187
188 case "$method" in
189     (default)   doDefaultMethod "$@";;
190     (sync)      doInternalMethod "$method" "$@";;
191     (*)         panic $"Unknown method '$method' used by vserver '$VSERVER'";;
192 esac