aboutsummaryrefslogtreecommitdiff
blob: b7e23404674e9f25493c90520545540f30d94f70 (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
136
137
138
139
140
141
142
143
144
145
146
147
#!/sbin/openrc-run
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id: 7f124381f12b60e421d0efe273d2b53cbaf67be1 $

CONTAINER=${SVCNAME#*.}

lxc_get_configfile() {
	LXC_PATH="$( readlink -e "$( lxc-config lxc.lxcpath 2>/dev/null || echo '/var/lib' )" )"
	if [ -d "/etc/lxc" ] && [ -f "/etc/lxc/${CONTAINER}.conf" -o -f "/etc/lxc/${CONTAINER}/config" ]; then
		#ewarn "Legacy LXC configuration directory '/etc/lxc' found - please migrate your"
		#ewarn "configuration files to '${LXC_PATH}'"
		LXC_PATH="/etc/lxc"
	elif [ -d "${LXC_PATH}/lxc" ] && [ -f "${LXC_PATH}/lxc/${CONTAINER}.conf" -o -f "${LXC_PATH}/lxc/${CONTAINER}/config" ]; then
		LXC_PATH="${LXC_PATH}/lxc"
	fi
	#einfo "Using '${LXC_PATH}' as LXC configuration directory"

	if [ -f "${LXC_PATH}/${CONTAINER}.conf" ]; then
		echo "${LXC_PATH}/${CONTAINER}.conf"
	elif [ -f "${LXC_PATH}/${CONTAINER}/config" ]; then
		echo "${LXC_PATH}/${CONTAINER}/config"
	else
		eerror "Unable to find a suitable configuration file."
		eerror "If you set up the container 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}
}

lxc_get_net_link_type() {
	awk 'BEGIN { FS="[ \t]*=[ \t]*"; _link=""; _type="" }
		$1 == "lxc.network.type" {_type=$2;}
		$1 == "lxc.network.link" {_link=$2;}
		{if(_link != "" && _type != ""){
			printf("%s:%s\n", _link, _type );
			_link=""; _type="";
		}; }' <${CONFIGFILE}
}

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

	local _x _if
	for _x in $(lxc_get_net_link_type); do
		_if=${_x%:*}
		case "${_x##*:}" in
			# when the network type is set to phys, we can make use of a
			# network service (for instance to set it up before we disable
			# the net_admin capability), but we might also not set it up
			# at all on the host and leave the net_admin capable service
			# to take care of it.
			phys)	use net.${_if} ;;
			*)	need net.${_if} ;;
		esac
	done
}

start() {
	checkconfig || return 1
	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; always use setarch
	# when required, as that makes it easier to deal with
	# x32-based containers.
	case $(scanelf -BF '%a#f' ${rootpath}/sbin/init) in
		EM_X86_64)	setarch=linux64;;
		EM_386)		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 /sys/fs/cgroup/cpuset/lxc/${CONTAINER} ]
	eend $?
}

stop() {
	checkconfig || return 1


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

	init_pid=$(lxc-info -n ${CONTAINER} --pid | awk '{ print $2 }')

	if [ -z "${init_pid}" ]; then
	    ewarn "${CONTAINER} doesn't seem to be running."
	    return 0
	fi

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

	TIMEOUT=${TIMEOUT:-30}
	i=0
	while [ -n "$(pgrep -P ${init_pid})" -a $i -lt ${TIMEOUT} ]; do
		sleep 1
		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 $?
}