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