]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/utils.c
move utils.h #endif to end of file
[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
e3642c43
DL
26#include <errno.h>
27#include <unistd.h>
d983b93c
MN
28#include <stdlib.h>
29#include <stddef.h>
61a1d519 30#include <string.h>
e3642c43 31#include <sys/types.h>
0cc417b2 32#include <sys/vfs.h>
e3642c43
DL
33#include <sys/stat.h>
34#include <sys/mman.h>
d983b93c 35#include <sys/param.h>
6e4bb2e0 36#include <sys/mount.h>
d983b93c
MN
37#include <dirent.h>
38#include <fcntl.h>
1b09f2c0 39#include <libgen.h>
9be53773
SH
40#include <sys/types.h>
41#include <sys/wait.h>
502657d5 42#include <assert.h>
0a4be28d 43#include <sys/prctl.h>
e3642c43 44
3ce74686 45#include "utils.h"
e3642c43 46#include "log.h"
025ed0f3 47#include "lxclock.h"
51d0854c 48#include "namespace.h"
e3642c43 49
5d6ef228
SG
50#ifndef PR_SET_MM
51#define PR_SET_MM 35
52#endif
53
553347e4
TA
54#ifndef PR_SET_MM_ARG_START
55#define PR_SET_MM_ARG_START 8
56#endif
57
58#ifndef PR_SET_MM_ARG_END
59#define PR_SET_MM_ARG_END 9
60#endif
61
62#ifndef PR_SET_MM_ENV_START
63#define PR_SET_MM_ENV_START 10
64#endif
65
66#ifndef PR_SET_MM_ENV_END
67#define PR_SET_MM_ENV_END 11
68#endif
69
e3642c43
DL
70lxc_log_define(lxc_utils, lxc);
71
4295c5de
SH
72/*
73 * if path is btrfs, tries to remove it and any subvolumes beneath it
74 */
75extern bool btrfs_try_remove_subvol(const char *path);
76
0cc417b2
SH
77static int _recursive_rmdir(char *dirname, dev_t pdev,
78 const char *exclude, int level, bool onedev)
60bf62d4
SH
79{
80 struct dirent dirent, *direntp;
81 DIR *dir;
82 int ret, failed=0;
83 char pathname[MAXPATHLEN];
18aa217b 84 bool hadexclude = false;
60bf62d4
SH
85
86 dir = opendir(dirname);
87 if (!dir) {
88 ERROR("%s: failed to open %s", __func__, dirname);
4355ab5f 89 return -1;
60bf62d4
SH
90 }
91
92 while (!readdir_r(dir, &dirent, &direntp)) {
93 struct stat mystat;
94 int rc;
95
96 if (!direntp)
97 break;
98
99 if (!strcmp(direntp->d_name, ".") ||
100 !strcmp(direntp->d_name, ".."))
101 continue;
102
103 rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name);
104 if (rc < 0 || rc >= MAXPATHLEN) {
105 ERROR("pathname too long");
106 failed=1;
107 continue;
108 }
18aa217b
SH
109
110 if (!level && exclude && !strcmp(direntp->d_name, exclude)) {
111 ret = rmdir(pathname);
112 if (ret < 0) {
113 switch(errno) {
114 case ENOTEMPTY:
0cc417b2 115 INFO("Not deleting snapshot %s", pathname);
18aa217b
SH
116 hadexclude = true;
117 break;
118 case ENOTDIR:
119 ret = unlink(pathname);
120 if (ret)
121 INFO("%s: failed to remove %s", __func__, pathname);
122 break;
123 default:
124 SYSERROR("%s: failed to rmdir %s", __func__, pathname);
125 failed = 1;
126 break;
127 }
128 }
129 continue;
130 }
131
60bf62d4
SH
132 ret = lstat(pathname, &mystat);
133 if (ret) {
134 ERROR("%s: failed to stat %s", __func__, pathname);
4295c5de 135 failed = 1;
60bf62d4
SH
136 continue;
137 }
4295c5de
SH
138 if (onedev && mystat.st_dev != pdev) {
139 /* TODO should we be checking /proc/self/mountinfo for
140 * pathname and not doing this if found? */
141 if (btrfs_try_remove_subvol(pathname))
142 INFO("Removed btrfs subvolume at %s\n", pathname);
60bf62d4 143 continue;
4295c5de 144 }
60bf62d4 145 if (S_ISDIR(mystat.st_mode)) {
0cc417b2 146 if (_recursive_rmdir(pathname, pdev, exclude, level+1, onedev) < 0)
60bf62d4
SH
147 failed=1;
148 } else {
149 if (unlink(pathname) < 0) {
0cc417b2 150 SYSERROR("%s: failed to delete %s", __func__, pathname);
60bf62d4
SH
151 failed=1;
152 }
153 }
154 }
155
4295c5de
SH
156 if (rmdir(dirname) < 0 && !btrfs_try_remove_subvol(dirname) && !hadexclude) {
157 ERROR("%s: failed to delete %s", __func__, dirname);
158 failed=1;
60bf62d4
SH
159 }
160
025ed0f3 161 ret = closedir(dir);
025ed0f3 162 if (ret) {
60bf62d4
SH
163 ERROR("%s: failed to close directory %s", __func__, dirname);
164 failed=1;
165 }
166
4355ab5f 167 return failed ? -1 : 0;
60bf62d4
SH
168}
169
0cc417b2
SH
170/* we have two different magic values for overlayfs, yay */
171#define OVERLAYFS_SUPER_MAGIC 0x794c764f
172#define OVERLAY_SUPER_MAGIC 0x794c7630
173/*
174 * In overlayfs, st_dev is unreliable. so on overlayfs we don't do
175 * the lxc_rmdir_onedev()
176 */
177static bool is_native_overlayfs(const char *path)
178{
179 struct statfs sb;
180
181 if (statfs(path, &sb) < 0)
182 return false;
183 if (sb.f_type == OVERLAYFS_SUPER_MAGIC ||
184 sb.f_type == OVERLAY_SUPER_MAGIC)
185 return true;
186 return false;
187}
188
4355ab5f 189/* returns 0 on success, -1 if there were any failures */
18aa217b 190extern int lxc_rmdir_onedev(char *path, const char *exclude)
60bf62d4
SH
191{
192 struct stat mystat;
0cc417b2
SH
193 bool onedev = true;
194
195 if (is_native_overlayfs(path)) {
196 onedev = false;
197 }
60bf62d4
SH
198
199 if (lstat(path, &mystat) < 0) {
200 ERROR("%s: failed to stat %s", __func__, path);
4355ab5f 201 return -1;
60bf62d4
SH
202 }
203
0cc417b2 204 return _recursive_rmdir(path, mystat.st_dev, exclude, 0, onedev);
60bf62d4
SH
205}
206
9ddaf3bf 207/* borrowed from iproute2 */
7c11d57a 208extern int get_u16(unsigned short *val, const char *arg, int base)
9ddaf3bf
JHS
209{
210 unsigned long res;
211 char *ptr;
212
213 if (!arg || !*arg)
214 return -1;
215
09bbd745 216 errno = 0;
9ddaf3bf 217 res = strtoul(arg, &ptr, base);
09bbd745 218 if (!ptr || ptr == arg || *ptr || res > 0xFFFF || errno != 0)
9ddaf3bf
JHS
219 return -1;
220
221 *val = res;
222
223 return 0;
224}
225
3ce74686 226extern int mkdir_p(const char *dir, mode_t mode)
1b09f2c0 227{
3ce74686
SH
228 const char *tmp = dir;
229 const char *orig = dir;
860fc865
RW
230 char *makeme;
231
232 do {
233 dir = tmp + strspn(tmp, "/");
234 tmp = dir + strcspn(dir, "/");
d74325c4 235 makeme = strndup(orig, dir - orig);
860fc865
RW
236 if (*makeme) {
237 if (mkdir(makeme, mode) && errno != EEXIST) {
959aee9c 238 SYSERROR("failed to create directory '%s'", makeme);
d74325c4 239 free(makeme);
860fc865
RW
240 return -1;
241 }
242 }
d74325c4 243 free(makeme);
860fc865 244 } while(tmp != dir);
1b09f2c0 245
98663823 246 return 0;
1b09f2c0 247}
2a59a681 248
44b9ae4b 249char *get_rundir()
9e60f51d 250{
97a696c6
SG
251 char *rundir;
252 const char *homedir;
9e60f51d 253
d6470e71 254 if (geteuid() == 0) {
c580b8d2 255 rundir = strdup(RUNTIME_PATH);
d6470e71
SG
256 return rundir;
257 }
97a696c6
SG
258
259 rundir = getenv("XDG_RUNTIME_DIR");
44b9ae4b
SG
260 if (rundir) {
261 rundir = strdup(rundir);
262 return rundir;
263 }
97a696c6 264
44b9ae4b
SG
265 INFO("XDG_RUNTIME_DIR isn't set in the environment.");
266 homedir = getenv("HOME");
267 if (!homedir) {
268 ERROR("HOME isn't set in the environment.");
269 return NULL;
97a696c6
SG
270 }
271
44b9ae4b
SG
272 rundir = malloc(sizeof(char) * (17 + strlen(homedir)));
273 sprintf(rundir, "%s/.cache/lxc/run/", homedir);
274
9e60f51d
DE
275 return rundir;
276}
277
9be53773
SH
278int wait_for_pid(pid_t pid)
279{
280 int status, ret;
281
282again:
283 ret = waitpid(pid, &status, 0);
284 if (ret == -1) {
71b9b8ed 285 if (errno == EINTR)
9be53773
SH
286 goto again;
287 return -1;
288 }
289 if (ret != pid)
290 goto again;
291 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
292 return -1;
293 return 0;
294}
c797a220
CS
295
296int lxc_wait_for_pid_status(pid_t pid)
297{
298 int status, ret;
299
300again:
301 ret = waitpid(pid, &status, 0);
302 if (ret == -1) {
303 if (errno == EINTR)
304 goto again;
305 return -1;
306 }
307 if (ret != pid)
308 goto again;
309 return status;
310}
92f023dc 311
650468bb 312ssize_t lxc_write_nointr(int fd, const void* buf, size_t count)
92f023dc 313{
650468bb 314 ssize_t ret;
92f023dc
CS
315again:
316 ret = write(fd, buf, count);
317 if (ret < 0 && errno == EINTR)
318 goto again;
319 return ret;
320}
321
650468bb 322ssize_t lxc_read_nointr(int fd, void* buf, size_t count)
92f023dc 323{
650468bb 324 ssize_t ret;
92f023dc
CS
325again:
326 ret = read(fd, buf, count);
327 if (ret < 0 && errno == EINTR)
328 goto again;
329 return ret;
330}
331
650468bb 332ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf)
92f023dc 333{
650468bb 334 ssize_t ret;
92f023dc
CS
335 ret = lxc_read_nointr(fd, buf, count);
336 if (ret <= 0)
337 return ret;
650468bb 338 if ((size_t)ret != count)
92f023dc
CS
339 return -1;
340 if (expected_buf && memcmp(buf, expected_buf, count) != 0) {
341 errno = EINVAL;
342 return -1;
343 }
344 return ret;
345}
3ce74686
SH
346
347#if HAVE_LIBGNUTLS
348#include <gnutls/gnutls.h>
349#include <gnutls/crypto.h>
41246cee
DE
350
351__attribute__((constructor))
352static void gnutls_lxc_init(void)
353{
354 gnutls_global_init();
355}
356
3ce74686
SH
357int sha1sum_file(char *fnam, unsigned char *digest)
358{
359 char *buf;
360 int ret;
361 FILE *f;
362 long flen;
363
364 if (!fnam)
365 return -1;
025ed0f3 366 f = fopen_cloexec(fnam, "r");
7be677a8 367 if (!f) {
3ce74686
SH
368 SYSERROR("Error opening template");
369 return -1;
370 }
371 if (fseek(f, 0, SEEK_END) < 0) {
372 SYSERROR("Error seeking to end of template");
dd1d77f9 373 fclose(f);
3ce74686
SH
374 return -1;
375 }
376 if ((flen = ftell(f)) < 0) {
377 SYSERROR("Error telling size of template");
dd1d77f9 378 fclose(f);
3ce74686
SH
379 return -1;
380 }
381 if (fseek(f, 0, SEEK_SET) < 0) {
382 SYSERROR("Error seeking to start of template");
dd1d77f9 383 fclose(f);
3ce74686
SH
384 return -1;
385 }
386 if ((buf = malloc(flen+1)) == NULL) {
387 SYSERROR("Out of memory");
dd1d77f9 388 fclose(f);
3ce74686
SH
389 return -1;
390 }
391 if (fread(buf, 1, flen, f) != flen) {
392 SYSERROR("Failure reading template");
393 free(buf);
dd1d77f9 394 fclose(f);
3ce74686
SH
395 return -1;
396 }
dd1d77f9 397 if (fclose(f) < 0) {
3ce74686
SH
398 SYSERROR("Failre closing template");
399 free(buf);
400 return -1;
401 }
402 buf[flen] = '\0';
403 ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest);
404 free(buf);
405 return ret;
406}
407#endif
61a1d519
CS
408
409char** lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup)
410{
411 va_list ap2;
412 size_t count = 1 + skip;
413 char **result;
414
415 /* first determine size of argument list, we don't want to reallocate
416 * constantly...
417 */
418 va_copy(ap2, ap);
419 while (1) {
420 char* arg = va_arg(ap2, char*);
421 if (!arg)
422 break;
423 count++;
424 }
425 va_end(ap2);
426
427 result = calloc(count, sizeof(char*));
428 if (!result)
429 return NULL;
430 count = skip;
431 while (1) {
432 char* arg = va_arg(ap, char*);
433 if (!arg)
434 break;
435 arg = do_strdup ? strdup(arg) : arg;
436 if (!arg)
437 goto oom;
438 result[count++] = arg;
439 }
440
441 /* calloc has already set last element to NULL*/
442 return result;
443
444oom:
445 free(result);
446 return NULL;
447}
448
449const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
450{
451 return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
452}
db27c8d7 453
ebec9176
AM
454extern struct lxc_popen_FILE *lxc_popen(const char *command)
455{
456 struct lxc_popen_FILE *fp = NULL;
457 int parent_end = -1, child_end = -1;
458 int pipe_fds[2];
459 pid_t child_pid;
460
461 int r = pipe2(pipe_fds, O_CLOEXEC);
462
463 if (r < 0) {
464 ERROR("pipe2 failure");
465 return NULL;
466 }
467
468 parent_end = pipe_fds[0];
469 child_end = pipe_fds[1];
470
471 child_pid = fork();
472
473 if (child_pid == 0) {
474 /* child */
475 int child_std_end = STDOUT_FILENO;
476
477 if (child_end != child_std_end) {
478 /* dup2() doesn't dup close-on-exec flag */
479 dup2(child_end, child_std_end);
480
481 /* it's safe not to close child_end here
482 * as it's marked close-on-exec anyway
483 */
484 } else {
485 /*
486 * The descriptor is already the one we will use.
487 * But it must not be marked close-on-exec.
488 * Undo the effects.
489 */
57d2be54
SG
490 if (fcntl(child_end, F_SETFD, 0) != 0) {
491 SYSERROR("Failed to remove FD_CLOEXEC from fd.");
492 exit(127);
493 }
ebec9176
AM
494 }
495
496 /*
497 * Unblock signals.
498 * This is the main/only reason
499 * why we do our lousy popen() emulation.
500 */
501 {
502 sigset_t mask;
503 sigfillset(&mask);
504 sigprocmask(SIG_UNBLOCK, &mask, NULL);
505 }
506
507 execl("/bin/sh", "sh", "-c", command, (char *) NULL);
508 exit(127);
509 }
510
511 /* parent */
512
513 close(child_end);
514 child_end = -1;
515
516 if (child_pid < 0) {
517 ERROR("fork failure");
518 goto error;
519 }
520
521 fp = calloc(1, sizeof(*fp));
522 if (!fp) {
523 ERROR("failed to allocate memory");
524 goto error;
525 }
526
527 fp->f = fdopen(parent_end, "r");
528 if (!fp->f) {
529 ERROR("fdopen failure");
530 goto error;
531 }
532
533 fp->child_pid = child_pid;
534
535 return fp;
536
537error:
538
539 if (fp) {
540 if (fp->f) {
541 fclose(fp->f);
542 parent_end = -1; /* so we do not close it second time */
543 }
544
545 free(fp);
546 }
547
ebec9176
AM
548 if (parent_end != -1)
549 close(parent_end);
550
551 return NULL;
552}
553
ebec9176
AM
554extern int lxc_pclose(struct lxc_popen_FILE *fp)
555{
556 FILE *f = NULL;
557 pid_t child_pid = 0;
558 int wstatus = 0;
559 pid_t wait_pid;
560
561 if (fp) {
562 f = fp->f;
563 child_pid = fp->child_pid;
564 /* free memory (we still need to close file stream) */
565 free(fp);
566 fp = NULL;
567 }
568
569 if (!f || fclose(f)) {
570 ERROR("fclose failure");
571 return -1;
572 }
573
574 do {
575 wait_pid = waitpid(child_pid, &wstatus, 0);
576 } while (wait_pid == -1 && errno == EINTR);
577
578 if (wait_pid == -1) {
579 ERROR("waitpid failure");
580 return -1;
581 }
582
583 return wstatus;
584}
585
502657d5
CS
586char *lxc_string_replace(const char *needle, const char *replacement, const char *haystack)
587{
588 ssize_t len = -1, saved_len = -1;
589 char *result = NULL;
590 size_t replacement_len = strlen(replacement);
591 size_t needle_len = strlen(needle);
592
593 /* should be executed exactly twice */
594 while (len == -1 || result == NULL) {
595 char *p;
596 char *last_p;
597 ssize_t part_len;
598
599 if (len != -1) {
600 result = calloc(1, len + 1);
601 if (!result)
602 return NULL;
603 saved_len = len;
604 }
605
606 len = 0;
607
608 for (last_p = (char *)haystack, p = strstr(last_p, needle); p; last_p = p, p = strstr(last_p, needle)) {
609 part_len = (ssize_t)(p - last_p);
610 if (result && part_len > 0)
611 memcpy(&result[len], last_p, part_len);
612 len += part_len;
613 if (result && replacement_len > 0)
614 memcpy(&result[len], replacement, replacement_len);
615 len += replacement_len;
616 p += needle_len;
617 }
618 part_len = strlen(last_p);
619 if (result && part_len > 0)
620 memcpy(&result[len], last_p, part_len);
621 len += part_len;
622 }
623
624 /* make sure we did the same thing twice,
625 * once for calculating length, the other
626 * time for copying data */
627 assert(saved_len == len);
628 /* make sure we didn't overwrite any buffer,
629 * due to calloc the string should be 0-terminated */
630 assert(result[len] == '\0');
631
632 return result;
633}
634
635bool lxc_string_in_array(const char *needle, const char **haystack)
636{
637 for (; haystack && *haystack; haystack++)
638 if (!strcmp(needle, *haystack))
639 return true;
640 return false;
641}
642
643char *lxc_string_join(const char *sep, const char **parts, bool use_as_prefix)
644{
645 char *result;
646 char **p;
647 size_t sep_len = strlen(sep);
648 size_t result_len = use_as_prefix * sep_len;
649
650 /* calculate new string length */
651 for (p = (char **)parts; *p; p++)
652 result_len += (p > (char **)parts) * sep_len + strlen(*p);
653
654 result = calloc(result_len + 1, 1);
655 if (!result)
656 return NULL;
657
658 if (use_as_prefix)
659 strcpy(result, sep);
660 for (p = (char **)parts; *p; p++) {
661 if (p > (char **)parts)
662 strcat(result, sep);
663 strcat(result, *p);
664 }
665
666 return result;
667}
668
669char **lxc_normalize_path(const char *path)
670{
671 char **components;
672 char **p;
673 size_t components_len = 0;
674 size_t pos = 0;
675
676 components = lxc_string_split(path, '/');
677 if (!components)
678 return NULL;
679 for (p = components; *p; p++)
680 components_len++;
681
682 /* resolve '.' and '..' */
683 for (pos = 0; pos < components_len; ) {
684 if (!strcmp(components[pos], ".") || (!strcmp(components[pos], "..") && pos == 0)) {
685 /* eat this element */
686 free(components[pos]);
687 memmove(&components[pos], &components[pos+1], sizeof(char *) * (components_len - pos));
688 components_len--;
689 } else if (!strcmp(components[pos], "..")) {
690 /* eat this and the previous element */
691 free(components[pos - 1]);
692 free(components[pos]);
693 memmove(&components[pos-1], &components[pos+1], sizeof(char *) * (components_len - pos));
694 components_len -= 2;
695 pos--;
696 } else {
697 pos++;
698 }
699 }
700
701 return components;
702}
703
24b51482
CS
704char *lxc_append_paths(const char *first, const char *second)
705{
706 size_t len = strlen(first) + strlen(second) + 1;
707 const char *pattern = "%s%s";
708 char *result = NULL;
709
710 if (second[0] != '/') {
711 len += 1;
712 pattern = "%s/%s";
713 }
714
715 result = calloc(1, len);
716 if (!result)
717 return NULL;
718
719 snprintf(result, len, pattern, first, second);
720 return result;
721}
722
502657d5
CS
723bool lxc_string_in_list(const char *needle, const char *haystack, char _sep)
724{
725 char *token, *str, *saveptr = NULL;
726 char sep[2] = { _sep, '\0' };
727
728 if (!haystack || !needle)
729 return 0;
730
731 str = alloca(strlen(haystack)+1);
732 strcpy(str, haystack);
733 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
734 if (strcmp(needle, token) == 0)
735 return 1;
736 }
737
738 return 0;
739}
740
741char **lxc_string_split(const char *string, char _sep)
742{
743 char *token, *str, *saveptr = NULL;
744 char sep[2] = { _sep, '\0' };
745 char **result = NULL;
746 size_t result_capacity = 0;
747 size_t result_count = 0;
748 int r, saved_errno;
749
750 if (!string)
751 return calloc(1, sizeof(char *));
752
753 str = alloca(strlen(string)+1);
754 strcpy(str, string);
755 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
756 r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 16);
757 if (r < 0)
758 goto error_out;
759 result[result_count] = strdup(token);
760 if (!result[result_count])
761 goto error_out;
762 result_count++;
763 }
764
765 /* if we allocated too much, reduce it */
766 return realloc(result, (result_count + 1) * sizeof(char *));
767error_out:
768 saved_errno = errno;
769 lxc_free_array((void **)result, free);
770 errno = saved_errno;
771 return NULL;
772}
773
774char **lxc_string_split_and_trim(const char *string, char _sep)
775{
776 char *token, *str, *saveptr = NULL;
777 char sep[2] = { _sep, '\0' };
778 char **result = NULL;
779 size_t result_capacity = 0;
780 size_t result_count = 0;
781 int r, saved_errno;
782 size_t i = 0;
783
784 if (!string)
785 return calloc(1, sizeof(char *));
786
787 str = alloca(strlen(string)+1);
788 strcpy(str, string);
789 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
790 while (token[0] == ' ' || token[0] == '\t')
791 token++;
792 i = strlen(token);
793 while (i > 0 && (token[i - 1] == ' ' || token[i - 1] == '\t')) {
794 token[i - 1] = '\0';
795 i--;
796 }
797 r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 16);
798 if (r < 0)
799 goto error_out;
800 result[result_count] = strdup(token);
801 if (!result[result_count])
802 goto error_out;
803 result_count++;
804 }
805
806 /* if we allocated too much, reduce it */
807 return realloc(result, (result_count + 1) * sizeof(char *));
808error_out:
809 saved_errno = errno;
810 lxc_free_array((void **)result, free);
811 errno = saved_errno;
812 return NULL;
813}
814
815void lxc_free_array(void **array, lxc_free_fn element_free_fn)
816{
817 void **p;
818 for (p = array; p && *p; p++)
819 element_free_fn(*p);
820 free((void*)array);
821}
822
823int lxc_grow_array(void ***array, size_t* capacity, size_t new_size, size_t capacity_increment)
824{
825 size_t new_capacity;
826 void **new_array;
827
828 /* first time around, catch some trivial mistakes of the user
829 * only initializing one of these */
830 if (!*array || !*capacity) {
831 *array = NULL;
832 *capacity = 0;
833 }
834
835 new_capacity = *capacity;
836 while (new_size + 1 > new_capacity)
837 new_capacity += capacity_increment;
838 if (new_capacity != *capacity) {
839 /* we have to reallocate */
840 new_array = realloc(*array, new_capacity * sizeof(void *));
841 if (!new_array)
842 return -1;
843 memset(&new_array[*capacity], 0, (new_capacity - (*capacity)) * sizeof(void *));
844 *array = new_array;
845 *capacity = new_capacity;
846 }
847
848 /* array has sufficient elements */
849 return 0;
850}
851
852size_t lxc_array_len(void **array)
853{
854 void **p;
855 size_t result = 0;
856
857 for (p = array; p && *p; p++)
858 result++;
859
860 return result;
861}
862
0e95426b
CS
863int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool add_newline)
864{
865 int fd, saved_errno;
866 ssize_t ret;
867
868 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
869 if (fd < 0)
870 return -1;
871 ret = lxc_write_nointr(fd, buf, count);
872 if (ret < 0)
799f29ab 873 goto out_error;
0e95426b
CS
874 if ((size_t)ret != count)
875 goto out_error;
876 if (add_newline) {
877 ret = lxc_write_nointr(fd, "\n", 1);
878 if (ret != 1)
879 goto out_error;
880 }
881 close(fd);
882 return 0;
883
884out_error:
885 saved_errno = errno;
886 close(fd);
887 errno = saved_errno;
888 return -1;
889}
890
891int lxc_read_from_file(const char *filename, void* buf, size_t count)
892{
893 int fd = -1, saved_errno;
894 ssize_t ret;
895
896 fd = open(filename, O_RDONLY | O_CLOEXEC);
897 if (fd < 0)
898 return -1;
899
900 if (!buf || !count) {
901 char buf2[100];
902 size_t count2 = 0;
903 while ((ret = read(fd, buf2, 100)) > 0)
904 count2 += ret;
905 if (ret >= 0)
906 ret = count2;
907 } else {
908 memset(buf, 0, count);
909 ret = read(fd, buf, count);
910 }
911
912 if (ret < 0)
913 ERROR("read %s: %s", filename, strerror(errno));
914
915 saved_errno = errno;
916 close(fd);
917 errno = saved_errno;
918 return ret;
919}
799f29ab
ÇO
920
921void **lxc_append_null_to_array(void **array, size_t count)
922{
923 void **temp;
924
925 /* Append NULL to the array */
926 if (count) {
927 temp = realloc(array, (count + 1) * sizeof(*array));
928 if (!temp) {
929 int i;
930 for (i = 0; i < count; i++)
931 free(array[i]);
932 free(array);
933 return NULL;
934 }
935 array = temp;
936 array[count] = NULL;
937 }
938 return array;
939}
508c263e
SH
940
941int randseed(bool srand_it)
942{
943 /*
944 srand pre-seed function based on /dev/urandom
945 */
946 unsigned int seed=time(NULL)+getpid();
947
948 FILE *f;
949 f = fopen("/dev/urandom", "r");
950 if (f) {
951 int ret = fread(&seed, sizeof(seed), 1, f);
952 if (ret != 1)
953 DEBUG("unable to fread /dev/urandom, %s, fallback to time+pid rand seed", strerror(errno));
954 fclose(f);
955 }
956
957 if (srand_it)
958 srand(seed);
959
960 return seed;
961}
5d897655
SH
962
963uid_t get_ns_uid(uid_t orig)
964{
965 char *line = NULL;
966 size_t sz = 0;
967 uid_t nsid, hostid, range;
968 FILE *f = fopen("/proc/self/uid_map", "r");
969 if (!f)
970 return 0;
971
972 while (getline(&line, &sz, f) != -1) {
973 if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3)
974 continue;
975 if (hostid <= orig && hostid + range > orig) {
976 nsid += orig - hostid;
977 goto found;
978 }
979 }
980
981 nsid = 0;
982found:
983 fclose(f);
984 free(line);
985 return nsid;
986}
c476bdce
SH
987
988bool dir_exists(const char *path)
989{
990 struct stat sb;
991 int ret;
992
993 ret = stat(path, &sb);
994 if (ret < 0)
995 // could be something other than eexist, just say no
996 return false;
997 return S_ISDIR(sb.st_mode);
998}
93c379f0
ÇO
999
1000/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
1001 * FNV has good anti collision properties and we're not worried
1002 * about pre-image resistance or one-way-ness, we're just trying to make
1003 * the name unique in the 108 bytes of space we have.
1004 */
1005uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
1006{
1007 unsigned char *bp;
1008
1009 for(bp = buf; bp < (unsigned char *)buf + len; bp++)
1010 {
1011 /* xor the bottom with the current octet */
1012 hval ^= (uint64_t)*bp;
1013
1014 /* gcc optimised:
1015 * multiply by the 64 bit FNV magic prime mod 2^64
1016 */
1017 hval += (hval << 1) + (hval << 4) + (hval << 5) +
1018 (hval << 7) + (hval << 8) + (hval << 40);
1019 }
1020
1021 return hval;
1022}
2c6f3fc9
SH
1023
1024/*
1025 * Detect whether / is mounted MS_SHARED. The only way I know of to
1026 * check that is through /proc/self/mountinfo.
1027 * I'm only checking for /. If the container rootfs or mount location
1028 * is MS_SHARED, but not '/', then you're out of luck - figuring that
1029 * out would be too much work to be worth it.
1030 */
1031#define LINELEN 4096
1032int detect_shared_rootfs(void)
1033{
1034 char buf[LINELEN], *p;
1035 FILE *f;
1036 int i;
1037 char *p2;
1038
1039 f = fopen("/proc/self/mountinfo", "r");
1040 if (!f)
1041 return 0;
1042 while (fgets(buf, LINELEN, f)) {
1043 for (p = buf, i=0; p && i < 4; i++)
b7f954bb 1044 p = strchr(p+1, ' ');
2c6f3fc9
SH
1045 if (!p)
1046 continue;
b7f954bb 1047 p2 = strchr(p+1, ' ');
2c6f3fc9
SH
1048 if (!p2)
1049 continue;
1050 *p2 = '\0';
1051 if (strcmp(p+1, "/") == 0) {
1052 // this is '/'. is it shared?
b7f954bb 1053 p = strchr(p2+1, ' ');
2c6f3fc9
SH
1054 if (p && strstr(p, "shared:")) {
1055 fclose(f);
1056 return 1;
1057 }
1058 }
1059 }
1060 fclose(f);
1061 return 0;
1062}
0e6e3a41 1063
51d0854c
DY
1064bool switch_to_ns(pid_t pid, const char *ns) {
1065 int fd, ret;
1066 char nspath[MAXPATHLEN];
1067
1068 /* Switch to new ns */
1069 ret = snprintf(nspath, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns);
1070 if (ret < 0 || ret >= MAXPATHLEN)
1071 return false;
1072
1073 fd = open(nspath, O_RDONLY);
1074 if (fd < 0) {
1075 SYSERROR("failed to open %s", nspath);
1076 return false;
1077 }
1078
1079 ret = setns(fd, 0);
1080 if (ret) {
1081 SYSERROR("failed to set process %d to %s of %d.", pid, ns, fd);
1082 close(fd);
1083 return false;
1084 }
1085 close(fd);
1086 return true;
1087}
1088
b7f954bb
SH
1089/*
1090 * looking at fs/proc_namespace.c, it appears we can
1091 * actually expect the rootfs entry to very specifically contain
1092 * " - rootfs rootfs "
1093 * IIUC, so long as we've chrooted so that rootfs is not our root,
1094 * the rootfs entry should always be skipped in mountinfo contents.
1095 */
1096int detect_ramfs_rootfs(void)
1097{
1098 char buf[LINELEN], *p;
1099 FILE *f;
1100 int i;
1101 char *p2;
1102
1103 f = fopen("/proc/self/mountinfo", "r");
1104 if (!f)
1105 return 0;
1106 while (fgets(buf, LINELEN, f)) {
1107 for (p = buf, i=0; p && i < 4; i++)
1108 p = strchr(p+1, ' ');
1109 if (!p)
1110 continue;
1111 p2 = strchr(p+1, ' ');
1112 if (!p2)
1113 continue;
1114 *p2 = '\0';
1115 if (strcmp(p+1, "/") == 0) {
1116 // this is '/'. is it the ramfs?
1117 p = strchr(p2+1, '-');
1118 if (p && strncmp(p, "- rootfs rootfs ", 16) == 0) {
1119 fclose(f);
1120 return 1;
1121 }
1122 }
1123 }
1124 fclose(f);
1125 return 0;
1126}
1127
9d9c111c 1128char *on_path(char *cmd, const char *rootfs) {
0e6e3a41
SG
1129 char *path = NULL;
1130 char *entry = NULL;
1131 char *saveptr = NULL;
1132 char cmdpath[MAXPATHLEN];
1133 int ret;
1134
1135 path = getenv("PATH");
1136 if (!path)
8afb3e61 1137 return NULL;
0e6e3a41
SG
1138
1139 path = strdup(path);
1140 if (!path)
8afb3e61 1141 return NULL;
0e6e3a41
SG
1142
1143 entry = strtok_r(path, ":", &saveptr);
1144 while (entry) {
9d9c111c
SH
1145 if (rootfs)
1146 ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s/%s", rootfs, entry, cmd);
1147 else
1148 ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s", entry, cmd);
0e6e3a41
SG
1149
1150 if (ret < 0 || ret >= MAXPATHLEN)
1151 goto next_loop;
1152
1153 if (access(cmdpath, X_OK) == 0) {
1154 free(path);
8afb3e61 1155 return strdup(cmdpath);
0e6e3a41
SG
1156 }
1157
1158next_loop:
b707e368 1159 entry = strtok_r(NULL, ":", &saveptr);
0e6e3a41
SG
1160 }
1161
1162 free(path);
8afb3e61 1163 return NULL;
0e6e3a41 1164}
76a26f55
SH
1165
1166bool file_exists(const char *f)
1167{
1168 struct stat statbuf;
1169
1170 return stat(f, &statbuf) == 0;
1171}
9d9c111c
SH
1172
1173/* historically lxc-init has been under /usr/lib/lxc and under
1174 * /usr/lib/$ARCH/lxc. It now lives as $prefix/sbin/init.lxc.
1175 */
1176char *choose_init(const char *rootfs)
1177{
1178 char *retv = NULL;
370ec268
SF
1179 const char *empty = "",
1180 *tmp;
9d9c111c
SH
1181 int ret, env_set = 0;
1182 struct stat mystat;
1183
1184 if (!getenv("PATH")) {
1185 if (setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0))
1186 SYSERROR("Failed to setenv");
1187 env_set = 1;
1188 }
1189
1190 retv = on_path("init.lxc", rootfs);
1191
1192 if (env_set) {
1193 if (unsetenv("PATH"))
1194 SYSERROR("Failed to unsetenv");
1195 }
1196
1197 if (retv)
1198 return retv;
1199
1200 retv = malloc(PATH_MAX);
1201 if (!retv)
1202 return NULL;
1203
1204 if (rootfs)
370ec268 1205 tmp = rootfs;
9d9c111c 1206 else
370ec268
SF
1207 tmp = empty;
1208
1209 ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, SBINDIR, "/init.lxc");
9d9c111c
SH
1210 if (ret < 0 || ret >= PATH_MAX) {
1211 ERROR("pathname too long");
1212 goto out1;
1213 }
1214
1215 ret = stat(retv, &mystat);
1216 if (ret == 0)
1217 return retv;
1218
370ec268 1219 ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, LXCINITDIR, "/lxc/lxc-init");
9d9c111c
SH
1220 if (ret < 0 || ret >= PATH_MAX) {
1221 ERROR("pathname too long");
1222 goto out1;
1223 }
1224
1225 ret = stat(retv, &mystat);
1226 if (ret == 0)
1227 return retv;
1228
370ec268 1229 ret = snprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", tmp);
9d9c111c
SH
1230 if (ret < 0 || ret >= PATH_MAX) {
1231 ERROR("pathname too long");
1232 goto out1;
1233 }
1234 ret = stat(retv, &mystat);
1235 if (ret == 0)
1236 return retv;
1237
370ec268 1238 ret = snprintf(retv, PATH_MAX, "%s/sbin/lxc-init", tmp);
9d9c111c
SH
1239 if (ret < 0 || ret >= PATH_MAX) {
1240 ERROR("pathname too long");
1241 goto out1;
1242 }
1243 ret = stat(retv, &mystat);
1244 if (ret == 0)
1245 return retv;
1246
1247 /*
1248 * Last resort, look for the statically compiled init.lxc which we
1249 * hopefully bind-mounted in.
1250 * If we are called during container setup, and we get to this point,
1251 * then the init.lxc.static from the host will need to be bind-mounted
1252 * in. So we return NULL here to indicate that.
1253 */
1254 if (rootfs)
1255 goto out1;
1256
1257 ret = snprintf(retv, PATH_MAX, "/init.lxc.static");
1258 if (ret < 0 || ret >= PATH_MAX) {
1259 WARN("Nonsense - name /lxc.init.static too long");
1260 goto out1;
1261 }
1262 ret = stat(retv, &mystat);
1263 if (ret == 0)
1264 return retv;
1265
1266out1:
1267 free(retv);
1268 return NULL;
1269}
735f2c6e
TA
1270
1271int print_to_file(const char *file, const char *content)
1272{
1273 FILE *f;
1274 int ret = 0;
1275
1276 f = fopen(file, "w");
1277 if (!f)
1278 return -1;
1279 if (fprintf(f, "%s", content) != strlen(content))
1280 ret = -1;
1281 fclose(f);
1282 return ret;
1283}
e1daebd9
SH
1284
1285int is_dir(const char *path)
1286{
1287 struct stat statbuf;
1288 int ret = stat(path, &statbuf);
1289 if (ret == 0 && S_ISDIR(statbuf.st_mode))
1290 return 1;
1291 return 0;
1292}
6010a416
SG
1293
1294/*
1295 * Given the '-t' template option to lxc-create, figure out what to
1296 * do. If the template is a full executable path, use that. If it
1297 * is something like 'sshd', then return $templatepath/lxc-sshd.
1298 * On success return the template, on error return NULL.
1299 */
1300char *get_template_path(const char *t)
1301{
1302 int ret, len;
1303 char *tpath;
1304
1305 if (t[0] == '/' && access(t, X_OK) == 0) {
1306 tpath = strdup(t);
1307 return tpath;
1308 }
1309
1310 len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1;
1311 tpath = malloc(len);
1312 if (!tpath)
1313 return NULL;
1314 ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
1315 if (ret < 0 || ret >= len) {
1316 free(tpath);
1317 return NULL;
1318 }
1319 if (access(tpath, X_OK) < 0) {
1320 SYSERROR("bad template: %s", t);
1321 free(tpath);
1322 return NULL;
1323 }
1324
1325 return tpath;
1326}
0a4be28d
TA
1327
1328/*
1329 * Sets the process title to the specified title. Note:
1330 * 1. this function requires root to succeed
1331 * 2. it clears /proc/self/environ
1332 * 3. it may not succed (e.g. if title is longer than /proc/self/environ +
1333 * the original title)
1334 */
1335int setproctitle(char *title)
1336{
1337 char buf[2048], *tmp;
1338 FILE *f;
1339 int i, len, ret = 0;
1340 unsigned long arg_start, arg_end, env_start, env_end;
1341
1342 f = fopen_cloexec("/proc/self/stat", "r");
1343 if (!f) {
1344 return -1;
1345 }
1346
1347 tmp = fgets(buf, sizeof(buf), f);
1348 fclose(f);
1349 if (!tmp) {
1350 return -1;
1351 }
1352
1353 /* Skip the first 47 fields, column 48-51 are ARG_START and
1354 * ARG_END. */
1355 tmp = strchr(buf, ' ');
1356 for (i = 0; i < 46; i++) {
1357 if (!tmp)
1358 return -1;
1359 tmp = strchr(tmp+1, ' ');
1360 }
1361
73c1c887
SH
1362 if (!tmp)
1363 return -1;
1364
0a4be28d
TA
1365 i = sscanf(tmp, "%lu %lu %lu %lu", &arg_start, &arg_end, &env_start, &env_end);
1366 if (i != 4) {
1367 return -1;
1368 }
1369
96fe6d1d
TA
1370 /* Include the null byte here, because in the calculations below we
1371 * want to have room for it. */
1372 len = strlen(title) + 1;
1373
0a4be28d
TA
1374 /* We're truncating the environment, so we should use at most the
1375 * length of the argument + environment for the title. */
0a4be28d
TA
1376 if (len > env_end - arg_start) {
1377 arg_end = env_end;
1378 len = env_end - arg_start;
1379 } else {
1380 /* Only truncate the environment if we're actually going to
1381 * overwrite part of it. */
1382 if (len >= arg_end - arg_start) {
1383 env_start = env_end;
1384 }
70642c33 1385
69f97e3c
TA
1386 arg_end = arg_start + len;
1387
70642c33 1388 /* check overflow */
69f97e3c 1389 if (arg_end < len || arg_end < arg_start) {
70642c33
TA
1390 return -1;
1391 }
1392
0a4be28d
TA
1393 }
1394
96fe6d1d 1395 strcpy((char*)arg_start, title);
0a4be28d 1396
70642c33
TA
1397 ret |= prctl(PR_SET_MM, PR_SET_MM_ARG_START, arg_start, 0, 0);
1398 ret |= prctl(PR_SET_MM, PR_SET_MM_ARG_END, arg_end, 0, 0);
1399 ret |= prctl(PR_SET_MM, PR_SET_MM_ENV_START, env_start, 0, 0);
1400 ret |= prctl(PR_SET_MM, PR_SET_MM_ENV_END, env_end, 0, 0);
0a4be28d
TA
1401
1402 return ret;
1403}
ced03a01
SH
1404
1405/*
1406 * Mount a proc under @rootfs if proc self points to a pid other than
1407 * my own. This is needed to have a known-good proc mount for setting
1408 * up LSMs both at container startup and attach.
1409 *
1410 * @rootfs : the rootfs where proc should be mounted
1411 *
1412 * Returns < 0 on failure, 0 if the correct proc was already mounted
1413 * and 1 if a new proc was mounted.
1414 */
1415int mount_proc_if_needed(const char *rootfs)
1416{
1417 char path[MAXPATHLEN];
1418 char link[20];
1419 int linklen, ret;
fe447886 1420 int mypid;
ced03a01
SH
1421
1422 ret = snprintf(path, MAXPATHLEN, "%s/proc/self", rootfs);
1423 if (ret < 0 || ret >= MAXPATHLEN) {
1424 SYSERROR("proc path name too long");
1425 return -1;
1426 }
1427 memset(link, 0, 20);
1428 linklen = readlink(path, link, 20);
fe447886
SH
1429 mypid = (int)getpid();
1430 INFO("I am %d, /proc/self points to '%s'", mypid, link);
ced03a01
SH
1431 ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs);
1432 if (linklen < 0) /* /proc not mounted */
1433 goto domount;
fe447886 1434 if (atoi(link) != mypid) {
ced03a01
SH
1435 /* wrong /procs mounted */
1436 umount2(path, MNT_DETACH); /* ignore failure */
1437 goto domount;
1438 }
1439 /* the right proc is already mounted */
1440 return 0;
1441
1442domount:
1443 if (mount("proc", path, "proc", 0, NULL))
1444 return -1;
1445 INFO("Mounted /proc in container for security transition");
1446 return 1;
1447}