]> git.proxmox.com Git - mirror_lxcfs.git/blob - cgmanager.c
add autoconf boilerplate and cgmanager fns
[mirror_lxcfs.git] / cgmanager.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 * (C) Copyright Canonical, Inc, 2014
6 *
7 * Authors:
8 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * Serge Hallyn <serge.hallyn@ubuntu.com>
10 *
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.
15 *
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.
20 *
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
24 */
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <dirent.h>
33 #include <fcntl.h>
34 #include <ctype.h>
35 #include <pthread.h>
36 #include <grp.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/param.h>
40 #include <sys/inotify.h>
41 #include <sys/mount.h>
42 #include <netinet/in.h>
43 #include <net/if.h>
44 #include <stdbool.h>
45
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>
51
52 #include "cgmanager.h"
53
54 static NihDBusProxy *cgroup_manager = NULL;
55 static int32_t api_version;
56
57 static void cgm_dbus_disconnect(void)
58 {
59 if (cgroup_manager) {
60 dbus_connection_flush(cgroup_manager->connection);
61 dbus_connection_close(cgroup_manager->connection);
62 nih_free(cgroup_manager);
63 }
64 cgroup_manager = NULL;
65 }
66
67 #define CGMANAGER_DBUS_SOCK "unix:path=/sys/fs/cgroup/cgmanager/sock"
68 static bool cgm_dbus_connect(void)
69 {
70 DBusError dbus_error;
71 static DBusConnection *connection;
72
73 dbus_error_init(&dbus_error);
74
75 connection = dbus_connection_open_private(CGMANAGER_DBUS_SOCK, &dbus_error);
76 if (!connection) {
77 fprintf(stderr, "Failed opening dbus connection: %s: %s",
78 dbus_error.name, dbus_error.message);
79 dbus_error_free(&dbus_error);
80 return false;
81 }
82 dbus_connection_set_exit_on_disconnect(connection, FALSE);
83 dbus_error_free(&dbus_error);
84 cgroup_manager = nih_dbus_proxy_new(NULL, connection,
85 NULL /* p2p */,
86 "/org/linuxcontainers/cgmanager", NULL, NULL);
87 dbus_connection_unref(connection);
88 if (!cgroup_manager) {
89 NihError *nerr;
90 nerr = nih_error_get();
91 fprintf(stderr, "Error opening cgmanager proxy: %s", nerr->message);
92 nih_free(nerr);
93 cgm_dbus_disconnect();
94 return false;
95 }
96
97 // get the api version
98 if (cgmanager_get_api_version_sync(NULL, cgroup_manager, &api_version) != 0) {
99 NihError *nerr;
100 nerr = nih_error_get();
101 fprintf(stderr, "Error cgroup manager api version: %s", nerr->message);
102 nih_free(nerr);
103 cgm_dbus_disconnect();
104 return false;
105 }
106 return true;
107 }
108
109 bool cgm_get_controllers(char ***contrls)
110 {
111 if (!cgm_dbus_connect()) {
112 return false;
113 }
114
115 if ( cgmanager_list_controllers_sync(NULL, cgroup_manager, contrls) != 0 ) {
116 NihError *nerr;
117 nerr = nih_error_get();
118 fprintf(stderr, "call to list_controllers failed: %s", nerr->message);
119 nih_free(nerr);
120 cgm_dbus_disconnect();
121 return false;
122 }
123
124 cgm_dbus_disconnect();
125 return true;
126 }
127
128 bool cgm_list_keys(const char *controller, const char *cgroup, struct cgm_keys ***keys)
129 {
130 if (!cgm_dbus_connect()) {
131 return false;
132 }
133
134 if ( cgmanager_list_keys_sync(NULL, cgroup_manager, controller, cgroup,
135 (CgmanagerListKeysOutputElement ***)keys) != 0 ) {
136 NihError *nerr;
137 nerr = nih_error_get();
138 fprintf(stderr, "call to list_keys failed: %s", nerr->message);
139 nih_free(nerr);
140 cgm_dbus_disconnect();
141 return false;
142 }
143
144 cgm_dbus_disconnect();
145 return true;
146 }
147
148 bool cgm_list_children(const char *controller, const char *cgroup, char ***list)
149 {
150 if (!cgm_dbus_connect()) {
151 return false;
152 }
153
154 if ( cgmanager_list_children_sync(NULL, cgroup_manager, controller, cgroup, list) != 0 ) {
155 NihError *nerr;
156 nerr = nih_error_get();
157 fprintf(stderr, "call to list_children failed: %s", nerr->message);
158 nih_free(nerr);
159 cgm_dbus_disconnect();
160 return false;
161 }
162
163 cgm_dbus_disconnect();
164 return true;
165 }
166
167 char *cgm_get_pid_cgroup(pid_t pid, const char *controller)
168 {
169 char *output = NULL;
170
171 if (!cgm_dbus_connect()) {
172 return NULL;
173 }
174
175 if ( cgmanager_get_pid_cgroup_sync(NULL, cgroup_manager, controller, pid, &output) != 0 ) {
176 NihError *nerr;
177 nerr = nih_error_get();
178 fprintf(stderr, "call to get_pid_cgroup failed: %s", nerr->message);
179 nih_free(nerr);
180 cgm_dbus_disconnect();
181 return NULL;
182 }
183
184 cgm_dbus_disconnect();
185 return output;
186 }
187
188 bool cgm_escape_cgroup(void)
189 {
190 if (!cgm_dbus_connect()) {
191 return false;
192 }
193
194 if ( cgmanager_move_pid_abs_sync(NULL, cgroup_manager, "all", "/", (int32_t) getpid()) != 0 ) {
195 NihError *nerr;
196 nerr = nih_error_get();
197 fprintf(stderr, "call to move_pid_abs failed: %s", nerr->message);
198 nih_free(nerr);
199 cgm_dbus_disconnect();
200 return false;
201 }
202
203 cgm_dbus_disconnect();
204 return true;
205 }