]>
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 we can't mount /dev/shm, continue anyway */
51 if (mount_fs("shmfs", "/dev/shm", "tmpfs"))
52 INFO("failed to mount /dev/shm");
54 /* If we were able to mount /dev/shm, then /dev exists */
55 /* Sure, but it's read-only per config :) */
56 if (access("/dev/mqueue", F_OK
) && mkdir("/dev/mqueue", 0666)) {
57 DEBUG("failed to create '/dev/mqueue'");
61 /* continue even without posix message queue support */
62 if (mount_fs("mqueue", "/dev/mqueue", "mqueue"))
63 INFO("failed to mount /dev/mqueue");
66 static char *copy_global_config_value(char *p
)
73 if (p
[len
-1] == '\n') {
77 retbuf
= malloc(len
+1);
84 const char *lxc_global_config_value(const char *option_name
)
86 static const char * const options
[][2] = {
87 { "lxc.bdev.lvm.vg", DEFAULT_VG
},
88 { "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL
},
89 { "lxc.bdev.zfs.root", DEFAULT_ZFSROOT
},
90 { "lxc.lxcpath", NULL
},
91 { "lxc.default_config", NULL
},
92 { "lxc.cgroup.pattern", NULL
},
93 { "lxc.cgroup.use", NULL
},
97 /* placed in the thread local storage pool for non-bionic targets */
99 static __thread
const char *values
[sizeof(options
) / sizeof(options
[0])] = { 0 };
101 static const char *values
[sizeof(options
) / sizeof(options
[0])] = { 0 };
104 /* user_config_path is freed as soon as it is used */
105 char *user_config_path
= NULL
;
108 * The following variables are freed at bottom unconditionally.
109 * So NULL the value if it is to be returned to the caller
111 char *user_default_config_path
= NULL
;
112 char *user_lxc_path
= NULL
;
113 char *user_cgroup_pattern
= NULL
;
116 const char *user_home
= getenv("HOME");
120 user_config_path
= malloc(sizeof(char) * (22 + strlen(user_home
)));
121 user_default_config_path
= malloc(sizeof(char) * (26 + strlen(user_home
)));
122 user_lxc_path
= malloc(sizeof(char) * (19 + strlen(user_home
)));
124 sprintf(user_config_path
, "%s/.config/lxc/lxc.conf", user_home
);
125 sprintf(user_default_config_path
, "%s/.config/lxc/default.conf", user_home
);
126 sprintf(user_lxc_path
, "%s/.local/share/lxc/", user_home
);
127 user_cgroup_pattern
= strdup("lxc/%n");
130 user_config_path
= strdup(LXC_GLOBAL_CONF
);
131 user_default_config_path
= strdup(LXC_DEFAULT_CONFIG
);
132 user_lxc_path
= strdup(LXCPATH
);
133 user_cgroup_pattern
= strdup(DEFAULT_CGROUP_PATTERN
);
136 const char * const (*ptr
)[2];
138 char buf
[1024], *p
, *p2
;
141 for (i
= 0, ptr
= options
; (*ptr
)[0]; ptr
++, i
++) {
142 if (!strcmp(option_name
, (*ptr
)[0]))
146 free(user_config_path
);
147 free(user_default_config_path
);
149 free(user_cgroup_pattern
);
155 free(user_config_path
);
156 free(user_default_config_path
);
158 free(user_cgroup_pattern
);
162 fin
= fopen_cloexec(user_config_path
, "r");
163 free(user_config_path
);
165 while (fgets(buf
, 1024, fin
)) {
168 p
= strstr(buf
, option_name
);
171 /* see if there was just white space in front
174 for (p2
= buf
; p2
< p
; p2
++) {
175 if (*p2
!= ' ' && *p2
!= '\t')
183 /* see if there was just white space after
186 for (p2
+= strlen(option_name
); p2
< p
; p2
++) {
187 if (*p2
!= ' ' && *p2
!= '\t')
193 while (*p
&& (*p
== ' ' || *p
== '\t')) p
++;
197 if (strcmp(option_name
, "lxc.lxcpath") == 0) {
199 user_lxc_path
= copy_global_config_value(p
);
200 remove_trailing_slashes(user_lxc_path
);
201 values
[i
] = user_lxc_path
;
202 user_lxc_path
= NULL
;
206 values
[i
] = copy_global_config_value(p
);
210 /* could not find value, use default */
211 if (strcmp(option_name
, "lxc.lxcpath") == 0) {
212 remove_trailing_slashes(user_lxc_path
);
213 values
[i
] = user_lxc_path
;
214 user_lxc_path
= NULL
;
216 else if (strcmp(option_name
, "lxc.default_config") == 0) {
217 values
[i
] = user_default_config_path
;
218 user_default_config_path
= NULL
;
220 else if (strcmp(option_name
, "lxc.cgroup.pattern") == 0) {
221 values
[i
] = user_cgroup_pattern
;
222 user_cgroup_pattern
= NULL
;
225 values
[i
] = (*ptr
)[1];
227 /* special case: if default value is NULL,
228 * and there is no config, don't view that
237 free(user_cgroup_pattern
);
238 free(user_default_config_path
);
244 extern void remove_trailing_slashes(char *p
)
247 while (--l
>= 0 && (p
[l
] == '/' || p
[l
] == '\n'))
251 FILE *fopen_cloexec(const char *path
, const char *mode
)
259 if (!strncmp(mode
, "r+", 2)) {
262 } else if (!strncmp(mode
, "r", 1)) {
263 open_mode
= O_RDONLY
;
265 } else if (!strncmp(mode
, "w+", 2)) {
266 open_mode
= O_RDWR
| O_TRUNC
| O_CREAT
;
268 } else if (!strncmp(mode
, "w", 1)) {
269 open_mode
= O_WRONLY
| O_TRUNC
| O_CREAT
;
271 } else if (!strncmp(mode
, "a+", 2)) {
272 open_mode
= O_RDWR
| O_CREAT
| O_APPEND
;
274 } else if (!strncmp(mode
, "a", 1)) {
275 open_mode
= O_WRONLY
| O_CREAT
| O_APPEND
;
278 for (; mode
[step
]; step
++)
279 if (mode
[step
] == 'x')
281 open_mode
|= O_CLOEXEC
;
283 fd
= open(path
, open_mode
, 0666);
287 ret
= fdopen(fd
, mode
);