summaryrefslogtreecommitdiff
blob: 7275826025a1ce683813c1dd54ddc914c9bf058b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/sbin/runscript
# Copyright 1999-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/lxc/files/lxc.initd,v 1.8 2011/09/28 21:47:46 flameeyes Exp $

CONTAINER=${SVCNAME#*.}

lxc_get_configfile() {
	if [ -f "/etc/lxc/${CONTAINER}.conf" ]; then
		echo "/etc/lxc/${CONTAINER}.conf"
	elif [ -f "/etc/lxc/${CONTAINER}/config" ]; then
		echo "/etc/lxc/${CONTAINER}/config"
	else
		eerror "Unable to find a suitable configuration file."
		eerror "If you set up the contianer in a non-standard"
		eerror "location, please set the CONFIGFILE variable."
		return 1
	fi
}

[ $CONTAINER != $SVCNAME ] && CONFIGFILE=${CONFIGFILE:-$(lxc_get_configfile)}

lxc_get_var() {
	awk 'BEGIN { FS="[ \t]*=[ \t]*" } $1 == "'$1'" { print $2; exit }' ${CONFIGFILE}
}

cgroup_get_mount() {
	mount | awk '$5 == "cgroup" { print $3; exit }'
}

checkconfig() {
	if [ ${CONTAINER} = ${SVCNAME} ]; then
		eerror "You have to create an init script for each container:"
		eerror " ln -s lxc /etc/init.d/lxc.container"
		return 1
	fi

	# no need to output anything, the function takes care of that.
	[ -z "${CONFIGFILE}" ] && return 1

	utsname=$(lxc_get_var lxc.utsname)
	if [ ${CONTAINER} != ${utsname} ]; then
	    eerror "You should use the same name for the service and the"
	    eerror "container. Right now the container is called ${utsname}"
	    return 1
	fi
}

depend() {
	# be quiet, since we have to run depend() also for the
	# non-muxed init script, unfortunately.
	checkconfig 2>/dev/null || return 0

	config ${CONFIGFILE}
	need localmount

	# find out which network interface the container is linked to,
	# and then require that to be enabled, so that the
	# dependencies are correct.
	netif=$(lxc_get_var lxc.network.link)
	[ -n "${netif}" ] && use net.${netif}
}

start() {
	checkconfig || return 1

	# make sure that cgroup is mounted if it isn't already, this
	# ensures that we can actually proceed!
	cgroupmount=$(cgroup_get_mount)
	if [ -z ${cgroupmount} ]; then
	    mkdir -p /cgroup

	    if ! mount -t cgroup cgroup /cgroup; then
	        eerror "Unable to mount cgroup pseudo-filesystem on /cgroup"
	        return 1
	    fi

	    cgroupmount=/cgroup
	fi

	rm /var/log/lxc/${CONTAINER}.log

	rootpath=$(lxc_get_var lxc.rootfs)

	# Check the format of our init and the chroot's init, to see if we
	# have to use linux32 or linux64...
	case $(scanelf -BF '%M#f' /sbin/init ${rootpath}/sbin/init | tr '\n' ':') in
		ELFCLASS64:ELFCLASS64:) setarch=;;
		ELFCLASS32:ELFCLASS32:) setarch=;;
		ELFCLASS32:ELFCLASS64:) setarch=linux64;;
		ELFCLASS64:ELFCLASS32:) setarch=linux32;;
	esac

	ebegin "Starting ${CONTAINER}"
	env -i ${setarch} $(type -p lxc-start) -l WARN -n ${CONTAINER} -f ${CONFIGFILE} -d -o /var/log/lxc/${CONTAINER}.log
	sleep 0.5

	# lxc-start -d will _always_ report a correct startup, even if it
	# failed, so rather than trust that, check that the cgroup exists.
	[ -d ${cgroupmount}/${CONTAINER} ]
	eend $?
}

stop() {
	checkconfig || return 1

	cgroupmount=$(cgroup_get_mount)

	if ! [ -d ${cgroupmount}/${CONTAINER} ]; then
	    ewarn "${CONTAINER} doesn't seem to be started."
	    return 0
	fi

	init_pid=$(lxc-info -n ${CONTAINER} --pid | cut -d: -f 2)

	ebegin "Shutting down system in ${CONTAINER}"
	kill -INT ${init_pid}
	eend $?

	TIMEOUT=${TIMEOUT:-30}
	i=0
	while [ -n "${missingprocs}" -a $i -lt ${TIMEOUT} ]; do
		sleep 1
		missingprocs=$(pgrep -P ${init_pid})
		i=$(expr $i + 1)
	done

	if [ -n "${missingprocs}" ]; then
		ewarn "Something failed to properly shut down in ${CONTAINER}"
	fi

	ebegin "Stopping ${CONTAINER}"
	lxc-stop -n ${CONTAINER}
	eend $?
}