Lines 1-139
Link Here
|
1 |
#!/sbin/runscript |
1 |
#!/sbin/runscript |
2 |
# Copyright 1999-2015 Gentoo Foundation |
2 |
# Copyright 1999-2014 Gentoo Foundation |
3 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
# Distributed under the terms of the GNU General Public License v2 |
4 |
# $Header: /var/cvsroot/gentoo-x86/app-emulation/lxc/files/lxc.initd.3,v 1.3 2015/06/13 11:54:25 hwoarang Exp $ |
4 |
# $Header: $ |
5 |
|
5 |
|
|
|
6 |
#_name=${SVCNAME#*.} |
6 |
CONTAINER=${SVCNAME#*.} |
7 |
CONTAINER=${SVCNAME#*.} |
7 |
|
8 |
name="Linux Container ${CONTAINER}" |
8 |
LXC_PATH=`lxc-config lxc.lxcpath` |
9 |
extra_commands="info halt unfreeze" |
9 |
|
10 |
extra_started_commands="freeze attach" |
10 |
lxc_get_configfile() { |
11 |
|
11 |
if [ -f "${LXC_PATH}/${CONTAINER}.conf" ]; then |
12 |
description="Service to start Linux Container" |
12 |
echo "${LXC_PATH}/${CONTAINER}.conf" |
13 |
description_info="Get info about container" |
13 |
elif [ -f "${LXC_PATH}/${CONTAINER}/config" ]; then |
14 |
description_halt="Forse to killing container" |
14 |
echo "${LXC_PATH}/${CONTAINER}/config" |
15 |
description_freeze="Freeze running container" |
15 |
else |
16 |
description_unfreeze="Unfreeze freezed container" |
16 |
eerror "Unable to find a suitable configuration file." |
17 |
description_attach="Start a shell inside a running container" |
17 |
eerror "If you set up the container in a non-standard" |
18 |
|
18 |
eerror "location, please set the CONFIGFILE variable." |
19 |
## if necessary, you can manually set the value of these variables in the /etc/rc.conf or /etc/conf.d/lxc |
19 |
return 1 |
20 |
## be sure when you change this variables |
20 |
fi |
21 |
: ${rc_lxc__cgrouppath:=/sys/fs/cgroup/*/lxc} |
21 |
} |
22 |
# to avoid situation like as this https://bugs.gentoo.org/show_bug.cgi?id=416643 |
22 |
|
23 |
: ${rc_lxc__lxcpath:=$(lxc-config lxc.lxcpath)} |
23 |
[ $CONTAINER != $SVCNAME ] && CONFIGFILE=${CONFIGFILE:-$(lxc_get_configfile)} |
24 |
## https://bugs.gentoo.org/show_bug.cgi?id=525956 |
24 |
|
25 |
[ -f "${rc_lxc__lxcpath}/${CONTAINER}.conf" ] && \ |
25 |
lxc_get_var() { |
26 |
CONFIGFILE="${rc_lxc__lxcpath}/${CONTAINER}.conf" || \ |
26 |
awk 'BEGIN { FS="[ \t]*=[ \t]*" } $1 == "'$1'" { print $2; exit }' ${CONFIGFILE} |
27 |
CONFIGFILE="${rc_lxc__lxcpath}/${CONTAINER}/config" |
27 |
} |
28 |
|
|
|
29 |
eval pidfile="\${rc_${SVCNAME//./_}__pidfile:-/run/lxc/\${CONTAINER}.pid}" |
30 |
eval logfile="\${rc_${SVCNAME//./_}__logfile:-/var/log/lxc/\${CONTAINER}.log}" |
31 |
eval logpriority="\${rc_${SVCNAME//./_}__logpriority:-\${rc_lxc__logpriority:-WARN}}" |
32 |
eval CONSOLELOG="\$rc_${SVCNAME//./_}__consolelog" |
33 |
|
34 |
command="/usr/sbin/lxc-start" |
35 |
command_args="--name '${CONTAINER}' --rcfile '${CONFIGFILE}' --logfile '${logfile}' --logpriority '${logpriority}' --pidfile '${pidfile}' --daemon${CONSOLELOG:+ --console-log '${CONSOLELOG}'}" |
36 |
required_files=${CONFIGFILE} |
28 |
|
37 |
|
29 |
lxc_get_net_link_type() { |
38 |
lxc_get_net_link_type() { |
30 |
awk 'BEGIN { FS="[ \t]*=[ \t]*"; _link=""; _type="" } |
39 |
awk 'BEGIN { FS="[ \t]*=[ \t]*"; _link=""; _type="" } |
31 |
$1 == "lxc.network.type" {_type=$2;} |
40 |
$1 == "lxc.network.type" {_type=$2;} |
32 |
$1 == "lxc.network.link" {_link=$2;} |
41 |
$1 == "lxc.network.link" {_link=$2;} |
33 |
{if(_link != "" && _type != ""){ |
42 |
{if(_link != "" && _type != ""){ |
34 |
printf("%s:%s\n", _link, _type ); |
43 |
printf("%s:%s\n", _link, _type ); |
35 |
_link=""; _type=""; |
44 |
_link=""; _type=""; |
36 |
}; }' <${CONFIGFILE} |
45 |
}; }' < "${CONFIGFILE}" |
37 |
} |
46 |
} |
38 |
|
47 |
|
39 |
checkconfig() { |
48 |
checkconfig() { |
40 |
if [ ${CONTAINER} = ${SVCNAME} ]; then |
49 |
if [[ "${SVCNAME}" = "${CONTAINER}" ]]; then |
41 |
eerror "You have to create an init script for each container:" |
50 |
eerror "You have to create an init script for each container:" |
42 |
eerror " ln -s lxc /etc/init.d/lxc.container" |
51 |
eerror " ln -s lxc /etc/init.d/lxc.container" |
43 |
return 1 |
52 |
return 1 |
44 |
fi |
53 |
fi |
45 |
|
54 |
local _ret=0 |
46 |
# no need to output anything, the function takes care of that. |
55 |
## protection against bad SVCNAME |
47 |
[ -z "${CONFIGFILE}" ] && return 1 |
56 |
## Since ${SVCNAME//./_} may be used in some rc_.. environment, names must be correct |
48 |
|
57 |
if [[ -n "${SVCNAME//[0-9A-Za-z.]/}" ]]; then |
49 |
utsname=$(lxc_get_var lxc.utsname) |
58 |
eerror "Bad service name '${SVCNAME}'" |
50 |
if [ ${CONTAINER} != ${utsname} ]; then |
59 |
eerror "You can not use dashes in service name" |
51 |
eerror "You should use the same name for the service and the" |
60 |
_ret=1 |
52 |
eerror "container. Right now the container is called ${utsname}" |
61 |
fi |
53 |
return 1 |
62 |
if [[ "${SVCNAME//_/}" != "${SVCNAME}" ]]; then |
54 |
fi |
63 |
ewarn "This is a bad idea to use underline in the name of container service" |
|
|
64 |
ewarn "Some environments may conflict with services like as '${SVCNAME//_/.}'" |
65 |
fi |
66 |
return $_ret |
55 |
} |
67 |
} |
56 |
|
68 |
|
57 |
depend() { |
69 |
depend() { |
58 |
# be quiet, since we have to run depend() also for the |
70 |
checkconfig &>/dev/null || return 0 |
59 |
# non-muxed init script, unfortunately. |
71 |
config "${CONFIGFILE}" |
60 |
checkconfig 2>/dev/null || return 0 |
72 |
need localmount |
61 |
|
73 |
local _x _if |
62 |
config ${CONFIGFILE} |
74 |
for _x in $(lxc_get_net_link_type); do |
63 |
need localmount |
75 |
_if=${_x%:*} |
64 |
|
76 |
case "${_x##*:}" in |
65 |
local _x _if |
77 |
# when the network type is set to phys, we can make use of a |
66 |
for _x in $(lxc_get_net_link_type); do |
78 |
# network service (for instance to set it up before we disable |
67 |
_if=${_x%:*} |
79 |
# the net_admin capability), but we might also not set it up |
68 |
case "${_x##*:}" in |
80 |
# at all on the host and leave the net_admin capable service |
69 |
# when the network type is set to phys, we can make use of a |
81 |
# to take care of it. |
70 |
# network service (for instance to set it up before we disable |
82 |
phys) use net.${_if} ;; |
71 |
# the net_admin capability), but we might also not set it up |
83 |
*) need net.${_if} ;; |
72 |
# at all on the host and leave the net_admin capable service |
84 |
esac |
73 |
# to take care of it. |
85 |
done |
74 |
phys) use net.${_if} ;; |
86 |
} |
75 |
*) need net.${_if} ;; |
87 |
|
76 |
esac |
88 |
start_pre() { |
77 |
done |
89 |
checkconfig || return 1 |
78 |
} |
90 |
if lxc-info -n "${CONTAINER}" 2>/dev/null| grep -qiE '^state:\s+stopped$'; then |
79 |
|
91 |
local _c _p= |
80 |
start() { |
92 |
for _c in ${rc_lxc__cgrouppath}/"${CONTAINER}"; do |
81 |
checkconfig || return 1 |
93 |
[ -e "$_c" ] && \ |
82 |
rm /var/log/lxc/${CONTAINER}.log |
94 |
_p="$_p '$_c'" && \ |
83 |
|
95 |
eerror "Found '$_c'. Perhaps the last time the container '${CONTAINER}' was completed with an error." |
84 |
rootpath=$(lxc_get_var lxc.rootfs) |
96 |
done |
85 |
|
97 |
[ -z "$_p" ] && \ |
86 |
# Check the format of our init and the chroot's init, to see |
98 |
checkpath -q -d "$(dirname "${pidfile}")" && \ |
87 |
# if we have to use linux32 or linux64; always use setarch |
99 |
return 0 |
88 |
# when required, as that makes it easier to deal with |
100 |
ewarn "Possibly for you can help comand: rmdir${_p}" |
89 |
# x32-based containers. |
101 |
return 1 |
90 |
case $(scanelf -BF '%a#f' ${rootpath}/sbin/init) in |
102 |
else |
91 |
EM_X86_64) setarch=linux64;; |
103 |
if lxc-info -n "${CONTAINER}" 2>/dev/null | grep -qie '^state:'; then |
92 |
EM_386) setarch=linux32;; |
104 |
eerror "Can't start ${name}. It's not sopped." |
93 |
esac |
105 |
else |
94 |
|
106 |
eerror "Can't start ${name}. It's not found." |
95 |
ebegin "Starting ${CONTAINER}" |
107 |
fi |
96 |
env -i ${setarch} $(type -p lxc-start) -l WARN -n ${CONTAINER} -f ${CONFIGFILE} -d -o /var/log/lxc/${CONTAINER}.log |
108 |
fi |
97 |
sleep 0.5 |
109 |
} |
98 |
|
110 |
|
99 |
# lxc-start -d will _always_ report a correct startup, even if it |
111 |
start_post() { |
100 |
# failed, so rather than trust that, check that the cgroup exists. |
112 |
ebegin "Try to make sure ${name} started correctly" |
101 |
[ -d /sys/fs/cgroup/cpuset/lxc/${CONTAINER} ] |
113 |
ewaitfile 15 ${rc_lxc__cgrouppath}/"${CONTAINER}" |
102 |
eend $? |
114 |
eend $? |
|
|
115 |
} |
116 |
|
117 |
_halt(){ |
118 |
eval local HALT_TIMEOUT=\${rc_${SVCNAME//./_}__halt_timeout-${rc_lxc__halt_timeout-15}} |
119 |
ebegin "Halting ${name}" |
120 |
( lxc-stop --name "${CONTAINER}" --kill --nowait & ) &>/dev/null |
121 |
lxc-wait --name "${CONTAINER}" -s STOPPED ${HALT_TIMEOUT:+-t ${HALT_TIMEOUT}} |
122 |
if eend $? "Some error on halting ${name}"; then |
123 |
mark_service_stopped "${SVCNAME}" |
124 |
else |
125 |
mark_service_stopping "${SVCNAME}" |
126 |
return 1 |
127 |
fi |
128 |
} |
129 |
|
130 |
halt() { |
131 |
service_stopped "${SVCNAME}" && ewarn "WARNING: ${SVCNAME} is already marked as stopped, but I still try to kill ${name}" |
132 |
_halt |
103 |
} |
133 |
} |
104 |
|
134 |
|
105 |
stop() { |
135 |
stop() { |
106 |
checkconfig || return 1 |
136 |
eval local STOP_PWR_TIMEOUT=\${rc_${SVCNAME//./_}__stop_power_timeout-${rc_lxc__stop_power_timeout-15}} |
|
|
137 |
eval local STOP_NOKILL_TIMEOUT=\${rc_${SVCNAME//./_}__stop_nokill_timeout-${rc_lxc__stop_nokill_timeout-15}} |
138 |
if ! service_wasinactive "${SVCNAME}"; then |
139 |
if [ -n "${STOP_PWR_TIMEOUT}" ]; then |
140 |
ebegin "Sending signal to stop ${name}" |
141 |
kill -s SIGPWR "$(lxc-info --pid --no-humanize --name "${CONTAINER}")" &>/dev/null |
142 |
lxc-wait --name "${CONTAINER}" -s STOPPED -t ${STOP_PWR_TIMEOUT} |
143 |
eend $? && return 0 |
144 |
fi |
145 |
if [ -n "${STOP_NOKILL_TIMEOUT}" ]; then |
146 |
ebegin "Try to request a clean shutdown ${name}" |
147 |
( lxc-stop --name "${CONTAINER}" --nokill & ) &>/dev/null |
148 |
lxc-wait --name "${CONTAINER}" -s STOPPED -t ${STOP_NOKILL_TIMEOUT} |
149 |
eend $? && return 0 |
150 |
fi |
151 |
fi |
152 |
_halt |
153 |
} |
154 |
|
155 |
freeze() { |
156 |
ebegin "Freeze all the processes of the container ${CONTAINER}" |
157 |
lxc-freeze --name "${CONTAINER}" |
158 |
eend $? "Problem whith freezing container ${CONTAINER}" && mark_service_inactive "${SVCNAME}" |
159 |
} |
160 |
|
161 |
unfreeze() { |
162 |
if service_inactive "${SVCNAME}"; then |
163 |
ebegin "Unfreeze container ${CONTAINER}" |
164 |
lxc-unfreeze --name "${CONTAINER}" |
165 |
eend $? "Problem whith unfreezing container ${CONTAINER}" && mark_service_started "${SVCNAME}" |
166 |
else |
167 |
eerror "${SVCNAME}: cannot \`unfreeze' as it has not been started" |
168 |
fi |
169 |
} |
107 |
|
170 |
|
|
|
171 |
info() { |
172 |
lxc-info --name "${CONTAINER}" |
173 |
} |
108 |
|
174 |
|
109 |
if ! [ -d /sys/fs/cgroup/cpuset/lxc/${CONTAINER} ]; then |
175 |
attach() { |
110 |
ewarn "${CONTAINER} doesn't seem to be started." |
176 |
lxc-attach --name "${CONTAINER}" |
111 |
return 0 |
|
|
112 |
fi |
113 |
|
114 |
init_pid=$(lxc-info -n ${CONTAINER} --pid | awk '{ print $2 }') |
115 |
|
116 |
if [ -z "${init_pid}" ]; then |
117 |
ewarn "${CONTAINER} doesn't seem to be running." |
118 |
return 0 |
119 |
fi |
120 |
|
121 |
ebegin "Shutting down system in ${CONTAINER}" |
122 |
kill -PWR ${init_pid} |
123 |
eend $? |
124 |
|
125 |
TIMEOUT=${TIMEOUT:-30} |
126 |
i=0 |
127 |
while [ -n "$(pgrep -P ${init_pid})" -a $i -lt ${TIMEOUT} ]; do |
128 |
sleep 1 |
129 |
i=$(expr $i + 1) |
130 |
done |
131 |
|
132 |
if [ -n "${missingprocs}" ]; then |
133 |
ewarn "Something failed to properly shut down in ${CONTAINER}" |
134 |
fi |
135 |
|
136 |
ebegin "Stopping ${CONTAINER}" |
137 |
lxc-stop -n ${CONTAINER} |
138 |
eend $? |
139 |
} |
177 |
} |