[lxc-devel] [PATCH RFC] cgmanager: don't stay connected
Serge Hallyn
serge.hallyn at ubuntu.com
Fri Feb 28 23:50:22 UTC 2014
There are only a few times when we need to be connected to the
cgroup manager:
* when starting a container, from cgm_init until we've set cgroup limits
* when changing a cgroup setting (while running)
* when cleaning up (when shutting down)
* around the cgroup entering at attach
So only connect/disconnect the cgmanager socket on-demand as
needed. This should have a few benefits.
1. Reduce the # open fds when many containers are running
2. if cgmanager is stopped and restarted, the container
doesn't have to deal with the disconnection.
This is currently RFC. There are a few issues outstanding:
1. the cgm_set and cgm_get may need to be made thread-safe.
2. a non-daemonized start which fails while cgm is connected,
will not disconnected.
Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
src/lxc/cgmanager.c | 19 +++++++++++++++++--
src/lxc/cgroup.c | 6 ++++++
src/lxc/cgroup.h | 1 +
src/lxc/start.c | 2 ++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/src/lxc/cgmanager.c b/src/lxc/cgmanager.c
index 7391675..7be94a7 100644
--- a/src/lxc/cgmanager.c
+++ b/src/lxc/cgmanager.c
@@ -92,13 +92,13 @@ static NihDBusProxy *cgroup_manager = NULL;
static struct cgroup_ops cgmanager_ops;
static int nr_subsystems;
static char **subsystems;
+static DBusConnection *connection;
#define CGMANAGER_DBUS_SOCK "unix:path=/sys/fs/cgroup/cgmanager/sock"
static void cgm_dbus_disconnected(DBusConnection *connection);
static bool cgm_dbus_connect(void)
{
DBusError dbus_error;
- DBusConnection *connection;
dbus_error_init(&dbus_error);
lock_mutex(&thread_mutex);
@@ -118,7 +118,6 @@ static bool cgm_dbus_connect(void)
cgroup_manager = nih_dbus_proxy_new(NULL, connection,
NULL /* p2p */,
"/org/linuxcontainers/cgmanager", NULL, NULL);
- dbus_connection_unref(connection);
if (!cgroup_manager) {
NihError *nerr;
nerr = nih_error_get();
@@ -145,13 +144,19 @@ static void cgm_dbus_disconnect(void)
if (cgroup_manager)
nih_free(cgroup_manager);
cgroup_manager = NULL;
+ dbus_connection_unref(connection);
+ connection = NULL;
unlock_mutex(&thread_mutex);
}
static void cgm_dbus_disconnected(DBusConnection *connection)
{
+ lock_mutex(&thread_mutex);
WARN("Cgroup manager connection was terminated");
cgroup_manager = NULL;
+ dbus_connection_unref(connection);
+ connection = NULL;
+ unlock_mutex(&thread_mutex);
if (cgm_dbus_connect()) {
INFO("New cgroup manager connection was opened");
} else {
@@ -398,6 +403,7 @@ static void *cgm_init(const char *name)
{
struct cgm_data *d;
+ cgm_dbus_connect();
d = malloc(sizeof(*d));
if (!d)
return NULL;
@@ -430,6 +436,7 @@ static void cgm_destroy(void *hdata)
if (!d)
return;
+ cgm_dbus_connect();
for (i = 0; i < nr_subsystems; i++)
cgm_remove_cgroup(subsystems[i], d->cgroup_path);
@@ -437,6 +444,7 @@ static void cgm_destroy(void *hdata)
if (d->cgroup_path)
free(d->cgroup_path);
free(d);
+ cgm_dbus_disconnect();
}
/*
@@ -602,6 +610,7 @@ static int cgm_get(const char *filename, char *value, size_t len, const char *na
cgroup = lxc_cmd_get_cgroup_path(name, lxcpath, controller);
if (!cgroup)
return -1;
+ cgm_dbus_connect();
lock_mutex(&thread_mutex);
if (cgmanager_get_value_sync(NULL, cgroup_manager, controller, cgroup, filename, &result) != 0) {
/*
@@ -614,9 +623,11 @@ static int cgm_get(const char *filename, char *value, size_t len, const char *na
nih_free(nerr);
free(cgroup);
unlock_mutex(&thread_mutex);
+ cgm_dbus_disconnect();
return -1;
}
unlock_mutex(&thread_mutex);
+ cgm_dbus_disconnect();
free(cgroup);
newlen = strlen(result);
if (!value) {
@@ -675,7 +686,9 @@ static int cgm_set(const char *filename, const char *value, const char *name, co
controller, lxcpath, name);
return -1;
}
+ cgm_dbus_connect();
ret = cgm_do_set(controller, filename, cgroup, value);
+ cgm_dbus_disconnect();
free(cgroup);
return ret;
}
@@ -875,8 +888,10 @@ static bool cgm_attach(const char *name, const char *lxcpath, pid_t pid)
goto out;
}
+ cgm_dbus_connect();
if (!(pass = do_cgm_enter(pid, cgroup)))
ERROR("Failed to enter group %s", cgroup);
+ cgm_dbus_disconnect();
out:
free(cgroup);
diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
index d931520..23c8c96 100644
--- a/src/lxc/cgroup.c
+++ b/src/lxc/cgroup.c
@@ -175,3 +175,9 @@ void restart_cgroups(void)
ops = NULL;
cgroup_ops_init();
}
+
+void cgroup_disconnect(void)
+{
+ if (ops && ops->disconnect)
+ ops->disconnect();
+}
diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h
index e3cf6e0..8cba030 100644
--- a/src/lxc/cgroup.h
+++ b/src/lxc/cgroup.h
@@ -66,5 +66,6 @@ extern int cgroup_nrtasks(struct lxc_handler *handler);
extern const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem);
extern bool cgroup_unfreeze(struct lxc_handler *handler);
extern void restart_cgroups(void);
+extern void cgroup_disconnect(void);
#endif
diff --git a/src/lxc/start.c b/src/lxc/start.c
index fe3d093..97c8207 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -952,6 +952,8 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net;
}
+ cgroup_disconnect();
+
/* Tell the child to complete its initialization and wait for
* it to exec or return an error. (the child will never
* return LXC_SYNC_POST_CGROUP+1. It will either close the
--
1.9.0
More information about the lxc-devel
mailing list