More cgroup stuff

Signed-off-by: fbt <fbt@fleshless.org>
This commit is contained in:
Jack L. Frost 2018-01-08 10:33:06 +03:00
parent f191b625dc
commit a715783fbf
1 changed files with 86 additions and 17 deletions

103
ssm
View File

@ -23,6 +23,8 @@ var() {
('==') mode=compare;;
('=~') mode=regex;;
('u') mode=includes;;
(*) die 71 \"Syntax error in \$FUNCNAME!\";;
esac
shift
@ -45,6 +47,14 @@ var() {
(*) return 0;;
esac
;;
(includes)
for i in \"\${_var[@]}\"; do
[[ \"\$i\" == \"\$*\" ]] && return 0
done
return 1
;;
esac
}; readonly -f \"${varname}\"
@ -90,8 +100,8 @@ svc() {
# Cgroups
if cgroups; then
mkdir -p "$cgroup_home/$service_name"
echo "$BASHPID" > "$cgroup_home/$service_name/cgroup.procs"
mkdir -p "$cgroup_home/$service_cgroup_name"
echo "$BASHPID" > "$cgroup_home/$service_cgroup_name/cgroup.procs"
fi
svc::cleanup() {
@ -292,15 +302,23 @@ read_systemd_service() {
start() {
service_running && return 3
rm -f "$service_stopped_flag"
[[ -f "${service_command[0]}" ]] || return 9
if cgroups; then
if service_cgroup_exclusive; then
if ! service_cgroup_empty; then
return 15
fi
fi
fi
depend "${service_depends[@]}" || return 7
depend_ready "${service_depends_ready[@]}" || return 7
mktmpfiles || return 13
rm -f "$service_stopped_flag"
if service_managed; then
if service_respawn; then
svc respawn "${service_command[@]}" &
@ -318,6 +336,12 @@ start() {
(( res )) && return "$res"
printf '1' > "$service_enabled_flag"
else
# Put ourselves into the cgroup, so that even when we die, whatever we started stays in it
if cgroups; then
mkdir -p "$cgroup_home/$service_cgroup_name"
echo "$BASHPID" > "$cgroup_home/$service_cgroup_name/cgroup.procs"
fi
exec "${service_command[@]}" 1>"$service_logfile_out" 2>"$service_logfile_err" &
fi
@ -350,6 +374,16 @@ stop() {
pid_wait "$service_pid" || return 5
> "$service_stopped_flag"
# Cgroup stuff
if cgroups; then
if service_cgroup_wait; then
for p in "${service_cgroup_procs[@]}"; do
pid_wait "$p" &
wait || return 5
done
fi
fi
return 0
fi
}
@ -384,7 +418,14 @@ info() {
"PID" "${service_pid:-none}"
fi
printf "%12s: %s\n" "${_info_items[@]}"
# Show the cgroup
if cgroups; then
_info_items += "Cgroup" "$cgroup_home/$service_cgroup_name" \
"Cgroup procs" "${#service_cgroup_procs[@]}"
fi
printf "%16s: %s\n" "${_info_items[@]}"
}
## Restart just calls the script twice by default
@ -427,6 +468,8 @@ var service_pid \
service_ready_flag \
service_enabled_flag \
service_stopped_flag \
service_cgroup_name \
service_cgroup_procs \
cgroup_home \
failed_deps \
svc_pidfile \
@ -443,25 +486,31 @@ var XDG_CONFIG_HOME := "$HOME/.config"
var XDG_RUNTIME_DIR := "/run/user/$UID"
## Let's set some defaults
# These are meaningful to reconfigure.
var service_respawn = 0 # Respawn the service if it exits
var service_workdir = '/'
var service_stop_timeout = 30
var service_ready_timeout = 15
var service_signals = 1 10 12
var service_reload_signal = 1
var service_stop_signal = 15
var service_cgroup_exclusive = 0 # Refuse to start the service if its cgroup is not empty
var service_cgroup_wait = 0 # Wait on all the members of the cgroup to exit when stopping the service.
var systemd = 0 # Enable systemd-related functions.
var systemd_service_path = /etc/systemd/system /run/systemd/system /lib/systemd/system
var cgroups = 0 # Enable cgroup-related functions
var usrdir = '/usr/share/ssm'
# These are not
var service_managed = 1
var service_respawn = 0
var service_oneshot = 0
var service_running = 0
var service_enabled = 0
var service_stopped = 0
var service_systemd = 0
var service_workdir = '/'
var service_stop_timeout = 30
var service_ready_timeout = 15
var service_stop_signal = 15
var service_reload_signal = 1
var service_signals = 1 10 12
var service_nologs = 0
var usrdir = '/usr/share/ssm'
var systemd = 0
var systemd_service_path = /etc/systemd/system /run/systemd/system /lib/systemd/system
var service_cgroup_empty = 1
var ssm_config = 0
var cgroups = 0
## Figure out our full path
case "$0" in
@ -588,6 +637,7 @@ service_logfile_err := "$logdir/${service_name}.err.log"
service_ready_flag := "$rundir/$service_name.ready"
service_enabled_flag := "$rundir/$service_name.enabled"
service_stopped_flag := "$rundir/$service_name.stopped"
service_cgroup_name := "$service_name"
# A shortcut for disabling logging
if service_nologs; then
@ -617,6 +667,24 @@ if [[ -f "$service_stopped_flag" ]]; then
service_stopped = 1
fi
# Check cgroups, if enabled
if cgroups; then
if [[ -d "$cgroup_home/$service_cgroup_name" ]]; then
while read -r line; do
service_cgroup_procs += "$line"
done < "$cgroup_home/$service_cgroup_name/cgroup.procs"
if (( ${#service_cgroup_procs[@]} )); then
service_cgroup_empty = 0
fi
fi
# If there's a service PID, check if it's in the service's cgroup
if service_pid; then
service_cgroup_procs u "$service_pid" || die 29 "Recorded service PID is not in the service's cgroup, bailing!"
fi
fi
# Check if action is even defined
is_function "$2" || die 17 "Function $2 is not defined for $service_name."
@ -651,7 +719,8 @@ case "$2" in
5 "Readyness check for $service_name timed out" \
7 "Failed to start dependencies for $service_name: ${failed_deps[@]}" \
9 "service_command does not exist: ${service_command[0]}" \
13 "Failed to create temporary files for $service_name"
13 "Failed to create temporary files for $service_name" \
15 "Refusing to start $service_name: the service cgroup is not empty and \$service_cgroup_exclusive is set"
;;
reload)