1#!/bin/sh
2#
3# PROVIDE: xendomains
4# REQUIRE: xencommons
5# KEYWORD: shutdown
6#
7# xendomains		This required variable is a whitespace-separated
8#			list of domains, e.g., xendomains="dom1 dom2 dom3".
9#
10# xendomains_config	This optional variable is a format string that
11#			represents the path to the configuration file for
12#			each domain.  "%s" is substituted with the name of
13#			the domain.  The default is "@PKG_SYSCONFDIR@/%s".
14#
15# xendomains_prehook	This optional variable is a format string that
16#			represents the command to run, if it exists, before
17#			starting each domain.  "%s" is substituted with the
18#			name of the domain.  The default is
19#			"@PKG_SYSCONFDIR@/%s-pre".
20#
21# xendomains_posthook	This optional variable is a format string that
22#			represents the command to run, if it exists, after
23#			stopping each domain.  "%s" is substituted with the
24#			name of the domain.  The default is
25#			"@PKG_SYSCONFDIR@/%s-post".
26#
27
28. /etc/rc.subr
29
30DIR=$(dirname "$0")
31. "${DIR}/xen-hotplugpath.sh"
32
33LD_LIBRARY_PATH="${libdir}"
34export LD_LIBRARY_PATH
35
36name="xendomains"
37ctl_command="${sbindir}/xl"
38start_cmd="xendomains_start"
39stop_cmd="xendomains_stop"
40list_cmd="xendomains_list"
41extra_commands="list"
42required_files="/kern/xen/privcmd"
43
44xendomains_start()
45{
46	[ -n "$xendomains" ] || return
47
48	echo "Starting xen domains."
49	for domain in $xendomains; do
50		case "$domain" in
51		"")	continue ;;
52		esac
53
54		# Start off by running the pre-hook script if it's present.
55		if [ -n "${xendomains_prehook}" ]; then
56			cmdline=`printf "${xendomains_prehook}" $domain`
57			cmd="${cmdline%% *}"
58			if [ -x "$cmd" ]; then
59				$cmdline || echo "Pre-hook \`\`$cmdline'' failed... skipping $domain."
60				continue
61			fi
62		fi
63
64		# Ask xend to create the domain.
65		if [ -n "${xendomains_config}" ]; then
66			file=`printf "${xendomains_config}" $domain`
67			if [ -f "$file" ]; then
68				${ctl_command} create "$file"
69			fi
70		fi
71	done
72}
73
74xendomains_list() {
75	# Output a whitespace-separated list of live guest domains.
76	${ctl_command} list | awk '
77		(FNR <= 2) { next }
78		($5 !~ /s/) { s = s " " $1 }
79		END { sub(" *", "", s); print s }'
80}
81
82xendomains_stop()
83{
84	# Determine an appropriate timeout waiting for all domains to
85	# stop -- always wait at least 60s, and add 5s per active domain.
86	#
87	numdomains=$(xendomains_list | awk '{ print NF }')
88	[ $numdomains -gt 0 ] || return
89	timeout=$((60 + numdomains * 5))
90
91	# Ask xend to stop every domain, and poll xend every 10s up to the
92	# timeout period to check if all the domains are stopped.  We
93	# consider a domain in the "s" (shutdown) state to be stopped.
94	#
95	echo "Stopping xen domains."
96	for domain in $(xendomains_list); do
97		${ctl_command} shutdown $domain
98	done
99	while [ $timeout -gt 0 ]; do
100		livedomains=$(xendomains_list)
101		[ -n "$livedomains" ] || break
102		timeout=$((timeout - 10))
103		sleep 10
104	done
105	livedomains=$(xendomains_list)
106	if [ -n "$livedomains" ]; then
107		echo "Failed to stop: $livedomains"
108	else
109		echo "All domains stopped."
110	fi
111
112	# Finish off by running the post-hook script if it's present.
113	for domain in $xendomains; do
114		case "$domain" in
115		"")	continue ;;
116		esac
117		if [ -n "${xendomains_posthook}" ]; then
118			cmdline=`printf "${xendomains_posthook}" $domain`
119			cmd="${cmdline%% *}"
120			if [ -x "$cmd" ]; then
121				$cmdline || echo "Post-hook \`\`$cmdline'' failed."
122			fi
123		fi
124	done
125}
126
127load_rc_config $name
128
129: ${xendomains_config="${XEN_CONFIG_DIR}/%s"}
130: ${xendomains_prehook="${XEN_CONFIG_DIR}/%s-pre"}
131: ${xendomains_posthook="${XEN_CONFIG_DIR}/%s-post"}
132
133run_rc_command "$1"
134