]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/storage/overlay.c
define am_guest_unpriv
[mirror_lxc.git] / src / lxc / storage / overlay.c
CommitLineData
38683db4
CB
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#define _GNU_SOURCE
25#include <errno.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
38683db4
CB
30#include "conf.h"
31#include "confile.h"
32#include "log.h"
33#include "lxccontainer.h"
28d832c4
CB
34#include "overlay.h"
35#include "rsync.h"
36#include "storage.h"
ba115175 37#include "storage_utils.h"
38683db4
CB
38#include "utils.h"
39
10bc1861 40lxc_log_define(overlay, lxc);
38683db4 41
5c484f79 42static char *ovl_name;
88232d3f 43static char *ovl_version[] = {"overlay", "overlayfs"};
5c484f79 44
5c484f79 45static char *ovl_detect_name(void);
17a367d8 46static int ovl_do_rsync(const char *src, const char *dest,
3188197d 47 struct lxc_conf *conf);
88232d3f
CB
48static int ovl_remount_on_enodev(const char *lower, const char *target,
49 const char *name, unsigned long mountflags,
50 const void *options);
38683db4 51
10bc1861 52int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char *oldname,
83e79752
CB
53 const char *cname, const char *oldpath, const char *lxcpath,
54 int snap, uint64_t newsize, struct lxc_conf *conf)
38683db4 55{
241978fa 56 int ret;
41dc7155 57 const char *src;
4d463f62 58
38683db4 59 if (!snap) {
241978fa
CB
60 ERROR("The overlay storage driver can only be used for "
61 "snapshots");
38683db4
CB
62 return -22;
63 }
64
65 if (!orig->src || !orig->dest)
66 return -1;
67
241978fa 68 new->dest = must_make_path(lxcpath, cname, "rootfs", NULL);
ba115175 69
241978fa
CB
70 ret = mkdir_p(new->dest, 0755);
71 if (ret < 0 && errno != EEXIST) {
72 SYSERROR("Failed to create directory \"%s\"", new->dest);
38683db4 73 return -1;
241978fa 74 }
38683db4 75
5384e99d 76 if (am_host_unpriv()) {
241978fa
CB
77 ret = chown_mapped_root(new->dest, conf);
78 if (ret < 0)
79 WARN("Failed to update ownership of %s", new->dest);
80 }
38683db4
CB
81
82 if (strcmp(orig->type, "dir") == 0) {
83 char *delta, *lastslash;
84 char *work;
85 int ret, len, lastslashidx;
86
241978fa
CB
87 /* If we have "/var/lib/lxc/c2/rootfs" then delta will be
88 * "/var/lib/lxc/c2/delta0".
5c484f79 89 */
38683db4 90 lastslash = strrchr(new->dest, '/');
241978fa
CB
91 if (!lastslash) {
92 ERROR("Failed to detect \"/\" in string \"%s\"",
93 new->dest);
38683db4 94 return -22;
241978fa
CB
95 }
96
97 if (strlen(lastslash) < (sizeof("/rootfs") - 1)) {
98 ERROR("Failed to detect \"/rootfs\" in string \"%s\"",
99 new->dest);
38683db4 100 return -22;
241978fa
CB
101 }
102
38683db4
CB
103 lastslash++;
104 lastslashidx = lastslash - new->dest;
105
106 delta = malloc(lastslashidx + 7);
241978fa
CB
107 if (!delta) {
108 ERROR("Failed to allocate memory");
38683db4 109 return -1;
241978fa
CB
110 }
111
180c477a
CB
112 memcpy(delta, new->dest, lastslashidx + 1);
113 memcpy(delta + lastslashidx, "delta0", sizeof("delta0") - 1);
114 delta[lastslashidx + sizeof("delta0") - 1] = '\0';
241978fa
CB
115
116 ret = mkdir(delta, 0755);
117 if (ret < 0 && errno != EEXIST) {
118 SYSERROR("Failed to create directory \"%s\"", delta);
38683db4
CB
119 free(delta);
120 return -1;
121 }
38683db4 122
5384e99d 123 if (am_host_unpriv()) {
241978fa
CB
124 ret = chown_mapped_root(delta, conf);
125 if (ret < 0)
126 WARN("Failed to update ownership of %s", delta);
127 }
128
129 /* Make workdir for overlayfs.v22 or higher:
5c484f79
CB
130 * The workdir will be
131 * /var/lib/lxc/c2/olwork
132 * and is used to prepare files before they are atomically
133 * switched to the overlay destination. Workdirs need to be on
134 * the same filesystem as the upperdir so it's OK for it to be
135 * empty.
136 */
38683db4
CB
137 work = malloc(lastslashidx + 7);
138 if (!work) {
241978fa 139 ERROR("Failed to allocate memory");
38683db4
CB
140 free(delta);
141 return -1;
142 }
241978fa 143
180c477a
CB
144 memcpy(work, new->dest, lastslashidx + 1);
145 memcpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
146 work[lastslashidx + sizeof("olwork") - 1] = '\0';
241978fa 147
180c477a
CB
148 ret = mkdir(work, 0755);
149 if (ret < 0) {
150 SYSERROR("Failed to create directory \"%s\"", work);
38683db4
CB
151 free(delta);
152 free(work);
153 return -1;
154 }
241978fa 155
5384e99d 156 if (am_host_unpriv()) {
241978fa
CB
157 ret = chown_mapped_root(work, conf);
158 if (ret < 0)
159 WARN("Failed to update ownership of %s", work);
160 }
38683db4
CB
161 free(work);
162
241978fa
CB
163 /* strlen("overlay:") = 8
164 * +
165 * strlen(delta)
166 * +
167 * :
168 * +
169 * strlen(src)
170 * +
171 * \0
172 */
4d463f62 173 src = lxc_storage_get_path(orig->src, orig->type);
241978fa 174 len = 8 + strlen(delta) + 1 + strlen(src) + 1;
38683db4
CB
175 new->src = malloc(len);
176 if (!new->src) {
241978fa 177 ERROR("Failed to allocate memory");
38683db4
CB
178 free(delta);
179 return -ENOMEM;
180 }
241978fa 181
ba115175 182 ret = snprintf(new->src, len, "overlay:%s:%s", src, delta);
38683db4 183 free(delta);
241978fa
CB
184 if (ret < 0 || (size_t)ret >= len) {
185 ERROR("Failed to create string");
ba115175 186 return -1;
241978fa
CB
187 }
188 } else if (!strcmp(orig->type, "overlayfs") ||
189 !strcmp(orig->type, "overlay")) {
70e95c8d
CB
190 char *clean_old_path, *clean_new_path;
191 char *lastslash, *ndelta, *nsrc, *odelta, *osrc, *s1, *s2, *s3,
192 *work;
241978fa 193 int ret, lastslashidx;
70e95c8d 194 size_t len, name_len;
ba115175
CB
195
196 osrc = strdup(orig->src);
197 if (!osrc) {
241978fa 198 ERROR("Failed to duplicate string \"%s\"", orig->src);
38683db4 199 return -22;
241978fa 200 }
ba115175 201
09f6f8c4
CB
202 nsrc = osrc;
203 if (strncmp(osrc, "overlay:", 8) == 0)
204 nsrc += 8;
205 else if (strncmp(osrc, "overlayfs:", 10) == 0)
206 nsrc += 10;
ba115175
CB
207
208 odelta = strchr(nsrc, ':');
209 if (!odelta) {
241978fa 210 ERROR("Failed to find \":\" in \"%s\"", nsrc);
b44c0a67 211 free(osrc);
38683db4
CB
212 return -22;
213 }
ba115175 214
38683db4
CB
215 *odelta = '\0';
216 odelta++;
241978fa 217 ndelta = must_make_path(lxcpath, cname, "delta0", NULL);
ba115175
CB
218
219 ret = mkdir(ndelta, 0755);
220 if (ret < 0 && errno != EEXIST) {
e10e9f59 221 SYSERROR("Failed to create directory \"%s\"", ndelta);
38683db4
CB
222 free(osrc);
223 free(ndelta);
224 return -1;
225 }
ba115175 226
5384e99d 227 if (am_host_unpriv()) {
241978fa
CB
228 ret = chown_mapped_root(ndelta, conf);
229 if (ret < 0)
230 WARN("Failed to update ownership of %s",
231 ndelta);
232 }
38683db4 233
241978fa
CB
234 /* Make workdir for overlayfs.v22 or higher (See the comment
235 * further up.).
5c484f79 236 */
38683db4 237 lastslash = strrchr(ndelta, '/');
278d97f7 238 if (!lastslash) {
e10e9f59 239 ERROR("Failed to detect \"/\" in \"%s\"", ndelta);
278d97f7
SH
240 free(osrc);
241 free(ndelta);
38683db4 242 return -1;
278d97f7 243 }
38683db4
CB
244 lastslash++;
245 lastslashidx = lastslash - ndelta;
246
247 work = malloc(lastslashidx + 7);
278d97f7
SH
248 if (!work) {
249 free(osrc);
250 free(ndelta);
ba115175 251 ERROR("Failed to allocate memory");
38683db4 252 return -1;
278d97f7 253 }
241978fa 254
180c477a
CB
255 memcpy(work, ndelta, lastslashidx + 1);
256 memcpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
257 work[lastslashidx + sizeof("olwork") - 1] = '\0';
241978fa 258
ba115175
CB
259 ret = mkdir(work, 0755);
260 if (ret < 0 && errno != EEXIST) {
e10e9f59 261 SYSERROR("Failed to create directory \"%s\"", ndelta);
278d97f7
SH
262 free(osrc);
263 free(ndelta);
38683db4
CB
264 free(work);
265 return -1;
266 }
ba115175 267
5384e99d 268 if (am_host_unpriv()) {
241978fa
CB
269 ret = chown_mapped_root(work, conf);
270 if (ret < 0)
271 WARN("Failed to update ownership of %s", work);
272 }
38683db4
CB
273 free(work);
274
241978fa
CB
275 /* strlen("overlay:") = 8
276 * +
277 * strlen(delta)
278 * +
279 * :
280 * +
281 * strlen(src)
282 * +
283 * \0
284 */
285 len = 8 + strlen(ndelta) + 1 + strlen(nsrc) + 1;
38683db4
CB
286 new->src = malloc(len);
287 if (!new->src) {
288 free(osrc);
289 free(ndelta);
ba115175 290 ERROR("Failed to allocate memory");
38683db4
CB
291 return -ENOMEM;
292 }
ba115175 293 ret = snprintf(new->src, len, "overlay:%s:%s", nsrc, ndelta);
241978fa 294 if (ret < 0 || (size_t)ret >= len) {
ba115175 295 ERROR("Failed to create string");
17a367d8
CB
296 free(osrc);
297 free(ndelta);
ba115175 298 return -1;
241978fa 299 }
38683db4 300
17a367d8
CB
301 ret = ovl_do_rsync(odelta, ndelta, conf);
302 free(osrc);
303 free(ndelta);
70e95c8d
CB
304 if (ret < 0)
305 return -1;
306
307 /* When we create an overlay snapshot of an overlay container in
308 * the snapshot directory under "<lxcpath>/<name>/snaps/" we
309 * don't need to record a dependency. If we would restore would
310 * also fail.
311 */
312 clean_old_path = lxc_deslashify(oldpath);
313 if (!clean_old_path)
314 return -1;
315
316 clean_new_path = lxc_deslashify(lxcpath);
317 if (!clean_new_path) {
318 free(clean_old_path);
319 return -1;
320 }
321
322 s1 = strrchr(clean_old_path, '/');
323 if (!s1) {
e10e9f59 324 ERROR("Failed to detect \"/\" in string \"%s\"", clean_old_path);
70e95c8d
CB
325 free(clean_old_path);
326 free(clean_new_path);
327 return -1;
328 }
329
330 s2 = strrchr(clean_new_path, '/');
331 if (!s2) {
e10e9f59 332 ERROR("Failed to detect \"/\" in string \"%s\"", clean_new_path);
70e95c8d
CB
333 free(clean_old_path);
334 free(clean_new_path);
335 return -1;
336 }
337
338 if (!strncmp(s1, "/snaps", sizeof("/snaps") - 1)) {
339 s1 = clean_new_path;
340 s2 = clean_old_path;
341 s3 = (char *)cname;
70e95c8d
CB
342 } else if (!strncmp(s2, "/snaps", sizeof("/snaps") - 1)) {
343 s1 = clean_old_path;
344 s2 = clean_new_path;
345 s3 = (char *)oldname;
70e95c8d
CB
346 } else {
347 free(clean_old_path);
348 free(clean_new_path);
349 return 0;
350 }
351
7f022483 352 len = strlen(s1);
70e95c8d
CB
353 if (!strncmp(s1, s2, len)) {
354 char *tmp;
355
356 tmp = (char *)(s2 + len + 1);
357 if (*tmp == '\0') {
358 free(clean_old_path);
359 free(clean_new_path);
360 return 0;
361 }
362
363 name_len = strlen(s3);
364 if (strncmp(s3, tmp, name_len)) {
365 free(clean_old_path);
366 free(clean_new_path);
367 return 0;
368 }
369
7f022483
CB
370 free(clean_old_path);
371 free(clean_new_path);
372 return LXC_CLONE_SNAPSHOT;
70e95c8d
CB
373 }
374
375 free(clean_old_path);
376 free(clean_new_path);
377 return 0;
38683db4 378 } else {
ba115175 379 ERROR("overlay clone of %s container is not yet supported",
5c484f79 380 orig->type);
241978fa 381 /* Note, supporting this will require ovl_mount supporting
5c484f79
CB
382 * mounting of the underlay. No big deal, just needs to be done.
383 */
38683db4
CB
384 return -1;
385 }
386
387 return 0;
388}
389
241978fa
CB
390/* To say "lxc-create -t ubuntu -n o1 -B overlay" means you want
391 * "<lxcpath>/<lxcname>/rootfs" to have the created container, while all changes
392 * after starting the container are written to "<lxcpath>/<lxcname>/delta0".
38683db4 393 */
10bc1861 394int ovl_create(struct lxc_storage *bdev, const char *dest, const char *n,
241978fa 395 struct bdev_specs *specs)
38683db4
CB
396{
397 char *delta;
241978fa
CB
398 int ret;
399 size_t len, newlen;
38683db4 400
241978fa
CB
401 len = strlen(dest);
402 if (len < 8 || strcmp(dest + len - 7, "/rootfs")) {
403 ERROR("Failed to detect \"/rootfs\" in \"%s\"", dest);
38683db4 404 return -1;
241978fa 405 }
38683db4 406
241978fa
CB
407 bdev->dest = strdup(dest);
408 if (!bdev->dest) {
409 ERROR("Failed to duplicate string \"%s\"", dest);
38683db4
CB
410 return -1;
411 }
412
fe348547 413 delta = strdup(dest);
241978fa
CB
414 if (!delta) {
415 ERROR("Failed to allocate memory");
416 return -1;
417 }
180c477a 418 memcpy(delta + len - 6, "delta0", sizeof("delta0") - 1);
38683db4 419
241978fa
CB
420 ret = mkdir_p(delta, 0755);
421 if (ret < 0) {
422 SYSERROR("Failed to create directory \"%s\"", delta);
423 free(delta);
38683db4
CB
424 return -1;
425 }
426
241978fa 427 /* overlay:lower:upper */
ba115175 428 newlen = (2 * len) + strlen("overlay:") + 2;
38683db4
CB
429 bdev->src = malloc(newlen);
430 if (!bdev->src) {
241978fa
CB
431 ERROR("Failed to allocate memory");
432 free(delta);
38683db4
CB
433 return -1;
434 }
241978fa 435
ba115175 436 ret = snprintf(bdev->src, newlen, "overlay:%s:%s", dest, delta);
241978fa
CB
437 if (ret < 0 || (size_t)ret >= newlen) {
438 ERROR("Failed to create string");
439 free(delta);
38683db4 440 return -1;
241978fa 441 }
38683db4 442
241978fa
CB
443 ret = mkdir_p(bdev->dest, 0755);
444 if (ret < 0) {
445 SYSERROR("Failed to create directory \"%s\"", bdev->dest);
446 free(delta);
38683db4
CB
447 return -1;
448 }
449
241978fa 450 free(delta);
38683db4
CB
451 return 0;
452}
453
10bc1861 454int ovl_destroy(struct lxc_storage *orig)
5c484f79 455{
ba115175 456 char *upper = orig->src;
5c484f79 457
17a367d8
CB
458 /* For an overlay container the rootfs is considered immutable
459 * and cannot be removed when restoring from a snapshot.
460 */
461 if (orig->flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)
462 return 0;
463
09f6f8c4 464 if (strncmp(upper, "overlay:", 8) == 0)
241978fa 465 upper += 8;
09f6f8c4 466 else if (strncmp(upper, "overlayfs:", 10) == 0)
241978fa 467 upper += 10;
ba115175
CB
468
469 upper = strchr(upper, ':');
5c484f79
CB
470 if (!upper)
471 return -22;
472 upper++;
ba115175 473
5c484f79
CB
474 return lxc_rmdir_onedev(upper, NULL);
475}
476
3d2ae1e2 477bool ovl_detect(const char *path)
5c484f79 478{
09f6f8c4 479 if (!strncmp(path, "overlay:", 8))
3d2ae1e2 480 return true;
f7ac4459 481
09f6f8c4 482 if (!strncmp(path, "overlayfs:", 10))
3d2ae1e2 483 return true;
f7ac4459 484
3d2ae1e2 485 return false;
5c484f79
CB
486}
487
10bc1861 488int ovl_mount(struct lxc_storage *bdev)
5c484f79 489{
9208af16 490 char *tmp, *options, *dup, *lower, *upper;
5c484f79
CB
491 char *options_work, *work, *lastslash;
492 int lastslashidx;
241978fa 493 size_t len, len2;
5c484f79
CB
494 unsigned long mntflags;
495 char *mntdata;
496 int ret, ret2;
497
ba115175 498 if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs"))
5c484f79 499 return -22;
ba115175 500
5c484f79
CB
501 if (!bdev->src || !bdev->dest)
502 return -22;
503
504 if (!ovl_name)
505 ovl_name = ovl_detect_name();
506
241978fa
CB
507 /* Separately mount it first:
508 * mount -t overlay * -o upperdir=${upper},lowerdir=${lower} lower dest
5c484f79 509 */
241978fa
CB
510 dup = strdup(bdev->src);
511 if (!dup) {
512 ERROR("Failed to allocate memory");
513 return -1;
514 }
09f6f8c4
CB
515 upper = dup;
516 lower = dup;
241978fa 517
09f6f8c4
CB
518 if (strncmp(dup, "overlay:", 8) == 0)
519 lower += 8;
520 else if (strncmp(dup, "overlayfs:", 10) == 0)
521 lower += 10;
522 if (upper != lower)
523 upper = lower;
241978fa 524
09f6f8c4
CB
525 /* support multiple lower layers */
526 while ((tmp = strstr(upper, ":/"))) {
527 tmp++;
9208af16
CB
528 upper = tmp;
529 }
241978fa
CB
530
531 upper--;
532 if (upper == lower) {
533 free(dup);
5c484f79 534 return -22;
241978fa 535 }
5c484f79
CB
536 *upper = '\0';
537 upper++;
538
241978fa 539 /* if delta doesn't yet exist, create it */
adcdf4e4 540 ret = mkdir_p(upper, 0755);
241978fa
CB
541 if (ret < 0 && errno != EEXIST) {
542 SYSERROR("Failed to create directory \"%s\"", upper);
543 free(dup);
5c484f79 544 return -22;
241978fa 545 }
5c484f79 546
241978fa 547 /* overlayfs.v22 or higher needs workdir option:
5c484f79
CB
548 * if upper is
549 * /var/lib/lxc/c2/delta0
550 * then workdir is
551 * /var/lib/lxc/c2/olwork
552 */
553 lastslash = strrchr(upper, '/');
241978fa
CB
554 if (!lastslash) {
555 ERROR("Failed to detect \"/\" in string \"%s\"", upper);
556 free(dup);
5c484f79 557 return -22;
241978fa
CB
558 }
559
5c484f79
CB
560 lastslash++;
561 lastslashidx = lastslash - upper;
562
241978fa
CB
563 work = malloc(lastslashidx + 7);
564 if (!work) {
565 ERROR("Failed to allocate memory");
566 free(dup);
567 return -22;
568 }
5c484f79 569
180c477a
CB
570 memcpy(work, upper, lastslashidx + 1);
571 memcpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
572 work[lastslashidx + sizeof("olwork") - 1] = '\0';
241978fa
CB
573
574 ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
575 if (ret < 0) {
576 ERROR("Failed to parse mount options");
5c484f79 577 free(mntdata);
241978fa
CB
578 free(dup);
579 free(work);
5c484f79
CB
580 return -22;
581 }
582
241978fa
CB
583 ret = mkdir_p(work, 0755);
584 if (ret < 0 && errno != EEXIST) {
585 SYSERROR("Failed to create directory \"%s\"", work);
5c484f79 586 free(mntdata);
241978fa
CB
587 free(dup);
588 free(work);
5c484f79
CB
589 return -22;
590 }
591
592 /*
593 * TODO:
594 * We should check whether bdev->src is a blockdev but for now only
595 * support overlays of a basic directory
596 */
597
598 if (mntdata) {
241978fa
CB
599 len = strlen(lower) + strlen(upper) +
600 strlen("upperdir=,lowerdir=,") + strlen(mntdata) + 1;
5c484f79 601 options = alloca(len);
241978fa
CB
602 ret = snprintf(options, len, "upperdir=%s,lowerdir=%s,%s",
603 upper, lower, mntdata);
5c484f79 604
241978fa
CB
605 len2 = strlen(lower) + strlen(upper) + strlen(work) +
606 strlen("upperdir=,lowerdir=,workdir=") +
607 strlen(mntdata) + 1;
5c484f79 608 options_work = alloca(len2);
241978fa
CB
609 ret2 = snprintf(options, len2,
610 "upperdir=%s,lowerdir=%s,workdir=%s,%s", upper,
611 lower, work, mntdata);
5c484f79 612 } else {
241978fa
CB
613 len = strlen(lower) + strlen(upper) +
614 strlen("upperdir=,lowerdir=") + 1;
5c484f79 615 options = alloca(len);
241978fa
CB
616 ret = snprintf(options, len, "upperdir=%s,lowerdir=%s", upper,
617 lower);
5c484f79 618
241978fa
CB
619 len2 = strlen(lower) + strlen(upper) + strlen(work) +
620 strlen("upperdir=,lowerdir=,workdir=") + 1;
5c484f79 621 options_work = alloca(len2);
241978fa
CB
622 ret2 = snprintf(options_work, len2,
623 "upperdir=%s,lowerdir=%s,workdir=%s", upper,
624 lower, work);
5c484f79
CB
625 }
626
627 if (ret < 0 || ret >= len || ret2 < 0 || ret2 >= len2) {
241978fa 628 ERROR("Failed to create string");
5c484f79 629 free(mntdata);
241978fa
CB
630 free(dup);
631 free(work);
5c484f79
CB
632 return -1;
633 }
634
241978fa 635 /* Assume we need a workdir as we are on a overlay version >= v22. */
88232d3f
CB
636 ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name,
637 MS_MGC_VAL | mntflags, options_work);
5c484f79 638 if (ret < 0) {
241978fa
CB
639 INFO("Failed to mount \"%s\" on \"%s\" with options \"%s\". "
640 "Retrying without workdir: %s",
88232d3f 641 lower, bdev->dest, options_work, strerror(errno));
5c484f79 642
241978fa
CB
643 /* Assume we cannot use a workdir as we are on a version <= v21.
644 */
88232d3f 645 ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name,
241978fa 646 MS_MGC_VAL | mntflags, options);
5c484f79 647 if (ret < 0)
241978fa
CB
648 SYSERROR("Failed to mount \"%s\" on \"%s\" with "
649 "options \"%s\": %s",
650 lower, bdev->dest, options, strerror(errno));
5c484f79 651 else
241978fa 652 INFO("Mounted \"%s\" on \"%s\" with options \"%s\"",
88232d3f 653 lower, bdev->dest, options);
5c484f79 654 } else {
241978fa 655 INFO("Mounted \"%s\" on \"%s\" with options \"%s\"", lower,
88232d3f 656 bdev->dest, options_work);
5c484f79 657 }
241978fa
CB
658
659 free(dup);
660 free(work);
5c484f79
CB
661 return ret;
662}
663
10bc1861 664int ovl_umount(struct lxc_storage *bdev)
5c484f79 665{
241978fa
CB
666 int ret;
667
ba115175 668 if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs"))
5c484f79 669 return -22;
ba115175 670
5c484f79
CB
671 if (!bdev->src || !bdev->dest)
672 return -22;
ba115175 673
241978fa
CB
674 ret = umount(bdev->dest);
675 if (ret < 0)
676 SYSERROR("Failed to unmount \"%s\"", bdev->dest);
677 else
678 TRACE("Unmounted \"%s\"", bdev->dest);
679
680 return ret;
5c484f79
CB
681}
682
41dc7155 683const char *ovl_get_lower(const char *rootfs_path)
ba115175 684{
41dc7155 685 const char *s1 = rootfs_path;
241978fa 686
41dc7155
CB
687 if (strncmp(rootfs_path, "overlay:", 8) == 0)
688 s1 += 8;
689 else if (strncmp(rootfs_path, "overlayfs:", 10) == 0)
690 s1 += 10;
ba115175
CB
691
692 s1 = strstr(s1, ":/");
693 if (!s1)
694 return NULL;
695 s1++;
696
697 return s1;
698}
699
5c484f79
CB
700char *ovl_get_rootfs(const char *rootfs_path, size_t *rootfslen)
701{
702 char *rootfsdir = NULL;
703 char *s1 = NULL;
704 char *s2 = NULL;
705 char *s3 = NULL;
706
707 if (!rootfs_path || !rootfslen)
708 return NULL;
709
710 s1 = strdup(rootfs_path);
711 if (!s1)
712 return NULL;
713
41dc7155
CB
714 s2 = s1;
715 if (strncmp(rootfs_path, "overlay:", 8) == 0)
716 s2 += 8;
717 else if (strncmp(rootfs_path, "overlayfs:", 10) == 0)
718 s2 += 10;
719
720 s3 = strstr(s2, ":/");
721 if (s3)
722 *s3 = '\0';
723
724 rootfsdir = strdup(s2);
a61b4e85 725 free(s1);
5c484f79 726 if (!rootfsdir)
a61b4e85 727 return NULL;
5c484f79
CB
728
729 *rootfslen = strlen(rootfsdir);
730
731 return rootfsdir;
732}
733
734int ovl_mkdir(const struct mntent *mntent, const struct lxc_rootfs *rootfs,
735 const char *lxc_name, const char *lxc_path)
736{
737 char lxcpath[MAXPATHLEN];
241978fa
CB
738 char **opts;
739 int ret;
180c477a 740 size_t arrlen, i, len, rootfslen;
5c484f79 741 int fret = -1;
180c477a 742 size_t dirlen = 0;
241978fa
CB
743 char *rootfs_dir = NULL, *rootfs_path = NULL, *upperdir = NULL,
744 *workdir = NULL;
5c484f79 745
9769034f
CB
746 /* When rootfs == NULL we have a container without a rootfs. */
747 if (rootfs && rootfs->path)
748 rootfs_path = rootfs->path;
5c484f79
CB
749
750 opts = lxc_string_split(mntent->mnt_opts, ',');
751 if (opts)
752 arrlen = lxc_array_len((void **)opts);
753 else
754 goto err;
755
756 for (i = 0; i < arrlen; i++) {
241978fa
CB
757 if (strstr(opts[i], "upperdir=") &&
758 (strlen(opts[i]) > (len = strlen("upperdir="))))
5c484f79 759 upperdir = opts[i] + len;
241978fa
CB
760 else if (strstr(opts[i], "workdir=") &&
761 (strlen(opts[i]) > (len = strlen("workdir="))))
5c484f79
CB
762 workdir = opts[i] + len;
763 }
764
9769034f 765 if (rootfs_path) {
180c477a 766 ret = snprintf(lxcpath, MAXPATHLEN, "%s/%s", lxc_path, lxc_name);
9769034f
CB
767 if (ret < 0 || ret >= MAXPATHLEN)
768 goto err;
5c484f79 769
241978fa
CB
770 rootfs_dir = ovl_get_rootfs(rootfs_path, &rootfslen);
771 if (!rootfs_dir)
9769034f 772 goto err;
5c484f79 773
9769034f
CB
774 dirlen = strlen(lxcpath);
775 }
5c484f79
CB
776
777 /*
778 * We neither allow users to create upperdirs and workdirs outside the
779 * containerdir nor inside the rootfs. The latter might be debatable.
9769034f 780 * When we have a container without a rootfs we skip the checks.
5c484f79 781 */
9769034f
CB
782 ret = 0;
783 if (upperdir) {
784 if (!rootfs_path)
785 ret = mkdir_p(upperdir, 0755);
241978fa
CB
786 else if (!strncmp(upperdir, lxcpath, dirlen) &&
787 strncmp(upperdir, rootfs_dir, rootfslen))
9769034f
CB
788 ret = mkdir_p(upperdir, 0755);
789 if (ret < 0)
241978fa
CB
790 WARN("Failed to create directory \"%s\": %s", upperdir,
791 strerror(errno));
9769034f
CB
792 }
793
794 ret = 0;
795 if (workdir) {
796 if (!rootfs_path)
797 ret = mkdir_p(workdir, 0755);
241978fa
CB
798 else if (!strncmp(workdir, lxcpath, dirlen) &&
799 strncmp(workdir, rootfs_dir, rootfslen))
9769034f
CB
800 ret = mkdir_p(workdir, 0755);
801 if (ret < 0)
241978fa
CB
802 WARN("Failed to create directory \"%s\": %s", workdir,
803 strerror(errno));
9769034f 804 }
5c484f79
CB
805
806 fret = 0;
807
808err:
241978fa 809 free(rootfs_dir);
5c484f79
CB
810 lxc_free_array((void **)opts, free);
811 return fret;
812}
813
241978fa 814/* To be called from lxcapi_clone() in lxccontainer.c: When we clone a container
38683db4
CB
815 * with overlay lxc.mount.entry entries we need to update absolute paths for
816 * upper- and workdir. This update is done in two locations:
817 * lxc_conf->unexpanded_config and lxc_conf->mount_list. Both updates are done
241978fa
CB
818 * independent of each other since lxc_conf->mountlist may contain more mount
819 * entries (e.g. from other included files) than lxc_conf->unexpanded_config.
38683db4 820 */
83e79752
CB
821int ovl_update_abs_paths(struct lxc_conf *lxc_conf, const char *lxc_path,
822 const char *lxc_name, const char *newpath,
823 const char *newname)
38683db4 824{
241978fa
CB
825 char new_upper[MAXPATHLEN], new_work[MAXPATHLEN], old_upper[MAXPATHLEN],
826 old_work[MAXPATHLEN];
84760c11 827 size_t i;
241978fa
CB
828 struct lxc_list *iterator;
829 char *cleanpath = NULL;
38683db4
CB
830 int fret = -1;
831 int ret = 0;
38683db4
CB
832 const char *ovl_dirs[] = {"br", "upperdir", "workdir"};
833
834 cleanpath = strdup(newpath);
835 if (!cleanpath)
836 goto err;
837
838 remove_trailing_slashes(cleanpath);
839
5c484f79
CB
840 /*
841 * We have to update lxc_conf->unexpanded_config separately from
842 * lxc_conf->mount_list.
843 */
38683db4
CB
844 for (i = 0; i < sizeof(ovl_dirs) / sizeof(ovl_dirs[0]); i++) {
845 if (!clone_update_unexp_ovl_paths(lxc_conf, lxc_path, newpath,
846 lxc_name, newname,
847 ovl_dirs[i]))
848 goto err;
849 }
850
241978fa
CB
851 ret =
852 snprintf(old_work, MAXPATHLEN, "workdir=%s/%s", lxc_path, lxc_name);
38683db4
CB
853 if (ret < 0 || ret >= MAXPATHLEN)
854 goto err;
855
241978fa
CB
856 ret =
857 snprintf(new_work, MAXPATHLEN, "workdir=%s/%s", cleanpath, newname);
38683db4
CB
858 if (ret < 0 || ret >= MAXPATHLEN)
859 goto err;
860
861 lxc_list_for_each(iterator, &lxc_conf->mount_list) {
241978fa
CB
862 char *mnt_entry = NULL, *new_mnt_entry = NULL, *tmp = NULL,
863 *tmp_mnt_entry = NULL;
864
38683db4
CB
865 mnt_entry = iterator->elem;
866
867 if (strstr(mnt_entry, "overlay"))
868 tmp = "upperdir";
869 else if (strstr(mnt_entry, "aufs"))
870 tmp = "br";
871
872 if (!tmp)
873 continue;
874
241978fa
CB
875 ret = snprintf(old_upper, MAXPATHLEN, "%s=%s/%s", tmp, lxc_path,
876 lxc_name);
38683db4
CB
877 if (ret < 0 || ret >= MAXPATHLEN)
878 goto err;
879
241978fa
CB
880 ret = snprintf(new_upper, MAXPATHLEN, "%s=%s/%s", tmp,
881 cleanpath, newname);
38683db4
CB
882 if (ret < 0 || ret >= MAXPATHLEN)
883 goto err;
884
885 if (strstr(mnt_entry, old_upper)) {
241978fa
CB
886 tmp_mnt_entry =
887 lxc_string_replace(old_upper, new_upper, mnt_entry);
38683db4
CB
888 }
889
890 if (strstr(mnt_entry, old_work)) {
891 if (tmp_mnt_entry)
241978fa
CB
892 new_mnt_entry = lxc_string_replace(
893 old_work, new_work, tmp_mnt_entry);
38683db4 894 else
241978fa
CB
895 new_mnt_entry = lxc_string_replace(
896 old_work, new_work, mnt_entry);
38683db4
CB
897 }
898
899 if (new_mnt_entry) {
900 free(iterator->elem);
901 iterator->elem = strdup(new_mnt_entry);
902 } else if (tmp_mnt_entry) {
903 free(iterator->elem);
904 iterator->elem = strdup(tmp_mnt_entry);
905 }
906
907 free(new_mnt_entry);
908 free(tmp_mnt_entry);
909 }
910
911 fret = 0;
912err:
913 free(cleanpath);
914 return fret;
915}
916
88232d3f
CB
917static int ovl_remount_on_enodev(const char *lower, const char *target,
918 const char *name, unsigned long mountflags,
919 const void *options)
920{
241978fa
CB
921 int ret;
922 ret = mount(lower, target, ovl_name, MS_MGC_VAL | mountflags, options);
923 if (ret < 0 && errno == ENODEV) /* Try other module name. */
88232d3f
CB
924 ret = mount(lower, target,
925 ovl_name == ovl_version[0] ? ovl_version[1]
926 : ovl_version[0],
927 MS_MGC_VAL | mountflags, options);
241978fa 928 return ret;
5c484f79
CB
929}
930
931static char *ovl_detect_name(void)
932{
241978fa 933 FILE *f;
88232d3f 934 char *v = ovl_version[0];
5c484f79
CB
935 char *line = NULL;
936 size_t len = 0;
241978fa
CB
937
938 f = fopen("/proc/filesystems", "r");
5c484f79
CB
939 if (!f)
940 return v;
941
942 while (getline(&line, &len, f) != -1) {
88232d3f
CB
943 if (strcmp(line, "nodev\toverlayfs\n") == 0) {
944 v = ovl_version[1];
5c484f79
CB
945 break;
946 }
947 }
948
949 fclose(f);
950 free(line);
951 return v;
952}
953
17a367d8 954static int ovl_do_rsync(const char *src, const char *dest,
241978fa 955 struct lxc_conf *conf)
5c484f79
CB
956{
957 int ret = -1;
17a367d8 958 struct rsync_data_char rdata = {0};
241978fa 959 char cmd_output[MAXPATHLEN] = {0};
5c484f79 960
17a367d8
CB
961 rdata.src = (char *)src;
962 rdata.dest = (char *)dest;
5384e99d 963 if (am_host_unpriv())
5c05427a
CB
964 ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
965 "lxc_rsync_exec_wrapper");
17a367d8 966 else
241978fa
CB
967 ret = run_command(cmd_output, sizeof(cmd_output),
968 lxc_rsync_exec_wrapper, (void *)&rdata);
17a367d8
CB
969 if (ret < 0)
970 ERROR("Failed to rsync from \"%s\" into \"%s\"%s%s", src, dest,
971 cmd_output[0] != '\0' ? ": " : "",
972 cmd_output[0] != '\0' ? cmd_output : "");
5c484f79
CB
973
974 return ret;
975}