]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/cgroup.c
add some traces in the code for the logger
[mirror_lxc.git] / src / lxc / cgroup.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #undef _GNU_SOURCE
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <mntent.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/param.h>
35 #include <sys/inotify.h>
36 #include <netinet/in.h>
37 #include <net/if.h>
38
39 #include "error.h"
40
41 #include <lxc/lxc.h>
42 #include <lxc/log.h>
43
44 lxc_log_define(lxc_cgroup, lxc);
45
46 #define MTAB "/etc/mtab"
47
48 static int get_cgroup_mount(const char *mtab, char *mnt)
49 {
50 struct mntent *mntent;
51 FILE *file = NULL;
52 int err = -1;
53
54 file = setmntent(mtab, "r");
55 if (!file) {
56 SYSERROR("failed to open %s", mtab);
57 goto out;
58 }
59
60 while ((mntent = getmntent(file))) {
61
62 /* there is a cgroup mounted named "lxc" */
63 if (!strcmp(mntent->mnt_fsname, "lxc") &&
64 !strcmp(mntent->mnt_type, "cgroup")) {
65 strcpy(mnt, mntent->mnt_dir);
66 err = 0;
67 break;
68 }
69
70 /* fallback to the first non-lxc cgroup found */
71 if (!strcmp(mntent->mnt_type, "cgroup") && err) {
72 strcpy(mnt, mntent->mnt_dir);
73 err = 0;
74 }
75 };
76
77 DEBUG("using cgroup mounted at '%s'", mnt);
78
79 fclose(file);
80 out:
81 return err;
82 }
83
84 int lxc_rename_nsgroup(const char *name, pid_t pid)
85 {
86 char oldname[MAXPATHLEN];
87 char newname[MAXPATHLEN];
88 char cgroup[MAXPATHLEN];
89 int ret;
90
91 if (get_cgroup_mount(MTAB, cgroup)) {
92 ERROR("cgroup is not mounted");
93 return -1;
94 }
95
96 snprintf(oldname, MAXPATHLEN, "%s/%d", cgroup, pid);
97 snprintf(newname, MAXPATHLEN, "%s/%s", cgroup, name);
98
99 /* there is a previous cgroup, assume it is empty, otherwise
100 * that fails */
101 if (!access(newname, F_OK)) {
102 ret = rmdir(newname);
103 if (ret) {
104 SYSERROR("failed to remove previous cgroup '%s'",
105 newname);
106 return ret;
107 }
108 }
109
110 ret = rename(oldname, newname);
111 if (ret)
112 SYSERROR("failed to rename cgroup %s->%s", oldname, newname);
113 else
114 DEBUG("'%s' renamed to '%s'", oldname, newname);
115
116 return ret;
117 }
118
119 int lxc_link_nsgroup(const char *name)
120 {
121 char lxc[MAXPATHLEN];
122 char nsgroup[MAXPATHLEN];
123 char cgroup[MAXPATHLEN];
124 int ret;
125
126 if (get_cgroup_mount(MTAB, cgroup)) {
127 ERROR("cgroup is not mounted");
128 return -1;
129 }
130
131 snprintf(lxc, MAXPATHLEN, LXCPATH "/%s/nsgroup", name);
132 snprintf(nsgroup, MAXPATHLEN, "%s/%s", cgroup, name);
133
134 unlink(lxc);
135 ret = symlink(nsgroup, lxc);
136 if (ret)
137 SYSERROR("failed to create symlink %s->%s", nsgroup, lxc);
138 else
139 DEBUG("'%s' linked to '%s'", nsgroup, lxc);
140
141 return ret;
142 }
143
144 int lxc_unlink_nsgroup(const char *name)
145 {
146 char nsgroup[MAXPATHLEN];
147 char path[MAXPATHLEN];
148 ssize_t len;
149
150 snprintf(nsgroup, MAXPATHLEN, LXCPATH "/%s/nsgroup", name);
151
152 len = readlink(nsgroup, path, MAXPATHLEN-1);
153 if (len > 0) {
154 path[len] = '\0';
155 rmdir(path);
156 }
157
158 DEBUG("unlinking '%s'", nsgroup);
159
160 return unlink(nsgroup);
161 }
162
163 int lxc_cgroup_set(const char *name, const char *subsystem, const char *value)
164 {
165 int fd, ret = -1;
166 char path[MAXPATHLEN];
167
168 snprintf(path, MAXPATHLEN, LXCPATH "/%s/nsgroup/%s", name, subsystem);
169
170 fd = open(path, O_WRONLY);
171 if (fd < 0) {
172 ERROR("open %s : %s", path, strerror(errno));
173 return -1;
174 }
175
176 if (write(fd, value, strlen(value)) < 0) {
177 ERROR("write %s : %s", path, strerror(errno));
178 goto out;
179 }
180
181 ret = 0;
182 out:
183 close(fd);
184 return ret;
185 }
186
187 int lxc_cgroup_get(const char *name, const char *subsystem,
188 char *value, size_t len)
189 {
190 int fd, ret = -1;
191 char path[MAXPATHLEN];
192
193 snprintf(path, MAXPATHLEN, LXCPATH "/%s/nsgroup/%s", name, subsystem);
194
195 fd = open(path, O_RDONLY);
196 if (fd < 0) {
197 ERROR("open %s : %s", path, strerror(errno));
198 return -1;
199 }
200
201 if (read(fd, value, len) < 0) {
202 ERROR("read %s : %s", path, strerror(errno));
203 goto out;
204 }
205
206 ret = 0;
207 out:
208 close(fd);
209 return ret;
210 }