]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/storage/dir.c
stringutils: include stdarg for va_list
[mirror_lxc.git] / src / lxc / storage / dir.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE 1
26 #endif
27 #include <stdint.h>
28 #include <string.h>
29
30 #include "config.h"
31 #include "log.h"
32 #include "storage.h"
33 #include "utils.h"
34
35 lxc_log_define(dir, lxc);
36
37 /* For a simple directory bind mount, we substitute the old container name and
38 * paths for the new.
39 */
40 int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
41 const char *oldname, const char *cname, const char *oldpath,
42 const char *lxcpath, int snap, uint64_t newsize,
43 struct lxc_conf *conf)
44 {
45 const char *src_no_prefix;
46 int ret;
47 size_t len;
48
49 if (snap) {
50 ERROR("Directories cannot be snapshotted");
51 return -1;
52 }
53
54 if (!orig->dest || !orig->src)
55 return -1;
56
57 len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 4 + 3;
58 new->src = malloc(len);
59 if (!new->src) {
60 ERROR("Failed to allocate memory");
61 return -1;
62 }
63
64 ret = snprintf(new->src, len, "dir:%s/%s/rootfs", lxcpath, cname);
65 if (ret < 0 || (size_t)ret >= len) {
66 ERROR("Failed to create string");
67 return -1;
68 }
69
70 src_no_prefix = lxc_storage_get_path(new->src, new->type);
71 new->dest = strdup(src_no_prefix);
72 if (!new->dest) {
73 ERROR("Failed to duplicate string \"%s\"", new->src);
74 return -1;
75 }
76
77 TRACE("Created new path \"%s\" for dir storage driver", new->dest);
78 return 0;
79 }
80
81 int dir_create(struct lxc_storage *bdev, const char *dest, const char *n,
82 struct bdev_specs *specs)
83 {
84 int ret;
85 const char *src;
86 size_t len;
87
88 /* strlen("dir:") */
89 len = 4;
90 if (specs && specs->dir)
91 src = specs->dir;
92 else
93 src = dest;
94
95 len += strlen(src) + 1;
96 bdev->src = malloc(len);
97 if (!bdev->src) {
98 ERROR("Failed to allocate memory");
99 return -1;
100 }
101
102 ret = snprintf(bdev->src, len, "dir:%s", src);
103 if (ret < 0 || (size_t)ret >= len) {
104 ERROR("Failed to create string");
105 return -1;
106 }
107
108 bdev->dest = strdup(dest);
109 if (!bdev->dest) {
110 ERROR("Failed to duplicate string \"%s\"", dest);
111 return -1;
112 }
113
114 ret = mkdir_p(dest, 0755);
115 if (ret < 0) {
116 ERROR("Failed to create directory \"%s\"", dest);
117 return -1;
118 }
119 TRACE("Created directory \"%s\"", dest);
120
121 return 0;
122 }
123
124 int dir_destroy(struct lxc_storage *orig)
125 {
126 int ret;
127 const char *src;
128
129 src = lxc_storage_get_path(orig->src, orig->src);
130
131 ret = lxc_rmdir_onedev(src, NULL);
132 if (ret < 0) {
133 ERROR("Failed to delete \"%s\"", src);
134 return -1;
135 }
136
137 return 0;
138 }
139
140 bool dir_detect(const char *path)
141 {
142 struct stat statbuf;
143 int ret;
144
145 if (!strncmp(path, "dir:", 4))
146 return true;
147
148 ret = stat(path, &statbuf);
149 if (ret == -1 && errno == EPERM) {
150 SYSERROR("dir_detect: failed to look at \"%s\"", path);
151 return false;
152 }
153
154 if (ret == 0 && S_ISDIR(statbuf.st_mode))
155 return true;
156
157 return false;
158 }
159
160 int dir_mount(struct lxc_storage *bdev)
161 {
162 int ret;
163 unsigned long mflags = 0, mntflags = 0, pflags = 0;
164 char *mntdata;
165 const char *src;
166
167 if (strcmp(bdev->type, "dir"))
168 return -22;
169
170 if (!bdev->src || !bdev->dest)
171 return -22;
172
173 ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
174 if (ret < 0) {
175 ERROR("Failed to parse mount options \"%s\"", bdev->mntopts);
176 free(mntdata);
177 return -EINVAL;
178 }
179
180 ret = parse_propagationopts(bdev->mntopts, &pflags);
181 if (ret < 0) {
182 ERROR("Failed to parse propagation options \"%s\"", bdev->mntopts);
183 free(mntdata);
184 return -EINVAL;
185 }
186
187 src = lxc_storage_get_path(bdev->src, bdev->type);
188
189 ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata);
190 if ((0 == ret) && (mntflags & MS_RDONLY)) {
191 DEBUG("Remounting \"%s\" on \"%s\" readonly",
192 src ? src : "(none)", bdev->dest ? bdev->dest : "(none)");
193 mflags = add_required_remount_flags(src, bdev->dest, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT);
194 ret = mount(src, bdev->dest, "bind", mflags, mntdata);
195 }
196
197 if (ret < 0) {
198 SYSERROR("Failed to mount \"%s\" on \"%s\"", src, bdev->dest);
199 free(mntdata);
200 return -1;
201 }
202
203 TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest);
204 free(mntdata);
205 return ret;
206 }
207
208 int dir_umount(struct lxc_storage *bdev)
209 {
210 if (strcmp(bdev->type, "dir"))
211 return -22;
212
213 if (!bdev->src || !bdev->dest)
214 return -22;
215
216 return umount(bdev->dest);
217 }