Commit 42bb48c2 authored by Franco Lanza's avatar Franco Lanza

Recreated upstream 0.33

parent 5d061d0a
#! /bin/sh
### BEGIN INIT INFO
# Provides: cgmanager
# Required-Start: mountkernfs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Cgroup manager daemon
# Description:
# The cgroup manager accepts cgroup administration requests
# over dbus, honoring privilege by root users in mapped user
# namespaces over the non-root mapped uids. This allows safe
# nesting of lxc containers by unprivileged users.
### END INIT INFO
# Do NOT "set -e"
PATH=/sbin:/bin
DAEMON=/sbin/cgmanager
NAME=cgmanager
DESC="cgroup management daemon"
BASEOPTS="--daemon -m name=systemd"
test -x $DAEMON || exit 0
PIDFILE=/run/$NAME.pid
if [ -f /etc/default/cgmanager ]; then
# get cgmanager_opts if specified
. /etc/default/cgmanager
fi
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
DAEMON_ARGS="$BASEOPTS $cgmanager_opts $cgm_extra_mounts"
do_stop()
{
# If the cgmanager stops, the proxy must stop
/etc/init.d/cgproxy stop >/dev/null 2>&1 || true
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
# Kill any existing cgproxy
/etc/init.d/cgproxy stop >/dev/null 2>&1 || true
# check whether to start cgproxy or cgmanager
if /sbin/cgproxy --check-master; then
NESTED=yes /etc/init.d/cgproxy start || true && { exit 0; }
fi
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return $?
# Todo - once the compiled cgm is installed we could use it here to ping
# cgmanager as our test for readiness.
sleep 1
}
case "$1" in
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
start)
log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:
[Unit]
Description=Cgroup management daemon
ConditionVirtualization=!container
Before=cgproxy.service
After=local-fs.target
[Service]
Type=simple
ExecStart=/sbin/cgmanager -m name=systemd
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
description "cgroup management daemon"
author "Serge Hallyn <serge.hallyn@ubuntu.com>"
respawn
expect stop
# in trusty /sys/fs/cgroup will be mounted for us.
# prior to saucy, we would need to start on mounted
# MOUNTPOINT=/sys, and mount /sys/fs/cgroup ourselves
start on mounted MOUNTPOINT=/sys/fs/cgroup or virtual-filesystems or starting dbus
stop on runlevel [06]
# to get debug output into /var/log/upstart/cgmanager.log, create/edit
# /etc/default/cgmanager and set cgmanager_opts="--debug"
env cgmanager_opts=""
# unbound subsystems cgmanager should mount. If you need to add more,
# make the list comma-separated, for instance:
# env cgm_extra_mounts="-m name=systemd,name=yyy"
env cgm_extra_mounts="-m name=systemd"
pre-start script
# Kill any existing cgproxy. This is required to allow proper
# respawning of cgmanager.
stop cgproxy >/dev/null 2>&1 || true
# check whether we should start a cgproxy or a cgmanager
if cgproxy --check-master; then
start cgproxy NESTED=yes || true && { stop; exit 0; }
fi
end script
script
[ -r /etc/default/cgmanager ] && . /etc/default/cgmanager
exec /sbin/cgmanager --sigstop $cgmanager_opts $cgm_extra_mounts
end script
post-start script
initctl notify-cgroup-manager-address "unix:path=/sys/fs/cgroup/cgmanager/sock" || true
end script
#! /bin/sh
### BEGIN INIT INFO
# Provides: cgproxy
# Required-Start: cgmanager
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Cgroup manager daemon
# Description:
# The cgroup manager accepts cgroup administration requests
# over dbus, honoring privilege by root users in mapped user
# namespaces over the non-root mapped uids. This allows safe
# nesting of lxc containers by unprivileged users.
### END INIT INFO
# Do NOT "set -e"
PATH=/sbin:/bin
DAEMON=/sbin/cgproxy
NAME=cgproxy
DESC="cgroup management proxy daemon"
BASEOPTS="--daemon"
test -x $DAEMON || exit 0
PIDFILE=/run/$NAME.pid
if [ -f /etc/default/cgmanager ]; then
# get cgmanager_opts if specified
. /etc/default/cgmanager
fi
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
DAEMON_ARGS="$BASEOPTS $cgmanager_opts"
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
# cgproxy should only run on container unless on older kernel
if [ -e /proc/self/ns/pid ] && [ "$NESTED" != "yes" ]; then
log_end_msg 0
exit 0
fi
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return $?
# Todo - once the compiled cgm is installed we could use it here to ping
# cgmanager as our test for readiness.
sleep 1
}
case "$1" in
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
start)
log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:
[Unit]
Description=Cgroup management proxy
ConditionVirtualization=container
After=cgmanager.service
[Service]
Type=simple
ExecStart=/sbin/cgproxy
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
description "cgroup management proxy"
author "Serge Hallyn <serge.hallyn@ubuntu.com>"
respawn
expect stop
emits cgmanager-ready
# in trusty /sys/fs/cgroup will be mounted for us.
# prior to saucy, we would need to start on mounted
# MOUNTPOINT=/sys, and mount /sys/fs/cgroup ourselves
start on started cgmanager
stop on runlevel [06]
# to get debug output into /var/log/upstart/cgproxy.log, create/edit
# /etc/default/cgmanager and set cgmanager_opts="--debug"
env cgmanager_opts=""
env NESTED="no"
pre-start script
# check whether we should start
if [ -e /proc/self/ns/pid ] && [ "$NESTED" = "no" ]; then
initctl emit -n cgmanager-ready
{ stop; exit 0; }
fi
end script
script
[ -r /etc/default/cgmanager ] && . /etc/default/cgmanager
exec /sbin/cgproxy --sigstop $cgmanager_opts
end script
post-start script
initctl emit -n cgmanager-ready
initctl notify-cgroup-manager-address "unix:path=/sys/fs/cgroup/cgmanager/sock" || true
end script
sbin
bin/* usr/bin/
debian/notify-cgmanager.conf usr/share/upstart/sessions/
cgmanager.8
cgproxy.8
cgm.1
This diff is collapsed.
Source: cgmanager
Section: admin
Priority: optional
Maintainer: Serge Hallyn <serge.hallyn@ubuntu.com>
Build-Depends:
autotools-dev,
debhelper (>= 9),
dh-autoreconf,
dh-systemd,
help2man,
libdbus-1-dev,
libnih-dbus-dev,
libnih-dev,
libtool,
nih-dbus-tool,
pkg-config,
Standards-Version: 3.9.5
Homepage: http://cgmanager.linuxcontainers.org/
XS-Testsuite: autopkgtest
Package: cgmanager
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: cgmanager-utils
Conflicts: cgmanager-utils (<< 0.30-1)
Replaces: cgmanager-utils (<< 0.30-1)
Description: Central cgroup manager daemon
cgmanager provides a central cgroup manager daemon and a
per-namespace manager proxy, allowing users and programs
to administrate cgroups through D-Bus requests.
.
This package contains the cgroup management daemon and
proxy.
Package: cgmanager-tests
Architecture: all
Depends: cgmanager, ${misc:Depends}
Description: Central cgroup manager daemon (tests)
cgmanager provides a central cgroup manager daemon and a
per-namespace manager proxy, allowing users and programs
to administrate cgroups through D-Bus requests.
.
This package contains the test scripts.
Package: libcgmanager0
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Multi-Arch: same
Description: Central cgroup manager daemon (client library)
cgmanager provides a central cgroup manager daemon and a
per-namespace manager proxy, allowing users and programs
to administrate cgroups through D-Bus requests.
.
This package contains the shared library.
Package: libcgmanager-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: ${misc:Depends},
libcgmanager0 (= ${binary:Version}),
libdbus-1-dev,
libnih-dbus-dev
Description: Central cgroup manager daemon (dev)
cgmanager provides a central cgroup manager daemon and a
per-namespace manager proxy, allowing users and programs
to administrate cgroups through D-Bus requests.
.
This package contains the static library and C header files
needed for developing software using libcgmanager.
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: cgmanager
Upstream-Contact: cgmanager-devel@lists.linuxcontainers.org
Source: http://cgmanager.linuxcontainers.org/downloads
Files: *
Copyright: 2013-2014 Stéphane Graber <stgraber@ubuntu.com>
2013-2014 Canonical Ltd.
2013 S.Çağlar Onur <caglar@10ur.org>
License: GPL-2
Files: access_checks.c access_checks.h fs.c fs.h
Copyright: 2013-2014 Serge Hallyn <serge.hallyn@ubuntu.com>
2007-2008 IBM Corp.
License: LGPL-2.1+
License: GPL-2
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2, as
published by the Free Software Foundation.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
License: LGPL-2.1+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the full text of the GNU Lesser General Public
License version 2.1 can be found in the file
`/usr/share/common-licenses/LGPL-2.1'.
usr/lib/*/pkgconfig/libcgmanager.pc
usr/include/cgmanager
usr/lib/*/libcgmanager.so
libcgmanager.so.0 libcgmanager0 #MINVER#
cgmanager_chmod@Base 0.28
cgmanager_chmod_scm@Base 0.28
cgmanager_chmod_scm_sync@Base 0.28
cgmanager_chmod_sync@Base 0.28
cgmanager_chown@Base 0.28
cgmanager_chown_scm@Base 0.28
cgmanager_chown_scm_sync@Base 0.28
cgmanager_chown_sync@Base 0.28
cgmanager_create@Base 0.28
cgmanager_create_scm@Base 0.28
cgmanager_create_scm_sync@Base 0.28
cgmanager_create_sync@Base 0.28
cgmanager_get_all@Base 0.28
cgmanager_get_all_sync@Base 0.28
cgmanager_get_api_version@Base 0.28
cgmanager_get_api_version_sync@Base 0.28
cgmanager_get_pid_cgroup@Base 0.28
cgmanager_get_pid_cgroup_abs@Base 0.28
cgmanager_get_pid_cgroup_abs_scm@Base 0.28
cgmanager_get_pid_cgroup_abs_scm_sync@Base 0.28
cgmanager_get_pid_cgroup_abs_sync@Base 0.28
cgmanager_get_pid_cgroup_scm@Base 0.28
cgmanager_get_pid_cgroup_scm_sync@Base 0.28
cgmanager_get_pid_cgroup_sync@Base 0.28
cgmanager_get_tasks@Base 0.28
cgmanager_get_tasks_scm@Base 0.28
cgmanager_get_tasks_scm_sync@Base 0.28
cgmanager_get_tasks_sync@Base 0.28
cgmanager_get_value@Base 0.28
cgmanager_get_value_scm@Base 0.28
cgmanager_get_value_scm_sync@Base 0.28
cgmanager_get_value_sync@Base 0.28
cgmanager_interfaces@Base 0.28
cgmanager_list_children@Base 0.28
cgmanager_list_children_scm@Base 0.28
cgmanager_list_children_scm_sync@Base 0.28
cgmanager_list_children_sync@Base 0.28
cgmanager_move_pid@Base 0.28
cgmanager_move_pid_abs@Base 0.28
cgmanager_move_pid_abs_scm@Base 0.28
cgmanager_move_pid_abs_scm_sync@Base 0.28
cgmanager_move_pid_abs_sync@Base 0.28
cgmanager_move_pid_scm@Base 0.28
cgmanager_move_pid_scm_sync@Base 0.28
cgmanager_move_pid_sync@Base 0.28
cgmanager_org_linuxcontainers_cgmanager0_0@Base 0.28
cgmanager_ping@Base 0.28
cgmanager_ping_sync@Base 0.28
cgmanager_remove@Base 0.28
cgmanager_remove_on_empty@Base 0.28
cgmanager_remove_on_empty_scm@Base 0.28
cgmanager_remove_on_empty_scm_sync@Base 0.28
cgmanager_remove_on_empty_sync@Base 0.28
cgmanager_remove_scm@Base 0.28
cgmanager_remove_scm_sync@Base 0.28
cgmanager_remove_sync@Base 0.28
cgmanager_set_value@Base 0.28
cgmanager_set_value_scm@Base 0.28
cgmanager_set_value_scm_sync@Base 0.28
cgmanager_set_value_sync@Base 0.28
cgmanager_get_tasks_recursive@Base 0.32
cgmanager_get_tasks_recursive_scm@Base 0.32
cgmanager_get_tasks_recursive_scm_sync@Base 0.32
cgmanager_get_tasks_recursive_sync@Base 0.32
cgmanager_list_controllers@Base 0.32
cgmanager_list_controllers_sync@Base 0.32
cgmanager_prune@Base 0.32
cgmanager_prune_scm@Base 0.32
cgmanager_prune_scm_sync@Base 0.32
cgmanager_prune_sync@Base 0.32
start on startup
description "Notify cgroup manager address"
task
script
initctl notify-cgroup-manager-address "unix:path=/sys/fs/cgroup/cgmanager/sock" || true
end script
From 33c51da88a480d70103d264a98c70d277b98f312 Mon Sep 17 00:00:00 2001
From: Cameron Norman <camerontnorman@gmail.com>
Date: Sun, 12 Oct 2014 10:38:47 -0700
Subject: [PATCH 1/2] do_move_pid_main: don't break out of while loop on error;
return error after
---
cgmanager.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/cgmanager.c b/cgmanager.c
index e77fd64..28a9264 100644
--- a/cgmanager.c
+++ b/cgmanager.c
@@ -188,6 +188,7 @@ int do_move_pid_main(const char *controller, const char *cgroup, struct ucred p,
nih_local char *c = NULL;
char *tok;
int ret;
+ int while_ret = 0;
if (!sane_cgroup(cgroup)) {
nih_error("%s: unsafe cgroup", __func__);
@@ -214,15 +215,16 @@ int do_move_pid_main(const char *controller, const char *cgroup, struct ucred p,
tok = strtok(c, ",");
while (tok) {
ret = per_ctrl_move_pid_main(tok, cgroup, p, r, v, escape);
- if (ret == -2) // permission denied - ignore for group requests
- goto next;
- if (ret != 0)
- return -1;
-next:
+
+ /* Save error for later (but ignore permission denied, -2),
+ but try to complete rest of moves anyway */
+ if (ret != 0 && ret != -2)
+ while_ret = -1;
+
tok = strtok(NULL, ",");
}
- return 0;
+ return while_ret;
}
int move_pid_main(const char *controller, const char *cgroup, struct ucred p,
--
2.1.0
From 7aafbaf9983412c70a4e687fcf37ae16864a6b4a Mon Sep 17 00:00:00 2001
From: Marcin Szewczyk <marcin.szewczyk@wodny.org>
Date: Sun, 12 Oct 2014 18:45:58 +0200
Subject: [PATCH 2/2] check "enabled" column when parsing /proc/cgroups
---
fs.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/fs.c b/fs.c
index 7568ce5..7b10593 100644
--- a/fs.c
+++ b/fs.c
@@ -554,6 +554,15 @@ static bool collect_kernel_subsystems(void)
continue;
*p = '\0';
+ // TODO: How stable is /proc/cgroups interface?
+ // Check the 'enabled' column
+ p = strrchr(p+1, '\t');
+ if (!p)
+ continue;
+
+ if (*(p+1) != '1')
+ continue;
+
if (!save_mount_subsys(line)) {
nih_fatal("Error storing subsystem %s", line);
goto out;
--
2.1.0
From 6267916d4ea939794e0583cd8b08bd0b9594a6e2 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@ubuntu.com>
Date: Wed, 26 Nov 2014 01:00:10 -0600
Subject: [PATCH 1/1] make sure to check cgroup hierarchy
Some cases weren't doing that, although at least those were still
checking for proper ownership.
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
---
cgmanager.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 80 insertions(+), 5 deletions(-)
Index: cgmanager-0.33/cgmanager.c
===================================================================
--- cgmanager-0.33.orig/cgmanager.c
+++ cgmanager-0.33/cgmanager.c
@@ -558,13 +558,20 @@ next:
int get_value_main(void *parent, const char *controller, const char *cgroup,
const char *key, struct ucred p, struct ucred r, char **value)
{
- char path[MAXPATHLEN];
+ char pcgpath[MAXPATHLEN], path[MAXPATHLEN];
if (!sane_cgroup(cgroup)) {
nih_error("%s: unsafe cgroup", __func__);
return -1;
}
+ // Get p's current cgroup in pcgpath
+ if (!compute_pid_cgroup(p.pid, controller, "", pcgpath, NULL)) {
+ nih_error("%s: Could not determine the proxy's cgroup for %s",
+ __func__, controller);
+ return -1;
+ }
+
if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
nih_error("%s: Could not determine the requested cgroup (%s:%s)",
__func__, controller, cgroup);
@@ -577,6 +584,14 @@ int get_value_main(void *parent, const c
return -1;
}
+ // Make sure target cgroup is under proxy's
+ int plen = strlen(pcgpath);
+ if (strncmp(pcgpath, path, plen) != 0) {
+ nih_error("%s: target cgroup is not below r (%d)'s", __func__,
+ r.pid);
+ return -1;
+ }
+
/* append the filename */
if (strlen(path) + strlen(key) + 2 > MAXPATHLEN) {
nih_error("%s: filename too long for cgroup %s key %s", __func__, path, key);
@@ -608,19 +623,34 @@ int set_value_main(const char *controlle
struct ucred r)