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