2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
5 * (C) Copyright Canonical, Inc, 2014
8 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * Serge Hallyn <serge.hallyn@ubuntu.com>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
37 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/inotify.h>
41 #include <sys/mount.h>
42 #include <netinet/in.h>
46 #include <nih-dbus/dbus_connection.h>
47 #include <cgmanager/cgmanager-client.h>
48 #include <nih/alloc.h>
49 #include <nih/error.h>
50 #include <nih/string.h>
52 #include "cgmanager.h"
54 static NihDBusProxy
*cgroup_manager
= NULL
;
55 static int32_t api_version
;
57 static void cgm_dbus_disconnect(void)
60 dbus_connection_flush(cgroup_manager
->connection
);
61 dbus_connection_close(cgroup_manager
->connection
);
62 nih_free(cgroup_manager
);
64 cgroup_manager
= NULL
;
67 #define CGMANAGER_DBUS_SOCK "unix:path=/sys/fs/cgroup/cgmanager/sock"
68 static bool cgm_dbus_connect(void)
71 static DBusConnection
*connection
;
73 dbus_error_init(&dbus_error
);
75 connection
= dbus_connection_open_private(CGMANAGER_DBUS_SOCK
, &dbus_error
);
77 fprintf(stderr
, "Failed opening dbus connection: %s: %s",
78 dbus_error
.name
, dbus_error
.message
);
79 dbus_error_free(&dbus_error
);
82 dbus_connection_set_exit_on_disconnect(connection
, FALSE
);
83 dbus_error_free(&dbus_error
);
84 cgroup_manager
= nih_dbus_proxy_new(NULL
, connection
,
86 "/org/linuxcontainers/cgmanager", NULL
, NULL
);
87 dbus_connection_unref(connection
);
88 if (!cgroup_manager
) {
90 nerr
= nih_error_get();
91 fprintf(stderr
, "Error opening cgmanager proxy: %s", nerr
->message
);
93 cgm_dbus_disconnect();
97 // get the api version
98 if (cgmanager_get_api_version_sync(NULL
, cgroup_manager
, &api_version
) != 0) {
100 nerr
= nih_error_get();
101 fprintf(stderr
, "Error cgroup manager api version: %s", nerr
->message
);
103 cgm_dbus_disconnect();
109 bool cgm_get_controllers(char ***contrls
)
111 if (!cgm_dbus_connect()) {
115 if ( cgmanager_list_controllers_sync(NULL
, cgroup_manager
, contrls
) != 0 ) {
117 nerr
= nih_error_get();
118 fprintf(stderr
, "call to list_controllers failed: %s", nerr
->message
);
120 cgm_dbus_disconnect();
124 cgm_dbus_disconnect();
128 bool cgm_list_keys(const char *controller
, const char *cgroup
, struct cgm_keys
***keys
)
130 if (!cgm_dbus_connect()) {
134 if ( cgmanager_list_keys_sync(NULL
, cgroup_manager
, controller
, cgroup
,
135 (CgmanagerListKeysOutputElement
***)keys
) != 0 ) {
137 nerr
= nih_error_get();
138 fprintf(stderr
, "call to list_keys failed: %s", nerr
->message
);
140 cgm_dbus_disconnect();
144 cgm_dbus_disconnect();
148 bool cgm_list_children(const char *controller
, const char *cgroup
, char ***list
)
150 if (!cgm_dbus_connect()) {
154 if ( cgmanager_list_children_sync(NULL
, cgroup_manager
, controller
, cgroup
, list
) != 0 ) {
156 nerr
= nih_error_get();
157 fprintf(stderr
, "call to list_children failed: %s", nerr
->message
);
159 cgm_dbus_disconnect();
163 cgm_dbus_disconnect();
167 char *cgm_get_pid_cgroup(pid_t pid
, const char *controller
)
171 if (!cgm_dbus_connect()) {
175 if ( cgmanager_get_pid_cgroup_sync(NULL
, cgroup_manager
, controller
, pid
, &output
) != 0 ) {
177 nerr
= nih_error_get();
178 fprintf(stderr
, "call to get_pid_cgroup failed: %s", nerr
->message
);
180 cgm_dbus_disconnect();
184 cgm_dbus_disconnect();
188 bool cgm_escape_cgroup(void)
190 if (!cgm_dbus_connect()) {
194 if ( cgmanager_move_pid_abs_sync(NULL
, cgroup_manager
, "all", "/", (int32_t) getpid()) != 0 ) {
196 nerr
= nih_error_get();
197 fprintf(stderr
, "call to move_pid_abs failed: %s", nerr
->message
);
199 cgm_dbus_disconnect();
203 cgm_dbus_disconnect();