]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/utils.c
mkdir_p: account for '//foo/bar'
[mirror_lxc.git] / src / lxc / utils.c
CommitLineData
e3642c43
DL
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
e3642c43
DL
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
d983b93c 24#define _GNU_SOURCE
e3642c43
DL
25#include <errno.h>
26#include <unistd.h>
d983b93c
MN
27#include <stdlib.h>
28#include <stddef.h>
e3642c43
DL
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/mman.h>
d983b93c 32#include <sys/param.h>
6e4bb2e0 33#include <sys/mount.h>
d983b93c
MN
34#include <dirent.h>
35#include <fcntl.h>
1b09f2c0 36#include <libgen.h>
e3642c43
DL
37
38#include "log.h"
39
40lxc_log_define(lxc_utils, lxc);
41
6e4bb2e0
MN
42static int mount_fs(const char *source, const char *target, const char *type)
43{
44 /* the umount may fail */
45 if (umount(target))
46 WARN("failed to unmount %s : %s", target, strerror(errno));
47
48 if (mount(source, target, type, 0, NULL)) {
49 ERROR("failed to mount %s : %s", target, strerror(errno));
50 return -1;
51 }
52
53 DEBUG("'%s' mounted on '%s'", source, target);
54
55 return 0;
56}
57
58extern int lxc_setup_fs(void)
59{
60 if (mount_fs("proc", "/proc", "proc"))
61 return -1;
62
721d262c 63 /* if we can't mount /dev/shm, continue anyway */
6e4bb2e0 64 if (mount_fs("shmfs", "/dev/shm", "tmpfs"))
3283db09 65 INFO("failed to mount /dev/shm");
6e4bb2e0
MN
66
67 /* If we were able to mount /dev/shm, then /dev exists */
b91b1cd7 68 /* Sure, but it's read-only per config :) */
6e4bb2e0 69 if (access("/dev/mqueue", F_OK) && mkdir("/dev/mqueue", 0666)) {
b91b1cd7
SH
70 DEBUG("failed to create '/dev/mqueue'");
71 return 0;
6e4bb2e0
MN
72 }
73
74 if (mount_fs("mqueue", "/dev/mqueue", "mqueue"))
75 return -1;
76
77 return 0;
78}
9ddaf3bf
JHS
79
80/* borrowed from iproute2 */
7c11d57a 81extern int get_u16(unsigned short *val, const char *arg, int base)
9ddaf3bf
JHS
82{
83 unsigned long res;
84 char *ptr;
85
86 if (!arg || !*arg)
87 return -1;
88
89 res = strtoul(arg, &ptr, base);
90 if (!ptr || ptr == arg || *ptr || res > 0xFFFF)
91 return -1;
92
93 *val = res;
94
95 return 0;
96}
97
883f4a1e
SH
98static int is_all_slashes(char *path)
99{
100 while (*path && *path == '/')
101 path++;
102 if (*path)
103 return 0;
104 return 1;
105}
106
1b09f2c0
DL
107extern int mkdir_p(char *dir, mode_t mode)
108{
109 int ret;
110 char *d;
111
883f4a1e 112 if (is_all_slashes(dir))
1b09f2c0
DL
113 return 0;
114
115 d = strdup(dir);
116 if (!d)
117 return -1;
118
119 ret = mkdir_p(dirname(d), mode);
120 free(d);
121 if (ret)
122 return -1;
123
124 if (!access(dir, F_OK))
125 return 0;
126
127 if (mkdir(dir, mode)) {
128 SYSERROR("failed to create directory '%s'\n", dir);
129 return -1;
130 }
131
132 return 0;
133}
2a59a681
SH
134
135static char *copypath(char *p)
136{
137 int len = strlen(p);
138 char *retbuf;
139
140 if (len < 1)
141 return NULL;
142 if (p[len-1] == '\n') {
143 p[len-1] = '\0';
144 len--;
145 }
146 retbuf = malloc(len+1);
147 if (!retbuf)
148 return NULL;
149 strcpy(retbuf, p);
150 return retbuf;
151}
152
67e571de
SG
153char *default_lxcpath;
154
155const char *default_lxc_path(void)
2a59a681 156{
67e571de 157 char buf[1024], *p;
2a59a681
SH
158 FILE *fin;
159
67e571de
SG
160 if (default_lxcpath)
161 return default_lxcpath;
162
2a59a681
SH
163 fin = fopen(LXC_GLOBAL_CONF, "r");
164 if (fin) {
165 while (fgets(buf, 1024, fin)) {
166 if (buf[0] == '#')
167 continue;
168 p = strstr(buf, "lxcpath");
169 if (!p)
170 continue;
171 p = strchr(p, '=');
172 if (!p)
173 continue;
174 p++;
175 while (*p && (*p == ' ' || *p == '\t')) p++;
176 if (!*p)
177 continue;
67e571de 178 default_lxcpath = copypath(p);
2a59a681
SH
179 goto out;
180 }
181 }
182 /* we couldn't open the file, or didn't find a lxcpath
183 * entry there. Return @LXCPATH@ */
67e571de 184 default_lxcpath = LXCPATH;
2a59a681
SH
185
186out:
187 if (fin)
188 fclose(fin);
67e571de 189 return default_lxcpath;
2a59a681 190}