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