]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/utils.c
tree-wide: s/getpid()/lxc_raw_getpid()/g
[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
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e3642c43
DL
22 */
23
052616eb
ÇO
24#include "config.h"
25
7935833c 26#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
643c1984 27#include <ctype.h>
a1e5280d 28#include <dirent.h>
e3642c43 29#include <errno.h>
a1e5280d 30#include <fcntl.h>
dbaf55a3 31#include <grp.h>
7935833c 32#include <inttypes.h>
a1e5280d 33#include <libgen.h>
d983b93c 34#include <stddef.h>
a1e5280d
CB
35#include <stdio.h>
36#include <stdlib.h>
61a1d519 37#include <string.h>
981f6029 38#include <unistd.h>
e3642c43 39#include <sys/mman.h>
6e4bb2e0 40#include <sys/mount.h>
a1e5280d
CB
41#include <sys/param.h>
42#include <sys/prctl.h>
43#include <sys/stat.h>
9be53773
SH
44#include <sys/types.h>
45#include <sys/wait.h>
e3642c43
DL
46
47#include "log.h"
025ed0f3 48#include "lxclock.h"
51d0854c 49#include "namespace.h"
e3db0162 50#include "parse.h"
981f6029 51#include "utils.h"
e3642c43 52
4928c718
SG
53#ifndef O_PATH
54#define O_PATH 010000000
55#endif
56
57#ifndef O_NOFOLLOW
58#define O_NOFOLLOW 00400000
59#endif
60
e3642c43
DL
61lxc_log_define(lxc_utils, lxc);
62
4295c5de
SH
63/*
64 * if path is btrfs, tries to remove it and any subvolumes beneath it
65 */
66extern bool btrfs_try_remove_subvol(const char *path);
67
41dc7155 68static int _recursive_rmdir(const char *dirname, dev_t pdev,
0cc417b2 69 const char *exclude, int level, bool onedev)
60bf62d4 70{
74f96976 71 struct dirent *direntp;
60bf62d4
SH
72 DIR *dir;
73 int ret, failed=0;
74 char pathname[MAXPATHLEN];
18aa217b 75 bool hadexclude = false;
60bf62d4
SH
76
77 dir = opendir(dirname);
78 if (!dir) {
b103ceac 79 ERROR("failed to open %s", dirname);
4355ab5f 80 return -1;
60bf62d4
SH
81 }
82
74f96976 83 while ((direntp = readdir(dir))) {
60bf62d4
SH
84 struct stat mystat;
85 int rc;
86
87 if (!direntp)
88 break;
89
90 if (!strcmp(direntp->d_name, ".") ||
91 !strcmp(direntp->d_name, ".."))
92 continue;
93
94 rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name);
95 if (rc < 0 || rc >= MAXPATHLEN) {
96 ERROR("pathname too long");
97 failed=1;
98 continue;
99 }
18aa217b
SH
100
101 if (!level && exclude && !strcmp(direntp->d_name, exclude)) {
102 ret = rmdir(pathname);
103 if (ret < 0) {
104 switch(errno) {
105 case ENOTEMPTY:
0cc417b2 106 INFO("Not deleting snapshot %s", pathname);
18aa217b
SH
107 hadexclude = true;
108 break;
109 case ENOTDIR:
110 ret = unlink(pathname);
111 if (ret)
b103ceac 112 INFO("Failed to remove %s", pathname);
18aa217b
SH
113 break;
114 default:
b103ceac 115 SYSERROR("Failed to rmdir %s", pathname);
18aa217b
SH
116 failed = 1;
117 break;
118 }
119 }
120 continue;
121 }
122
60bf62d4
SH
123 ret = lstat(pathname, &mystat);
124 if (ret) {
b103ceac 125 ERROR("Failed to stat %s", pathname);
4295c5de 126 failed = 1;
60bf62d4
SH
127 continue;
128 }
4295c5de
SH
129 if (onedev && mystat.st_dev != pdev) {
130 /* TODO should we be checking /proc/self/mountinfo for
131 * pathname and not doing this if found? */
132 if (btrfs_try_remove_subvol(pathname))
133 INFO("Removed btrfs subvolume at %s\n", pathname);
60bf62d4 134 continue;
4295c5de 135 }
60bf62d4 136 if (S_ISDIR(mystat.st_mode)) {
0cc417b2 137 if (_recursive_rmdir(pathname, pdev, exclude, level+1, onedev) < 0)
60bf62d4
SH
138 failed=1;
139 } else {
140 if (unlink(pathname) < 0) {
b103ceac 141 SYSERROR("Failed to delete %s", pathname);
60bf62d4
SH
142 failed=1;
143 }
144 }
145 }
146
4295c5de 147 if (rmdir(dirname) < 0 && !btrfs_try_remove_subvol(dirname) && !hadexclude) {
b103ceac 148 ERROR("Failed to delete %s", dirname);
4295c5de 149 failed=1;
60bf62d4
SH
150 }
151
025ed0f3 152 ret = closedir(dir);
025ed0f3 153 if (ret) {
b103ceac 154 ERROR("Failed to close directory %s", dirname);
60bf62d4
SH
155 failed=1;
156 }
157
4355ab5f 158 return failed ? -1 : 0;
60bf62d4
SH
159}
160
29a11a7f
CB
161/* We have two different magic values for overlayfs, yay. */
162#ifndef OVERLAYFS_SUPER_MAGIC
0cc417b2 163#define OVERLAYFS_SUPER_MAGIC 0x794c764f
29a11a7f
CB
164#endif
165
166#ifndef OVERLAY_SUPER_MAGIC
0cc417b2 167#define OVERLAY_SUPER_MAGIC 0x794c7630
29a11a7f
CB
168#endif
169
170/* In overlayfs, st_dev is unreliable. So on overlayfs we don't do the
171 * lxc_rmdir_onedev()
0cc417b2
SH
172 */
173static bool is_native_overlayfs(const char *path)
174{
29a11a7f
CB
175 if (has_fs_type(path, OVERLAY_SUPER_MAGIC) ||
176 has_fs_type(path, OVERLAYFS_SUPER_MAGIC))
0cc417b2 177 return true;
29a11a7f 178
0cc417b2
SH
179 return false;
180}
181
4355ab5f 182/* returns 0 on success, -1 if there were any failures */
41dc7155 183extern int lxc_rmdir_onedev(const char *path, const char *exclude)
60bf62d4
SH
184{
185 struct stat mystat;
0cc417b2
SH
186 bool onedev = true;
187
41dc7155 188 if (is_native_overlayfs(path))
0cc417b2 189 onedev = false;
60bf62d4
SH
190
191 if (lstat(path, &mystat) < 0) {
067650d0
SH
192 if (errno == ENOENT)
193 return 0;
41dc7155 194
b103ceac 195 ERROR("Failed to stat %s", path);
4355ab5f 196 return -1;
60bf62d4
SH
197 }
198
0cc417b2 199 return _recursive_rmdir(path, mystat.st_dev, exclude, 0, onedev);
60bf62d4
SH
200}
201
9ddaf3bf 202/* borrowed from iproute2 */
7c11d57a 203extern int get_u16(unsigned short *val, const char *arg, int base)
9ddaf3bf
JHS
204{
205 unsigned long res;
206 char *ptr;
207
208 if (!arg || !*arg)
209 return -1;
210
09bbd745 211 errno = 0;
9ddaf3bf 212 res = strtoul(arg, &ptr, base);
09bbd745 213 if (!ptr || ptr == arg || *ptr || res > 0xFFFF || errno != 0)
9ddaf3bf
JHS
214 return -1;
215
216 *val = res;
217
218 return 0;
219}
220
3ce74686 221extern int mkdir_p(const char *dir, mode_t mode)
1b09f2c0 222{
3ce74686
SH
223 const char *tmp = dir;
224 const char *orig = dir;
860fc865
RW
225 char *makeme;
226
227 do {
228 dir = tmp + strspn(tmp, "/");
229 tmp = dir + strcspn(dir, "/");
d74325c4 230 makeme = strndup(orig, dir - orig);
860fc865
RW
231 if (*makeme) {
232 if (mkdir(makeme, mode) && errno != EEXIST) {
959aee9c 233 SYSERROR("failed to create directory '%s'", makeme);
d74325c4 234 free(makeme);
860fc865
RW
235 return -1;
236 }
237 }
d74325c4 238 free(makeme);
860fc865 239 } while(tmp != dir);
1b09f2c0 240
98663823 241 return 0;
1b09f2c0 242}
2a59a681 243
44b9ae4b 244char *get_rundir()
9e60f51d 245{
97a696c6
SG
246 char *rundir;
247 const char *homedir;
9e60f51d 248
d6470e71 249 if (geteuid() == 0) {
c580b8d2 250 rundir = strdup(RUNTIME_PATH);
d6470e71
SG
251 return rundir;
252 }
97a696c6
SG
253
254 rundir = getenv("XDG_RUNTIME_DIR");
44b9ae4b
SG
255 if (rundir) {
256 rundir = strdup(rundir);
257 return rundir;
258 }
97a696c6 259
44b9ae4b
SG
260 INFO("XDG_RUNTIME_DIR isn't set in the environment.");
261 homedir = getenv("HOME");
262 if (!homedir) {
263 ERROR("HOME isn't set in the environment.");
264 return NULL;
97a696c6
SG
265 }
266
44b9ae4b
SG
267 rundir = malloc(sizeof(char) * (17 + strlen(homedir)));
268 sprintf(rundir, "%s/.cache/lxc/run/", homedir);
269
9e60f51d
DE
270 return rundir;
271}
272
9be53773
SH
273int wait_for_pid(pid_t pid)
274{
275 int status, ret;
276
277again:
278 ret = waitpid(pid, &status, 0);
279 if (ret == -1) {
71b9b8ed 280 if (errno == EINTR)
9be53773
SH
281 goto again;
282 return -1;
283 }
284 if (ret != pid)
285 goto again;
286 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
287 return -1;
288 return 0;
289}
c797a220
CS
290
291int lxc_wait_for_pid_status(pid_t pid)
292{
293 int status, ret;
294
295again:
296 ret = waitpid(pid, &status, 0);
297 if (ret == -1) {
298 if (errno == EINTR)
299 goto again;
300 return -1;
301 }
302 if (ret != pid)
303 goto again;
304 return status;
305}
92f023dc 306
650468bb 307ssize_t lxc_write_nointr(int fd, const void* buf, size_t count)
92f023dc 308{
650468bb 309 ssize_t ret;
92f023dc
CS
310again:
311 ret = write(fd, buf, count);
312 if (ret < 0 && errno == EINTR)
313 goto again;
314 return ret;
315}
316
650468bb 317ssize_t lxc_read_nointr(int fd, void* buf, size_t count)
92f023dc 318{
650468bb 319 ssize_t ret;
92f023dc
CS
320again:
321 ret = read(fd, buf, count);
322 if (ret < 0 && errno == EINTR)
323 goto again;
324 return ret;
325}
326
650468bb 327ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf)
92f023dc 328{
650468bb 329 ssize_t ret;
92f023dc
CS
330 ret = lxc_read_nointr(fd, buf, count);
331 if (ret <= 0)
332 return ret;
650468bb 333 if ((size_t)ret != count)
92f023dc
CS
334 return -1;
335 if (expected_buf && memcmp(buf, expected_buf, count) != 0) {
336 errno = EINVAL;
337 return -1;
338 }
339 return ret;
340}
3ce74686
SH
341
342#if HAVE_LIBGNUTLS
343#include <gnutls/gnutls.h>
344#include <gnutls/crypto.h>
41246cee
DE
345
346__attribute__((constructor))
347static void gnutls_lxc_init(void)
348{
349 gnutls_global_init();
350}
351
3ce74686
SH
352int sha1sum_file(char *fnam, unsigned char *digest)
353{
354 char *buf;
355 int ret;
356 FILE *f;
357 long flen;
358
359 if (!fnam)
360 return -1;
025ed0f3 361 f = fopen_cloexec(fnam, "r");
7be677a8 362 if (!f) {
3ce74686
SH
363 SYSERROR("Error opening template");
364 return -1;
365 }
366 if (fseek(f, 0, SEEK_END) < 0) {
367 SYSERROR("Error seeking to end of template");
dd1d77f9 368 fclose(f);
3ce74686
SH
369 return -1;
370 }
371 if ((flen = ftell(f)) < 0) {
372 SYSERROR("Error telling size of template");
dd1d77f9 373 fclose(f);
3ce74686
SH
374 return -1;
375 }
376 if (fseek(f, 0, SEEK_SET) < 0) {
377 SYSERROR("Error seeking to start of template");
dd1d77f9 378 fclose(f);
3ce74686
SH
379 return -1;
380 }
381 if ((buf = malloc(flen+1)) == NULL) {
382 SYSERROR("Out of memory");
dd1d77f9 383 fclose(f);
3ce74686
SH
384 return -1;
385 }
386 if (fread(buf, 1, flen, f) != flen) {
387 SYSERROR("Failure reading template");
388 free(buf);
dd1d77f9 389 fclose(f);
3ce74686
SH
390 return -1;
391 }
dd1d77f9 392 if (fclose(f) < 0) {
3ce74686
SH
393 SYSERROR("Failre closing template");
394 free(buf);
395 return -1;
396 }
397 buf[flen] = '\0';
398 ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest);
399 free(buf);
400 return ret;
401}
402#endif
61a1d519
CS
403
404char** lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup)
405{
406 va_list ap2;
407 size_t count = 1 + skip;
408 char **result;
409
410 /* first determine size of argument list, we don't want to reallocate
411 * constantly...
412 */
413 va_copy(ap2, ap);
414 while (1) {
415 char* arg = va_arg(ap2, char*);
416 if (!arg)
417 break;
418 count++;
419 }
420 va_end(ap2);
421
422 result = calloc(count, sizeof(char*));
423 if (!result)
424 return NULL;
425 count = skip;
426 while (1) {
427 char* arg = va_arg(ap, char*);
428 if (!arg)
429 break;
430 arg = do_strdup ? strdup(arg) : arg;
431 if (!arg)
432 goto oom;
433 result[count++] = arg;
434 }
435
436 /* calloc has already set last element to NULL*/
437 return result;
438
439oom:
440 free(result);
441 return NULL;
442}
443
444const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
445{
446 return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
447}
db27c8d7 448
8bd8018e 449struct lxc_popen_FILE *lxc_popen(const char *command)
ebec9176 450{
3f323207 451 int ret;
ebec9176
AM
452 int pipe_fds[2];
453 pid_t child_pid;
8bd8018e 454 struct lxc_popen_FILE *fp = NULL;
ebec9176 455
8bd8018e
CB
456 ret = pipe2(pipe_fds, O_CLOEXEC);
457 if (ret < 0)
ebec9176 458 return NULL;
ebec9176
AM
459
460 child_pid = fork();
8bd8018e
CB
461 if (child_pid < 0)
462 goto on_error;
463
464 if (!child_pid) {
465 sigset_t mask;
466
467 close(pipe_fds[0]);
468
469 /* duplicate stdout */
470 if (pipe_fds[1] != STDOUT_FILENO)
471 ret = dup2(pipe_fds[1], STDOUT_FILENO);
472 else
473 ret = fcntl(pipe_fds[1], F_SETFD, 0);
474 if (ret < 0) {
475 close(pipe_fds[1]);
476 exit(EXIT_FAILURE);
3f323207
CB
477 }
478
8bd8018e
CB
479 /* duplicate stderr */
480 if (pipe_fds[1] != STDERR_FILENO)
481 ret = dup2(pipe_fds[1], STDERR_FILENO);
482 else
483 ret = fcntl(pipe_fds[1], F_SETFD, 0);
484 close(pipe_fds[1]);
485 if (ret < 0)
486 exit(EXIT_FAILURE);
487
488 /* unblock all signals */
489 ret = sigfillset(&mask);
490 if (ret < 0)
491 exit(EXIT_FAILURE);
492
493 ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
494 if (ret < 0)
495 exit(EXIT_FAILURE);
496
497 execl("/bin/sh", "sh", "-c", command, (char *)NULL);
ebec9176
AM
498 exit(127);
499 }
500
8bd8018e
CB
501 close(pipe_fds[1]);
502 pipe_fds[1] = -1;
ebec9176 503
8bd8018e
CB
504 fp = malloc(sizeof(*fp));
505 if (!fp)
506 goto on_error;
ebec9176
AM
507
508 fp->child_pid = child_pid;
8bd8018e 509 fp->pipe = pipe_fds[0];
ebec9176 510
8bd8018e
CB
511 fp->f = fdopen(pipe_fds[0], "r");
512 if (!fp->f)
513 goto on_error;
ebec9176 514
8bd8018e 515 return fp;
ebec9176 516
8bd8018e
CB
517on_error:
518 if (fp)
ebec9176 519 free(fp);
ebec9176 520
8bd8018e
CB
521 if (pipe_fds[0] >= 0)
522 close(pipe_fds[0]);
523
524 if (pipe_fds[1] >= 0)
525 close(pipe_fds[1]);
ebec9176
AM
526
527 return NULL;
528}
529
8bd8018e 530int lxc_pclose(struct lxc_popen_FILE *fp)
ebec9176 531{
ebec9176 532 pid_t wait_pid;
8bd8018e 533 int wstatus = 0;
ebec9176 534
8bd8018e 535 if (!fp)
ebec9176 536 return -1;
ebec9176
AM
537
538 do {
8bd8018e
CB
539 wait_pid = waitpid(fp->child_pid, &wstatus, 0);
540 } while (wait_pid < 0 && errno == EINTR);
ebec9176 541
8bd8018e
CB
542 close(fp->pipe);
543 fclose(fp->f);
544 free(fp);
545
546 if (wait_pid < 0)
ebec9176 547 return -1;
ebec9176
AM
548
549 return wstatus;
550}
551
502657d5
CS
552char *lxc_string_replace(const char *needle, const char *replacement, const char *haystack)
553{
554 ssize_t len = -1, saved_len = -1;
555 char *result = NULL;
556 size_t replacement_len = strlen(replacement);
557 size_t needle_len = strlen(needle);
558
559 /* should be executed exactly twice */
560 while (len == -1 || result == NULL) {
561 char *p;
562 char *last_p;
563 ssize_t part_len;
564
565 if (len != -1) {
566 result = calloc(1, len + 1);
567 if (!result)
568 return NULL;
569 saved_len = len;
570 }
571
572 len = 0;
573
574 for (last_p = (char *)haystack, p = strstr(last_p, needle); p; last_p = p, p = strstr(last_p, needle)) {
575 part_len = (ssize_t)(p - last_p);
576 if (result && part_len > 0)
577 memcpy(&result[len], last_p, part_len);
578 len += part_len;
579 if (result && replacement_len > 0)
580 memcpy(&result[len], replacement, replacement_len);
581 len += replacement_len;
582 p += needle_len;
583 }
584 part_len = strlen(last_p);
585 if (result && part_len > 0)
586 memcpy(&result[len], last_p, part_len);
587 len += part_len;
588 }
589
590 /* make sure we did the same thing twice,
591 * once for calculating length, the other
592 * time for copying data */
97bc2422
CB
593 if (saved_len != len) {
594 free(result);
595 return NULL;
596 }
502657d5
CS
597 /* make sure we didn't overwrite any buffer,
598 * due to calloc the string should be 0-terminated */
97bc2422
CB
599 if (result[len] != '\0') {
600 free(result);
601 return NULL;
602 }
502657d5
CS
603
604 return result;
605}
606
607bool lxc_string_in_array(const char *needle, const char **haystack)
608{
609 for (; haystack && *haystack; haystack++)
610 if (!strcmp(needle, *haystack))
611 return true;
612 return false;
613}
614
615char *lxc_string_join(const char *sep, const char **parts, bool use_as_prefix)
616{
617 char *result;
618 char **p;
619 size_t sep_len = strlen(sep);
620 size_t result_len = use_as_prefix * sep_len;
621
622 /* calculate new string length */
623 for (p = (char **)parts; *p; p++)
624 result_len += (p > (char **)parts) * sep_len + strlen(*p);
625
626 result = calloc(result_len + 1, 1);
627 if (!result)
628 return NULL;
629
630 if (use_as_prefix)
631 strcpy(result, sep);
632 for (p = (char **)parts; *p; p++) {
633 if (p > (char **)parts)
634 strcat(result, sep);
635 strcat(result, *p);
636 }
637
638 return result;
639}
640
641char **lxc_normalize_path(const char *path)
642{
643 char **components;
644 char **p;
645 size_t components_len = 0;
646 size_t pos = 0;
647
648 components = lxc_string_split(path, '/');
649 if (!components)
650 return NULL;
651 for (p = components; *p; p++)
652 components_len++;
653
654 /* resolve '.' and '..' */
655 for (pos = 0; pos < components_len; ) {
656 if (!strcmp(components[pos], ".") || (!strcmp(components[pos], "..") && pos == 0)) {
657 /* eat this element */
658 free(components[pos]);
659 memmove(&components[pos], &components[pos+1], sizeof(char *) * (components_len - pos));
660 components_len--;
661 } else if (!strcmp(components[pos], "..")) {
662 /* eat this and the previous element */
663 free(components[pos - 1]);
664 free(components[pos]);
665 memmove(&components[pos-1], &components[pos+1], sizeof(char *) * (components_len - pos));
666 components_len -= 2;
667 pos--;
668 } else {
669 pos++;
670 }
671 }
672
673 return components;
674}
675
eda0afd4 676char *lxc_deslashify(const char *path)
aeb3682f 677{
eda0afd4 678 char *dup, *p;
c56a9652
CB
679 char **parts = NULL;
680 size_t n, len;
aeb3682f 681
eda0afd4
CB
682 dup = strdup(path);
683 if (!dup)
684 return NULL;
685
686 parts = lxc_normalize_path(dup);
687 if (!parts) {
688 free(dup);
689 return NULL;
690 }
aeb3682f 691
c56a9652
CB
692 /* We'll end up here if path == "///" or path == "". */
693 if (!*parts) {
eda0afd4 694 len = strlen(dup);
f85b16a1 695 if (!len) {
eda0afd4
CB
696 lxc_free_array((void **)parts, free);
697 return dup;
f85b16a1 698 }
eda0afd4 699 n = strcspn(dup, "/");
c56a9652 700 if (n == len) {
eda0afd4
CB
701 free(dup);
702 lxc_free_array((void **)parts, free);
703
c56a9652
CB
704 p = strdup("/");
705 if (!p)
eda0afd4
CB
706 return NULL;
707
708 return p;
c56a9652
CB
709 }
710 }
711
eda0afd4
CB
712 p = lxc_string_join("/", (const char **)parts, *dup == '/');
713 free(dup);
f85b16a1 714 lxc_free_array((void **)parts, free);
eda0afd4 715 return p;
aeb3682f
TA
716}
717
24b51482
CS
718char *lxc_append_paths(const char *first, const char *second)
719{
e8eb3956
CB
720 int ret;
721 size_t len;
24b51482 722 char *result = NULL;
e8eb3956 723 const char *pattern = "%s%s";
24b51482 724
e8eb3956 725 len = strlen(first) + strlen(second) + 1;
24b51482
CS
726 if (second[0] != '/') {
727 len += 1;
728 pattern = "%s/%s";
729 }
730
731 result = calloc(1, len);
732 if (!result)
733 return NULL;
734
e8eb3956
CB
735 ret = snprintf(result, len, pattern, first, second);
736 if (ret < 0 || (size_t)ret >= len) {
737 free(result);
738 return NULL;
739 }
740
24b51482
CS
741 return result;
742}
743
502657d5
CS
744bool lxc_string_in_list(const char *needle, const char *haystack, char _sep)
745{
746 char *token, *str, *saveptr = NULL;
747 char sep[2] = { _sep, '\0' };
748
749 if (!haystack || !needle)
750 return 0;
751
752 str = alloca(strlen(haystack)+1);
753 strcpy(str, haystack);
754 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
755 if (strcmp(needle, token) == 0)
756 return 1;
757 }
758
759 return 0;
760}
761
762char **lxc_string_split(const char *string, char _sep)
763{
764 char *token, *str, *saveptr = NULL;
605ea1f7
CB
765 char sep[2] = {_sep, '\0'};
766 char **tmp = NULL, **result = NULL;
502657d5
CS
767 size_t result_capacity = 0;
768 size_t result_count = 0;
769 int r, saved_errno;
770
771 if (!string)
772 return calloc(1, sizeof(char *));
773
605ea1f7 774 str = alloca(strlen(string) + 1);
502657d5
CS
775 strcpy(str, string);
776 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
777 r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 16);
778 if (r < 0)
779 goto error_out;
780 result[result_count] = strdup(token);
781 if (!result[result_count])
782 goto error_out;
783 result_count++;
784 }
785
786 /* if we allocated too much, reduce it */
605ea1f7
CB
787 tmp = realloc(result, (result_count + 1) * sizeof(char *));
788 if (!tmp)
789 goto error_out;
790 result = tmp;
791 /* Make sure we don't return uninitialized memory. */
792 if (result_count == 0)
793 *result = NULL;
794 return result;
502657d5
CS
795error_out:
796 saved_errno = errno;
797 lxc_free_array((void **)result, free);
798 errno = saved_errno;
799 return NULL;
800}
801
3dca1af0
SH
802static bool complete_word(char ***result, char *start, char *end, size_t *cap, size_t *cnt)
803{
804 int r;
805
806 r = lxc_grow_array((void ***)result, cap, 2 + *cnt, 16);
807 if (r < 0)
808 return false;
809 (*result)[*cnt] = strndup(start, end - start);
810 if (!(*result)[*cnt])
811 return false;
812 (*cnt)++;
813
814 return true;
815}
816
817/*
818 * Given a a string 'one two "three four"', split into three words,
819 * one, two, and "three four"
820 */
821char **lxc_string_split_quoted(char *string)
822{
823 char *nextword = string, *p, state;
824 char **result = NULL;
825 size_t result_capacity = 0;
826 size_t result_count = 0;
827
828 if (!string || !*string)
829 return calloc(1, sizeof(char *));
830
831 // TODO I'm *not* handling escaped quote
832 state = ' ';
833 for (p = string; *p; p++) {
834 switch(state) {
835 case ' ':
836 if (isspace(*p))
837 continue;
838 else if (*p == '"' || *p == '\'') {
839 nextword = p;
840 state = *p;
841 continue;
842 }
843 nextword = p;
844 state = 'a';
845 continue;
846 case 'a':
847 if (isspace(*p)) {
848 complete_word(&result, nextword, p, &result_capacity, &result_count);
849 state = ' ';
850 continue;
851 }
852 continue;
853 case '"':
854 case '\'':
855 if (*p == state) {
856 complete_word(&result, nextword+1, p, &result_capacity, &result_count);
857 state = ' ';
858 continue;
859 }
860 continue;
861 }
862 }
863
864 if (state == 'a')
865 complete_word(&result, nextword, p, &result_capacity, &result_count);
866
867 return realloc(result, (result_count + 1) * sizeof(char *));
868}
869
502657d5
CS
870char **lxc_string_split_and_trim(const char *string, char _sep)
871{
872 char *token, *str, *saveptr = NULL;
873 char sep[2] = { _sep, '\0' };
874 char **result = NULL;
875 size_t result_capacity = 0;
876 size_t result_count = 0;
877 int r, saved_errno;
878 size_t i = 0;
879
880 if (!string)
881 return calloc(1, sizeof(char *));
882
883 str = alloca(strlen(string)+1);
884 strcpy(str, string);
885 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
886 while (token[0] == ' ' || token[0] == '\t')
887 token++;
888 i = strlen(token);
889 while (i > 0 && (token[i - 1] == ' ' || token[i - 1] == '\t')) {
890 token[i - 1] = '\0';
891 i--;
892 }
893 r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 16);
894 if (r < 0)
895 goto error_out;
896 result[result_count] = strdup(token);
897 if (!result[result_count])
898 goto error_out;
899 result_count++;
900 }
901
902 /* if we allocated too much, reduce it */
903 return realloc(result, (result_count + 1) * sizeof(char *));
904error_out:
905 saved_errno = errno;
906 lxc_free_array((void **)result, free);
907 errno = saved_errno;
908 return NULL;
909}
910
911void lxc_free_array(void **array, lxc_free_fn element_free_fn)
912{
913 void **p;
914 for (p = array; p && *p; p++)
915 element_free_fn(*p);
916 free((void*)array);
917}
918
919int lxc_grow_array(void ***array, size_t* capacity, size_t new_size, size_t capacity_increment)
920{
921 size_t new_capacity;
922 void **new_array;
923
924 /* first time around, catch some trivial mistakes of the user
925 * only initializing one of these */
926 if (!*array || !*capacity) {
927 *array = NULL;
928 *capacity = 0;
929 }
930
931 new_capacity = *capacity;
932 while (new_size + 1 > new_capacity)
933 new_capacity += capacity_increment;
934 if (new_capacity != *capacity) {
935 /* we have to reallocate */
936 new_array = realloc(*array, new_capacity * sizeof(void *));
937 if (!new_array)
938 return -1;
939 memset(&new_array[*capacity], 0, (new_capacity - (*capacity)) * sizeof(void *));
940 *array = new_array;
941 *capacity = new_capacity;
942 }
943
944 /* array has sufficient elements */
945 return 0;
946}
947
948size_t lxc_array_len(void **array)
949{
950 void **p;
951 size_t result = 0;
952
953 for (p = array; p && *p; p++)
954 result++;
955
956 return result;
957}
958
0e95426b
CS
959int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool add_newline)
960{
961 int fd, saved_errno;
962 ssize_t ret;
963
964 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
965 if (fd < 0)
966 return -1;
967 ret = lxc_write_nointr(fd, buf, count);
968 if (ret < 0)
799f29ab 969 goto out_error;
0e95426b
CS
970 if ((size_t)ret != count)
971 goto out_error;
972 if (add_newline) {
973 ret = lxc_write_nointr(fd, "\n", 1);
974 if (ret != 1)
975 goto out_error;
976 }
977 close(fd);
978 return 0;
979
980out_error:
981 saved_errno = errno;
982 close(fd);
983 errno = saved_errno;
984 return -1;
985}
986
987int lxc_read_from_file(const char *filename, void* buf, size_t count)
988{
989 int fd = -1, saved_errno;
990 ssize_t ret;
991
992 fd = open(filename, O_RDONLY | O_CLOEXEC);
993 if (fd < 0)
994 return -1;
995
996 if (!buf || !count) {
997 char buf2[100];
998 size_t count2 = 0;
999 while ((ret = read(fd, buf2, 100)) > 0)
1000 count2 += ret;
1001 if (ret >= 0)
1002 ret = count2;
1003 } else {
1004 memset(buf, 0, count);
1005 ret = read(fd, buf, count);
1006 }
1007
1008 if (ret < 0)
1009 ERROR("read %s: %s", filename, strerror(errno));
1010
1011 saved_errno = errno;
1012 close(fd);
1013 errno = saved_errno;
1014 return ret;
1015}
799f29ab
ÇO
1016
1017void **lxc_append_null_to_array(void **array, size_t count)
1018{
1019 void **temp;
1020
1021 /* Append NULL to the array */
1022 if (count) {
1023 temp = realloc(array, (count + 1) * sizeof(*array));
1024 if (!temp) {
84760c11 1025 size_t i;
799f29ab
ÇO
1026 for (i = 0; i < count; i++)
1027 free(array[i]);
1028 free(array);
1029 return NULL;
1030 }
1031 array = temp;
1032 array[count] = NULL;
1033 }
1034 return array;
1035}
508c263e
SH
1036
1037int randseed(bool srand_it)
1038{
1039 /*
1040 srand pre-seed function based on /dev/urandom
1041 */
091045f8 1042 unsigned int seed = time(NULL) + getpid();
508c263e
SH
1043
1044 FILE *f;
1045 f = fopen("/dev/urandom", "r");
1046 if (f) {
1047 int ret = fread(&seed, sizeof(seed), 1, f);
1048 if (ret != 1)
1049 DEBUG("unable to fread /dev/urandom, %s, fallback to time+pid rand seed", strerror(errno));
1050 fclose(f);
1051 }
1052
1053 if (srand_it)
1054 srand(seed);
1055
1056 return seed;
1057}
5d897655
SH
1058
1059uid_t get_ns_uid(uid_t orig)
1060{
1061 char *line = NULL;
1062 size_t sz = 0;
1063 uid_t nsid, hostid, range;
1064 FILE *f = fopen("/proc/self/uid_map", "r");
1065 if (!f)
1066 return 0;
1067
1068 while (getline(&line, &sz, f) != -1) {
1069 if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3)
1070 continue;
1071 if (hostid <= orig && hostid + range > orig) {
1072 nsid += orig - hostid;
1073 goto found;
1074 }
1075 }
1076
1077 nsid = 0;
1078found:
1079 fclose(f);
1080 free(line);
1081 return nsid;
1082}
c476bdce
SH
1083
1084bool dir_exists(const char *path)
1085{
1086 struct stat sb;
1087 int ret;
1088
1089 ret = stat(path, &sb);
1090 if (ret < 0)
1a0e70ac 1091 /* Could be something other than eexist, just say "no". */
c476bdce
SH
1092 return false;
1093 return S_ISDIR(sb.st_mode);
1094}
93c379f0
ÇO
1095
1096/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
1097 * FNV has good anti collision properties and we're not worried
1098 * about pre-image resistance or one-way-ness, we're just trying to make
1099 * the name unique in the 108 bytes of space we have.
1100 */
1101uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
1102{
1103 unsigned char *bp;
1104
1105 for(bp = buf; bp < (unsigned char *)buf + len; bp++)
1106 {
1107 /* xor the bottom with the current octet */
1108 hval ^= (uint64_t)*bp;
1109
1110 /* gcc optimised:
1111 * multiply by the 64 bit FNV magic prime mod 2^64
1112 */
1113 hval += (hval << 1) + (hval << 4) + (hval << 5) +
1114 (hval << 7) + (hval << 8) + (hval << 40);
1115 }
1116
1117 return hval;
1118}
2c6f3fc9
SH
1119
1120/*
1121 * Detect whether / is mounted MS_SHARED. The only way I know of to
1122 * check that is through /proc/self/mountinfo.
1123 * I'm only checking for /. If the container rootfs or mount location
1124 * is MS_SHARED, but not '/', then you're out of luck - figuring that
1125 * out would be too much work to be worth it.
1126 */
2c6f3fc9
SH
1127int detect_shared_rootfs(void)
1128{
eab15c1e 1129 char buf[LXC_LINELEN], *p;
2c6f3fc9
SH
1130 FILE *f;
1131 int i;
1132 char *p2;
1133
1134 f = fopen("/proc/self/mountinfo", "r");
1135 if (!f)
1136 return 0;
eab15c1e
CB
1137 while (fgets(buf, LXC_LINELEN, f)) {
1138 for (p = buf, i = 0; p && i < 4; i++)
1139 p = strchr(p + 1, ' ');
2c6f3fc9
SH
1140 if (!p)
1141 continue;
eab15c1e 1142 p2 = strchr(p + 1, ' ');
2c6f3fc9
SH
1143 if (!p2)
1144 continue;
1145 *p2 = '\0';
eab15c1e 1146 if (strcmp(p + 1, "/") == 0) {
1a0e70ac 1147 /* This is '/'. Is it shared? */
eab15c1e 1148 p = strchr(p2 + 1, ' ');
2c6f3fc9
SH
1149 if (p && strstr(p, "shared:")) {
1150 fclose(f);
1151 return 1;
1152 }
1153 }
1154 }
1155 fclose(f);
1156 return 0;
1157}
0e6e3a41 1158
51d0854c
DY
1159bool switch_to_ns(pid_t pid, const char *ns) {
1160 int fd, ret;
1161 char nspath[MAXPATHLEN];
1162
1163 /* Switch to new ns */
1164 ret = snprintf(nspath, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns);
1165 if (ret < 0 || ret >= MAXPATHLEN)
1166 return false;
1167
1168 fd = open(nspath, O_RDONLY);
1169 if (fd < 0) {
1170 SYSERROR("failed to open %s", nspath);
1171 return false;
1172 }
1173
1174 ret = setns(fd, 0);
1175 if (ret) {
1176 SYSERROR("failed to set process %d to %s of %d.", pid, ns, fd);
1177 close(fd);
1178 return false;
1179 }
1180 close(fd);
1181 return true;
1182}
1183
b7f954bb
SH
1184/*
1185 * looking at fs/proc_namespace.c, it appears we can
1186 * actually expect the rootfs entry to very specifically contain
1187 * " - rootfs rootfs "
1188 * IIUC, so long as we've chrooted so that rootfs is not our root,
1189 * the rootfs entry should always be skipped in mountinfo contents.
1190 */
fa454c8e 1191bool detect_ramfs_rootfs(void)
b7f954bb 1192{
b7f954bb 1193 FILE *f;
fa454c8e
CB
1194 char *p, *p2;
1195 char *line = NULL;
1196 size_t len = 0;
b7f954bb 1197 int i;
b7f954bb
SH
1198
1199 f = fopen("/proc/self/mountinfo", "r");
1200 if (!f)
fa454c8e
CB
1201 return false;
1202
1203 while (getline(&line, &len, f) != -1) {
1204 for (p = line, i = 0; p && i < 4; i++)
1205 p = strchr(p + 1, ' ');
b7f954bb
SH
1206 if (!p)
1207 continue;
fa454c8e 1208 p2 = strchr(p + 1, ' ');
b7f954bb
SH
1209 if (!p2)
1210 continue;
1211 *p2 = '\0';
fa454c8e 1212 if (strcmp(p + 1, "/") == 0) {
1a0e70ac 1213 /* This is '/'. Is it the ramfs? */
fa454c8e 1214 p = strchr(p2 + 1, '-');
b7f954bb 1215 if (p && strncmp(p, "- rootfs rootfs ", 16) == 0) {
fa454c8e 1216 free(line);
b7f954bb 1217 fclose(f);
fa454c8e 1218 return true;
b7f954bb
SH
1219 }
1220 }
1221 }
fa454c8e 1222 free(line);
b7f954bb 1223 fclose(f);
fa454c8e 1224 return false;
b7f954bb
SH
1225}
1226
df6a2945 1227char *on_path(const char *cmd, const char *rootfs) {
0e6e3a41
SG
1228 char *path = NULL;
1229 char *entry = NULL;
1230 char *saveptr = NULL;
1231 char cmdpath[MAXPATHLEN];
1232 int ret;
1233
1234 path = getenv("PATH");
1235 if (!path)
8afb3e61 1236 return NULL;
0e6e3a41
SG
1237
1238 path = strdup(path);
1239 if (!path)
8afb3e61 1240 return NULL;
0e6e3a41
SG
1241
1242 entry = strtok_r(path, ":", &saveptr);
1243 while (entry) {
9d9c111c
SH
1244 if (rootfs)
1245 ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s/%s", rootfs, entry, cmd);
1246 else
1247 ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s", entry, cmd);
0e6e3a41
SG
1248
1249 if (ret < 0 || ret >= MAXPATHLEN)
1250 goto next_loop;
1251
1252 if (access(cmdpath, X_OK) == 0) {
1253 free(path);
8afb3e61 1254 return strdup(cmdpath);
0e6e3a41
SG
1255 }
1256
1257next_loop:
b707e368 1258 entry = strtok_r(NULL, ":", &saveptr);
0e6e3a41
SG
1259 }
1260
1261 free(path);
8afb3e61 1262 return NULL;
0e6e3a41 1263}
76a26f55
SH
1264
1265bool file_exists(const char *f)
1266{
1267 struct stat statbuf;
1268
1269 return stat(f, &statbuf) == 0;
1270}
9d9c111c 1271
12983ba4
SH
1272bool cgns_supported(void)
1273{
1274 return file_exists("/proc/self/ns/cgroup");
1275}
1276
9d9c111c
SH
1277/* historically lxc-init has been under /usr/lib/lxc and under
1278 * /usr/lib/$ARCH/lxc. It now lives as $prefix/sbin/init.lxc.
1279 */
1280char *choose_init(const char *rootfs)
1281{
1282 char *retv = NULL;
370ec268
SF
1283 const char *empty = "",
1284 *tmp;
9d9c111c 1285 int ret, env_set = 0;
9d9c111c
SH
1286
1287 if (!getenv("PATH")) {
1288 if (setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0))
1289 SYSERROR("Failed to setenv");
1290 env_set = 1;
1291 }
1292
1293 retv = on_path("init.lxc", rootfs);
1294
1295 if (env_set) {
1296 if (unsetenv("PATH"))
1297 SYSERROR("Failed to unsetenv");
1298 }
1299
1300 if (retv)
1301 return retv;
1302
1303 retv = malloc(PATH_MAX);
1304 if (!retv)
1305 return NULL;
1306
1307 if (rootfs)
370ec268 1308 tmp = rootfs;
9d9c111c 1309 else
370ec268
SF
1310 tmp = empty;
1311
1312 ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, SBINDIR, "/init.lxc");
9d9c111c
SH
1313 if (ret < 0 || ret >= PATH_MAX) {
1314 ERROR("pathname too long");
1315 goto out1;
1316 }
e57cd7e9 1317 if (access(retv, X_OK) == 0)
9d9c111c
SH
1318 return retv;
1319
370ec268 1320 ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, LXCINITDIR, "/lxc/lxc-init");
9d9c111c
SH
1321 if (ret < 0 || ret >= PATH_MAX) {
1322 ERROR("pathname too long");
1323 goto out1;
1324 }
e57cd7e9 1325 if (access(retv, X_OK) == 0)
9d9c111c
SH
1326 return retv;
1327
370ec268 1328 ret = snprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", tmp);
9d9c111c
SH
1329 if (ret < 0 || ret >= PATH_MAX) {
1330 ERROR("pathname too long");
1331 goto out1;
1332 }
e57cd7e9 1333 if (access(retv, X_OK) == 0)
9d9c111c
SH
1334 return retv;
1335
370ec268 1336 ret = snprintf(retv, PATH_MAX, "%s/sbin/lxc-init", tmp);
9d9c111c
SH
1337 if (ret < 0 || ret >= PATH_MAX) {
1338 ERROR("pathname too long");
1339 goto out1;
1340 }
e57cd7e9 1341 if (access(retv, X_OK) == 0)
9d9c111c
SH
1342 return retv;
1343
1344 /*
1345 * Last resort, look for the statically compiled init.lxc which we
1346 * hopefully bind-mounted in.
1347 * If we are called during container setup, and we get to this point,
1348 * then the init.lxc.static from the host will need to be bind-mounted
1349 * in. So we return NULL here to indicate that.
1350 */
1351 if (rootfs)
1352 goto out1;
1353
1354 ret = snprintf(retv, PATH_MAX, "/init.lxc.static");
1355 if (ret < 0 || ret >= PATH_MAX) {
1356 WARN("Nonsense - name /lxc.init.static too long");
1357 goto out1;
1358 }
e57cd7e9 1359 if (access(retv, X_OK) == 0)
9d9c111c
SH
1360 return retv;
1361
1362out1:
1363 free(retv);
1364 return NULL;
1365}
735f2c6e
TA
1366
1367int print_to_file(const char *file, const char *content)
1368{
1369 FILE *f;
1370 int ret = 0;
1371
1372 f = fopen(file, "w");
1373 if (!f)
1374 return -1;
1375 if (fprintf(f, "%s", content) != strlen(content))
1376 ret = -1;
1377 fclose(f);
1378 return ret;
1379}
e1daebd9
SH
1380
1381int is_dir(const char *path)
1382{
1383 struct stat statbuf;
1384 int ret = stat(path, &statbuf);
1385 if (ret == 0 && S_ISDIR(statbuf.st_mode))
1386 return 1;
1387 return 0;
1388}
6010a416
SG
1389
1390/*
1391 * Given the '-t' template option to lxc-create, figure out what to
1392 * do. If the template is a full executable path, use that. If it
1393 * is something like 'sshd', then return $templatepath/lxc-sshd.
1394 * On success return the template, on error return NULL.
1395 */
1396char *get_template_path(const char *t)
1397{
1398 int ret, len;
1399 char *tpath;
1400
1401 if (t[0] == '/' && access(t, X_OK) == 0) {
1402 tpath = strdup(t);
1403 return tpath;
1404 }
1405
1406 len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1;
1407 tpath = malloc(len);
1408 if (!tpath)
1409 return NULL;
1410 ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
1411 if (ret < 0 || ret >= len) {
1412 free(tpath);
1413 return NULL;
1414 }
1415 if (access(tpath, X_OK) < 0) {
1416 SYSERROR("bad template: %s", t);
1417 free(tpath);
1418 return NULL;
1419 }
1420
1421 return tpath;
1422}
0a4be28d 1423
592fd47a
SH
1424/*
1425 * @path: a pathname where / replaced with '\0'.
1426 * @offsetp: pointer to int showing which path segment was last seen.
1427 * Updated on return to reflect the next segment.
1428 * @fulllen: full original path length.
1429 * Returns a pointer to the next path segment, or NULL if done.
1430 */
1431static char *get_nextpath(char *path, int *offsetp, int fulllen)
1432{
1433 int offset = *offsetp;
1434
1435 if (offset >= fulllen)
1436 return NULL;
1437
1438 while (path[offset] != '\0' && offset < fulllen)
1439 offset++;
1440 while (path[offset] == '\0' && offset < fulllen)
1441 offset++;
1442
1443 *offsetp = offset;
1444 return (offset < fulllen) ? &path[offset] : NULL;
1445}
1446
1447/*
1448 * Check that @subdir is a subdir of @dir. @len is the length of
1449 * @dir (to avoid having to recalculate it).
1450 */
1451static bool is_subdir(const char *subdir, const char *dir, size_t len)
1452{
1453 size_t subdirlen = strlen(subdir);
1454
1455 if (subdirlen < len)
1456 return false;
1457 if (strncmp(subdir, dir, len) != 0)
1458 return false;
1459 if (dir[len-1] == '/')
1460 return true;
1461 if (subdir[len] == '/' || subdirlen == len)
1462 return true;
1463 return false;
1464}
1465
1466/*
1467 * Check if the open fd is a symlink. Return -ELOOP if it is. Return
1468 * -ENOENT if we couldn't fstat. Return 0 if the fd is ok.
1469 */
1470static int check_symlink(int fd)
1471{
1472 struct stat sb;
1473 int ret = fstat(fd, &sb);
1474 if (ret < 0)
1475 return -ENOENT;
1476 if (S_ISLNK(sb.st_mode))
1477 return -ELOOP;
1478 return 0;
1479}
1480
1481/*
1482 * Open a file or directory, provided that it contains no symlinks.
1483 *
1484 * CAVEAT: This function must not be used for other purposes than container
1485 * setup before executing the container's init
1486 */
1487static int open_if_safe(int dirfd, const char *nextpath)
1488{
1489 int newfd = openat(dirfd, nextpath, O_RDONLY | O_NOFOLLOW);
1a0e70ac 1490 if (newfd >= 0) /* Was not a symlink, all good. */
592fd47a
SH
1491 return newfd;
1492
1493 if (errno == ELOOP)
1494 return newfd;
1495
1496 if (errno == EPERM || errno == EACCES) {
1a0e70ac
CB
1497 /* We're not root (cause we got EPERM) so try opening with
1498 * O_PATH.
1499 */
592fd47a
SH
1500 newfd = openat(dirfd, nextpath, O_PATH | O_NOFOLLOW);
1501 if (newfd >= 0) {
1a0e70ac
CB
1502 /* O_PATH will return an fd for symlinks. We know
1503 * nextpath wasn't a symlink at last openat, so if fd is
1504 * now a link, then something * fishy is going on.
592fd47a
SH
1505 */
1506 int ret = check_symlink(newfd);
1507 if (ret < 0) {
1508 close(newfd);
1509 newfd = ret;
1510 }
1511 }
1512 }
1513
1514 return newfd;
1515}
1516
1517/*
1518 * Open a path intending for mounting, ensuring that the final path
1519 * is inside the container's rootfs.
1520 *
1521 * CAVEAT: This function must not be used for other purposes than container
1522 * setup before executing the container's init
1523 *
1524 * @target: path to be opened
1525 * @prefix_skip: a part of @target in which to ignore symbolic links. This
1526 * would be the container's rootfs.
1527 *
1528 * Return an open fd for the path, or <0 on error.
1529 */
1530static int open_without_symlink(const char *target, const char *prefix_skip)
1531{
1532 int curlen = 0, dirfd, fulllen, i;
1533 char *dup = NULL;
1534
1535 fulllen = strlen(target);
1536
1537 /* make sure prefix-skip makes sense */
01074e5b 1538 if (prefix_skip && strlen(prefix_skip) > 0) {
592fd47a
SH
1539 curlen = strlen(prefix_skip);
1540 if (!is_subdir(target, prefix_skip, curlen)) {
1541 ERROR("WHOA there - target '%s' didn't start with prefix '%s'",
1542 target, prefix_skip);
1543 return -EINVAL;
1544 }
1545 /*
1546 * get_nextpath() expects the curlen argument to be
1547 * on a (turned into \0) / or before it, so decrement
1548 * curlen to make sure that happens
1549 */
1550 if (curlen)
1551 curlen--;
1552 } else {
1553 prefix_skip = "/";
1554 curlen = 0;
1555 }
1556
1557 /* Make a copy of target which we can hack up, and tokenize it */
1558 if ((dup = strdup(target)) == NULL) {
1559 SYSERROR("Out of memory checking for symbolic link");
1560 return -ENOMEM;
1561 }
1562 for (i = 0; i < fulllen; i++) {
1563 if (dup[i] == '/')
1564 dup[i] = '\0';
1565 }
1566
1567 dirfd = open(prefix_skip, O_RDONLY);
1568 if (dirfd < 0)
1569 goto out;
1570 while (1) {
1571 int newfd, saved_errno;
1572 char *nextpath;
1573
1574 if ((nextpath = get_nextpath(dup, &curlen, fulllen)) == NULL)
1575 goto out;
1576 newfd = open_if_safe(dirfd, nextpath);
1577 saved_errno = errno;
1578 close(dirfd);
1579 dirfd = newfd;
1580 if (newfd < 0) {
1581 errno = saved_errno;
1582 if (errno == ELOOP)
1583 SYSERROR("%s in %s was a symbolic link!", nextpath, target);
592fd47a
SH
1584 goto out;
1585 }
1586 }
1587
1588out:
1589 free(dup);
1590 return dirfd;
1591}
1592
1593/*
1594 * Safely mount a path into a container, ensuring that the mount target
1595 * is under the container's @rootfs. (If @rootfs is NULL, then the container
1596 * uses the host's /)
1597 *
1598 * CAVEAT: This function must not be used for other purposes than container
1599 * setup before executing the container's init
1600 */
1601int safe_mount(const char *src, const char *dest, const char *fstype,
1602 unsigned long flags, const void *data, const char *rootfs)
1603{
1a0e70ac
CB
1604 int destfd, ret, saved_errno;
1605 /* Only needs enough for /proc/self/fd/<fd>. */
1606 char srcbuf[50], destbuf[50];
1607 int srcfd = -1;
592fd47a
SH
1608 const char *mntsrc = src;
1609
1610 if (!rootfs)
1611 rootfs = "";
1612
1613 /* todo - allow symlinks for relative paths if 'allowsymlinks' option is passed */
1614 if (flags & MS_BIND && src && src[0] != '/') {
1615 INFO("this is a relative bind mount");
1616 srcfd = open_without_symlink(src, NULL);
1617 if (srcfd < 0)
1618 return srcfd;
1619 ret = snprintf(srcbuf, 50, "/proc/self/fd/%d", srcfd);
1620 if (ret < 0 || ret > 50) {
1621 close(srcfd);
1622 ERROR("Out of memory");
1623 return -EINVAL;
1624 }
1625 mntsrc = srcbuf;
1626 }
1627
1628 destfd = open_without_symlink(dest, rootfs);
1629 if (destfd < 0) {
88e078ba
CB
1630 if (srcfd != -1) {
1631 saved_errno = errno;
592fd47a 1632 close(srcfd);
88e078ba
CB
1633 errno = saved_errno;
1634 }
592fd47a
SH
1635 return destfd;
1636 }
1637
1638 ret = snprintf(destbuf, 50, "/proc/self/fd/%d", destfd);
1639 if (ret < 0 || ret > 50) {
1640 if (srcfd != -1)
1641 close(srcfd);
1642 close(destfd);
1643 ERROR("Out of memory");
1644 return -EINVAL;
1645 }
1646
1647 ret = mount(mntsrc, destbuf, fstype, flags, data);
1648 saved_errno = errno;
1649 if (srcfd != -1)
1650 close(srcfd);
1651 close(destfd);
1652 if (ret < 0) {
1653 errno = saved_errno;
0103eb53 1654 SYSERROR("Failed to mount %s onto %s", src ? src : "(null)", dest);
592fd47a
SH
1655 return ret;
1656 }
1657
1658 return 0;
1659}
1660
ced03a01
SH
1661/*
1662 * Mount a proc under @rootfs if proc self points to a pid other than
1663 * my own. This is needed to have a known-good proc mount for setting
1664 * up LSMs both at container startup and attach.
1665 *
1666 * @rootfs : the rootfs where proc should be mounted
1667 *
1668 * Returns < 0 on failure, 0 if the correct proc was already mounted
1669 * and 1 if a new proc was mounted.
f267d666
BP
1670 *
1671 * NOTE: not to be called from inside the container namespace!
ced03a01 1672 */
943144d9 1673int lxc_mount_proc_if_needed(const char *rootfs)
ced03a01
SH
1674{
1675 char path[MAXPATHLEN];
6b1ba5d6
CB
1676 int link_to_pid, linklen, mypid, ret;
1677 char link[LXC_NUMSTRLEN64] = {0};
ced03a01
SH
1678
1679 ret = snprintf(path, MAXPATHLEN, "%s/proc/self", rootfs);
1680 if (ret < 0 || ret >= MAXPATHLEN) {
1681 SYSERROR("proc path name too long");
1682 return -1;
1683 }
fc2ad9dc 1684
6b1ba5d6 1685 linklen = readlink(path, link, LXC_NUMSTRLEN64);
fc2ad9dc 1686
ced03a01 1687 ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs);
d539a2b2
CB
1688 if (ret < 0 || ret >= MAXPATHLEN) {
1689 SYSERROR("proc path name too long");
1690 return -1;
1691 }
fc2ad9dc
CB
1692
1693 /* /proc not mounted */
1694 if (linklen < 0) {
1695 if (mkdir(path, 0755) && errno != EEXIST)
1696 return -1;
ced03a01 1697 goto domount;
6b1ba5d6
CB
1698 } else if (linklen >= LXC_NUMSTRLEN64) {
1699 link[linklen - 1] = '\0';
1700 ERROR("readlink returned truncated content: \"%s\"", link);
1701 return -1;
fc2ad9dc
CB
1702 }
1703
0059379f 1704 mypid = lxc_raw_getpid();
6b1ba5d6
CB
1705 INFO("I am %d, /proc/self points to \"%s\"", mypid, link);
1706
2d036cca
CB
1707 if (lxc_safe_int(link, &link_to_pid) < 0)
1708 return -1;
fc2ad9dc 1709
6b1ba5d6
CB
1710 /* correct procfs is already mounted */
1711 if (link_to_pid == mypid)
1712 return 0;
fc2ad9dc 1713
6b1ba5d6
CB
1714 ret = umount2(path, MNT_DETACH);
1715 if (ret < 0)
1716 WARN("failed to umount \"%s\" with MNT_DETACH", path);
ced03a01
SH
1717
1718domount:
fc2ad9dc 1719 /* rootfs is NULL */
6b1ba5d6 1720 if (!strcmp(rootfs, ""))
f267d666
BP
1721 ret = mount("proc", path, "proc", 0, NULL);
1722 else
1723 ret = safe_mount("proc", path, "proc", 0, NULL, rootfs);
f267d666 1724 if (ret < 0)
ced03a01 1725 return -1;
f267d666 1726
fc2ad9dc 1727 INFO("mounted /proc in container for security transition");
ced03a01
SH
1728 return 1;
1729}
69aeabac 1730
f8dd0275 1731int open_devnull(void)
69aeabac 1732{
f8dd0275
AM
1733 int fd = open("/dev/null", O_RDWR);
1734
1735 if (fd < 0)
1736 SYSERROR("Can't open /dev/null");
1737
1738 return fd;
1739}
69aeabac 1740
f8dd0275
AM
1741int set_stdfds(int fd)
1742{
bbbf65ee
CB
1743 int ret;
1744
69aeabac
TA
1745 if (fd < 0)
1746 return -1;
1747
bbbf65ee
CB
1748 ret = dup2(fd, STDIN_FILENO);
1749 if (ret < 0)
f8dd0275 1750 return -1;
bbbf65ee
CB
1751
1752 ret = dup2(fd, STDOUT_FILENO);
1753 if (ret < 0)
f8dd0275 1754 return -1;
bbbf65ee
CB
1755
1756 ret = dup2(fd, STDERR_FILENO);
1757 if (ret < 0)
f8dd0275
AM
1758 return -1;
1759
1760 return 0;
1761}
1762
1763int null_stdfds(void)
1764{
1765 int ret = -1;
1766 int fd = open_devnull();
1767
1768 if (fd >= 0) {
1769 ret = set_stdfds(fd);
1770 close(fd);
1771 }
69aeabac 1772
69aeabac
TA
1773 return ret;
1774}
ccb4cabe
SH
1775
1776/*
1777 * Return the number of lines in file @fn, or -1 on error
1778 */
1779int lxc_count_file_lines(const char *fn)
1780{
1781 FILE *f;
1782 char *line = NULL;
1783 size_t sz = 0;
1784 int n = 0;
1785
1786 f = fopen_cloexec(fn, "r");
1787 if (!f)
1788 return -1;
1789
1790 while (getline(&line, &sz, f) != -1) {
1791 n++;
1792 }
1793 free(line);
1794 fclose(f);
1795 return n;
1796}
1adbd020 1797
25086a5f
CB
1798void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
1799 off_t offset)
1adbd020
CB
1800{
1801 void *tmp = NULL, *overlap = NULL;
1802
1803 /* We establish an anonymous mapping that is one byte larger than the
1804 * underlying file. The pages handed to us are zero filled. */
1805 tmp = mmap(addr, length + 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1806 if (tmp == MAP_FAILED)
a1e5280d 1807 return tmp;
1adbd020
CB
1808
1809 /* Now we establish a fixed-address mapping starting at the address we
1810 * received from our anonymous mapping and replace all bytes excluding
1811 * the additional \0-byte with the file. This allows us to use normal
a1e5280d 1812 * string-handling functions. */
1adbd020
CB
1813 overlap = mmap(tmp, length, prot, MAP_FIXED | flags, fd, offset);
1814 if (overlap == MAP_FAILED)
a1e5280d 1815 munmap(tmp, length + 1);
1adbd020 1816
1adbd020
CB
1817 return overlap;
1818}
1819
25086a5f 1820int lxc_strmunmap(void *addr, size_t length)
1adbd020
CB
1821{
1822 return munmap(addr, length + 1);
1823}
330ae3d3
CB
1824
1825/* Check whether a signal is blocked by a process. */
de3c491b 1826/* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */
eab15c1e 1827#define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
330ae3d3
CB
1828bool task_blocking_signal(pid_t pid, int signal)
1829{
1830 bool bret = false;
1831 char *line = NULL;
1832 long unsigned int sigblk = 0;
1833 size_t n = 0;
1834 int ret;
1835 FILE *f;
1836
de3c491b 1837 char status[__PROC_STATUS_LEN];
330ae3d3 1838
de3c491b
CB
1839 ret = snprintf(status, __PROC_STATUS_LEN, "/proc/%d/status", pid);
1840 if (ret < 0 || ret >= __PROC_STATUS_LEN)
330ae3d3
CB
1841 return bret;
1842
1843 f = fopen(status, "r");
1844 if (!f)
1845 return bret;
1846
1847 while (getline(&line, &n, f) != -1) {
6fbcbe3b
CB
1848 if (strncmp(line, "SigBlk:\t", 8))
1849 continue;
1850
1851 if (sscanf(line + 8, "%lx", &sigblk) != 1)
1852 goto out;
330ae3d3
CB
1853 }
1854
6fbcbe3b 1855 if (sigblk & (1LU << (signal - 1)))
330ae3d3
CB
1856 bret = true;
1857
1858out:
1859 free(line);
1860 fclose(f);
1861 return bret;
1862}
000dfda7
CB
1863
1864static int lxc_append_null_to_list(void ***list)
1865{
1866 int newentry = 0;
1867 void **tmp;
1868
1869 if (*list)
1870 for (; (*list)[newentry]; newentry++) {
1871 ;
1872 }
1873
1874 tmp = realloc(*list, (newentry + 2) * sizeof(void **));
1875 if (!tmp)
1876 return -1;
1877
1878 *list = tmp;
1879 (*list)[newentry + 1] = NULL;
1880
1881 return newentry;
1882}
1883
1884int lxc_append_string(char ***list, char *entry)
1885{
000dfda7 1886 char *copy;
a54694f8
CB
1887 int newentry;
1888
1889 newentry = lxc_append_null_to_list((void ***)list);
1890 if (newentry < 0)
1891 return -1;
000dfda7
CB
1892
1893 copy = strdup(entry);
1894 if (!copy)
1895 return -1;
1896
1897 (*list)[newentry] = copy;
1898
1899 return 0;
1900}
a687256f
CB
1901
1902int lxc_preserve_ns(const int pid, const char *ns)
1903{
1904 int ret;
a052913d
CB
1905/* 5 /proc + 21 /int_as_str + 3 /ns + 20 /NS_NAME + 1 \0 */
1906#define __NS_PATH_LEN 50
1907 char path[__NS_PATH_LEN];
a687256f 1908
4d8ac866
CB
1909 /* This way we can use this function to also check whether namespaces
1910 * are supported by the kernel by passing in the NULL or the empty
1911 * string.
1912 */
a052913d 1913 ret = snprintf(path, __NS_PATH_LEN, "/proc/%d/ns%s%s", pid,
4d8ac866
CB
1914 !ns || strcmp(ns, "") == 0 ? "" : "/",
1915 !ns || strcmp(ns, "") == 0 ? "" : ns);
134284c3 1916 errno = EFBIG;
a052913d 1917 if (ret < 0 || (size_t)ret >= __NS_PATH_LEN)
134284c3 1918 return -EFBIG;
a687256f
CB
1919
1920 return open(path, O_RDONLY | O_CLOEXEC);
1921}
6bc2eafe
CB
1922
1923int lxc_safe_uint(const char *numstr, unsigned int *converted)
1924{
1925 char *err = NULL;
1926 unsigned long int uli;
1927
643c1984
CB
1928 while (isspace(*numstr))
1929 numstr++;
1930
1931 if (*numstr == '-')
1932 return -EINVAL;
1933
6bc2eafe
CB
1934 errno = 0;
1935 uli = strtoul(numstr, &err, 0);
643c1984 1936 if (errno == ERANGE && uli == ULONG_MAX)
ff0e49c7 1937 return -ERANGE;
6bc2eafe 1938
643c1984 1939 if (err == numstr || *err != '\0')
6bc2eafe
CB
1940 return -EINVAL;
1941
1942 if (uli > UINT_MAX)
1943 return -ERANGE;
1944
8c57d930 1945 *converted = (unsigned int)uli;
6bc2eafe
CB
1946 return 0;
1947}
b5f845e7 1948
681188c1
CB
1949int lxc_safe_ulong(const char *numstr, unsigned long *converted)
1950{
1951 char *err = NULL;
1952 unsigned long int uli;
1953
1954 while (isspace(*numstr))
1955 numstr++;
1956
1957 if (*numstr == '-')
1958 return -EINVAL;
1959
1960 errno = 0;
1961 uli = strtoul(numstr, &err, 0);
1962 if (errno == ERANGE && uli == ULONG_MAX)
1963 return -ERANGE;
1964
1965 if (err == numstr || *err != '\0')
1966 return -EINVAL;
1967
1968 *converted = uli;
1969 return 0;
1970}
1971
b5f845e7
CB
1972int lxc_safe_int(const char *numstr, int *converted)
1973{
1974 char *err = NULL;
1975 signed long int sli;
1976
1977 errno = 0;
1978 sli = strtol(numstr, &err, 0);
643c1984 1979 if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
ff0e49c7 1980 return -ERANGE;
643c1984
CB
1981
1982 if (errno != 0 && sli == 0)
ff0e49c7 1983 return -EINVAL;
b5f845e7 1984
643c1984 1985 if (err == numstr || *err != '\0')
b5f845e7
CB
1986 return -EINVAL;
1987
643c1984 1988 if (sli > INT_MAX || sli < INT_MIN)
b5f845e7
CB
1989 return -ERANGE;
1990
1991 *converted = (int)sli;
1992 return 0;
1993}
8c57d930
CB
1994
1995int lxc_safe_long(const char *numstr, long int *converted)
1996{
1997 char *err = NULL;
1998 signed long int sli;
1999
2000 errno = 0;
2001 sli = strtol(numstr, &err, 0);
643c1984 2002 if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
ff0e49c7 2003 return -ERANGE;
8c57d930 2004
643c1984 2005 if (errno != 0 && sli == 0)
ff0e49c7 2006 return -EINVAL;
8c57d930 2007
643c1984
CB
2008 if (err == numstr || *err != '\0')
2009 return -EINVAL;
8c57d930
CB
2010
2011 *converted = sli;
2012 return 0;
2013}
dbaf55a3 2014
b037bc67
CB
2015int lxc_safe_long_long(const char *numstr, long long int *converted)
2016{
2017 char *err = NULL;
2018 signed long long int sli;
2019
2020 errno = 0;
2021 sli = strtoll(numstr, &err, 0);
2022 if (errno == ERANGE && (sli == LLONG_MAX || sli == LLONG_MIN))
2023 return -ERANGE;
2024
2025 if (errno != 0 && sli == 0)
2026 return -EINVAL;
2027
2028 if (err == numstr || *err != '\0')
2029 return -EINVAL;
2030
2031 *converted = sli;
2032 return 0;
2033}
2034
dbaf55a3
CB
2035int lxc_switch_uid_gid(uid_t uid, gid_t gid)
2036{
2037 if (setgid(gid) < 0) {
2038 SYSERROR("Failed to switch to gid %d.", gid);
2039 return -errno;
2040 }
2041 NOTICE("Switched to gid %d.", gid);
2042
2043 if (setuid(uid) < 0) {
2044 SYSERROR("Failed to switch to uid %d.", uid);
2045 return -errno;
2046 }
2047 NOTICE("Switched to uid %d.", uid);
2048
2049 return 0;
2050}
2051
2052/* Simple covenience function which enables uniform logging. */
2053int lxc_setgroups(int size, gid_t list[])
2054{
2055 if (setgroups(size, list) < 0) {
2056 SYSERROR("Failed to setgroups().");
2057 return -errno;
2058 }
2059 NOTICE("Dropped additional groups.");
2060
2061 return 0;
2062}
c6868a1f
CB
2063
2064static int lxc_get_unused_loop_dev_legacy(char *loop_name)
2065{
2066 struct dirent *dp;
2067 struct loop_info64 lo64;
2068 DIR *dir;
2069 int dfd = -1, fd = -1, ret = -1;
2070
2071 dir = opendir("/dev");
2072 if (!dir)
2073 return -1;
2074
2075 while ((dp = readdir(dir))) {
2076 if (!dp)
2077 break;
2078
2079 if (strncmp(dp->d_name, "loop", 4) != 0)
2080 continue;
2081
2082 dfd = dirfd(dir);
2083 if (dfd < 0)
2084 continue;
2085
2086 fd = openat(dfd, dp->d_name, O_RDWR);
2087 if (fd < 0)
2088 continue;
2089
2090 ret = ioctl(fd, LOOP_GET_STATUS64, &lo64);
2091 if (ret < 0) {
2092 if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0 ||
2093 errno != ENXIO) {
2094 close(fd);
2095 fd = -1;
2096 continue;
2097 }
2098 }
2099
2100 ret = snprintf(loop_name, LO_NAME_SIZE, "/dev/%s", dp->d_name);
2101 if (ret < 0 || ret >= LO_NAME_SIZE) {
2102 close(fd);
2103 fd = -1;
2104 continue;
2105 }
2106
2107 break;
2108 }
2109
2110 closedir(dir);
2111
2112 if (fd < 0)
2113 return -1;
2114
2115 return fd;
2116}
2117
2118static int lxc_get_unused_loop_dev(char *name_loop)
2119{
2120 int loop_nr, ret;
2121 int fd_ctl = -1, fd_tmp = -1;
2122
2123 fd_ctl = open("/dev/loop-control", O_RDWR | O_CLOEXEC);
2124 if (fd_ctl < 0)
2125 return -ENODEV;
2126
2127 loop_nr = ioctl(fd_ctl, LOOP_CTL_GET_FREE);
2128 if (loop_nr < 0)
2129 goto on_error;
2130
2131 ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr);
2132 if (ret < 0 || ret >= LO_NAME_SIZE)
2133 goto on_error;
2134
2135 fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC);
2136 if (fd_tmp < 0)
2137 goto on_error;
2138
2139on_error:
2140 close(fd_ctl);
2141 return fd_tmp;
2142}
2143
2144int lxc_prepare_loop_dev(const char *source, char *loop_dev, int flags)
2145{
2146 int ret;
2147 struct loop_info64 lo64;
2148 int fd_img = -1, fret = -1, fd_loop = -1;
2149
2150 fd_loop = lxc_get_unused_loop_dev(loop_dev);
2151 if (fd_loop < 0) {
2152 if (fd_loop == -ENODEV)
2153 fd_loop = lxc_get_unused_loop_dev_legacy(loop_dev);
2154 else
2155 goto on_error;
2156 }
2157
2158 fd_img = open(source, O_RDWR | O_CLOEXEC);
2159 if (fd_img < 0)
2160 goto on_error;
2161
2162 ret = ioctl(fd_loop, LOOP_SET_FD, fd_img);
2163 if (ret < 0)
2164 goto on_error;
2165
2166 memset(&lo64, 0, sizeof(lo64));
2167 lo64.lo_flags = flags;
2168
2169 ret = ioctl(fd_loop, LOOP_SET_STATUS64, &lo64);
2170 if (ret < 0)
2171 goto on_error;
2172
2173 fret = 0;
2174
2175on_error:
2176 if (fd_img >= 0)
2177 close(fd_img);
2178
2179 if (fret < 0 && fd_loop >= 0) {
2180 close(fd_loop);
2181 fd_loop = -1;
2182 }
2183
2184 return fd_loop;
2185}
74251e49
CB
2186
2187int lxc_unstack_mountpoint(const char *path, bool lazy)
2188{
2189 int ret;
2190 int umounts = 0;
2191
2192pop_stack:
2193 ret = umount2(path, lazy ? MNT_DETACH : 0);
2194 if (ret < 0) {
2195 /* We consider anything else than EINVAL deadly to prevent going
2196 * into an infinite loop. (The other alternative is constantly
2197 * parsing /proc/self/mountinfo which is yucky and probably
2198 * racy.)
2199 */
2200 if (errno != EINVAL)
2201 return -errno;
2202 } else {
b4a40f7b
CB
2203 /* Just stop counting when this happens. That'd just be so
2204 * stupid that we won't even bother trying to report back the
2205 * correct value anymore.
2206 */
2207 if (umounts != INT_MAX)
2208 umounts++;
74251e49
CB
2209 /* We succeeded in umounting. Make sure that there's no other
2210 * mountpoint stacked underneath.
2211 */
74251e49
CB
2212 goto pop_stack;
2213 }
2214
2215 return umounts;
2216}
ea3a694f
CB
2217
2218int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
2219{
2220 pid_t child;
2221 int ret, fret, pipefd[2];
2222 ssize_t bytes;
2223
2224 /* Make sure our callers do not receive unitialized memory. */
2225 if (buf_size > 0 && buf)
2226 buf[0] = '\0';
2227
2228 if (pipe(pipefd) < 0) {
2229 SYSERROR("failed to create pipe");
2230 return -1;
2231 }
2232
2d728b2f 2233 child = lxc_raw_clone(0);
ea3a694f
CB
2234 if (child < 0) {
2235 close(pipefd[0]);
2236 close(pipefd[1]);
2237 SYSERROR("failed to create new process");
2238 return -1;
2239 }
2240
2241 if (child == 0) {
2242 /* Close the read-end of the pipe. */
2243 close(pipefd[0]);
2244
2245 /* Redirect std{err,out} to write-end of the
2246 * pipe.
2247 */
2248 ret = dup2(pipefd[1], STDOUT_FILENO);
2249 if (ret >= 0)
2250 ret = dup2(pipefd[1], STDERR_FILENO);
2251
2252 /* Close the write-end of the pipe. */
2253 close(pipefd[1]);
2254
2255 if (ret < 0) {
2256 SYSERROR("failed to duplicate std{err,out} file descriptor");
2257 exit(EXIT_FAILURE);
2258 }
2259
2260 /* Does not return. */
2261 child_fn(args);
2262 ERROR("failed to exec command");
2263 exit(EXIT_FAILURE);
2264 }
2265
2266 /* close the write-end of the pipe */
2267 close(pipefd[1]);
2268
7a643c7c
CB
2269 if (buf && buf_size > 0) {
2270 bytes = read(pipefd[0], buf, buf_size - 1);
2271 if (bytes > 0)
2272 buf[bytes - 1] = '\0';
2273 }
ea3a694f
CB
2274
2275 fret = wait_for_pid(child);
2276 /* close the read-end of the pipe */
2277 close(pipefd[0]);
2278
2279 return fret;
2280}
04ad7ffe
CB
2281
2282char *must_make_path(const char *first, ...)
2283{
2284 va_list args;
2285 char *cur, *dest;
2286 size_t full_len = strlen(first);
2287
2288 dest = must_copy_string(first);
2289
2290 va_start(args, first);
2291 while ((cur = va_arg(args, char *)) != NULL) {
2292 full_len += strlen(cur);
2293 if (cur[0] != '/')
2294 full_len++;
2295 dest = must_realloc(dest, full_len + 1);
2296 if (cur[0] != '/')
2297 strcat(dest, "/");
2298 strcat(dest, cur);
2299 }
2300 va_end(args);
2301
2302 return dest;
2303}
2304
2305char *must_copy_string(const char *entry)
2306{
2307 char *ret;
2308
2309 if (!entry)
2310 return NULL;
2311 do {
2312 ret = strdup(entry);
2313 } while (!ret);
2314
2315 return ret;
2316}
2317
2318void *must_realloc(void *orig, size_t sz)
2319{
2320 void *ret;
2321
2322 do {
2323 ret = realloc(orig, sz);
2324 } while (!ret);
2325
2326 return ret;
2327}
a035c53a
CB
2328
2329bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val)
2330{
2331 return (fs->f_type == (fs_type_magic)magic_val);
2332}
2333
2334bool has_fs_type(const char *path, fs_type_magic magic_val)
2335{
2336 bool has_type;
2337 int ret;
2338 struct statfs sb;
2339
2340 ret = statfs(path, &sb);
2341 if (ret < 0)
2342 return false;
2343
2344 has_type = is_fs_type(&sb, magic_val);
2345 if (!has_type && magic_val == RAMFS_MAGIC)
2346 WARN("When the ramfs it a tmpfs statfs() might report tmpfs");
2347
2348 return has_type;
2349}
d75c14e2
CB
2350
2351bool lxc_nic_exists(char *nic)
2352{
2353#define __LXC_SYS_CLASS_NET_LEN 15 + IFNAMSIZ + 1
2354 char path[__LXC_SYS_CLASS_NET_LEN];
2355 int ret;
2356 struct stat sb;
2357
2358 if (!strcmp(nic, "none"))
2359 return true;
2360
2361 ret = snprintf(path, __LXC_SYS_CLASS_NET_LEN, "/sys/class/net/%s", nic);
2362 if (ret < 0 || (size_t)ret >= __LXC_SYS_CLASS_NET_LEN)
2363 return false;
2364
2365 ret = stat(path, &sb);
2366 if (ret < 0)
2367 return false;
2368
2369 return true;
2370}
127c6e70
CB
2371
2372int lxc_make_tmpfile(char *template, bool rm)
2373{
2374 int fd, ret;
2375
2376 fd = mkstemp(template);
2377 if (fd < 0)
2378 return -1;
2379
2380 if (!rm)
2381 return fd;
2382
2383 ret = unlink(template);
2384 if (ret < 0) {
2385 close(fd);
2386 return -1;
2387 }
2388
2389 return fd;
2390}
e4636123 2391
e3db0162
CB
2392int parse_byte_size_string(const char *s, int64_t *converted)
2393{
2394 int ret, suffix_len;
2395 long long int conv;
2396 int64_t mltpl, overflow;
2397 char *end;
2398 char dup[LXC_NUMSTRLEN64 + 2];
2399 char suffix[3];
2400
2401 if (!s || !strcmp(s, ""))
2402 return -EINVAL;
2403
2404 end = stpncpy(dup, s, sizeof(dup));
2405 if (*end != '\0')
2406 return -EINVAL;
2407
2408 if (isdigit(*(end - 1)))
2409 suffix_len = 0;
2410 else if (isalpha(*(end - 1)))
2411 suffix_len = 1;
2412 else
2413 return -EINVAL;
2414
2415 if ((end - 2) == dup && !isdigit(*(end - 2)))
2416 return -EINVAL;
2417
2418 if (isalpha(*(end - 2))) {
2419 if (suffix_len == 1)
2420 suffix_len++;
2421 else
2422 return -EINVAL;
2423 }
2424
2425 if (suffix_len > 0) {
2426 memcpy(suffix, end - suffix_len, suffix_len);
2427 *(suffix + suffix_len) = '\0';
2428 *(end - suffix_len) = '\0';
2429 }
2430 dup[lxc_char_right_gc(dup, strlen(dup))] = '\0';
2431
2432 ret = lxc_safe_long_long(dup, &conv);
2433 if (ret < 0)
2434 return -ret;
2435
2436 if (suffix_len != 2) {
2437 *converted = conv;
2438 return 0;
2439 }
2440
2441 if (!strcmp(suffix, "kB"))
2442 mltpl = 1024;
2443 else if (!strcmp(suffix, "MB"))
2444 mltpl = 1024 * 1024;
2445 else if (!strcmp(suffix, "GB"))
2446 mltpl = 1024 * 1024 * 1024;
2447 else
2448 return -EINVAL;
2449
2450 overflow = conv * mltpl;
2451 if (conv != 0 && (overflow / conv) != mltpl)
2452 return -ERANGE;
2453
2454 *converted = overflow;
2455 return 0;
2456}
6222c3f4
CB
2457
2458uint64_t lxc_find_next_power2(uint64_t n)
2459{
2460 /* 0 is not valid input. We return 0 to the caller since 0 is not a
2461 * valid power of two.
2462 */
2463 if (n == 0)
2464 return 0;
2465
2466 if (!(n & (n - 1)))
2467 return n;
2468
2469 while (n & (n - 1))
2470 n = n & (n - 1);
2471
2472 n = n << 1;
2473 return n;
2474}