]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/initutils.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "initutils.h"
27 lxc_log_define(lxc_initutils
, lxc
);
29 static int mount_fs(const char *source
, const char *target
, const char *type
)
31 /* the umount may fail */
33 WARN("Failed to unmount %s : %s", target
, strerror(errno
));
35 if (mount(source
, target
, type
, 0, NULL
)) {
36 ERROR("Failed to mount %s : %s", target
, strerror(errno
));
40 DEBUG("'%s' mounted on '%s'", source
, target
);
45 extern void lxc_setup_fs(void)
47 if (mount_fs("proc", "/proc", "proc"))
48 INFO("Failed to remount proc");
50 /* if /dev has been populated by us, /dev/shm does not exist */
51 if (access("/dev/shm", F_OK
) && mkdir("/dev/shm", 0777))
52 INFO("Failed to create /dev/shm");
54 /* if we can't mount /dev/shm, continue anyway */
55 if (mount_fs("shmfs", "/dev/shm", "tmpfs"))
56 INFO("Failed to mount /dev/shm");
58 /* If we were able to mount /dev/shm, then /dev exists */
59 /* Sure, but it's read-only per config :) */
60 if (access("/dev/mqueue", F_OK
) && mkdir("/dev/mqueue", 0666)) {
61 DEBUG("Failed to create '/dev/mqueue'");
65 /* continue even without posix message queue support */
66 if (mount_fs("mqueue", "/dev/mqueue", "mqueue"))
67 INFO("Failed to mount /dev/mqueue");
70 static char *copy_global_config_value(char *p
)
77 if (p
[len
-1] == '\n') {
81 retbuf
= malloc(len
+1);
88 const char *lxc_global_config_value(const char *option_name
)
90 static const char * const options
[][2] = {
91 { "lxc.bdev.lvm.vg", DEFAULT_VG
},
92 { "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL
},
93 { "lxc.bdev.zfs.root", DEFAULT_ZFSROOT
},
94 { "lxc.bdev.rbd.rbdpool", DEFAULT_RBDPOOL
},
95 { "lxc.lxcpath", NULL
},
96 { "lxc.default_config", NULL
},
97 { "lxc.cgroup.pattern", NULL
},
98 { "lxc.cgroup.use", NULL
},
102 /* placed in the thread local storage pool for non-bionic targets */
104 static __thread
const char *values
[sizeof(options
) / sizeof(options
[0])] = { 0 };
106 static const char *values
[sizeof(options
) / sizeof(options
[0])] = { 0 };
109 /* user_config_path is freed as soon as it is used */
110 char *user_config_path
= NULL
;
113 * The following variables are freed at bottom unconditionally.
114 * So NULL the value if it is to be returned to the caller
116 char *user_default_config_path
= NULL
;
117 char *user_lxc_path
= NULL
;
118 char *user_cgroup_pattern
= NULL
;
121 const char *user_home
= getenv("HOME");
125 user_config_path
= malloc(sizeof(char) * (22 + strlen(user_home
)));
126 user_default_config_path
= malloc(sizeof(char) * (26 + strlen(user_home
)));
127 user_lxc_path
= malloc(sizeof(char) * (19 + strlen(user_home
)));
129 sprintf(user_config_path
, "%s/.config/lxc/lxc.conf", user_home
);
130 sprintf(user_default_config_path
, "%s/.config/lxc/default.conf", user_home
);
131 sprintf(user_lxc_path
, "%s/.local/share/lxc/", user_home
);
132 user_cgroup_pattern
= strdup("lxc/%n");
135 user_config_path
= strdup(LXC_GLOBAL_CONF
);
136 user_default_config_path
= strdup(LXC_DEFAULT_CONFIG
);
137 user_lxc_path
= strdup(LXCPATH
);
138 user_cgroup_pattern
= strdup(DEFAULT_CGROUP_PATTERN
);
141 const char * const (*ptr
)[2];
143 char buf
[1024], *p
, *p2
;
146 for (i
= 0, ptr
= options
; (*ptr
)[0]; ptr
++, i
++) {
147 if (!strcmp(option_name
, (*ptr
)[0]))
151 free(user_config_path
);
152 free(user_default_config_path
);
154 free(user_cgroup_pattern
);
160 free(user_config_path
);
161 free(user_default_config_path
);
163 free(user_cgroup_pattern
);
167 fin
= fopen_cloexec(user_config_path
, "r");
168 free(user_config_path
);
170 while (fgets(buf
, 1024, fin
)) {
173 p
= strstr(buf
, option_name
);
176 /* see if there was just white space in front
179 for (p2
= buf
; p2
< p
; p2
++) {
180 if (*p2
!= ' ' && *p2
!= '\t')
188 /* see if there was just white space after
191 for (p2
+= strlen(option_name
); p2
< p
; p2
++) {
192 if (*p2
!= ' ' && *p2
!= '\t')
198 while (*p
&& (*p
== ' ' || *p
== '\t')) p
++;
202 if (strcmp(option_name
, "lxc.lxcpath") == 0) {
204 user_lxc_path
= copy_global_config_value(p
);
205 remove_trailing_slashes(user_lxc_path
);
206 values
[i
] = user_lxc_path
;
207 user_lxc_path
= NULL
;
211 values
[i
] = copy_global_config_value(p
);
215 /* could not find value, use default */
216 if (strcmp(option_name
, "lxc.lxcpath") == 0) {
217 remove_trailing_slashes(user_lxc_path
);
218 values
[i
] = user_lxc_path
;
219 user_lxc_path
= NULL
;
221 else if (strcmp(option_name
, "lxc.default_config") == 0) {
222 values
[i
] = user_default_config_path
;
223 user_default_config_path
= NULL
;
225 else if (strcmp(option_name
, "lxc.cgroup.pattern") == 0) {
226 values
[i
] = user_cgroup_pattern
;
227 user_cgroup_pattern
= NULL
;
230 values
[i
] = (*ptr
)[1];
232 /* special case: if default value is NULL,
233 * and there is no config, don't view that
242 free(user_cgroup_pattern
);
243 free(user_default_config_path
);
249 extern void remove_trailing_slashes(char *p
)
252 while (--l
>= 0 && (p
[l
] == '/' || p
[l
] == '\n'))
256 FILE *fopen_cloexec(const char *path
, const char *mode
)
264 if (!strncmp(mode
, "r+", 2)) {
267 } else if (!strncmp(mode
, "r", 1)) {
268 open_mode
= O_RDONLY
;
270 } else if (!strncmp(mode
, "w+", 2)) {
271 open_mode
= O_RDWR
| O_TRUNC
| O_CREAT
;
273 } else if (!strncmp(mode
, "w", 1)) {
274 open_mode
= O_WRONLY
| O_TRUNC
| O_CREAT
;
276 } else if (!strncmp(mode
, "a+", 2)) {
277 open_mode
= O_RDWR
| O_CREAT
| O_APPEND
;
279 } else if (!strncmp(mode
, "a", 1)) {
280 open_mode
= O_WRONLY
| O_CREAT
| O_APPEND
;
283 for (; mode
[step
]; step
++)
284 if (mode
[step
] == 'x')
286 open_mode
|= O_CLOEXEC
;
288 fd
= open(path
, open_mode
, 0666);
292 ret
= fdopen(fd
, mode
);