Quoting Serge Hallyn ([email protected]): > 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.
Next week I will add a cgmanager socket refcount to allow parallel threads using cgm_get/set, and put the cgmanager sock reference at end of failed start and attach. > Signed-off-by: Serge Hallyn <[email protected]> > --- > 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 > > _______________________________________________ > lxc-devel mailing list > [email protected] > http://lists.linuxcontainers.org/listinfo/lxc-devel _______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
