]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/lxccontainer.c
lxccontainer: create_partial()
[mirror_lxc.git] / src / lxc / lxccontainer.c
CommitLineData
72d0e1cb
SG
1/* liblxcapi
2 *
3 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
4 * Copyright © 2012 Canonical Ltd.
5 *
d75462e4
SH
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
72d0e1cb
SG
19 */
20
9be53773 21#define _GNU_SOURCE
38683db4 22#include <dirent.h>
9be53773 23#include <errno.h>
93dc5327 24#include <fcntl.h>
38683db4 25#include <grp.h>
f2363e38 26#include <libgen.h>
38683db4
CB
27#include <pthread.h>
28#include <sched.h>
29#include <stdarg.h>
d659597e 30#include <stdint.h>
9fc7f8c0 31#include <stdio.h>
38683db4
CB
32#include <unistd.h>
33#include <arpa/inet.h>
66c1f8c2 34#include <sys/sysmacros.h>
38683db4
CB
35#include <sys/mman.h>
36#include <sys/mount.h>
5f7eba0b 37#include <sys/syscall.h>
38683db4
CB
38#include <sys/types.h>
39#include <sys/wait.h>
f2363e38 40
5e5576a4 41#include "af_unix.h"
38683db4 42#include "attach.h"
38683db4 43#include "cgroup.h"
72d0e1cb 44#include "conf.h"
38683db4
CB
45#include "config.h"
46#include "commands.h"
92e35018 47#include "commands_utils.h"
72d0e1cb 48#include "confile.h"
4222a9f4 49#include "confile_utils.h"
b5159817 50#include "console.h"
e29fe1dd 51#include "criu.h"
238b3e5e 52#include "error.h"
a6f151a7 53#include "initutils.h"
72d0e1cb 54#include "log.h"
38683db4
CB
55#include "lxc.h"
56#include "lxccontainer.h"
57#include "lxclock.h"
f2363e38
ÇO
58#include "monitor.h"
59#include "namespace.h"
fed29fad 60#include "network.h"
9994d140 61#include "parse.h"
aa460476 62#include "start.h"
38683db4 63#include "state.h"
28d832c4 64#include "storage.h"
ec5d663c 65#include "storage_utils.h"
28d832c4
CB
66#include "storage/btrfs.h"
67#include "storage/overlay.h"
68#include "sync.h"
38683db4
CB
69#include "utils.h"
70#include "version.h"
4ba0d9af 71
af6824fc
ST
72/* major()/minor() */
73#ifdef MAJOR_IN_MKDEV
238b3e5e 74#include <sys/mkdev.h>
af6824fc 75#endif
af6824fc 76
4ba0d9af 77#if HAVE_IFADDRS_H
9c83a661 78#include <ifaddrs.h>
4ba0d9af
SG
79#else
80#include <../include/ifaddrs.h>
81#endif
72d0e1cb 82
684f79a5
SG
83#if IS_BIONIC
84#include <../include/lxcmntent.h>
85#else
86#include <mntent.h>
87#endif
88
5f7eba0b
SG
89/* Define faccessat() if missing from the C library */
90#ifndef HAVE_FACCESSAT
91static int faccessat(int __fd, const char *__file, int __type, int __flag)
92{
93#ifdef __NR_faccessat
238b3e5e 94 return syscall(__NR_faccessat, __fd, __file, __type, __flag);
5f7eba0b 95#else
238b3e5e
CB
96 errno = ENOSYS;
97 return -1;
5f7eba0b
SG
98#endif
99}
100#endif
101
72d0e1cb
SG
102lxc_log_define(lxc_container, lxc);
103
858377e4
SH
104static bool do_lxcapi_destroy(struct lxc_container *c);
105static const char *lxcapi_get_config_path(struct lxc_container *c);
106#define do_lxcapi_get_config_path(c) lxcapi_get_config_path(c)
107static bool do_lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v);
17a367d8
CB
108static bool container_destroy(struct lxc_container *c,
109 struct lxc_storage *storage);
858377e4
SH
110static bool get_snappath_dir(struct lxc_container *c, char *snappath);
111static bool lxcapi_snapshot_destroy_all(struct lxc_container *c);
112static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file);
113
a41f104b
SH
114static bool config_file_exists(const char *lxcpath, const char *cname)
115{
ef1ab8f1
CB
116 int ret;
117 size_t len;
118 char *fname;
a41f104b 119
ef1ab8f1
CB
120 /* $lxcpath + '/' + $cname + '/config' + \0 */
121 len = strlen(lxcpath) + strlen(cname) + 9;
122 fname = alloca(len);
123 ret = snprintf(fname, len, "%s/%s/config", lxcpath, cname);
124 if (ret < 0 || (size_t)ret >= len)
a41f104b
SH
125 return false;
126
127 return file_exists(fname);
128}
129
444249ea
CB
130/* A few functions to help detect when a container creation failed. If a
131 * container creation was killed partway through, then trying to actually start
132 * that container could harm the host. We detect this by creating a 'partial'
133 * file under the container directory, and keeping an advisory lock. When
134 * container creation completes, we remove that file. When we load or try to
135 * start a container, if we find that file, without a flock, we remove the
136 * container.
3e625e2d 137 */
74a3920a 138static int ongoing_create(struct lxc_container *c)
3e625e2d 139{
3e625e2d 140 int fd, ret;
444249ea
CB
141 size_t len;
142 char *path;
93dc5327
SH
143 struct flock lk;
144
444249ea
CB
145 len = strlen(c->config_path) + strlen(c->name) + 10;
146 path = alloca(len);
3e625e2d 147 ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
444249ea 148 if (ret < 0 || (size_t)ret >= len)
3e625e2d 149 return -1;
3e625e2d
SH
150
151 if (!file_exists(path))
152 return 0;
444249ea 153
025ed0f3 154 fd = open(path, O_RDWR);
444249ea 155 if (fd < 0)
3e625e2d 156 return 0;
444249ea 157
93dc5327
SH
158 lk.l_type = F_WRLCK;
159 lk.l_whence = SEEK_SET;
160 lk.l_start = 0;
161 lk.l_len = 0;
162 lk.l_pid = -1;
444249ea
CB
163
164 ret = fcntl(fd, F_GETLK, &lk);
165 close(fd);
166 if (ret == 0 && lk.l_pid != -1) {
1a0e70ac 167 /* create is still ongoing */
3e625e2d
SH
168 return 1;
169 }
444249ea
CB
170
171 /* Create completed but partial is still there. */
3e625e2d
SH
172 return 2;
173}
174
74a3920a 175static int create_partial(struct lxc_container *c)
3e625e2d 176{
3e625e2d 177 int fd, ret;
f5cd0252
CB
178 size_t len;
179 char *path;
93dc5327
SH
180 struct flock lk;
181
f5cd0252
CB
182 /* $lxcpath + '/' + $name + '/partial' + \0 */
183 len = strlen(c->config_path) + strlen(c->name) + 10;
184 path = alloca(len);
3e625e2d 185 ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
f5cd0252 186 if (ret < 0 || (size_t)ret >= len)
3e625e2d 187 return -1;
f5cd0252
CB
188
189 fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0755);
190 if (fd < 0)
3e625e2d 191 return -1;
f5cd0252 192
93dc5327
SH
193 lk.l_type = F_WRLCK;
194 lk.l_whence = SEEK_SET;
195 lk.l_start = 0;
196 lk.l_len = 0;
f5cd0252
CB
197
198 ret = fcntl(fd, F_SETLKW, &lk);
199 if (ret < 0) {
200 SYSERROR("Failed to lock partial file %s", path);
3e625e2d 201 close(fd);
3e625e2d
SH
202 return -1;
203 }
3e625e2d
SH
204
205 return fd;
206}
207
74a3920a 208static void remove_partial(struct lxc_container *c, int fd)
3e625e2d 209{
1a0e70ac 210 /* $lxcpath + '/' + $name + '/partial' + \0 */
3e625e2d
SH
211 int len = strlen(c->config_path) + strlen(c->name) + 10;
212 char *path = alloca(len);
213 int ret;
214
215 close(fd);
216 ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
217 if (ret < 0 || ret >= len) {
218 ERROR("Error writing partial pathname");
219 return;
220 }
3e625e2d
SH
221 if (unlink(path) < 0)
222 SYSERROR("Error unlink partial file %s", path);
3e625e2d
SH
223}
224
72d0e1cb 225/* LOCKING
3bc449ed
SH
226 * 1. container_mem_lock(c) protects the struct lxc_container from multiple threads.
227 * 2. container_disk_lock(c) protects the on-disk container data - in particular the
228 * container configuration file.
229 * The container_disk_lock also takes the container_mem_lock.
230 * 3. thread_mutex protects process data (ex: fd table) from multiple threads.
72d0e1cb
SG
231 * NOTHING mutexes two independent programs with their own struct
232 * lxc_container for the same c->name, between API calls. For instance,
233 * c->config_read(); c->start(); Between those calls, data on disk
234 * could change (which shouldn't bother the caller unless for instance
235 * the rootfs get moved). c->config_read(); update; c->config_write();
236 * Two such updaters could race. The callers should therefore check their
237 * results. Trying to prevent that would necessarily expose us to deadlocks
238 * due to hung callers. So I prefer to keep the locks only within our own
239 * functions, not across functions.
240 *
3bc449ed 241 * If you're going to clone while holding a lxccontainer, increment
72d0e1cb
SG
242 * c->numthreads (under privlock) before forking. When deleting,
243 * decrement numthreads under privlock, then if it hits 0 you can delete.
244 * Do not ever use a lxccontainer whose numthreads you did not bump.
245 */
246
247static void lxc_container_free(struct lxc_container *c)
248{
249 if (!c)
250 return;
251
f10fad2f
ME
252 free(c->configfile);
253 c->configfile = NULL;
254 free(c->error_string);
255 c->error_string = NULL;
d95db067 256 if (c->slock) {
df271a59 257 lxc_putlock(c->slock);
d95db067
DE
258 c->slock = NULL;
259 }
72d0e1cb 260 if (c->privlock) {
df271a59 261 lxc_putlock(c->privlock);
72d0e1cb
SG
262 c->privlock = NULL;
263 }
f10fad2f
ME
264 free(c->name);
265 c->name = NULL;
d95db067
DE
266 if (c->lxc_conf) {
267 lxc_conf_free(c->lxc_conf);
268 c->lxc_conf = NULL;
269 }
f10fad2f
ME
270 free(c->config_path);
271 c->config_path = NULL;
72cf75fa 272
72d0e1cb
SG
273 free(c);
274}
275
43d1aa34
SH
276/*
277 * Consider the following case:
278freer | racing get()er
279==================================================================
280lxc_container_put() | lxc_container_get()
281\ lxclock(c->privlock) | c->numthreads < 1? (no)
282\ c->numthreads = 0 | \ lxclock(c->privlock) -> waits
283\ lxcunlock() | \
284\ lxc_container_free() | \ lxclock() returns
285 | \ c->numthreads < 1 -> return 0
286\ \ (free stuff) |
287\ \ sem_destroy(privlock) |
288
289 * When the get()er checks numthreads the first time, one of the following
290 * is true:
291 * 1. freer has set numthreads = 0. get() returns 0
292 * 2. freer is between lxclock and setting numthreads to 0. get()er will
293 * sem_wait on privlock, get lxclock after freer() drops it, then see
294 * numthreads is 0 and exit without touching lxclock again..
295 * 3. freer has not yet locked privlock. If get()er runs first, then put()er
296 * will see --numthreads = 1 and not call lxc_container_free().
297*/
298
72d0e1cb
SG
299int lxc_container_get(struct lxc_container *c)
300{
301 if (!c)
302 return 0;
303
1a0e70ac
CB
304 /* If someone else has already started freeing the container, don't try
305 * to take the lock, which may be invalid.
306 */
43d1aa34
SH
307 if (c->numthreads < 1)
308 return 0;
309
5cee8c50 310 if (container_mem_lock(c))
72d0e1cb 311 return 0;
1a0e70ac
CB
312
313 /* Bail without trying to unlock, bc the privlock is now probably in
314 * freed memory.
315 */
316 if (c->numthreads < 1)
72d0e1cb 317 return 0;
1a0e70ac 318
72d0e1cb 319 c->numthreads++;
5cee8c50 320 container_mem_unlock(c);
72d0e1cb
SG
321 return 1;
322}
323
324int lxc_container_put(struct lxc_container *c)
325{
326 if (!c)
327 return -1;
5cee8c50 328 if (container_mem_lock(c))
72d0e1cb
SG
329 return -1;
330 if (--c->numthreads < 1) {
5cee8c50 331 container_mem_unlock(c);
72d0e1cb
SG
332 lxc_container_free(c);
333 return 1;
334 }
5cee8c50 335 container_mem_unlock(c);
72d0e1cb
SG
336 return 0;
337}
338
858377e4 339static bool do_lxcapi_is_defined(struct lxc_container *c)
72d0e1cb
SG
340{
341 struct stat statbuf;
342 bool ret = false;
343 int statret;
344
345 if (!c)
346 return false;
347
5cee8c50 348 if (container_mem_lock(c))
72d0e1cb
SG
349 return false;
350 if (!c->configfile)
351 goto out;
352 statret = stat(c->configfile, &statbuf);
353 if (statret != 0)
354 goto out;
355 ret = true;
356
357out:
5cee8c50 358 container_mem_unlock(c);
72d0e1cb
SG
359 return ret;
360}
361
858377e4
SH
362#define WRAP_API(rettype, fnname) \
363static rettype fnname(struct lxc_container *c) \
364{ \
365 rettype ret; \
8164f0e2
TA
366 bool reset_config = false; \
367 \
368 if (!current_config && c && c->lxc_conf) { \
369 current_config = c->lxc_conf; \
370 reset_config = true; \
371 } \
372 \
858377e4 373 ret = do_##fnname(c); \
8164f0e2
TA
374 if (reset_config) \
375 current_config = NULL; \
376 \
858377e4
SH
377 return ret; \
378}
379
380#define WRAP_API_1(rettype, fnname, t1) \
381static rettype fnname(struct lxc_container *c, t1 a1) \
382{ \
383 rettype ret; \
8164f0e2
TA
384 bool reset_config = false; \
385 \
386 if (!current_config && c && c->lxc_conf) { \
387 current_config = c->lxc_conf; \
388 reset_config = true; \
389 } \
390 \
858377e4 391 ret = do_##fnname(c, a1); \
8164f0e2
TA
392 if (reset_config) \
393 current_config = NULL; \
394 \
858377e4
SH
395 return ret; \
396}
397
398#define WRAP_API_2(rettype, fnname, t1, t2) \
399static rettype fnname(struct lxc_container *c, t1 a1, t2 a2) \
400{ \
401 rettype ret; \
8164f0e2
TA
402 bool reset_config = false; \
403 \
404 if (!current_config && c && c->lxc_conf) { \
405 current_config = c->lxc_conf; \
406 reset_config = true; \
407 } \
408 \
858377e4 409 ret = do_##fnname(c, a1, a2); \
8164f0e2
TA
410 if (reset_config) \
411 current_config = NULL; \
412 \
858377e4
SH
413 return ret; \
414}
415
416#define WRAP_API_3(rettype, fnname, t1, t2, t3) \
417static rettype fnname(struct lxc_container *c, t1 a1, t2 a2, t3 a3) \
418{ \
419 rettype ret; \
8164f0e2
TA
420 bool reset_config = false; \
421 \
422 if (!current_config && c && c->lxc_conf) { \
423 current_config = c->lxc_conf; \
424 reset_config = true; \
425 } \
426 \
858377e4 427 ret = do_##fnname(c, a1, a2, a3); \
8164f0e2
TA
428 if (reset_config) \
429 current_config = NULL; \
430 \
858377e4
SH
431 return ret; \
432}
433
434WRAP_API(bool, lxcapi_is_defined)
435
436static const char *do_lxcapi_state(struct lxc_container *c)
72d0e1cb 437{
72d0e1cb
SG
438 lxc_state_t s;
439
440 if (!c)
441 return NULL;
13f5be62 442 s = lxc_getstate(c->name, c->config_path);
39dc698c 443 return lxc_state2str(s);
72d0e1cb
SG
444}
445
858377e4
SH
446WRAP_API(const char *, lxcapi_state)
447
39dc698c 448static bool is_stopped(struct lxc_container *c)
794dd120
SH
449{
450 lxc_state_t s;
13f5be62 451 s = lxc_getstate(c->name, c->config_path);
794dd120
SH
452 return (s == STOPPED);
453}
454
858377e4 455static bool do_lxcapi_is_running(struct lxc_container *c)
72d0e1cb
SG
456{
457 const char *s;
458
459 if (!c)
460 return false;
858377e4 461 s = do_lxcapi_state(c);
72d0e1cb
SG
462 if (!s || strcmp(s, "STOPPED") == 0)
463 return false;
464 return true;
465}
466
858377e4
SH
467WRAP_API(bool, lxcapi_is_running)
468
469static bool do_lxcapi_freeze(struct lxc_container *c)
72d0e1cb
SG
470{
471 int ret;
472 if (!c)
473 return false;
474
9123e471 475 ret = lxc_freeze(c->name, c->config_path);
72d0e1cb
SG
476 if (ret)
477 return false;
478 return true;
479}
480
858377e4
SH
481WRAP_API(bool, lxcapi_freeze)
482
483static bool do_lxcapi_unfreeze(struct lxc_container *c)
72d0e1cb
SG
484{
485 int ret;
486 if (!c)
487 return false;
488
9123e471 489 ret = lxc_unfreeze(c->name, c->config_path);
72d0e1cb
SG
490 if (ret)
491 return false;
492 return true;
493}
494
858377e4
SH
495WRAP_API(bool, lxcapi_unfreeze)
496
497static int do_lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *masterfd)
0115f8fd
DE
498{
499 int ttyfd;
500 if (!c)
501 return -1;
502
b5159817 503 ttyfd = lxc_console_getfd(c, ttynum, masterfd);
0115f8fd
DE
504 return ttyfd;
505}
506
858377e4
SH
507WRAP_API_2(int, lxcapi_console_getfd, int *, int *)
508
b5159817
DE
509static int lxcapi_console(struct lxc_container *c, int ttynum, int stdinfd,
510 int stdoutfd, int stderrfd, int escape)
511{
858377e4
SH
512 int ret;
513
514 if (!c)
515 return -1;
516
517 current_config = c->lxc_conf;
518 ret = lxc_console(c, ttynum, stdinfd, stdoutfd, stderrfd, escape);
519 current_config = NULL;
520 return ret;
b5159817
DE
521}
522
191d43cc
CB
523static int do_lxcapi_console_log(struct lxc_container *c, struct lxc_console_log *log)
524{
525 int ret;
526
527 ret = lxc_cmd_console_log(c->name, do_lxcapi_get_config_path(c), log);
528 if (ret < 0) {
529 if (ret == -ENODATA)
63b74cda 530 NOTICE("The console log is empty");
191d43cc 531 else if (ret == -EFAULT)
63b74cda
CB
532 NOTICE("The container does not keep a console log");
533 else if (ret == -ENOENT)
534 NOTICE("The container does not keep a console log file");
535 else if (ret == -EIO)
536 NOTICE("Failed to write console log to log file");
191d43cc 537 else
63b74cda 538 ERROR("Failed to retrieve console log");
191d43cc
CB
539 }
540
541 return ret;
542}
543
544WRAP_API_1(int, lxcapi_console_log, struct lxc_console_log *)
545
858377e4 546static pid_t do_lxcapi_init_pid(struct lxc_container *c)
72d0e1cb 547{
72d0e1cb
SG
548 if (!c)
549 return -1;
550
5cee8c50 551 return lxc_cmd_get_init_pid(c->name, c->config_path);
72d0e1cb
SG
552}
553
858377e4
SH
554WRAP_API(pid_t, lxcapi_init_pid)
555
12a50cc6 556static bool load_config_locked(struct lxc_container *c, const char *fname)
8eb5694b
SH
557{
558 if (!c->lxc_conf)
559 c->lxc_conf = lxc_conf_init();
6b0d5538
SH
560 if (!c->lxc_conf)
561 return false;
d08779d4
SH
562 if (lxc_config_read(fname, c->lxc_conf, false) != 0)
563 return false;
d08779d4 564 return true;
8eb5694b
SH
565}
566
858377e4 567static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
72d0e1cb 568{
39dc698c
SH
569 bool ret = false, need_disklock = false;
570 int lret;
12a50cc6 571 const char *fname;
72d0e1cb
SG
572 if (!c)
573 return false;
574
575 fname = c->configfile;
576 if (alt_file)
577 fname = alt_file;
578 if (!fname)
579 return false;
39dc698c
SH
580 /*
581 * If we're reading something other than the container's config,
582 * we only need to lock the in-memory container. If loading the
583 * container's config file, take the disk lock.
584 */
585 if (strcmp(fname, c->configfile) == 0)
586 need_disklock = true;
587
588 if (need_disklock)
589 lret = container_disk_lock(c);
590 else
591 lret = container_mem_lock(c);
592 if (lret)
72d0e1cb 593 return false;
39dc698c 594
8eb5694b 595 ret = load_config_locked(c, fname);
39dc698c
SH
596
597 if (need_disklock)
598 container_disk_unlock(c);
599 else
600 container_mem_unlock(c);
72d0e1cb
SG
601 return ret;
602}
603
858377e4
SH
604WRAP_API_1(bool, lxcapi_load_config, const char *)
605
606static bool do_lxcapi_want_daemonize(struct lxc_container *c, bool state)
72d0e1cb 607{
497a2995 608 if (!c || !c->lxc_conf)
540f932a 609 return false;
f02abefe 610 if (container_mem_lock(c)) {
3bc449ed 611 ERROR("Error getting mem lock");
540f932a 612 return false;
3bc449ed 613 }
a2739df5 614 c->daemonize = state;
3bc449ed 615 container_mem_unlock(c);
540f932a 616 return true;
72d0e1cb
SG
617}
618
858377e4
SH
619WRAP_API_1(bool, lxcapi_want_daemonize, bool)
620
621static bool do_lxcapi_want_close_all_fds(struct lxc_container *c, bool state)
130a1888
ÇO
622{
623 if (!c || !c->lxc_conf)
49badbbe 624 return false;
130a1888
ÇO
625 if (container_mem_lock(c)) {
626 ERROR("Error getting mem lock");
49badbbe 627 return false;
130a1888 628 }
540f932a 629 c->lxc_conf->close_all_fds = state;
130a1888 630 container_mem_unlock(c);
49badbbe 631 return true;
130a1888
ÇO
632}
633
858377e4
SH
634WRAP_API_1(bool, lxcapi_want_close_all_fds, bool)
635
636static bool do_lxcapi_wait(struct lxc_container *c, const char *state, int timeout)
7a44c8b4
SG
637{
638 int ret;
639
640 if (!c)
641 return false;
642
67e571de 643 ret = lxc_wait(c->name, state, timeout, c->config_path);
7a44c8b4
SG
644 return ret == 0;
645}
646
858377e4 647WRAP_API_2(bool, lxcapi_wait, const char *, int)
7a44c8b4 648
2d834aa8
SH
649static bool am_single_threaded(void)
650{
74f96976 651 struct dirent *direntp;
2d834aa8
SH
652 DIR *dir;
653 int count=0;
654
2d834aa8 655 dir = opendir("/proc/self/task");
2d834aa8
SH
656 if (!dir) {
657 INFO("failed to open /proc/self/task");
658 return false;
659 }
660
74f96976 661 while ((direntp = readdir(dir))) {
2d834aa8
SH
662 if (!strcmp(direntp->d_name, "."))
663 continue;
664
665 if (!strcmp(direntp->d_name, ".."))
666 continue;
667 if (++count > 1)
668 break;
669 }
2d834aa8 670 closedir(dir);
2d834aa8
SH
671 return count == 1;
672}
673
fd51a89b
SH
674static void push_arg(char ***argp, char *arg, int *nargs)
675{
676 char **argv;
677 char *copy;
678
679 do {
680 copy = strdup(arg);
681 } while (!copy);
682 do {
683 argv = realloc(*argp, (*nargs + 2) * sizeof(char *));
684 } while (!argv);
685 *argp = argv;
686 argv[*nargs] = copy;
687 (*nargs)++;
688 argv[*nargs] = NULL;
689}
690
691static char **split_init_cmd(const char *incmd)
692{
693 size_t len;
694 int nargs = 0;
5590a671 695 char *copy, *p, *saveptr = NULL;
fd51a89b
SH
696 char **argv;
697
698 if (!incmd)
699 return NULL;
700
701 len = strlen(incmd) + 1;
702 copy = alloca(len);
703 strncpy(copy, incmd, len);
704 copy[len-1] = '\0';
705
706 do {
707 argv = malloc(sizeof(char *));
708 } while (!argv);
709 argv[0] = NULL;
710 for (p = strtok_r(copy, " ", &saveptr); p != NULL;
711 p = strtok_r(NULL, " ", &saveptr))
712 push_arg(&argv, p, &nargs);
713
714 if (nargs == 0) {
715 free(argv);
716 return NULL;
717 }
718 return argv;
719}
720
721static void free_init_cmd(char **argv)
722{
723 int i = 0;
724
725 if (!argv)
726 return;
727 while (argv[i])
728 free(argv[i++]);
729 free(argv);
730}
731
5e5576a4
CB
732static int lxc_rcv_status(int state_socket)
733{
734 int ret;
ee8377bd 735 int state = -1;
5e5576a4 736
ee8377bd 737again:
5e5576a4
CB
738 /* Receive container state. */
739 ret = lxc_abstract_unix_rcv_credential(state_socket, &state,
ee8377bd
CB
740 sizeof(int));
741 if (ret <= 0) {
742 if (errno != EINTR)
743 return -1;
744 TRACE("Caught EINTR; retrying");
745 goto again;
746 }
5e5576a4
CB
747
748 return state;
749}
750
751static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid)
752{
01c1b11e 753 int ret, state;
5e5576a4
CB
754
755 /* Close write end of the socket pair. */
756 close(handler->state_socket_pair[1]);
757 handler->state_socket_pair[1] = -1;
758
759 state = lxc_rcv_status(handler->state_socket_pair[0]);
760
761 /* Close read end of the socket pair. */
762 close(handler->state_socket_pair[0]);
763 handler->state_socket_pair[0] = -1;
764
765 /* The first child is going to fork() again and then exits. So we reap
766 * the first child here.
767 */
01c1b11e
CB
768 ret = wait_for_pid(pid);
769 if (ret < 0)
770 DEBUG("Failed waiting on first child %d", pid);
771 else
772 DEBUG("First child %d exited", pid);
5e5576a4
CB
773
774 if (state < 0) {
775 SYSERROR("Failed to receive the container state");
776 return false;
777 }
778
779 /* If we receive anything else then running we know that the container
780 * failed to start.
781 */
782 if (state != RUNNING) {
783 ERROR("Received container state \"%s\" instead of \"RUNNING\"",
784 lxc_state2str(state));
785 return false;
786 }
787
788 TRACE("Container is in \"RUNNING\" state");
789 return true;
790}
791
858377e4 792static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
72d0e1cb
SG
793{
794 int ret;
aa460476 795 struct lxc_handler *handler;
72d0e1cb 796 struct lxc_conf *conf;
540f932a 797 bool daemonize = false;
6eaac303 798 FILE *pid_fp = NULL;
72d0e1cb
SG
799 char *default_args[] = {
800 "/sbin/init",
13aad0ae 801 NULL,
72d0e1cb 802 };
fd51a89b 803 char **init_cmd = NULL;
c1a3e547 804 int keepfds[3] = {-1, -1, -1};
72d0e1cb 805
7cb19d44 806 /* container does exist */
72d0e1cb
SG
807 if (!c)
808 return false;
120146b9 809
7cb19d44
CB
810 /* If anything fails before we set error_num, we want an error in there.
811 */
120146b9
SG
812 c->error_num = 1;
813
7cb19d44 814 /* Container has not been setup. */
72d0e1cb
SG
815 if (!c->lxc_conf)
816 return false;
817
c47eafec
CB
818 ret = ongoing_create(c);
819 if (ret < 0) {
7cb19d44 820 ERROR("Failed checking for incomplete container creation");
3e625e2d 821 return false;
3e625e2d 822 } else if (ret == 1) {
7cb19d44 823 ERROR("Ongoing container creation detected");
3e625e2d 824 return false;
c47eafec 825 } else if (ret == 2) {
7cb19d44 826 ERROR("Failed to create container");
c47eafec
CB
827 do_lxcapi_destroy(c);
828 return false;
3e625e2d
SH
829 }
830
5cee8c50 831 if (container_mem_lock(c))
72d0e1cb
SG
832 return false;
833 conf = c->lxc_conf;
834 daemonize = c->daemonize;
72d0e1cb 835
aa460476 836 /* initialize handler */
5e5576a4 837 handler = lxc_init_handler(c->name, conf, c->config_path, daemonize);
dbc9832d 838 container_mem_unlock(c);
aa460476
CB
839 if (!handler)
840 return false;
841
fa30091b
CB
842 if (!argv) {
843 if (useinit && conf->execute_cmd)
844 argv = init_cmd = split_init_cmd(conf->execute_cmd);
845 else
846 argv = init_cmd = split_init_cmd(conf->init_cmd);
847 }
fd51a89b 848
7cb19d44 849 /* ... otherwise use default_args. */
fa30091b 850 if (!argv) {
e1e76423
CB
851 if (useinit) {
852 ERROR("No valid init detected");
853 lxc_free_handler(handler);
fa30091b 854 return false;
e1e76423
CB
855 }
856 argv = default_args;
fa30091b 857 }
72d0e1cb 858
7cb19d44
CB
859 /* I'm not sure what locks we want here.Any? Is liblxc's locking enough
860 * here to protect the on disk container? We don't want to exclude
861 * things like lxc_info while the container is running.
862 */
72d0e1cb 863 if (daemonize) {
a6b6ad7b 864 bool started;
0a4be28d 865 char title[2048];
c47eafec 866 pid_t pid;
71454076 867
c47eafec 868 pid = fork();
f2e07cb6 869 if (pid < 0) {
c47eafec 870 free_init_cmd(init_cmd);
f2e07cb6 871 lxc_free_handler(handler);
72d0e1cb 872 return false;
f2e07cb6 873 }
6eaac303 874
7cb19d44 875 /* first parent */
6eaac303
QH
876 if (pid != 0) {
877 /* Set to NULL because we don't want father unlink
878 * the PID file, child will do the free and unlink.
879 */
880 c->pidfile = NULL;
5e5576a4 881
7cb19d44
CB
882 /* Wait for container to tell us whether it started
883 * successfully.
884 */
a6b6ad7b
CB
885 started = wait_on_daemonized_start(handler, pid);
886
887 free_init_cmd(init_cmd);
888 lxc_free_handler(handler);
889 return started;
6eaac303 890 }
025ed0f3 891
7cb19d44
CB
892 /* first child */
893
0a4be28d 894 /* We don't really care if this doesn't print all the
7cb19d44
CB
895 * characters. All that it means is that the proctitle will be
896 * ugly. Similarly, we also don't care if setproctitle() fails.
897 * */
0a4be28d
TA
898 snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name);
899 INFO("Attempting to set proc title to %s", title);
900 setproctitle(title);
901
7cb19d44
CB
902 /* We fork() a second time to be reparented to init. Like
903 * POSIX's daemon() function we change to "/" and redirect
904 * std{in,out,err} to /dev/null.
905 */
697fa639
SH
906 pid = fork();
907 if (pid < 0) {
7cb19d44 908 SYSERROR("Failed to fork first child process");
d608fbda 909 _exit(EXIT_FAILURE);
697fa639 910 }
a6b6ad7b 911
7cb19d44 912 /* second parent */
a6b6ad7b
CB
913 if (pid != 0) {
914 free_init_cmd(init_cmd);
915 lxc_free_handler(handler);
d608fbda 916 _exit(EXIT_SUCCESS);
a6b6ad7b
CB
917 }
918
7cb19d44
CB
919 /* second child */
920
921 /* change to / directory */
922 ret = chdir("/");
923 if (ret < 0) {
924 SYSERROR("Failed to change to \"/\" directory");
d608fbda 925 _exit(EXIT_FAILURE);
c278cef2 926 }
7cb19d44 927
c1a3e547
CB
928 keepfds[0] = handler->conf->maincmd_fd;
929 keepfds[1] = handler->state_socket_pair[0];
930 keepfds[2] = handler->state_socket_pair[1];
931 ret = lxc_check_inherited(conf, true, keepfds,
932 sizeof(keepfds) / sizeof(keepfds[0]));
7cb19d44 933 if (ret < 0)
d608fbda 934 _exit(EXIT_FAILURE);
7cb19d44
CB
935
936 /* redirect std{in,out,err} to /dev/null */
937 ret = null_stdfds();
938 if (ret < 0) {
939 ERROR("Failed to redirect std{in,out,err} to /dev/null");
d608fbda 940 _exit(EXIT_FAILURE);
69aeabac 941 }
7cb19d44
CB
942
943 /* become session leader */
944 ret = setsid();
945 if (ret < 0)
0059379f 946 TRACE("Process %d is already process group leader", lxc_raw_getpid());
2d834aa8
SH
947 } else {
948 if (!am_single_threaded()) {
949 ERROR("Cannot start non-daemonized container when threaded");
a6b6ad7b 950 free_init_cmd(init_cmd);
f2e07cb6 951 lxc_free_handler(handler);
2d834aa8
SH
952 return false;
953 }
72d0e1cb
SG
954 }
955
aa460476 956 /* We need to write PID file after daemonize, so we always
6eaac303
QH
957 * write the right PID.
958 */
959 if (c->pidfile) {
960 pid_fp = fopen(c->pidfile, "w");
961 if (pid_fp == NULL) {
962 SYSERROR("Failed to create pidfile '%s' for '%s'",
963 c->pidfile, c->name);
c47eafec 964 free_init_cmd(init_cmd);
f2e07cb6 965 lxc_free_handler(handler);
13353dc4 966 if (daemonize)
d608fbda 967 _exit(EXIT_FAILURE);
6eaac303
QH
968 return false;
969 }
970
0059379f 971 if (fprintf(pid_fp, "%d\n", lxc_raw_getpid()) < 0) {
6eaac303
QH
972 SYSERROR("Failed to write '%s'", c->pidfile);
973 fclose(pid_fp);
974 pid_fp = NULL;
c47eafec 975 free_init_cmd(init_cmd);
f2e07cb6 976 lxc_free_handler(handler);
13353dc4 977 if (daemonize)
d608fbda 978 _exit(EXIT_FAILURE);
6eaac303
QH
979 return false;
980 }
981
982 fclose(pid_fp);
983 pid_fp = NULL;
984 }
985
72d0e1cb 986 conf->reboot = 0;
d2cf4c37 987
a8dfe4e0
WB
988 /* Unshare the mount namespace if requested */
989 if (conf->monitor_unshare) {
7cb19d44
CB
990 ret = unshare(CLONE_NEWNS);
991 if (ret < 0) {
a8dfe4e0 992 SYSERROR("failed to unshare mount namespace");
f2e07cb6 993 lxc_free_handler(handler);
a6b6ad7b 994 ret = 1;
7cb19d44 995 goto on_error;
a8dfe4e0 996 }
7cb19d44
CB
997
998 ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
999 if (ret < 0) {
a8dfe4e0 1000 SYSERROR("Failed to make / rslave at startup");
f2e07cb6 1001 lxc_free_handler(handler);
a6b6ad7b 1002 ret = 1;
7cb19d44 1003 goto on_error;
a8dfe4e0
WB
1004 }
1005 }
1006
8bee8851 1007reboot:
aa460476
CB
1008 if (conf->reboot == 2) {
1009 /* initialize handler */
5e5576a4 1010 handler = lxc_init_handler(c->name, conf, c->config_path, daemonize);
a6b6ad7b
CB
1011 if (!handler) {
1012 ret = 1;
7cb19d44 1013 goto on_error;
a6b6ad7b 1014 }
aa460476
CB
1015 }
1016
c1a3e547
CB
1017 keepfds[0] = handler->conf->maincmd_fd;
1018 keepfds[1] = handler->state_socket_pair[0];
1019 keepfds[2] = handler->state_socket_pair[1];
1020 ret = lxc_check_inherited(conf, daemonize, keepfds,
1021 sizeof(keepfds) / sizeof(keepfds[0]));
7cb19d44 1022 if (ret < 0) {
f2e07cb6 1023 lxc_free_handler(handler);
d2cf4c37 1024 ret = 1;
7cb19d44 1025 goto on_error;
d2cf4c37
SH
1026 }
1027
9605460f
CB
1028 if (useinit)
1029 ret = lxc_execute(c->name, argv, 1, handler, c->config_path, daemonize);
1030 else
1031 ret = lxc_start(c->name, argv, handler, c->config_path, daemonize);
cd5177e9 1032 c->error_num = handler->exit_status;
72d0e1cb 1033
8bee8851 1034 if (conf->reboot == 1) {
7cb19d44 1035 INFO("Container requested reboot");
8bee8851 1036 conf->reboot = 2;
72d0e1cb
SG
1037 goto reboot;
1038 }
1039
7cb19d44 1040on_error:
487d8008
QH
1041 if (c->pidfile) {
1042 unlink(c->pidfile);
1043 free(c->pidfile);
1044 c->pidfile = NULL;
1045 }
fd51a89b
SH
1046 free_init_cmd(init_cmd);
1047
7cb19d44 1048 if (daemonize && ret != 0)
d608fbda 1049 _exit(EXIT_FAILURE);
7cb19d44 1050 else if (daemonize)
d608fbda 1051 _exit(EXIT_SUCCESS);
7cb19d44
CB
1052
1053 if (ret != 0)
1054 return false;
1055
1056 return true;
72d0e1cb
SG
1057}
1058
858377e4
SH
1059static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
1060{
1061 bool ret;
1062 current_config = c ? c->lxc_conf : NULL;
1063 ret = do_lxcapi_start(c, useinit, argv);
1064 current_config = NULL;
1065 return ret;
1066}
1067
72d0e1cb
SG
1068/*
1069 * note there MUST be an ending NULL
1070 */
1071static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
1072{
1073 va_list ap;
a0e93eeb 1074 char **inargs = NULL;
72d0e1cb
SG
1075 bool bret = false;
1076
1077 /* container exists */
1078 if (!c)
1079 return false;
1080
858377e4
SH
1081 current_config = c->lxc_conf;
1082
72d0e1cb 1083 va_start(ap, useinit);
a0e93eeb 1084 inargs = lxc_va_arg_list_to_argv(ap, 0, 1);
72d0e1cb
SG
1085 va_end(ap);
1086
a0e93eeb
CS
1087 if (!inargs) {
1088 ERROR("Memory allocation error.");
1089 goto out;
72d0e1cb
SG
1090 }
1091
a0e93eeb 1092 /* pass NULL if no arguments were supplied */
858377e4 1093 bret = do_lxcapi_start(c, useinit, *inargs ? inargs : NULL);
72d0e1cb
SG
1094
1095out:
1096 if (inargs) {
4e03ae57
DE
1097 char **arg;
1098 for (arg = inargs; *arg; arg++)
1099 free(*arg);
72d0e1cb
SG
1100 free(inargs);
1101 }
1102
858377e4 1103 current_config = NULL;
72d0e1cb
SG
1104 return bret;
1105}
1106
858377e4 1107static bool do_lxcapi_stop(struct lxc_container *c)
72d0e1cb
SG
1108{
1109 int ret;
1110
1111 if (!c)
1112 return false;
1113
ef6e34ee 1114 ret = lxc_cmd_stop(c->name, c->config_path);
72d0e1cb 1115
d775f21b 1116 return ret == 0;
72d0e1cb
SG
1117}
1118
858377e4
SH
1119WRAP_API(bool, lxcapi_stop)
1120
d5752559
SH
1121static int do_create_container_dir(const char *path, struct lxc_conf *conf)
1122{
1123 int ret = -1, lasterr;
1124 char *p = alloca(strlen(path)+1);
1125 mode_t mask = umask(0002);
1126 ret = mkdir(path, 0770);
1127 lasterr = errno;
1128 umask(mask);
1129 errno = lasterr;
1130 if (ret) {
1131 if (errno == EEXIST)
1132 ret = 0;
1133 else {
1134 SYSERROR("failed to create container path %s", path);
1135 return -1;
1136 }
1137 }
1138 strcpy(p, path);
1139 if (!lxc_list_empty(&conf->id_map) && chown_mapped_root(p, conf) != 0) {
1140 ERROR("Failed to chown container dir");
1141 ret = -1;
1142 }
1143 return ret;
1144}
1145
72d0e1cb
SG
1146/*
1147 * create the standard expected container dir
1148 */
1149static bool create_container_dir(struct lxc_container *c)
1150{
1151 char *s;
1152 int len, ret;
1153
2a59a681 1154 len = strlen(c->config_path) + strlen(c->name) + 2;
72d0e1cb
SG
1155 s = malloc(len);
1156 if (!s)
1157 return false;
2a59a681 1158 ret = snprintf(s, len, "%s/%s", c->config_path, c->name);
72d0e1cb
SG
1159 if (ret < 0 || ret >= len) {
1160 free(s);
1161 return false;
1162 }
d5752559 1163 ret = do_create_container_dir(s, c->lxc_conf);
72d0e1cb
SG
1164 free(s);
1165 return ret == 0;
1166}
1167
10bc1861
CB
1168/* do_storage_create: thin wrapper around storage_create(). Like
1169 * storage_create(), it returns a mounted bdev on success, NULL on error.
72d0e1cb 1170 */
10bc1861
CB
1171static struct lxc_storage *do_storage_create(struct lxc_container *c,
1172 const char *type,
1173 struct bdev_specs *specs)
1897e3bc 1174{
e9e29a33 1175 int ret;
1897e3bc 1176 size_t len;
e9e29a33 1177 char *dest;
10bc1861 1178 struct lxc_storage *bdev;
1897e3bc 1179
cd219ae6 1180 /* rootfs.path or lxcpath/lxcname/rootfs */
e9e29a33
CB
1181 if (c->lxc_conf->rootfs.path &&
1182 (access(c->lxc_conf->rootfs.path, F_OK) == 0)) {
cf465fe4
SH
1183 const char *rpath = c->lxc_conf->rootfs.path;
1184 len = strlen(rpath) + 1;
cd219ae6 1185 dest = alloca(len);
cf465fe4 1186 ret = snprintf(dest, len, "%s", rpath);
cd219ae6 1187 } else {
858377e4 1188 const char *lxcpath = do_lxcapi_get_config_path(c);
cd219ae6
SY
1189 len = strlen(c->name) + strlen(lxcpath) + 9;
1190 dest = alloca(len);
1191 ret = snprintf(dest, len, "%s/%s/rootfs", lxcpath, c->name);
1192 }
e9e29a33 1193 if (ret < 0 || (size_t)ret >= len)
1897e3bc
SH
1194 return NULL;
1195
10bc1861 1196 bdev = storage_create(dest, type, c->name, specs);
d44e88c2 1197 if (!bdev) {
e9e29a33 1198 ERROR("Failed to create \"%s\" storage", type);
1897e3bc 1199 return NULL;
d44e88c2
SH
1200 }
1201
7a96a068 1202 if (!c->set_config_item(c, "lxc.rootfs.path", bdev->src)) {
e9e29a33 1203 ERROR("Failed to set \"lxc.rootfs.path = %s\"", bdev->src);
f7ac4459
CB
1204 return NULL;
1205 }
cf3ef16d 1206
e9e29a33
CB
1207 /* If we are not root, chown the rootfs dir to root in the target user
1208 * namespace.
f7ac4459 1209 */
e9e29a33
CB
1210 ret = geteuid();
1211 if (ret != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) {
1212 ret = chown_mapped_root(bdev->dest, c->lxc_conf);
1213 if (ret < 0) {
1214 ERROR("Error chowning \"%s\" to container root", bdev->dest);
97e9cfa0 1215 suggest_default_idmap();
10bc1861 1216 storage_put(bdev);
cf3ef16d
SH
1217 return NULL;
1218 }
1219 }
1220
1897e3bc
SH
1221 return bdev;
1222}
1223
96b3cb40 1224static char *lxcbasename(char *path)
72d0e1cb 1225{
47e55887
CB
1226 char *p;
1227
1228 p = path + strlen(path) - 1;
96b3cb40
SH
1229 while (*p != '/' && p > path)
1230 p--;
47e55887 1231
96b3cb40
SH
1232 return p;
1233}
72d0e1cb 1234
47e55887
CB
1235static bool create_run_template(struct lxc_container *c, char *tpath,
1236 bool need_null_stdfds, char *const argv[])
96b3cb40 1237{
47e55887 1238 int ret;
96b3cb40 1239 pid_t pid;
72d0e1cb 1240
72d0e1cb 1241 if (!tpath)
96b3cb40 1242 return true;
72d0e1cb
SG
1243
1244 pid = fork();
1245 if (pid < 0) {
7e34710e 1246 SYSERROR("Failed to fork task for container creation template");
96b3cb40 1247 return false;
72d0e1cb
SG
1248 }
1249
1a0e70ac 1250 if (pid == 0) { /* child */
47e55887
CB
1251 int i, len;
1252 char *namearg, *patharg, *rootfsarg;
96b3cb40 1253 char **newargv;
47e55887
CB
1254 int nargs = 0;
1255 struct lxc_storage *bdev = NULL;
cf3ef16d 1256 struct lxc_conf *conf = c->lxc_conf;
47e55887 1257 uid_t euid;
72d0e1cb 1258
47e55887
CB
1259 if (need_null_stdfds) {
1260 ret = null_stdfds();
1261 if (ret < 0)
1262 _exit(EXIT_FAILURE);
dc23c1c8 1263 }
1897e3bc 1264
8a388ed4 1265 bdev = storage_init(c->lxc_conf);
1897e3bc 1266 if (!bdev) {
47e55887 1267 ERROR("Failed to initialize storage");
7e34710e 1268 _exit(EXIT_FAILURE);
1897e3bc
SH
1269 }
1270
47e55887
CB
1271 euid = geteuid();
1272 if (euid == 0) {
1273 ret = unshare(CLONE_NEWNS);
1274 if (ret < 0) {
1275 ERROR("Failed to unshare CLONE_NEWNS");
7e34710e 1276 _exit(EXIT_FAILURE);
cf3ef16d 1277 }
47e55887
CB
1278
1279 ret = detect_shared_rootfs();
1280 if (ret == 1) {
1281 ret = mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL);
1282 if (ret < 0) {
1283 SYSERROR("Failed to make \"/\" rslave");
4de2791f
SH
1284 ERROR("Continuing...");
1285 }
1286 }
1287 }
47e55887
CB
1288
1289 if (strcmp(bdev->type, "dir") != 0 && strcmp(bdev->type, "btrfs") != 0) {
1290 if (euid != 0) {
1291 ERROR("Unprivileged users can only create "
1292 "btrfs and directory-backed containers");
eb70aaf0 1293 _exit(EXIT_FAILURE);
4de2791f 1294 }
241978fa 1295
47e55887
CB
1296 if (strcmp(bdev->type, "overlay") == 0 ||
1297 strcmp(bdev->type, "overlayfs") == 0) {
241978fa
CB
1298 /* If we create an overlay container we need to
1299 * rsync the contents into
1300 * <container-path>/<container-name>/rootfs.
1301 * However, the overlay mount function will
1302 * mount will mount
1303 * <container-path>/<container-name>/delta0
1304 * over
1305 * <container-path>/<container-name>/rootfs
1306 * which means we would rsync the rootfs into
1307 * the delta directory. That doesn't make sense
1308 * since the delta directory only exists to
1309 * record the differences to
1310 * <container-path>/<container-name>/rootfs. So
1311 * let's simply bind-mount here and then rsync
1312 * directly into
1313 * <container-path>/<container-name>/rootfs.
1314 */
1315 char *src;
1316
1317 src = ovl_get_rootfs(bdev->src, &(size_t){0});
1318 if (!src) {
1319 ERROR("Failed to get rootfs");
eb70aaf0 1320 _exit(EXIT_FAILURE);
241978fa
CB
1321 }
1322
1323 ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC, NULL);
1324 if (ret < 0) {
1325 ERROR("Failed to mount rootfs");
1326 return -1;
1327 }
1328 } else {
47e55887
CB
1329 ret = bdev->ops->mount(bdev);
1330 if (ret < 0) {
241978fa 1331 ERROR("Failed to mount rootfs");
eb70aaf0 1332 _exit(EXIT_FAILURE);
241978fa 1333 }
cf3ef16d 1334 }
1a0e70ac 1335 } else { /* TODO come up with a better way here! */
41dc7155 1336 const char *src;
f10fad2f 1337 free(bdev->dest);
e9705550
CB
1338 src = lxc_storage_get_path(bdev->src, bdev->type);
1339 bdev->dest = strdup(src);
1897e3bc
SH
1340 }
1341
47e55887
CB
1342 /* Create our new array, pre-pend the template name and base
1343 * args.
72d0e1cb
SG
1344 */
1345 if (argv)
47e55887
CB
1346 for (nargs = 0; argv[nargs]; nargs++) {
1347 ;
1348 }
1349 /* template, path, rootfs and name args */
1350 nargs += 4;
cf3ef16d 1351
72d0e1cb
SG
1352 newargv = malloc(nargs * sizeof(*newargv));
1353 if (!newargv)
7e34710e 1354 _exit(EXIT_FAILURE);
96b3cb40 1355 newargv[0] = lxcbasename(tpath);
72d0e1cb 1356
47e55887 1357 /* --path */
2a59a681 1358 len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
72d0e1cb
SG
1359 patharg = malloc(len);
1360 if (!patharg)
7e34710e 1361 _exit(EXIT_FAILURE);
2a59a681 1362 ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
72d0e1cb 1363 if (ret < 0 || ret >= len)
7e34710e 1364 _exit(EXIT_FAILURE);
72d0e1cb 1365 newargv[1] = patharg;
47e55887
CB
1366
1367 /* --name */
72d0e1cb
SG
1368 len = strlen("--name=") + strlen(c->name) + 1;
1369 namearg = malloc(len);
1370 if (!namearg)
7e34710e 1371 _exit(EXIT_FAILURE);
72d0e1cb
SG
1372 ret = snprintf(namearg, len, "--name=%s", c->name);
1373 if (ret < 0 || ret >= len)
7e34710e 1374 _exit(EXIT_FAILURE);
72d0e1cb
SG
1375 newargv[2] = namearg;
1376
47e55887 1377 /* --rootfs */
1897e3bc
SH
1378 len = strlen("--rootfs=") + 1 + strlen(bdev->dest);
1379 rootfsarg = malloc(len);
1380 if (!rootfsarg)
7e34710e 1381 _exit(EXIT_FAILURE);
1897e3bc
SH
1382 ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
1383 if (ret < 0 || ret >= len)
7e34710e 1384 _exit(EXIT_FAILURE);
1897e3bc
SH
1385 newargv[3] = rootfsarg;
1386
72d0e1cb
SG
1387 /* add passed-in args */
1388 if (argv)
1897e3bc 1389 for (i = 4; i < nargs; i++)
47e55887 1390 newargv[i] = argv[i - 4];
72d0e1cb
SG
1391
1392 /* add trailing NULL */
1393 nargs++;
1394 newargv = realloc(newargv, nargs * sizeof(*newargv));
1395 if (!newargv)
7e34710e 1396 _exit(EXIT_FAILURE);
72d0e1cb
SG
1397 newargv[nargs - 1] = NULL;
1398
47e55887
CB
1399 /* If we're running the template in a mapped userns, then we
1400 * prepend the template command with: lxc-usernsexec <-m map1>
1401 * ... <-m mapn> -- and we append "--mapped-uid x", where x is
1402 * the mapped uid for our geteuid()
cf3ef16d 1403 */
0e6e3a41 1404 if (!lxc_list_empty(&conf->id_map)) {
47e55887
CB
1405 int extraargs, hostuid_mapped, hostgid_mapped;
1406 char **n2;
1407 char txtuid[20], txtgid[20];
cf3ef16d
SH
1408 struct lxc_list *it;
1409 struct id_map *map;
47e55887 1410 int n2args = 1;
cf3ef16d 1411
47e55887
CB
1412 n2 = malloc(n2args * sizeof(*n2));
1413 if (!n2)
7e34710e 1414 _exit(EXIT_FAILURE);
47e55887 1415
cf3ef16d
SH
1416 newargv[0] = tpath;
1417 tpath = "lxc-usernsexec";
1418 n2[0] = "lxc-usernsexec";
1419 lxc_list_for_each(it, &conf->id_map) {
1420 map = it->elem;
1421 n2args += 2;
57d116ab 1422 n2 = realloc(n2, n2args * sizeof(char *));
cf3ef16d 1423 if (!n2)
7e34710e 1424 _exit(EXIT_FAILURE);
47e55887
CB
1425
1426 n2[n2args - 2] = "-m";
1427 n2[n2args - 1] = malloc(200);
1428 if (!n2[n2args - 1])
7e34710e 1429 _exit(EXIT_FAILURE);
47e55887
CB
1430
1431 ret = snprintf(n2[n2args - 1], 200, "%c:%lu:%lu:%lu",
1432 map->idtype == ID_TYPE_UID ? 'u' : 'g',
1433 map->nsid, map->hostid, map->range);
cf3ef16d 1434 if (ret < 0 || ret >= 200)
7e34710e 1435 _exit(EXIT_FAILURE);
cf3ef16d 1436 }
47e55887
CB
1437
1438 hostuid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
1439 extraargs = hostuid_mapped >= 0 ? 1 : 3;
57d116ab 1440 n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
cf3ef16d 1441 if (!n2)
7e34710e 1442 _exit(EXIT_FAILURE);
47e55887
CB
1443
1444 if (hostuid_mapped < 0) {
1445 hostuid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
cf3ef16d 1446 n2[n2args++] = "-m";
47e55887
CB
1447 if (hostuid_mapped < 0) {
1448 ERROR("Failed to find free uid to map");
7e34710e 1449 _exit(EXIT_FAILURE);
cf3ef16d 1450 }
47e55887 1451
cf3ef16d 1452 n2[n2args++] = malloc(200);
47e55887 1453 if (!n2[n2args - 1]) {
cf3ef16d 1454 SYSERROR("out of memory");
7e34710e 1455 _exit(EXIT_FAILURE);
cf3ef16d 1456 }
47e55887
CB
1457 ret = snprintf(n2[n2args - 1], 200, "u:%d:%d:1",
1458 hostuid_mapped, geteuid());
1459 if (ret < 0 || ret >= 200)
7e34710e 1460 _exit(EXIT_FAILURE);
cf3ef16d 1461 }
47e55887
CB
1462
1463 hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
2133f58c
SH
1464 extraargs = hostgid_mapped >= 0 ? 1 : 3;
1465 n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
1466 if (!n2)
7e34710e 1467 _exit(EXIT_FAILURE);
47e55887 1468
2133f58c 1469 if (hostgid_mapped < 0) {
339efad9 1470 hostgid_mapped = find_unmapped_nsid(conf, ID_TYPE_GID);
2133f58c
SH
1471 n2[n2args++] = "-m";
1472 if (hostgid_mapped < 0) {
47e55887 1473 ERROR("Failed to find free gid to map");
7e34710e 1474 _exit(EXIT_FAILURE);
2133f58c 1475 }
47e55887 1476
2133f58c 1477 n2[n2args++] = malloc(200);
47e55887 1478 if (!n2[n2args - 1]) {
2133f58c 1479 SYSERROR("out of memory");
7e34710e 1480 _exit(EXIT_FAILURE);
2133f58c 1481 }
47e55887
CB
1482
1483 ret = snprintf(n2[n2args - 1], 200, "g:%d:%d:1",
1484 hostgid_mapped, getegid());
1485 if (ret < 0 || ret >= 200)
7e34710e 1486 _exit(EXIT_FAILURE);
2133f58c 1487 }
cf3ef16d
SH
1488 n2[n2args++] = "--";
1489 for (i = 0; i < nargs; i++)
1490 n2[i + n2args] = newargv[i];
57d116ab 1491 n2args += nargs;
47e55887
CB
1492
1493 /* Finally add "--mapped-uid $uid" to tell template what
1494 * to chown cached images to.
1a0e70ac 1495 */
2133f58c 1496 n2args += 4;
57d116ab 1497 n2 = realloc(n2, n2args * sizeof(char *));
47e55887 1498 if (!n2)
7e34710e 1499 _exit(EXIT_FAILURE);
47e55887 1500
1a0e70ac 1501 /* note n2[n2args-1] is NULL */
47e55887
CB
1502 n2[n2args - 5] = "--mapped-uid";
1503 snprintf(txtuid, 20, "%d", hostuid_mapped);
1504 n2[n2args - 4] = txtuid;
1505 n2[n2args - 3] = "--mapped-gid";
2133f58c 1506 snprintf(txtgid, 20, "%d", hostgid_mapped);
47e55887
CB
1507 n2[n2args - 2] = txtgid;
1508 n2[n2args - 1] = NULL;
cf3ef16d
SH
1509 free(newargv);
1510 newargv = n2;
1511 }
47e55887 1512
cf3ef16d 1513 execvp(tpath, newargv);
e9705550 1514 SYSERROR("Failed to execute template %s", tpath);
7e34710e 1515 _exit(EXIT_FAILURE);
72d0e1cb
SG
1516 }
1517
47e55887
CB
1518 ret = wait_for_pid(pid);
1519 if (ret != 0) {
1520 ERROR("Failed to create container from template");
96b3cb40
SH
1521 return false;
1522 }
1523
1524 return true;
1525}
1526
74a3920a 1527static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
3ce74686 1528{
1fd9bd50 1529 long flen;
b4569e93 1530 char *contents;
3ce74686 1531 FILE *f;
025ed0f3 1532 int ret = -1;
52026772 1533#if HAVE_LIBGNUTLS
025ed0f3 1534 int i;
3ce74686 1535 unsigned char md_value[SHA_DIGEST_LENGTH];
b4569e93 1536 char *tpath;
52026772 1537#endif
3ce74686 1538
025ed0f3 1539 f = fopen(path, "r");
025ed0f3 1540 if (f == NULL)
3ce74686 1541 return false;
025ed0f3
SH
1542
1543 if (fseek(f, 0, SEEK_END) < 0)
1544 goto out_error;
1545 if ((flen = ftell(f)) < 0)
1546 goto out_error;
1547 if (fseek(f, 0, SEEK_SET) < 0)
1548 goto out_error;
1549 if ((contents = malloc(flen + 1)) == NULL)
1550 goto out_error;
1551 if (fread(contents, 1, flen, f) != flen)
1552 goto out_free_contents;
1553
3ce74686 1554 contents[flen] = '\0';
025ed0f3 1555 ret = fclose(f);
025ed0f3
SH
1556 f = NULL;
1557 if (ret < 0)
1558 goto out_free_contents;
3ce74686 1559
b4569e93 1560#if HAVE_LIBGNUTLS
01efd4d3 1561 tpath = get_template_path(t);
85db5535 1562 if (!tpath) {
959aee9c 1563 ERROR("bad template: %s", t);
025ed0f3 1564 goto out_free_contents;
3ce74686
SH
1565 }
1566
85db5535
DE
1567 ret = sha1sum_file(tpath, md_value);
1568 if (ret < 0) {
1569 ERROR("Error getting sha1sum of %s", tpath);
3ce74686 1570 free(tpath);
85db5535 1571 goto out_free_contents;
3ce74686 1572 }
85db5535 1573 free(tpath);
3ce74686
SH
1574#endif
1575
025ed0f3 1576 f = fopen(path, "w");
025ed0f3 1577 if (f == NULL) {
3ce74686
SH
1578 SYSERROR("reopening config for writing");
1579 free(contents);
1580 return false;
1581 }
1582 fprintf(f, "# Template used to create this container: %s\n", t);
1583 if (argv) {
1584 fprintf(f, "# Parameters passed to the template:");
1585 while (*argv) {
1586 fprintf(f, " %s", *argv);
1587 argv++;
1588 }
1589 fprintf(f, "\n");
1590 }
1591#if HAVE_LIBGNUTLS
56698177
SH
1592 fprintf(f, "# Template script checksum (SHA-1): ");
1593 for (i=0; i<SHA_DIGEST_LENGTH; i++)
1594 fprintf(f, "%02x", md_value[i]);
1595 fprintf(f, "\n");
3ce74686 1596#endif
0520c252 1597 fprintf(f, "# For additional config options, please look at lxc.container.conf(5)\n");
49a2ed80
SH
1598 fprintf(f, "\n# Uncomment the following line to support nesting containers:\n");
1599 fprintf(f, "#lxc.include = " LXCTEMPLATECONFIG "/nesting.conf\n");
1600 fprintf(f, "# (Be aware this has security implications)\n\n");
3ce74686
SH
1601 if (fwrite(contents, 1, flen, f) != flen) {
1602 SYSERROR("Writing original contents");
1603 free(contents);
1604 fclose(f);
1605 return false;
1606 }
025ed0f3
SH
1607 ret = 0;
1608out_free_contents:
3ce74686 1609 free(contents);
025ed0f3
SH
1610out_error:
1611 if (f) {
1612 int newret;
025ed0f3 1613 newret = fclose(f);
025ed0f3
SH
1614 if (ret == 0)
1615 ret = newret;
1616 }
1617 if (ret < 0) {
1618 SYSERROR("Error prepending header");
3ce74686
SH
1619 return false;
1620 }
1621 return true;
1622}
1623
4df7f012
SH
1624static void lxcapi_clear_config(struct lxc_container *c)
1625{
f979ac15
SH
1626 if (c) {
1627 if (c->lxc_conf) {
1628 lxc_conf_free(c->lxc_conf);
1629 c->lxc_conf = NULL;
1630 }
4df7f012
SH
1631 }
1632}
1633
858377e4
SH
1634#define do_lxcapi_clear_config(c) lxcapi_clear_config(c)
1635
96b3cb40
SH
1636/*
1637 * lxcapi_create:
1638 * create a container with the given parameters.
1639 * @c: container to be created. It has the lxcpath, name, and a starting
1640 * configuration already set
1641 * @t: the template to execute to instantiate the root filesystem and
1642 * adjust the configuration.
1643 * @bdevtype: backing store type to use. If NULL, dir will be used.
1644 * @specs: additional parameters for the backing store, i.e. LVM vg to
1645 * use.
1646 *
1647 * @argv: the arguments to pass to the template, terminated by NULL. If no
1648 * arguments, you can just pass NULL.
1649 */
858377e4 1650static bool do_lxcapi_create(struct lxc_container *c, const char *t,
85aec4ac
CB
1651 const char *bdevtype, struct bdev_specs *specs,
1652 int flags, char *const argv[])
96b3cb40 1653{
e9e29a33 1654 int partial_fd;
96b3cb40 1655 pid_t pid;
e9e29a33 1656 bool ret = false;
85db5535 1657 char *tpath = NULL;
96b3cb40
SH
1658
1659 if (!c)
1660 return false;
1661
85db5535
DE
1662 if (t) {
1663 tpath = get_template_path(t);
1664 if (!tpath) {
e9e29a33 1665 ERROR("Unknown template \"%s\"", t);
85db5535
DE
1666 goto out;
1667 }
96b3cb40
SH
1668 }
1669
e9e29a33
CB
1670 /* If a template is passed in, and the rootfs already is defined in the
1671 * container config and exists, then the caller is trying to create an
1672 * existing container. Return an error, but do NOT delete the container.
cf465fe4 1673 */
858377e4 1674 if (do_lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path &&
cf465fe4 1675 access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
e9e29a33
CB
1676 ERROR("Container \"%s\" already exists in \"%s\"", c->name,
1677 c->config_path);
6c6892b5 1678 goto free_tpath;
cf465fe4
SH
1679 }
1680
6c6892b5 1681 if (!c->lxc_conf) {
858377e4 1682 if (!do_lxcapi_load_config(c, lxc_global_config_value("lxc.default_config"))) {
e9e29a33
CB
1683 ERROR("Error loading default configuration file %s",
1684 lxc_global_config_value("lxc.default_config"));
6c6892b5
DE
1685 goto free_tpath;
1686 }
96b3cb40
SH
1687 }
1688
6c6892b5
DE
1689 if (!create_container_dir(c))
1690 goto free_tpath;
1691
e9e29a33
CB
1692 /* If both template and rootfs.path are set, template is setup as
1693 * rootfs.path. The container is already created if we have a config and
1694 * rootfs.path is accessible
0590e82c 1695 */
00370edd 1696 if (!c->lxc_conf->rootfs.path && !tpath) {
e9e29a33 1697 /* No template passed in and rootfs does not exist. */
00370edd 1698 if (!c->save_config(c, NULL)) {
e9e29a33 1699 ERROR("Failed to save initial config for \"%s\"", c->name);
00370edd
DW
1700 goto out;
1701 }
1702 ret = true;
0590e82c 1703 goto out;
00370edd 1704 }
e9e29a33
CB
1705
1706 /* Rootfs passed into configuration, but does not exist. */
0590e82c 1707 if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) != 0)
0590e82c 1708 goto out;
e9e29a33 1709
858377e4 1710 if (do_lxcapi_is_defined(c) && c->lxc_conf->rootfs.path && !tpath) {
e9e29a33
CB
1711 /* Rootfs already existed, user just wanted to save the loaded
1712 * configuration.
1713 */
0f4cdd77 1714 if (!c->save_config(c, NULL))
e9e29a33 1715 ERROR("Failed to save initial config for \"%s\"", c->name);
0590e82c
SH
1716 ret = true;
1717 goto out;
a69aad27 1718 }
96b3cb40
SH
1719
1720 /* Mark that this container is being created */
e9e29a33
CB
1721 partial_fd = create_partial(c);
1722 if (partial_fd < 0)
96b3cb40
SH
1723 goto out;
1724
e9e29a33 1725 /* No need to get disk lock bc we have the partial lock. */
96b3cb40 1726
e9e29a33 1727 /* Create the storage.
96b3cb40
SH
1728 * Note we can't do this in the same task as we use to execute the
1729 * template because of the way zfs works.
1730 * After you 'zfs create', zfs mounts the fs only in the initial
1731 * namespace.
1732 */
1733 pid = fork();
1734 if (pid < 0) {
e9e29a33 1735 SYSERROR("Failed to fork task for container creation template");
8eb5694b
SH
1736 goto out_unlock;
1737 }
1738
1a0e70ac 1739 if (pid == 0) { /* child */
10bc1861 1740 struct lxc_storage *bdev = NULL;
96b3cb40 1741
10bc1861
CB
1742 bdev = do_storage_create(c, bdevtype, specs);
1743 if (!bdev) {
e9e29a33
CB
1744 ERROR("Failed to create %s storage for %s",
1745 bdevtype ? bdevtype : "(none)", c->name);
85aec4ac 1746 _exit(EXIT_FAILURE);
96b3cb40
SH
1747 }
1748
e9e29a33 1749 /* Save config file again to store the new rootfs location. */
858377e4 1750 if (!do_lxcapi_save_config(c, NULL)) {
e9e29a33
CB
1751 ERROR("Failed to save initial config for %s", c->name);
1752 /* Parent task won't see the storage driver in the
1753 * config so we delete it.
1754 */
96b3cb40
SH
1755 bdev->ops->umount(bdev);
1756 bdev->ops->destroy(bdev);
85aec4ac 1757 _exit(EXIT_FAILURE);
96b3cb40 1758 }
85aec4ac 1759 _exit(EXIT_SUCCESS);
96b3cb40
SH
1760 }
1761 if (wait_for_pid(pid) != 0)
a09295f8 1762 goto out_unlock;
96b3cb40 1763
e9e29a33 1764 /* Reload config to get the rootfs. */
a3b47c09 1765 lxc_conf_free(c->lxc_conf);
96b3cb40
SH
1766 c->lxc_conf = NULL;
1767 if (!load_config_locked(c, c->configfile))
a09295f8 1768 goto out_unlock;
96b3cb40 1769
dc23c1c8 1770 if (!create_run_template(c, tpath, !!(flags & LXC_CREATE_QUIET), argv))
96b3cb40
SH
1771 goto out_unlock;
1772
1a0e70ac
CB
1773 /* Now clear out the lxc_conf we have, reload from the created
1774 * container.
1775 */
858377e4 1776 do_lxcapi_clear_config(c);
3ce74686 1777
9d65a487
KY
1778 if (t) {
1779 if (!prepend_lxc_header(c->configfile, tpath, argv)) {
e9e29a33 1780 ERROR("Failed to prepend header to config file");
9d65a487
KY
1781 goto out_unlock;
1782 }
3ce74686 1783 }
a69aad27 1784 ret = load_config_locked(c, c->configfile);
72d0e1cb
SG
1785
1786out_unlock:
3e625e2d
SH
1787 if (partial_fd >= 0)
1788 remove_partial(c, partial_fd);
72d0e1cb 1789out:
c55d4505 1790 if (!ret)
17a367d8 1791 container_destroy(c, NULL);
6c6892b5 1792free_tpath:
f10fad2f 1793 free(tpath);
a69aad27 1794 return ret;
72d0e1cb
SG
1795}
1796
858377e4 1797static bool lxcapi_create(struct lxc_container *c, const char *t,
e9e29a33
CB
1798 const char *bdevtype, struct bdev_specs *specs,
1799 int flags, char *const argv[])
858377e4
SH
1800{
1801 bool ret;
1802 current_config = c ? c->lxc_conf : NULL;
1803 ret = do_lxcapi_create(c, t, bdevtype, specs, flags, argv);
1804 current_config = NULL;
1805 return ret;
1806}
1807
1808static bool do_lxcapi_reboot(struct lxc_container *c)
3e625e2d
SH
1809{
1810 pid_t pid;
dd267776 1811 int rebootsignal = SIGINT;
3e625e2d
SH
1812
1813 if (!c)
1814 return false;
858377e4 1815 if (!do_lxcapi_is_running(c))
3e625e2d 1816 return false;
858377e4 1817 pid = do_lxcapi_init_pid(c);
3e625e2d
SH
1818 if (pid <= 0)
1819 return false;
dd267776
BP
1820 if (c->lxc_conf && c->lxc_conf->rebootsignal)
1821 rebootsignal = c->lxc_conf->rebootsignal;
591614a7
CB
1822 if (kill(pid, rebootsignal) < 0) {
1823 WARN("Could not send signal %d to pid %d.", rebootsignal, pid);
3e625e2d 1824 return false;
591614a7 1825 }
3e625e2d
SH
1826 return true;
1827
1828}
1829
858377e4
SH
1830WRAP_API(bool, lxcapi_reboot)
1831
d39b10eb
CB
1832static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
1833{
1834 int killret, ret;
1835 pid_t pid;
1836 int rebootsignal = SIGINT, state_client_fd = -1;
1837 lxc_state_t states[MAX_STATE] = {0};
1838
1839 if (!c)
1840 return false;
1841
1842 if (!do_lxcapi_is_running(c))
1843 return true;
1844
1845 pid = do_lxcapi_init_pid(c);
1846 if (pid <= 0)
1847 return true;
1848
1849 if (c->lxc_conf && c->lxc_conf->rebootsignal)
1850 rebootsignal = c->lxc_conf->rebootsignal;
1851
1852 /* Add a new state client before sending the shutdown signal so that we
1853 * don't miss a state.
1854 */
1855 if (timeout != 0) {
1856 states[RUNNING] = 2;
1857 ret = lxc_cmd_add_state_client(c->name, c->config_path, states,
1858 &state_client_fd);
1859 if (ret < 0)
1860 return false;
1861
1862 if (state_client_fd < 0)
1863 return false;
1864
1865 if (ret == RUNNING)
1866 return true;
1867
1868 if (ret < MAX_STATE)
1869 return false;
1870 }
1871
1872 /* Send reboot signal to container. */
1873 killret = kill(pid, rebootsignal);
1874 if (killret < 0) {
1875 WARN("Could not send signal %d to pid %d", rebootsignal, pid);
1876 if (state_client_fd >= 0)
1877 close(state_client_fd);
1878 return false;
1879 }
1880 TRACE("Sent signal %d to pid %d", rebootsignal, pid);
1881
1882 if (timeout == 0)
1883 return true;
1884
1885 ret = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
1886 close(state_client_fd);
1887 if (ret < 0)
1888 return false;
1889
1890 TRACE("Received state \"%s\"", lxc_state2str(ret));
1891 if (ret != RUNNING)
1892 return false;
1893
1894 return true;
1895}
1896
1897WRAP_API_1(bool, lxcapi_reboot2, int)
1898
858377e4 1899static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
72d0e1cb 1900{
f8bdb6dc 1901 int killret, ret;
72d0e1cb 1902 pid_t pid;
f8bdb6dc 1903 int haltsignal = SIGPWR, state_client_fd = -1;
92e35018 1904 lxc_state_t states[MAX_STATE] = {0};
72d0e1cb
SG
1905
1906 if (!c)
1907 return false;
1908
858377e4 1909 if (!do_lxcapi_is_running(c))
72d0e1cb 1910 return true;
f8bdb6dc 1911
858377e4 1912 pid = do_lxcapi_init_pid(c);
72d0e1cb
SG
1913 if (pid <= 0)
1914 return true;
330ae3d3
CB
1915
1916 /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */
1917 if (task_blocking_signal(pid, (SIGRTMIN + 3)))
1918 haltsignal = (SIGRTMIN + 3);
1919
b0227444 1920 if (c->lxc_conf && c->lxc_conf->haltsignal)
f0f1d8c0 1921 haltsignal = c->lxc_conf->haltsignal;
330ae3d3 1922
92e35018
CB
1923 /* Add a new state client before sending the shutdown signal so that we
1924 * don't miss a state.
1925 */
f8bdb6dc
CB
1926 if (timeout != 0) {
1927 states[STOPPED] = 1;
1928 ret = lxc_cmd_add_state_client(c->name, c->config_path, states,
1929 &state_client_fd);
1930 if (ret < 0)
1931 return false;
92e35018 1932
f8bdb6dc
CB
1933 if (state_client_fd < 0)
1934 return false;
1935
1936 if (ret == STOPPED)
1937 return true;
591614a7 1938
f8bdb6dc 1939 if (ret < MAX_STATE)
92e35018 1940 return false;
92e35018
CB
1941 }
1942
f8bdb6dc
CB
1943 /* Send shutdown signal to container. */
1944 killret = kill(pid, haltsignal);
1945 if (killret < 0) {
1946 WARN("Could not send signal %d to pid %d", haltsignal, pid);
1947 if (state_client_fd >= 0)
1948 close(state_client_fd);
1949 return false;
1950 }
1951 TRACE("Sent signal %d to pid %d", haltsignal, pid);
1952
1953 if (timeout == 0)
1954 return true;
1955
1956 ret = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
1957 close(state_client_fd);
1958 if (ret < 0)
1959 return false;
1960
1961 TRACE("Received state \"%s\"", lxc_state2str(ret));
1962 if (ret != STOPPED)
1963 return false;
1964
1965 return true;
72d0e1cb
SG
1966}
1967
858377e4
SH
1968WRAP_API_1(bool, lxcapi_shutdown, int)
1969
1897e3bc 1970static bool lxcapi_createl(struct lxc_container *c, const char *t,
dc23c1c8 1971 const char *bdevtype, struct bdev_specs *specs, int flags, ...)
72d0e1cb
SG
1972{
1973 bool bret = false;
a0e93eeb 1974 char **args = NULL;
72d0e1cb 1975 va_list ap;
72d0e1cb
SG
1976
1977 if (!c)
1978 return false;
1979
858377e4
SH
1980 current_config = c->lxc_conf;
1981
72d0e1cb
SG
1982 /*
1983 * since we're going to wait for create to finish, I don't think we
1984 * need to get a copy of the arguments.
1985 */
dc23c1c8 1986 va_start(ap, flags);
a0e93eeb 1987 args = lxc_va_arg_list_to_argv(ap, 0, 0);
72d0e1cb 1988 va_end(ap);
a0e93eeb 1989 if (!args) {
e9e29a33 1990 ERROR("Failed to allocate memory");
a0e93eeb
CS
1991 goto out;
1992 }
72d0e1cb 1993
858377e4 1994 bret = do_lxcapi_create(c, t, bdevtype, specs, flags, args);
72d0e1cb
SG
1995
1996out:
a0e93eeb 1997 free(args);
858377e4 1998 current_config = NULL;
72d0e1cb
SG
1999 return bret;
2000}
2001
6b0d5538
SH
2002static void do_clear_unexp_config_line(struct lxc_conf *conf, const char *key)
2003{
4222a9f4
CB
2004 if (!strcmp(key, "lxc.cgroup"))
2005 return clear_unexp_config_line(conf, key, true);
2006
2007 if (!strcmp(key, "lxc.network"))
2008 return clear_unexp_config_line(conf, key, true);
2009
2010 if (!strcmp(key, "lxc.net"))
2011 return clear_unexp_config_line(conf, key, true);
2012
2013 /* Clear a network with a specific index. */
2014 if (!strncmp(key, "lxc.net.", 8)) {
2015 int ret;
2016 const char *idx;
2017
2018 idx = key + 8;
2019 ret = lxc_safe_uint(idx, &(unsigned int){0});
2020 if (!ret)
2021 return clear_unexp_config_line(conf, key, true);
2022 }
2023
2024 if (!strcmp(key, "lxc.hook"))
2025 return clear_unexp_config_line(conf, key, true);
2026
2027 return clear_unexp_config_line(conf, key, false);
6b0d5538
SH
2028}
2029
6afd673f
CB
2030static bool do_lxcapi_clear_config_item(struct lxc_container *c,
2031 const char *key)
72d0e1cb 2032{
6afd673f
CB
2033 int ret = 1;
2034 struct lxc_config_t *config;
72d0e1cb
SG
2035
2036 if (!c || !c->lxc_conf)
2037 return false;
6afd673f 2038
5cee8c50 2039 if (container_mem_lock(c))
72d0e1cb 2040 return false;
6afd673f 2041
300df83e 2042 config = lxc_get_config(key);
6afd673f
CB
2043 /* Verify that the config key exists and that it has a callback
2044 * implemented.
2045 */
2046 if (config && config->clr)
26471403 2047 ret = config->clr(key, c->lxc_conf, NULL);
6b0d5538
SH
2048 if (!ret)
2049 do_clear_unexp_config_line(c->lxc_conf, key);
6afd673f 2050
5cee8c50 2051 container_mem_unlock(c);
72d0e1cb
SG
2052 return ret == 0;
2053}
2054
858377e4
SH
2055WRAP_API_1(bool, lxcapi_clear_config_item, const char *)
2056
e0f59189 2057static inline bool enter_net_ns(struct lxc_container *c)
51d0854c 2058{
858377e4 2059 pid_t pid = do_lxcapi_init_pid(c);
ae22a220 2060
0e6e3a41 2061 if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && access("/proc/self/ns/user", F_OK) == 0) {
51d0854c
DY
2062 if (!switch_to_ns(pid, "user"))
2063 return false;
9c83a661 2064 }
51d0854c 2065 return switch_to_ns(pid, "net");
799f29ab
ÇO
2066}
2067
1a0e70ac 2068/* Used by qsort and bsearch functions for comparing names. */
9c88ff1f
ÇO
2069static inline int string_cmp(char **first, char **second)
2070{
2071 return strcmp(*first, *second);
2072}
2073
1a0e70ac
CB
2074/* Used by qsort and bsearch functions for comparing container names. */
2075static inline int container_cmp(struct lxc_container **first,
2076 struct lxc_container **second)
9c88ff1f
ÇO
2077{
2078 return strcmp((*first)->name, (*second)->name);
2079}
2080
2081static bool add_to_array(char ***names, char *cname, int pos)
2082{
2083 char **newnames = realloc(*names, (pos+1) * sizeof(char *));
2084 if (!newnames) {
2085 ERROR("Out of memory");
2086 return false;
2087 }
2088
2089 *names = newnames;
2090 newnames[pos] = strdup(cname);
2091 if (!newnames[pos])
2092 return false;
2093
1a0e70ac
CB
2094 /* Sort the arrray as we will use binary search on it. */
2095 qsort(newnames, pos + 1, sizeof(char *),
2096 (int (*)(const void *, const void *))string_cmp);
9c88ff1f
ÇO
2097
2098 return true;
2099}
2100
1a0e70ac
CB
2101static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c,
2102 int pos, bool sort)
9c88ff1f 2103{
1a0e70ac 2104 struct lxc_container **newlist = realloc(*list, (pos + 1) * sizeof(struct lxc_container *));
9c88ff1f
ÇO
2105 if (!newlist) {
2106 ERROR("Out of memory");
2107 return false;
2108 }
2109
2110 *list = newlist;
2111 newlist[pos] = c;
2112
1a0e70ac 2113 /* Sort the arrray as we will use binary search on it. */
2871830a 2114 if (sort)
1a0e70ac
CB
2115 qsort(newlist, pos + 1, sizeof(struct lxc_container *),
2116 (int (*)(const void *, const void *))container_cmp);
9c88ff1f
ÇO
2117
2118 return true;
2119}
2120
2121static char** get_from_array(char ***names, char *cname, int size)
2122{
2123 return (char **)bsearch(&cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp);
2124}
2125
2126
2127static bool array_contains(char ***names, char *cname, int size) {
2128 if(get_from_array(names, cname, size) != NULL)
2129 return true;
2130 return false;
2131}
2132
2133static bool remove_from_array(char ***names, char *cname, int size)
2134{
2135 char **result = get_from_array(names, cname, size);
2136 if (result != NULL) {
2137 free(result);
2138 return true;
2139 }
2140 return false;
2141}
2142
858377e4 2143static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
799f29ab 2144{
ae22a220
ÇO
2145 pid_t pid;
2146 int i, count = 0, pipefd[2];
9c88ff1f 2147 char **interfaces = NULL;
ae22a220 2148 char interface[IFNAMSIZ];
799f29ab 2149
ae22a220
ÇO
2150 if(pipe(pipefd) < 0) {
2151 SYSERROR("pipe failed");
2152 return NULL;
c868b261
ÇO
2153 }
2154
ae22a220
ÇO
2155 pid = fork();
2156 if (pid < 0) {
959aee9c 2157 SYSERROR("failed to fork task to get interfaces information");
ae22a220
ÇO
2158 close(pipefd[0]);
2159 close(pipefd[1]);
2160 return NULL;
2161 }
799f29ab 2162
1a0e70ac 2163 if (pid == 0) { /* child */
ae22a220
ÇO
2164 int ret = 1, nbytes;
2165 struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
2166
2167 /* close the read-end of the pipe */
2168 close(pipefd[0]);
2169
e0f59189 2170 if (!enter_net_ns(c)) {
ae22a220
ÇO
2171 SYSERROR("failed to enter namespace");
2172 goto out;
2173 }
2174
2175 /* Grab the list of interfaces */
2176 if (getifaddrs(&interfaceArray)) {
2177 SYSERROR("failed to get interfaces list");
2178 goto out;
2179 }
2180
2181 /* Iterate through the interfaces */
2182 for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
2183 nbytes = write(pipefd[1], tempIfAddr->ifa_name, IFNAMSIZ);
2184 if (nbytes < 0) {
2185 ERROR("write failed");
2186 goto out;
2187 }
2188 count++;
2189 }
2190 ret = 0;
2191
2192 out:
2193 if (interfaceArray)
2194 freeifaddrs(interfaceArray);
2195
2196 /* close the write-end of the pipe, thus sending EOF to the reader */
2197 close(pipefd[1]);
02c611b0 2198 _exit(ret);
799f29ab
ÇO
2199 }
2200
ae22a220
ÇO
2201 /* close the write-end of the pipe */
2202 close(pipefd[1]);
2203
358afd84 2204 while (read(pipefd[0], &interface, IFNAMSIZ) == IFNAMSIZ) {
3151d4e2
CB
2205 interface[IFNAMSIZ - 1] = '\0';
2206
ae22a220
ÇO
2207 if (array_contains(&interfaces, interface, count))
2208 continue;
799f29ab 2209
ae22a220 2210 if(!add_to_array(&interfaces, interface, count))
3151d4e2
CB
2211 ERROR("Failed to add \"%s\" to array", interface);
2212
9c88ff1f
ÇO
2213 count++;
2214 }
799f29ab 2215
ae22a220
ÇO
2216 if (wait_for_pid(pid) != 0) {
2217 for(i=0;i<count;i++)
2218 free(interfaces[i]);
2219 free(interfaces);
2220 interfaces = NULL;
2221 }
9c88ff1f 2222
ae22a220
ÇO
2223 /* close the read-end of the pipe */
2224 close(pipefd[0]);
799f29ab 2225
9c88ff1f
ÇO
2226 /* Append NULL to the array */
2227 if(interfaces)
2228 interfaces = (char **)lxc_append_null_to_array((void **)interfaces, count);
799f29ab 2229
9c88ff1f 2230 return interfaces;
799f29ab
ÇO
2231}
2232
858377e4
SH
2233WRAP_API(char **, lxcapi_get_interfaces)
2234
2235static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface, const char* family, int scope)
799f29ab 2236{
ae22a220
ÇO
2237 pid_t pid;
2238 int i, count = 0, pipefd[2];
9c88ff1f 2239 char **addresses = NULL;
ae22a220 2240 char address[INET6_ADDRSTRLEN];
799f29ab 2241
ae22a220
ÇO
2242 if(pipe(pipefd) < 0) {
2243 SYSERROR("pipe failed");
2244 return NULL;
c868b261
ÇO
2245 }
2246
ae22a220
ÇO
2247 pid = fork();
2248 if (pid < 0) {
959aee9c 2249 SYSERROR("failed to fork task to get container ips");
ae22a220
ÇO
2250 close(pipefd[0]);
2251 close(pipefd[1]);
2252 return NULL;
9c83a661
SG
2253 }
2254
1a0e70ac 2255 if (pid == 0) { /* child */
ae22a220
ÇO
2256 int ret = 1, nbytes;
2257 struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
2258 char addressOutputBuffer[INET6_ADDRSTRLEN];
2259 void *tempAddrPtr = NULL;
2260 char *address = NULL;
fe218ca3 2261
ae22a220
ÇO
2262 /* close the read-end of the pipe */
2263 close(pipefd[0]);
2264
e0f59189 2265 if (!enter_net_ns(c)) {
ae22a220
ÇO
2266 SYSERROR("failed to enter namespace");
2267 goto out;
9c83a661 2268 }
ae22a220
ÇO
2269
2270 /* Grab the list of interfaces */
2271 if (getifaddrs(&interfaceArray)) {
2272 SYSERROR("failed to get interfaces list");
2273 goto out;
2274 }
2275
2276 /* Iterate through the interfaces */
2277 for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
2278 if (tempIfAddr->ifa_addr == NULL)
9c83a661
SG
2279 continue;
2280
ae22a220
ÇO
2281 if(tempIfAddr->ifa_addr->sa_family == AF_INET) {
2282 if (family && strcmp(family, "inet"))
2283 continue;
2284 tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_addr)->sin_addr;
2285 }
2286 else {
2287 if (family && strcmp(family, "inet6"))
2288 continue;
2289
2290 if (((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_scope_id != scope)
2291 continue;
2292
2293 tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_addr;
2294 }
2295
2296 if (interface && strcmp(interface, tempIfAddr->ifa_name))
2297 continue;
2298 else if (!interface && strcmp("lo", tempIfAddr->ifa_name) == 0)
9c83a661
SG
2299 continue;
2300
ae22a220
ÇO
2301 address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family,
2302 tempAddrPtr,
2303 addressOutputBuffer,
2304 sizeof(addressOutputBuffer));
2305 if (!address)
2306 continue;
2307
2308 nbytes = write(pipefd[1], address, INET6_ADDRSTRLEN);
2309 if (nbytes < 0) {
2310 ERROR("write failed");
2311 goto out;
2312 }
2313 count++;
9c83a661 2314 }
ae22a220 2315 ret = 0;
9c83a661 2316
ae22a220
ÇO
2317 out:
2318 if(interfaceArray)
2319 freeifaddrs(interfaceArray);
9c83a661 2320
ae22a220
ÇO
2321 /* close the write-end of the pipe, thus sending EOF to the reader */
2322 close(pipefd[1]);
fe1ce58c 2323 _exit(ret);
6849cb5b 2324 }
9c83a661 2325
ae22a220
ÇO
2326 /* close the write-end of the pipe */
2327 close(pipefd[1]);
2328
358afd84 2329 while (read(pipefd[0], &address, INET6_ADDRSTRLEN) == INET6_ADDRSTRLEN) {
9c88ff1f 2330 if(!add_to_array(&addresses, address, count))
ae22a220 2331 ERROR("PARENT: add_to_array failed");
9c88ff1f 2332 count++;
9c83a661
SG
2333 }
2334
ae22a220
ÇO
2335 if (wait_for_pid(pid) != 0) {
2336 for(i=0;i<count;i++)
2337 free(addresses[i]);
2338 free(addresses);
2339 addresses = NULL;
2340 }
9c83a661 2341
ae22a220
ÇO
2342 /* close the read-end of the pipe */
2343 close(pipefd[0]);
9c83a661
SG
2344
2345 /* Append NULL to the array */
9c88ff1f
ÇO
2346 if(addresses)
2347 addresses = (char **)lxc_append_null_to_array((void **)addresses, count);
9c83a661
SG
2348
2349 return addresses;
2350}
2351
858377e4
SH
2352WRAP_API_3(char **, lxcapi_get_ips, const char *, const char *, int)
2353
2354static int do_lxcapi_get_config_item(struct lxc_container *c, const char *key, char *retv, int inlen)
72d0e1cb 2355{
fce687aa
CB
2356 int ret = -1;
2357 struct lxc_config_t *config;
72d0e1cb
SG
2358
2359 if (!c || !c->lxc_conf)
2360 return -1;
fce687aa 2361
5cee8c50 2362 if (container_mem_lock(c))
72d0e1cb 2363 return -1;
fce687aa 2364
300df83e 2365 config = lxc_get_config(key);
fce687aa
CB
2366 /* Verify that the config key exists and that it has a callback
2367 * implemented.
2368 */
2369 if (config && config->get)
cccd2219 2370 ret = config->get(key, retv, inlen, c->lxc_conf, NULL);
fce687aa 2371
5cee8c50 2372 container_mem_unlock(c);
72d0e1cb
SG
2373 return ret;
2374}
2375
858377e4
SH
2376WRAP_API_3(int, lxcapi_get_config_item, const char *, char *, int)
2377
2378static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const char *key)
8ac18377
ÇO
2379{
2380 char *ret;
2381
2382 if (!c || !c->lxc_conf)
2383 return NULL;
2384 if (container_mem_lock(c))
2385 return NULL;
858377e4 2386 ret = lxc_cmd_get_config_item(c->name, key, do_lxcapi_get_config_path(c));
8ac18377
ÇO
2387 container_mem_unlock(c);
2388 return ret;
2389}
2390
858377e4
SH
2391WRAP_API_1(char *, lxcapi_get_running_config_item, const char *)
2392
2393static int do_lxcapi_get_keys(struct lxc_container *c, const char *key, char *retv, int inlen)
72d0e1cb 2394{
300df83e
CB
2395 int ret = -1;
2396
2397 /* List all config items. */
72d0e1cb 2398 if (!key)
cfc67626 2399 return lxc_list_config_items(retv, inlen);
300df83e 2400
72d0e1cb
SG
2401 if (!c || !c->lxc_conf)
2402 return -1;
300df83e 2403
5cee8c50 2404 if (container_mem_lock(c))
72d0e1cb 2405 return -1;
300df83e
CB
2406
2407 /* Support 'lxc.net.<idx>', i.e. 'lxc.net.0'
2408 * This is an intelligent result to show which keys are valid given the
2409 * type of nic it is.
2410 */
6fba98b5 2411 if (strncmp(key, "lxc.net.", 8) == 0)
01f55c40 2412 ret = lxc_list_net(c->lxc_conf, key, retv, inlen);
fe9b7349
CB
2413 else
2414 ret = lxc_list_subkeys(c->lxc_conf, key, retv, inlen);
300df83e 2415
5cee8c50 2416 container_mem_unlock(c);
72d0e1cb
SG
2417 return ret;
2418}
2419
858377e4
SH
2420WRAP_API_3(int, lxcapi_get_keys, const char *, char *, int)
2421
2422static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
72d0e1cb 2423{
0e1a60b0 2424 int fd, lret;
39dc698c 2425 bool ret = false, need_disklock = false;
39dc698c 2426
72d0e1cb
SG
2427 if (!alt_file)
2428 alt_file = c->configfile;
2429 if (!alt_file)
1a0e70ac 2430 return false;
39dc698c 2431
1a0e70ac 2432 /* If we haven't yet loaded a config, load the stock config. */
39dc698c 2433 if (!c->lxc_conf) {
858377e4 2434 if (!do_lxcapi_load_config(c, lxc_global_config_value("lxc.default_config"))) {
0e1a60b0
CB
2435 ERROR("Error loading default configuration file %s "
2436 "while saving %s",
2437 lxc_global_config_value("lxc.default_config"),
2438 c->name);
72d0e1cb
SG
2439 return false;
2440 }
39dc698c 2441 }
72d0e1cb 2442
5a3d2e1e
SG
2443 if (!create_container_dir(c))
2444 return false;
2445
1a0e70ac
CB
2446 /* If we're writing to the container's config file, take the disk lock.
2447 * Otherwise just take the memlock to protect the struct lxc_container
2448 * while we're traversing it.
39dc698c
SH
2449 */
2450 if (strcmp(c->configfile, alt_file) == 0)
2451 need_disklock = true;
2452
2453 if (need_disklock)
2454 lret = container_disk_lock(c);
2455 else
2456 lret = container_mem_lock(c);
2457
2458 if (lret)
72d0e1cb 2459 return false;
39dc698c 2460
0e1a60b0
CB
2461 fd = open(alt_file, O_WRONLY | O_CREAT | O_CLOEXEC,
2462 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
2463 if (fd < 0)
2464 goto on_error;
2465
2466 lret = write_config(fd, c->lxc_conf);
2467 close(fd);
2468 if (lret < 0)
2469 goto on_error;
2470
39dc698c
SH
2471 ret = true;
2472
0e1a60b0 2473on_error:
39dc698c
SH
2474 if (need_disklock)
2475 container_disk_unlock(c);
2476 else
2477 container_mem_unlock(c);
0e1a60b0 2478
39dc698c 2479 return ret;
72d0e1cb
SG
2480}
2481
858377e4
SH
2482WRAP_API_1(bool, lxcapi_save_config, const char *)
2483
0ea055b3
CB
2484
2485static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc)
dfb31b25 2486{
0ea055b3
CB
2487 FILE *f1;
2488 struct stat fbuf;
42342bed
CB
2489 void *buf = NULL;
2490 char *del = NULL;
dfb31b25 2491 char path[MAXPATHLEN];
0ea055b3
CB
2492 char newpath[MAXPATHLEN];
2493 int fd, ret, n = 0, v = 0;
dfb31b25 2494 bool bret = false;
42342bed 2495 size_t len = 0, bytes = 0;
dfb31b25 2496
0ea055b3 2497 if (container_disk_lock(c0))
dfb31b25 2498 return false;
0ea055b3
CB
2499
2500 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c0->config_path, c0->name);
dfb31b25
SH
2501 if (ret < 0 || ret > MAXPATHLEN)
2502 goto out;
0ea055b3
CB
2503 ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", c->config_path, c->name);
2504 if (ret < 0 || ret > MAXPATHLEN)
dfb31b25 2505 goto out;
0ea055b3
CB
2506
2507 /* If we find an lxc-snapshot file using the old format only listing the
2508 * number of snapshots we will keep using it. */
2509 f1 = fopen(path, "r");
2510 if (f1) {
2511 n = fscanf(f1, "%d", &v);
2512 fclose(f1);
2513 if (n == 1 && v == 0) {
2514 remove(path);
2515 n = 0;
2516 }
dfb31b25 2517 }
0ea055b3
CB
2518 if (n == 1) {
2519 v += inc ? 1 : -1;
2520 f1 = fopen(path, "w");
2521 if (!f1)
2522 goto out;
2523 if (fprintf(f1, "%d\n", v) < 0) {
2524 ERROR("Error writing new snapshots value");
2525 fclose(f1);
2526 goto out;
2527 }
2528 ret = fclose(f1);
2529 if (ret != 0) {
2530 SYSERROR("Error writing to or closing snapshots file");
2531 goto out;
2532 }
2533 } else {
2534 /* Here we know that we have or can use an lxc-snapshot file
2535 * using the new format. */
2536 if (inc) {
2537 f1 = fopen(path, "a");
2538 if (!f1)
2539 goto out;
2540
2541 if (fprintf(f1, "%s", newpath) < 0) {
2542 ERROR("Error writing new snapshots entry");
2543 ret = fclose(f1);
2544 if (ret != 0)
2545 SYSERROR("Error writing to or closing snapshots file");
2546 goto out;
2547 }
2548
2549 ret = fclose(f1);
2550 if (ret != 0) {
2551 SYSERROR("Error writing to or closing snapshots file");
2552 goto out;
2553 }
2554 } else if (!inc) {
d028235d
SG
2555 if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
2556 goto out;
2557
2558 if (fstat(fd, &fbuf) < 0) {
2559 close(fd);
2560 goto out;
2561 }
2562
2563 if (fbuf.st_size != 0) {
d028235d 2564
25086a5f 2565 buf = lxc_strmmap(NULL, fbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
d028235d
SG
2566 if (buf == MAP_FAILED) {
2567 SYSERROR("Failed to create mapping %s", path);
2568 close(fd);
2569 goto out;
2570 }
2571
2572 len = strlen(newpath);
2573 while ((del = strstr((char *)buf, newpath))) {
2574 memmove(del, del + len, strlen(del) - len + 1);
2575 bytes += len;
2576 }
2577
25086a5f 2578 lxc_strmunmap(buf, fbuf.st_size);
d028235d
SG
2579 if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
2580 SYSERROR("Failed to truncate file %s", path);
2581 close(fd);
2582 goto out;
2583 }
2584 }
2585 close(fd);
2586 }
0ea055b3
CB
2587
2588 /* If the lxc-snapshot file is empty, remove it. */
2589 if (stat(path, &fbuf) < 0)
2590 goto out;
d028235d
SG
2591 if (!fbuf.st_size) {
2592 remove(path);
0ea055b3 2593 }
dfb31b25
SH
2594 }
2595
2596 bret = true;
2597
2598out:
0ea055b3 2599 container_disk_unlock(c0);
dfb31b25
SH
2600 return bret;
2601}
2602
2603static void strip_newline(char *p)
2604{
2605 size_t len = strlen(p);
2606 if (len < 1)
2607 return;
2608 if (p[len-1] == '\n')
2609 p[len-1] = '\0';
2610}
2611
d825fff3 2612void mod_all_rdeps(struct lxc_container *c, bool inc)
dfb31b25
SH
2613{
2614 struct lxc_container *p;
2615 char *lxcpath = NULL, *lxcname = NULL, path[MAXPATHLEN];
2616 size_t pathlen = 0, namelen = 0;
2617 FILE *f;
2618 int ret;
2619
2620 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends",
2621 c->config_path, c->name);
2622 if (ret < 0 || ret >= MAXPATHLEN) {
2623 ERROR("Path name too long");
2624 return;
2625 }
025ed0f3 2626 f = fopen(path, "r");
025ed0f3 2627 if (f == NULL)
dfb31b25
SH
2628 return;
2629 while (getline(&lxcpath, &pathlen, f) != -1) {
2630 if (getline(&lxcname, &namelen, f) == -1) {
959aee9c 2631 ERROR("badly formatted file %s", path);
dfb31b25
SH
2632 goto out;
2633 }
2634 strip_newline(lxcpath);
2635 strip_newline(lxcname);
2636 if ((p = lxc_container_new(lxcname, lxcpath)) == NULL) {
2637 ERROR("Unable to find dependent container %s:%s",
2638 lxcpath, lxcname);
2639 continue;
2640 }
0ea055b3
CB
2641 if (!mod_rdep(p, c, inc))
2642 ERROR("Failed to update snapshots file for %s:%s",
dfb31b25
SH
2643 lxcpath, lxcname);
2644 lxc_container_put(p);
2645 }
2646out:
f10fad2f
ME
2647 free(lxcpath);
2648 free(lxcname);
dfb31b25
SH
2649 fclose(f);
2650}
2651
18aa217b 2652static bool has_fs_snapshots(struct lxc_container *c)
dfb31b25 2653{
0ea055b3 2654 FILE *f;
dfb31b25
SH
2655 char path[MAXPATHLEN];
2656 int ret, v;
0ea055b3 2657 struct stat fbuf;
dfb31b25
SH
2658 bool bret = false;
2659
2660 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c->config_path,
2661 c->name);
2662 if (ret < 0 || ret > MAXPATHLEN)
2663 goto out;
0ea055b3
CB
2664 /* If the file doesn't exist there are no snapshots. */
2665 if (stat(path, &fbuf) < 0)
dfb31b25 2666 goto out;
0ea055b3
CB
2667 v = fbuf.st_size;
2668 if (v != 0) {
2669 f = fopen(path, "r");
2670 if (!f)
2671 goto out;
2672 ret = fscanf(f, "%d", &v);
2673 fclose(f);
1a0e70ac 2674 /* TODO: Figure out what to do with the return value of fscanf. */
0ea055b3
CB
2675 if (ret != 1)
2676 INFO("Container uses new lxc-snapshots format %s", path);
2677 }
dfb31b25
SH
2678 bret = v != 0;
2679
2680out:
2681 return bret;
2682}
2683
18aa217b
SH
2684static bool has_snapshots(struct lxc_container *c)
2685{
2686 char path[MAXPATHLEN];
74f96976 2687 struct dirent *direntp;
18aa217b
SH
2688 int count=0;
2689 DIR *dir;
2690
2691 if (!get_snappath_dir(c, path))
2692 return false;
2693 dir = opendir(path);
2694 if (!dir)
2695 return false;
74f96976 2696 while ((direntp = readdir(dir))) {
18aa217b
SH
2697 if (!direntp)
2698 break;
2699
2700 if (!strcmp(direntp->d_name, "."))
2701 continue;
2702
2703 if (!strcmp(direntp->d_name, ".."))
2704 continue;
2705 count++;
2706 break;
2707 }
2708 closedir(dir);
2709 return count > 0;
2710}
2711
297c2d58 2712static bool do_destroy_container(struct lxc_conf *conf) {
ee484f7f
CB
2713 int ret;
2714
e0010464 2715 if (am_guest_unpriv()) {
ee484f7f
CB
2716 ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
2717 "storage_destroy_wrapper");
2718 if (ret < 0)
d028235d 2719 return false;
ee484f7f 2720
d028235d
SG
2721 return true;
2722 }
ee484f7f 2723
10bc1861 2724 return storage_destroy(conf);
297c2d58
CB
2725}
2726
4355ab5f
SH
2727static int lxc_rmdir_onedev_wrapper(void *data)
2728{
2729 char *arg = (char *) data;
18aa217b 2730 return lxc_rmdir_onedev(arg, "snaps");
4355ab5f
SH
2731}
2732
17a367d8 2733static int lxc_unlink_exec_wrapper(void *data)
72d0e1cb 2734{
17a367d8
CB
2735 char *arg = data;
2736 return unlink(arg);
2737}
2738
2739static bool container_destroy(struct lxc_container *c,
2740 struct lxc_storage *storage)
2741{
2742 const char *p1;
2743 size_t len;
2744 struct lxc_conf *conf;
2745 char *path = NULL;
c868b261 2746 bool bret = false;
297c2d58 2747 int ret = 0;
72d0e1cb 2748
858377e4 2749 if (!c || !do_lxcapi_is_defined(c))
5a3d2e1e
SG
2750 return false;
2751
a70a69e8 2752 conf = c->lxc_conf;
3bc449ed 2753 if (container_disk_lock(c))
72d0e1cb 2754 return false;
72d0e1cb 2755
39dc698c 2756 if (!is_stopped(c)) {
1a0e70ac 2757 /* We should queue some sort of error - in c->error_string? */
60bf62d4
SH
2758 ERROR("container %s is not stopped", c->name);
2759 goto out;
72d0e1cb
SG
2760 }
2761
a70a69e8 2762 if (conf && !lxc_list_empty(&conf->hooks[LXCHOOK_DESTROY])) {
37cf711b 2763 /* Start of environment variable setup for hooks */
cb8ff4d0 2764 if (setenv("LXC_NAME", c->name, 1))
17a367d8
CB
2765 SYSERROR("Failed to set environment variable for container name");
2766
2767 if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1))
2768 SYSERROR("Failed to set environment variable for config path");
2769
2770 if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1))
2771 SYSERROR("Failed to set environment variable for rootfs mount");
2772
2773 if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1))
2774 SYSERROR("Failed to set environment variable for rootfs mount");
2775
2776 if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1))
2777 SYSERROR("Failed to set environment variable for console path");
2778
2779 if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1))
2780 SYSERROR("Failed to set environment variable for console log");
37cf711b
SY
2781 /* End of environment variable setup for hooks */
2782
14a7b0f9 2783 if (run_lxc_hooks(c->name, "destroy", conf, NULL)) {
17a367d8 2784 ERROR("Failed to execute clone hook for \"%s\"", c->name);
37cf711b
SY
2785 goto out;
2786 }
2787 }
2788
2789 if (current_config && conf == current_config) {
858377e4 2790 current_config = NULL;
37cf711b
SY
2791 if (conf->logfd != -1) {
2792 close(conf->logfd);
2793 conf->logfd = -1;
858377e4
SH
2794 }
2795 }
2796
d028235d
SG
2797 if (conf && conf->rootfs.path && conf->rootfs.mount) {
2798 if (!do_destroy_container(conf)) {
2799 ERROR("Error destroying rootfs for %s", c->name);
2800 goto out;
2801 }
2802 INFO("Destroyed rootfs for %s", c->name);
2803 }
60bf62d4 2804
dfb31b25
SH
2805 mod_all_rdeps(c, false);
2806
17a367d8
CB
2807 p1 = do_lxcapi_get_config_path(c);
2808 /* strlen(p1)
2809 * +
2810 * /
2811 * +
2812 * strlen(c->name)
2813 * +
2814 * /
2815 * +
2816 * strlen("config") = 6
2817 * +
2818 * \0
2819 */
2820 len = strlen(p1) + 1 + strlen(c->name) + 1 + 6 + 1;
2821 path = malloc(len);
2822 if (!path) {
2823 ERROR("Failed to allocate memory");
2824 goto out;
2825 }
2826
2827 /* For an overlay container the rootfs is considered immutable and
2828 * cannot be removed when restoring from a snapshot.
2829 */
2830 if (storage && (!strcmp(storage->type, "overlay") ||
2831 !strcmp(storage->type, "overlayfs")) &&
2832 (storage->flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)) {
2833 ret = snprintf(path, len, "%s/%s/config", p1, c->name);
2834 if (ret < 0 || (size_t)ret >= len)
2835 goto out;
2836
e0010464 2837 if (am_guest_unpriv())
17a367d8
CB
2838 ret = userns_exec_1(conf, lxc_unlink_exec_wrapper, path,
2839 "lxc_unlink_exec_wrapper");
2840 else
2841 ret = unlink(path);
2842 if (ret < 0) {
2843 SYSERROR("Failed to destroy config file \"%s\" for \"%s\"",
2844 path, c->name);
2845 goto out;
2846 }
2847 INFO("Destroyed config file \"%s\" for \"%s\"", path, c->name);
2848
2849 bret = true;
2850 goto out;
2851 }
2852
2853 ret = snprintf(path, len, "%s/%s", p1, c->name);
2854 if (ret < 0 || (size_t)ret >= len)
2855 goto out;
e0010464 2856 if (am_guest_unpriv())
ee484f7f
CB
2857 ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
2858 "lxc_rmdir_onedev_wrapper");
4355ab5f 2859 else
18aa217b 2860 ret = lxc_rmdir_onedev(path, "snaps");
4355ab5f 2861 if (ret < 0) {
17a367d8
CB
2862 ERROR("Failed to destroy directory \"%s\" for \"%s\"", path,
2863 c->name);
60bf62d4
SH
2864 goto out;
2865 }
17a367d8 2866 INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name);
297c2d58 2867
fef48dc9 2868 bret = true;
60bf62d4
SH
2869
2870out:
17a367d8
CB
2871 if (path)
2872 free(path);
3bc449ed 2873 container_disk_unlock(c);
fef48dc9 2874 return bret;
72d0e1cb
SG
2875}
2876
858377e4 2877static bool do_lxcapi_destroy(struct lxc_container *c)
18aa217b
SH
2878{
2879 if (!c || !lxcapi_is_defined(c))
2880 return false;
2881 if (has_snapshots(c)) {
2882 ERROR("Container %s has snapshots; not removing", c->name);
2883 return false;
2884 }
2885
2886 if (has_fs_snapshots(c)) {
2887 ERROR("container %s has snapshots on its rootfs", c->name);
2888 return false;
2889 }
2890
17a367d8 2891 return container_destroy(c, NULL);
18aa217b
SH
2892}
2893
858377e4 2894WRAP_API(bool, lxcapi_destroy)
18aa217b 2895
858377e4 2896static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
18aa217b
SH
2897{
2898 if (!c || !lxcapi_is_defined(c))
2899 return false;
2900 if (!lxcapi_snapshot_destroy_all(c)) {
2901 ERROR("Error deleting all snapshots");
2902 return false;
2903 }
2904 return lxcapi_destroy(c);
2905}
2906
858377e4
SH
2907WRAP_API(bool, lxcapi_destroy_with_snapshots)
2908
0d9cd9c3
CB
2909int lxc_set_config_item_locked(struct lxc_conf *conf, const char *key,
2910 const char *v)
96532523 2911{
0d9cd9c3 2912 int ret;
96532523 2913 struct lxc_config_t *config;
0d9cd9c3
CB
2914 bool bret = true;
2915
2916 config = lxc_get_config(key);
2917 if (!config)
2918 return -EINVAL;
2919
2920 ret = config->set(key, v, conf, NULL);
2921 if (ret < 0)
2922 return -EINVAL;
2923
2924 if (lxc_config_value_empty(v))
2925 do_clear_unexp_config_line(conf, key);
2926 else
2927 bret = do_append_unexp_config_line(conf, key, v);
2928 if (!bret)
2929 return -ENOMEM;
2930
2931 return 0;
2932}
2933
2934static bool do_set_config_item_locked(struct lxc_container *c, const char *key,
2935 const char *v)
2936{
2937 int ret;
96532523
SH
2938
2939 if (!c->lxc_conf)
2940 c->lxc_conf = lxc_conf_init();
4222a9f4 2941
6b0d5538 2942 if (!c->lxc_conf)
96532523 2943 return false;
4222a9f4 2944
0d9cd9c3
CB
2945 ret = lxc_set_config_item_locked(c->lxc_conf, key, v);
2946 if (ret < 0)
f979ac15 2947 return false;
4222a9f4 2948
0d9cd9c3 2949 return true;
96532523
SH
2950}
2951
858377e4 2952static bool do_lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v)
72d0e1cb 2953{
72d0e1cb 2954 bool b = false;
72d0e1cb
SG
2955
2956 if (!c)
2957 return false;
2958
5cee8c50 2959 if (container_mem_lock(c))
72d0e1cb
SG
2960 return false;
2961
0d9cd9c3 2962 b = do_set_config_item_locked(c, key, v);
72d0e1cb 2963
5cee8c50 2964 container_mem_unlock(c);
72d0e1cb
SG
2965 return b;
2966}
2967
858377e4
SH
2968WRAP_API_2(bool, lxcapi_set_config_item, const char *, const char *)
2969
72d0e1cb
SG
2970static char *lxcapi_config_file_name(struct lxc_container *c)
2971{
2972 if (!c || !c->configfile)
2973 return NULL;
2974 return strdup(c->configfile);
2975}
2976
2a59a681
SH
2977static const char *lxcapi_get_config_path(struct lxc_container *c)
2978{
2979 if (!c || !c->config_path)
2980 return NULL;
2981 return (const char *)(c->config_path);
2982}
2983
afeecbba
SH
2984/*
2985 * not for export
2986 * Just recalculate the c->configfile based on the
2987 * c->config_path, which must be set.
2988 * The lxc_container must be locked or not yet public.
2989 */
2990static bool set_config_filename(struct lxc_container *c)
2991{
2992 char *newpath;
2993 int len, ret;
2994
2995 if (!c->config_path)
2996 return false;
2997
2998 /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */
2999 len = strlen(c->config_path) + strlen(c->name) + strlen("config") + 3;
3000 newpath = malloc(len);
3001 if (!newpath)
3002 return false;
3003
3004 ret = snprintf(newpath, len, "%s/%s/config", c->config_path, c->name);
3005 if (ret < 0 || ret >= len) {
3006 fprintf(stderr, "Error printing out config file name\n");
3007 free(newpath);
3008 return false;
3009 }
3010
f10fad2f 3011 free(c->configfile);
afeecbba
SH
3012 c->configfile = newpath;
3013
3014 return true;
3015}
3016
858377e4 3017static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
2a59a681
SH
3018{
3019 char *p;
3020 bool b = false;
afeecbba 3021 char *oldpath = NULL;
2a59a681
SH
3022
3023 if (!c)
3024 return b;
3025
5cee8c50 3026 if (container_mem_lock(c))
2a59a681
SH
3027 return b;
3028
3029 p = strdup(path);
afeecbba
SH
3030 if (!p) {
3031 ERROR("Out of memory setting new lxc path");
2a59a681 3032 goto err;
afeecbba
SH
3033 }
3034
2a59a681
SH
3035 b = true;
3036 if (c->config_path)
afeecbba 3037 oldpath = c->config_path;
2a59a681 3038 c->config_path = p;
afeecbba
SH
3039
3040 /* Since we've changed the config path, we have to change the
3041 * config file name too */
3042 if (!set_config_filename(c)) {
3043 ERROR("Out of memory setting new config filename");
3044 b = false;
3045 free(c->config_path);
3046 c->config_path = oldpath;
3047 oldpath = NULL;
3048 }
2a59a681 3049err:
f10fad2f 3050 free(oldpath);
5cee8c50 3051 container_mem_unlock(c);
2a59a681
SH
3052 return b;
3053}
3054
858377e4 3055WRAP_API_1(bool, lxcapi_set_config_path, const char *)
2a59a681 3056
858377e4 3057static bool do_lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsys, const char *value)
794dd120
SH
3058{
3059 int ret;
794dd120
SH
3060
3061 if (!c)
3062 return false;
3063
3bc449ed 3064 if (is_stopped(c))
794dd120
SH
3065 return false;
3066
3bc449ed
SH
3067 if (container_disk_lock(c))
3068 return false;
794dd120 3069
33ad9f1a 3070 ret = lxc_cgroup_set(subsys, value, c->name, c->config_path);
3bc449ed
SH
3071
3072 container_disk_unlock(c);
3073 return ret == 0;
794dd120
SH
3074}
3075
858377e4
SH
3076WRAP_API_2(bool, lxcapi_set_cgroup_item, const char *, const char *)
3077
3078static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys, char *retv, int inlen)
794dd120 3079{
3bc449ed 3080 int ret;
794dd120 3081
6502006a 3082 if (!c)
794dd120
SH
3083 return -1;
3084
3bc449ed 3085 if (is_stopped(c))
794dd120
SH
3086 return -1;
3087
3bc449ed
SH
3088 if (container_disk_lock(c))
3089 return -1;
794dd120 3090
33ad9f1a 3091 ret = lxc_cgroup_get(subsys, retv, inlen, c->name, c->config_path);
794dd120 3092
3bc449ed 3093 container_disk_unlock(c);
794dd120
SH
3094 return ret;
3095}
3096
858377e4
SH
3097WRAP_API_3(int, lxcapi_get_cgroup_item, const char *, char *, int)
3098
593e8478 3099const char *lxc_get_global_config_item(const char *key)
83c98d82 3100{
593e8478 3101 return lxc_global_config_value(key);
a8428dfa
SH
3102}
3103
b6b918a1
SG
3104const char *lxc_get_version(void)
3105{
95ee490b 3106 return LXC_VERSION;
b6b918a1
SG
3107}
3108
f0ca2726 3109static int copy_file(const char *old, const char *new)
9be53773
SH
3110{
3111 int in, out;
3112 ssize_t len, ret;
3113 char buf[8096];
3114 struct stat sbuf;
3115
3116 if (file_exists(new)) {
3117 ERROR("copy destination %s exists", new);
3118 return -1;
3119 }
3120 ret = stat(old, &sbuf);
3121 if (ret < 0) {
dfb31b25 3122 INFO("Error stat'ing %s", old);
9be53773
SH
3123 return -1;
3124 }
3125
3126 in = open(old, O_RDONLY);
3127 if (in < 0) {
dfb31b25 3128 SYSERROR("Error opening original file %s", old);
9be53773
SH
3129 return -1;
3130 }
3131 out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
3132 if (out < 0) {
dfb31b25 3133 SYSERROR("Error opening new file %s", new);
9be53773
SH
3134 close(in);
3135 return -1;
3136 }
3137
3138 while (1) {
3139 len = read(in, buf, 8096);
3140 if (len < 0) {
dfb31b25 3141 SYSERROR("Error reading old file %s", old);
9be53773
SH
3142 goto err;
3143 }
3144 if (len == 0)
3145 break;
3146 ret = write(out, buf, len);
1a0e70ac 3147 if (ret < len) { /* should we retry? */
dfb31b25 3148 SYSERROR("Error: write to new file %s was interrupted", new);
9be53773
SH
3149 goto err;
3150 }
3151 }
3152 close(in);
3153 close(out);
3154
1a0e70ac 3155 /* We set mode, but not owner/group. */
9be53773
SH
3156 ret = chmod(new, sbuf.st_mode);
3157 if (ret) {
dfb31b25 3158 SYSERROR("Error setting mode on %s", new);
9be53773
SH
3159 return -1;
3160 }
3161
3162 return 0;
3163
3164err:
3165 close(in);
3166 close(out);
3167 return -1;
3168}
3169
9be53773
SH
3170static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
3171{
619256b5 3172 int i, len, ret;
9be53773 3173 struct lxc_list *it;
619256b5
ÇO
3174 char *cpath;
3175
3176 len = strlen(oldc->config_path) + strlen(oldc->name) + 3;
3177 cpath = alloca(len);
3178 ret = snprintf(cpath, len, "%s/%s/", oldc->config_path, oldc->name);
3179 if (ret < 0 || ret >= len)
3180 return -1;
9be53773
SH
3181
3182 for (i=0; i<NUM_LXC_HOOKS; i++) {
3183 lxc_list_for_each(it, &c->lxc_conf->hooks[i]) {
3184 char *hookname = it->elem;
c32981c3 3185 char *fname = strrchr(hookname, '/');
9be53773 3186 char tmppath[MAXPATHLEN];
1a0e70ac 3187 if (!fname) /* relative path - we don't support, but maybe we should */
9be53773 3188 return 0;
619256b5 3189 if (strncmp(hookname, cpath, len - 1) != 0) {
1a0e70ac 3190 /* this hook is public - ignore */
619256b5
ÇO
3191 continue;
3192 }
1a0e70ac 3193 /* copy the script, and change the entry in confile */
9be53773
SH
3194 ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s",
3195 c->config_path, c->name, fname+1);
3196 if (ret < 0 || ret >= MAXPATHLEN)
3197 return -1;
3198 ret = copy_file(it->elem, tmppath);
3199 if (ret < 0)
3200 return -1;
3201 free(it->elem);
3202 it->elem = strdup(tmppath);
3203 if (!it->elem) {
3204 ERROR("out of memory copying hook path");
3205 return -1;
3206 }
9be53773
SH
3207 }
3208 }
3209
67702c21
SH
3210 if (!clone_update_unexp_hooks(c->lxc_conf, oldc->config_path,
3211 c->config_path, oldc->name, c->name)) {
6b0d5538
SH
3212 ERROR("Error saving new hooks in clone");
3213 return -1;
3214 }
858377e4 3215 do_lxcapi_save_config(c, NULL);
9be53773
SH
3216 return 0;
3217}
3218
9be53773
SH
3219
3220static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
3221{
3222 char newpath[MAXPATHLEN];
3223 char *oldpath = oldc->lxc_conf->fstab;
3224 int ret;
3225
3226 if (!oldpath)
3227 return 0;
3228
47148e96
CB
3229 clear_unexp_config_line(c->lxc_conf, "lxc.mount.fstab", false);
3230
c32981c3 3231 char *p = strrchr(oldpath, '/');
9be53773
SH
3232 if (!p)
3233 return -1;
3234 ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s",
3235 c->config_path, c->name, p);
3236 if (ret < 0 || ret >= MAXPATHLEN) {
3237 ERROR("error printing new path for %s", oldpath);
3238 return -1;
3239 }
3240 if (file_exists(newpath)) {
3241 ERROR("error: fstab file %s exists", newpath);
3242 return -1;
3243 }
3244
3245 if (copy_file(oldpath, newpath) < 0) {
3246 ERROR("error: copying %s to %s", oldpath, newpath);
3247 return -1;
3248 }
3249 free(c->lxc_conf->fstab);
3250 c->lxc_conf->fstab = strdup(newpath);
3251 if (!c->lxc_conf->fstab) {
3252 ERROR("error: allocating pathname");
3253 return -1;
3254 }
47148e96 3255 if (!do_append_unexp_config_line(c->lxc_conf, "lxc.mount.fstab", newpath)) {
6b0d5538
SH
3256 ERROR("error saving new lxctab");
3257 return -1;
3258 }
9be53773
SH
3259
3260 return 0;
3261}
3262
dfb31b25
SH
3263static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
3264{
3265 char path0[MAXPATHLEN], path1[MAXPATHLEN];
3266 int ret;
3267
3268 ret = snprintf(path0, MAXPATHLEN, "%s/%s/lxc_rdepends", c0->config_path,
3269 c0->name);
3270 if (ret < 0 || ret >= MAXPATHLEN) {
3271 WARN("Error copying reverse dependencies");
3272 return;
3273 }
3274 ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path,
3275 c->name);
3276 if (ret < 0 || ret >= MAXPATHLEN) {
3277 WARN("Error copying reverse dependencies");
3278 return;
3279 }
3280 if (copy_file(path0, path1) < 0) {
3281 INFO("Error copying reverse dependencies");
3282 return;
3283 }
3284}
3285
3286static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
3287{
3288 int ret;
3289 char path[MAXPATHLEN];
3290 FILE *f;
3291 bool bret;
3292
3293 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path,
3294 c->name);
3295 if (ret < 0 || ret >= MAXPATHLEN)
3296 return false;
3297 f = fopen(path, "a");
3298 if (!f)
3299 return false;
3300 bret = true;
1a0e70ac 3301 /* If anything goes wrong, just return an error. */
dfb31b25
SH
3302 if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0)
3303 bret = false;
3304 if (fclose(f) != 0)
3305 bret = false;
3306 return bret;
3307}
3308
15a90a10
SH
3309/*
3310 * If the fs natively supports snapshot clones with no penalty,
3311 * then default to those even if not requested.
3312 * Currently we only do this for btrfs.
3313 */
3314bool should_default_to_snapshot(struct lxc_container *c0,
3315 struct lxc_container *c1)
3316{
3317 size_t l0 = strlen(c0->config_path) + strlen(c0->name) + 2;
3318 size_t l1 = strlen(c1->config_path) + strlen(c1->name) + 2;
3319 char *p0 = alloca(l0 + 1);
3320 char *p1 = alloca(l1 + 1);
6e0fa6a0 3321 char *rootfs = c0->lxc_conf->rootfs.path;
15a90a10
SH
3322
3323 snprintf(p0, l0, "%s/%s", c0->config_path, c0->name);
3324 snprintf(p1, l1, "%s/%s", c1->config_path, c1->name);
9a09badc
CB
3325
3326 if (!is_btrfs_fs(p0) || !is_btrfs_fs(p1))
3327 return false;
3328
6e0fa6a0
CB
3329 if (is_btrfs_subvol(rootfs) <= 0)
3330 return false;
3331
15a90a10
SH
3332 return btrfs_same_fs(p0, p1) == 0;
3333}
3334
9be53773 3335static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
763429b6
CB
3336 const char *newtype, int flags, const char *bdevdata,
3337 uint64_t newsize)
9be53773 3338{
10bc1861 3339 struct lxc_storage *bdev;
07db51a2 3340 bool need_rdep;
9be53773 3341
15a90a10
SH
3342 if (should_default_to_snapshot(c0, c))
3343 flags |= LXC_CLONE_SNAPSHOT;
3344
10bc1861
CB
3345 bdev = storage_copy(c0, c->name, c->config_path, newtype, flags,
3346 bdevdata, newsize, &need_rdep);
9be53773 3347 if (!bdev) {
763429b6 3348 ERROR("Error copying storage.");
9be53773
SH
3349 return -1;
3350 }
763429b6
CB
3351
3352 /* Set new rootfs. */
9be53773
SH
3353 free(c->lxc_conf->rootfs.path);
3354 c->lxc_conf->rootfs.path = strdup(bdev->src);
10bc1861 3355 storage_put(bdev);
763429b6 3356
dfb31b25 3357 if (!c->lxc_conf->rootfs.path) {
763429b6
CB
3358 ERROR("Out of memory while setting storage path.");
3359 return -1;
3360 }
763429b6 3361
7a96a068
CB
3362 /* Append a new lxc.rootfs.path entry to the unexpanded config. */
3363 clear_unexp_config_line(c->lxc_conf, "lxc.rootfs.path", false);
3364 if (!do_append_unexp_config_line(c->lxc_conf, "lxc.rootfs.path",
763429b6
CB
3365 c->lxc_conf->rootfs.path)) {
3366 ERROR("Error saving new rootfs to cloned config.");
d0218321
SH
3367 return -1;
3368 }
763429b6 3369
eee59f94
SH
3370 if (flags & LXC_CLONE_SNAPSHOT)
3371 copy_rdepends(c, c0);
dfb31b25
SH
3372 if (need_rdep) {
3373 if (!add_rdepends(c, c0))
3374 WARN("Error adding reverse dependency from %s to %s",
763429b6 3375 c->name, c0->name);
dfb31b25
SH
3376 }
3377
3378 mod_all_rdeps(c, true);
3379
9be53773
SH
3380 return 0;
3381}
3382
1354955b
SH
3383struct clone_update_data {
3384 struct lxc_container *c0;
3385 struct lxc_container *c1;
3386 int flags;
3387 char **hookargs;
3388};
3389
3390static int clone_update_rootfs(struct clone_update_data *data)
9be53773 3391{
1354955b
SH
3392 struct lxc_container *c0 = data->c0;
3393 struct lxc_container *c = data->c1;
3394 int flags = data->flags;
3395 char **hookargs = data->hookargs;
9be53773
SH
3396 int ret = -1;
3397 char path[MAXPATHLEN];
10bc1861 3398 struct lxc_storage *bdev;
9be53773 3399 FILE *fout;
148e91f5 3400 struct lxc_conf *conf = c->lxc_conf;
9be53773
SH
3401
3402 /* update hostname in rootfs */
3403 /* we're going to mount, so run in a clean namespace to simplify cleanup */
3404
1354955b
SH
3405 if (setgid(0) < 0) {
3406 ERROR("Failed to setgid to 0");
3407 return -1;
3408 }
3409 if (setuid(0) < 0) {
3410 ERROR("Failed to setuid to 0");
9be53773 3411 return -1;
1354955b 3412 }
c476bdce
SH
3413 if (setgroups(0, NULL) < 0)
3414 WARN("Failed to clear groups");
9be53773 3415
1354955b
SH
3416 if (unshare(CLONE_NEWNS) < 0)
3417 return -1;
8a388ed4 3418 bdev = storage_init(c->lxc_conf);
9be53773 3419 if (!bdev)
1354955b 3420 return -1;
cf3ef16d
SH
3421 if (strcmp(bdev->type, "dir") != 0) {
3422 if (unshare(CLONE_NEWNS) < 0) {
3423 ERROR("error unsharing mounts");
10bc1861 3424 storage_put(bdev);
1354955b 3425 return -1;
cf3ef16d 3426 }
2c6f3fc9
SH
3427 if (detect_shared_rootfs()) {
3428 if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
3429 SYSERROR("Failed to make / rslave");
3430 ERROR("Continuing...");
3431 }
3432 }
e7de366c 3433 if (bdev->ops->mount(bdev) < 0) {
10bc1861 3434 storage_put(bdev);
1354955b 3435 return -1;
e7de366c 3436 }
1a0e70ac 3437 } else { /* TODO come up with a better way */
f10fad2f 3438 free(bdev->dest);
cf3ef16d
SH
3439 bdev->dest = strdup(bdev->src);
3440 }
148e91f5
SH
3441
3442 if (!lxc_list_empty(&conf->hooks[LXCHOOK_CLONE])) {
3443 /* Start of environment variable setup for hooks */
ab7efcf5 3444 if (c0->name && setenv("LXC_SRC_NAME", c0->name, 1)) {
1143ed39
DE
3445 SYSERROR("failed to set environment variable for source container name");
3446 }
cb8ff4d0 3447 if (setenv("LXC_NAME", c->name, 1)) {
148e91f5
SH
3448 SYSERROR("failed to set environment variable for container name");
3449 }
ab7efcf5 3450 if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) {
148e91f5
SH
3451 SYSERROR("failed to set environment variable for config path");
3452 }
ab7efcf5 3453 if (bdev->dest && setenv("LXC_ROOTFS_MOUNT", bdev->dest, 1)) {
148e91f5
SH
3454 SYSERROR("failed to set environment variable for rootfs mount");
3455 }
ab7efcf5 3456 if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) {
148e91f5
SH
3457 SYSERROR("failed to set environment variable for rootfs mount");
3458 }
3459
14a7b0f9 3460 if (run_lxc_hooks(c->name, "clone", conf, hookargs)) {
148e91f5 3461 ERROR("Error executing clone hook for %s", c->name);
10bc1861 3462 storage_put(bdev);
1354955b 3463 return -1;
148e91f5
SH
3464 }
3465 }
3466
3467 if (!(flags & LXC_CLONE_KEEPNAME)) {
3468 ret = snprintf(path, MAXPATHLEN, "%s/etc/hostname", bdev->dest);
10bc1861 3469 storage_put(bdev);
e7de366c 3470
148e91f5 3471 if (ret < 0 || ret >= MAXPATHLEN)
1354955b 3472 return -1;
8058be39 3473 if (!file_exists(path))
1354955b 3474 return 0;
148e91f5 3475 if (!(fout = fopen(path, "w"))) {
959aee9c 3476 SYSERROR("unable to open %s: ignoring", path);
1354955b 3477 return 0;
148e91f5 3478 }
a684f0b7
ÇO
3479 if (fprintf(fout, "%s", c->name) < 0) {
3480 fclose(fout);
1354955b 3481 return -1;
6849cb5b 3482 }
148e91f5 3483 if (fclose(fout) < 0)
1354955b 3484 return -1;
10bc1861
CB
3485 } else {
3486 storage_put(bdev);
9be53773 3487 }
e7de366c 3488
1354955b
SH
3489 return 0;
3490}
3491
3492static int clone_update_rootfs_wrapper(void *data)
3493{
3494 struct clone_update_data *arg = (struct clone_update_data *) data;
3495 return clone_update_rootfs(arg);
9be53773
SH
3496}
3497
3498/*
3499 * We want to support:
3500sudo lxc-clone -o o1 -n n1 -s -L|-fssize fssize -v|--vgname vgname \
3501 -p|--lvprefix lvprefix -t|--fstype fstype -B backingstore
3502
ba115175
CB
3503-s [ implies overlay]
3504-s -B overlay
9be53773
SH
3505-s -B aufs
3506
3507only rootfs gets converted (copied/snapshotted) on clone.
3508*/
3509
d5752559 3510static int create_file_dirname(char *path, struct lxc_conf *conf)
9be53773 3511{
c32981c3 3512 char *p = strrchr(path, '/');
d5752559 3513 int ret = -1;
9be53773
SH
3514
3515 if (!p)
3516 return -1;
3517 *p = '\0';
d028235d 3518 ret = do_create_container_dir(path, conf);
9be53773
SH
3519 *p = '/';
3520 return ret;
3521}
3522
858377e4 3523static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char *newname,
9be53773 3524 const char *lxcpath, int flags,
d659597e 3525 const char *bdevtype, const char *bdevdata, uint64_t newsize,
148e91f5 3526 char **hookargs)
9be53773 3527{
9be53773 3528 char newpath[MAXPATHLEN];
0e1a60b0 3529 int fd, ret;
1354955b 3530 struct clone_update_data data;
3b392519 3531 size_t saved_unexp_len;
1354955b 3532 pid_t pid;
17a367d8
CB
3533 int storage_copied = 0;
3534 char *origroot = NULL, *saved_unexp_conf = NULL;
3535 struct lxc_container *c2 = NULL;
9be53773 3536
858377e4 3537 if (!c || !do_lxcapi_is_defined(c))
9be53773
SH
3538 return NULL;
3539
5cee8c50 3540 if (container_mem_lock(c))
9be53773
SH
3541 return NULL;
3542
39dc698c 3543 if (!is_stopped(c)) {
9be53773
SH
3544 ERROR("error: Original container (%s) is running", c->name);
3545 goto out;
3546 }
3547
1a0e70ac 3548 /* Make sure the container doesn't yet exist. */
05d53f4c
SH
3549 if (!newname)
3550 newname = c->name;
3551 if (!lxcpath)
858377e4 3552 lxcpath = do_lxcapi_get_config_path(c);
05d53f4c 3553 ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", lxcpath, newname);
6849cb5b 3554 if (ret < 0 || ret >= MAXPATHLEN) {
9be53773
SH
3555 SYSERROR("clone: failed making config pathname");
3556 goto out;
3557 }
17a367d8 3558
9be53773
SH
3559 if (file_exists(newpath)) {
3560 ERROR("error: clone: %s exists", newpath);
3561 goto out;
3562 }
3563
d5752559 3564 ret = create_file_dirname(newpath, c->lxc_conf);
96532523 3565 if (ret < 0 && errno != EEXIST) {
9be53773
SH
3566 ERROR("Error creating container dir for %s", newpath);
3567 goto out;
3568 }
3569
1a0e70ac 3570 /* Copy the configuration. Tweak it as needed. */
8d2efe40
SH
3571 if (c->lxc_conf->rootfs.path) {
3572 origroot = c->lxc_conf->rootfs.path;
3573 c->lxc_conf->rootfs.path = NULL;
3574 }
0e1a60b0
CB
3575
3576 fd = open(newpath, O_WRONLY | O_CREAT | O_CLOEXEC,
3577 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
3578 if (fd < 0) {
3579 SYSERROR("Failed to open \"%s\"", newpath);
9be53773
SH
3580 goto out;
3581 }
5eea90e8
SH
3582
3583 saved_unexp_conf = c->lxc_conf->unexpanded_config;
3b392519 3584 saved_unexp_len = c->lxc_conf->unexpanded_len;
5eea90e8
SH
3585 c->lxc_conf->unexpanded_config = strdup(saved_unexp_conf);
3586 if (!c->lxc_conf->unexpanded_config) {
0e1a60b0 3587 close(fd);
5eea90e8
SH
3588 goto out;
3589 }
7a96a068 3590
7a96a068 3591 clear_unexp_config_line(c->lxc_conf, "lxc.rootfs.path", false);
0e1a60b0
CB
3592 write_config(fd, c->lxc_conf);
3593 close(fd);
8d2efe40 3594 c->lxc_conf->rootfs.path = origroot;
5eea90e8
SH
3595 free(c->lxc_conf->unexpanded_config);
3596 c->lxc_conf->unexpanded_config = saved_unexp_conf;
3597 saved_unexp_conf = NULL;
3b392519 3598 c->lxc_conf->unexpanded_len = saved_unexp_len;
9be53773 3599
90b366fc
CB
3600 ret = snprintf(newpath, MAXPATHLEN, "%s/%s/rootfs", lxcpath, newname);
3601 if (ret < 0 || ret >= MAXPATHLEN) {
3602 SYSERROR("clone: failed making rootfs pathname");
3603 goto out;
3604 }
17a367d8
CB
3605
3606 ret = mkdir(newpath, 0755);
3607 if (ret < 0) {
3608 /* For an overlay container the rootfs is considered immutable
3609 * and will not have been removed when restoring from a
3610 * snapshot.
3611 */
3612 if (errno != ENOENT &&
3613 !(flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)) {
3614 SYSERROR("Failed to create directory \"%s\"", newpath);
3615 goto out;
3616 }
9be53773
SH
3617 }
3618
e0010464 3619 if (am_guest_unpriv()) {
1354955b 3620 if (chown_mapped_root(newpath, c->lxc_conf) < 0) {
959aee9c 3621 ERROR("Error chowning %s to container root", newpath);
1354955b
SH
3622 goto out;
3623 }
3624 }
3625
05d53f4c 3626 c2 = lxc_container_new(newname, lxcpath);
375c2258 3627 if (!c2) {
05d53f4c
SH
3628 ERROR("clone: failed to create new container (%s %s)", newname,
3629 lxcpath);
9be53773
SH
3630 goto out;
3631 }
8d2efe40 3632
1a0e70ac 3633 /* copy/snapshot rootfs's */
8d2efe40
SH
3634 ret = copy_storage(c, c2, bdevtype, flags, bdevdata, newsize);
3635 if (ret < 0)
3636 goto out;
9be53773 3637
6b0d5538 3638
1a0e70ac 3639 /* update utsname */
3d7ad474
CB
3640 if (!(flags & LXC_CLONE_KEEPNAME)) {
3641 clear_unexp_config_line(c2->lxc_conf, "lxc.utsname", false);
b67771bc 3642 clear_unexp_config_line(c2->lxc_conf, "lxc.uts.name", false);
3d7ad474 3643
0d9cd9c3 3644 if (!do_set_config_item_locked(c2, "lxc.uts.name", newname)) {
3d7ad474
CB
3645 ERROR("Error setting new hostname");
3646 goto out;
3647 }
96532523
SH
3648 }
3649
1a0e70ac 3650 /* copy hooks */
619256b5
ÇO
3651 ret = copyhooks(c, c2);
3652 if (ret < 0) {
3653 ERROR("error copying hooks");
3654 goto out;
9be53773
SH
3655 }
3656
3657 if (copy_fstab(c, c2) < 0) {
3658 ERROR("error copying fstab");
9be53773
SH
3659 goto out;
3660 }
3661
1a0e70ac 3662 /* update macaddrs */
6b0d5538 3663 if (!(flags & LXC_CLONE_KEEPMACADDR)) {
67702c21
SH
3664 if (!network_new_hwaddrs(c2->lxc_conf)) {
3665 ERROR("Error updating mac addresses");
6b0d5538
SH
3666 goto out;
3667 }
3668 }
9be53773 3669
1a0e70ac 3670 /* Update absolute paths for overlay mount directories. */
83e79752 3671 if (ovl_update_abs_paths(c2->lxc_conf, c->config_path, c->name, lxcpath, newname) < 0)
030ce9a9
CB
3672 goto out;
3673
1a0e70ac
CB
3674 /* We've now successfully created c2's storage, so clear it out if we
3675 * fail after this.
3676 */
176d9acb
SH
3677 storage_copied = 1;
3678
375c2258 3679 if (!c2->save_config(c2, NULL))
9be53773 3680 goto out;
9be53773 3681
1354955b
SH
3682 if ((pid = fork()) < 0) {
3683 SYSERROR("fork");
9be53773 3684 goto out;
1354955b
SH
3685 }
3686 if (pid > 0) {
3687 ret = wait_for_pid(pid);
3688 if (ret)
3689 goto out;
3690 container_mem_unlock(c);
3691 return c2;
3692 }
3693 data.c0 = c;
3694 data.c1 = c2;
3695 data.flags = flags;
3696 data.hookargs = hookargs;
e0010464 3697 if (am_guest_unpriv())
ee484f7f
CB
3698 ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
3699 &data, "clone_update_rootfs_wrapper");
1354955b
SH
3700 else
3701 ret = clone_update_rootfs(&data);
3702 if (ret < 0)
d8480a31 3703 _exit(EXIT_FAILURE);
9be53773 3704
5cee8c50 3705 container_mem_unlock(c);
d8480a31 3706 _exit(EXIT_SUCCESS);
9be53773
SH
3707
3708out:
5cee8c50 3709 container_mem_unlock(c);
375c2258 3710 if (c2) {
176d9acb
SH
3711 if (!storage_copied)
3712 c2->lxc_conf->rootfs.path = NULL;
375c2258 3713 c2->destroy(c2);
9be53773 3714 lxc_container_put(c2);
375c2258 3715 }
9be53773
SH
3716
3717 return NULL;
3718}
3719
858377e4
SH
3720static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *newname,
3721 const char *lxcpath, int flags,
3722 const char *bdevtype, const char *bdevdata, uint64_t newsize,
3723 char **hookargs)
3724{
3725 struct lxc_container * ret;
3726 current_config = c ? c->lxc_conf : NULL;
3727 ret = do_lxcapi_clone(c, newname, lxcpath, flags, bdevtype, bdevdata, newsize, hookargs);
3728 current_config = NULL;
3729 return ret;
3730}
3731
3732static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
06e5650e 3733{
10bc1861 3734 struct lxc_storage *bdev;
06e5650e 3735 struct lxc_container *newc;
06e5650e 3736
d693cf93 3737 if (!c || !c->name || !c->config_path || !c->lxc_conf)
06e5650e
ÇO
3738 return false;
3739
18aa217b
SH
3740 if (has_fs_snapshots(c) || has_snapshots(c)) {
3741 ERROR("Renaming a container with snapshots is not supported");
3742 return false;
3743 }
8a388ed4 3744 bdev = storage_init(c->lxc_conf);
06e5650e
ÇO
3745 if (!bdev) {
3746 ERROR("Failed to find original backing store type");
3747 return false;
3748 }
3749
619256b5 3750 newc = lxcapi_clone(c, newname, c->config_path, LXC_CLONE_KEEPMACADDR, NULL, bdev->type, 0, NULL);
10bc1861 3751 storage_put(bdev);
06e5650e
ÇO
3752 if (!newc) {
3753 lxc_container_put(newc);
3754 return false;
3755 }
3756
3757 if (newc && lxcapi_is_defined(newc))
3758 lxc_container_put(newc);
3759
17a367d8 3760 if (!container_destroy(c, NULL)) {
06e5650e
ÇO
3761 ERROR("Could not destroy existing container %s", c->name);
3762 return false;
3763 }
3764 return true;
3765}
3766
858377e4
SH
3767WRAP_API_1(bool, lxcapi_rename, const char *)
3768
a0e93eeb
CS
3769static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process)
3770{
858377e4
SH
3771 int ret;
3772
a0e93eeb
CS
3773 if (!c)
3774 return -1;
3775
858377e4
SH
3776 current_config = c->lxc_conf;
3777
3778 ret = lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process);
3779 current_config = NULL;
3780 return ret;
a0e93eeb
CS
3781}
3782
858377e4 3783static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[])
a0e93eeb
CS
3784{
3785 lxc_attach_command_t command;
3786 pid_t pid;
3787 int r;
3788
3789 if (!c)
3790 return -1;
3791
3792 command.program = (char*)program;
3793 command.argv = (char**)argv;
3794 r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid);
3795 if (r < 0) {
3796 ERROR("ups");
3797 return r;
3798 }
3799 return lxc_wait_for_pid_status(pid);
3800}
3801
858377e4
SH
3802static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[])
3803{
3804 int ret;
3805 current_config = c ? c->lxc_conf : NULL;
3806 ret = do_lxcapi_attach_run_wait(c, options, program, argv);
3807 current_config = NULL;
3808 return ret;
3809}
3810
74a3920a 3811static int get_next_index(const char *lxcpath, char *cname)
f5dd1d53
SH
3812{
3813 char *fname;
3814 struct stat sb;
3815 int i = 0, ret;
3816
3817 fname = alloca(strlen(lxcpath) + 20);
3818 while (1) {
3819 sprintf(fname, "%s/snap%d", lxcpath, i);
3820 ret = stat(fname, &sb);
3821 if (ret != 0)
3822 return i;
3823 i++;
3824 }
3825}
3826
18aa217b
SH
3827static bool get_snappath_dir(struct lxc_container *c, char *snappath)
3828{
3829 int ret;
3830 /*
3831 * If the old style snapshot path exists, use it
3832 * /var/lib/lxc -> /var/lib/lxcsnaps
3833 */
3834 ret = snprintf(snappath, MAXPATHLEN, "%ssnaps", c->config_path);
3835 if (ret < 0 || ret >= MAXPATHLEN)
3836 return false;
3837 if (dir_exists(snappath)) {
3838 ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
3839 if (ret < 0 || ret >= MAXPATHLEN)
3840 return false;
3841 return true;
3842 }
3843
3844 /*
3845 * Use the new style path
3846 * /var/lib/lxc -> /var/lib/lxc + c->name + /snaps + \0
3847 */
3848 ret = snprintf(snappath, MAXPATHLEN, "%s/%s/snaps", c->config_path, c->name);
3849 if (ret < 0 || ret >= MAXPATHLEN)
3850 return false;
3851 return true;
3852}
3853
858377e4 3854static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
f5dd1d53
SH
3855{
3856 int i, flags, ret;
3857 struct lxc_container *c2;
3858 char snappath[MAXPATHLEN], newname[20];
3859
840f05df
SH
3860 if (!c || !lxcapi_is_defined(c))
3861 return -1;
3862
10bc1861 3863 if (!storage_can_backup(c->lxc_conf)) {
cdd01be2
SH
3864 ERROR("%s's backing store cannot be backed up.", c->name);
3865 ERROR("Your container must use another backing store type.");
3866 return -1;
3867 }
3868
18aa217b 3869 if (!get_snappath_dir(c, snappath))
f5dd1d53 3870 return -1;
18aa217b 3871
f5dd1d53
SH
3872 i = get_next_index(snappath, c->name);
3873
3874 if (mkdir_p(snappath, 0755) < 0) {
3875 ERROR("Failed to create snapshot directory %s", snappath);
3876 return -1;
3877 }
3878
3879 ret = snprintf(newname, 20, "snap%d", i);
3880 if (ret < 0 || ret >= 20)
3881 return -1;
3882
0a83cbbb
SH
3883 /*
3884 * We pass LXC_CLONE_SNAPSHOT to make sure that a rdepends file entry is
3885 * created in the original container
3886 */
3887 flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_KEEPMACADDR | LXC_CLONE_KEEPNAME |
3888 LXC_CLONE_KEEPBDEVTYPE | LXC_CLONE_MAYBE_SNAPSHOT;
068aa488 3889 if (storage_is_dir(c->lxc_conf)) {
8c39f7a4
SH
3890 ERROR("Snapshot of directory-backed container requested.");
3891 ERROR("Making a copy-clone. If you do want snapshots, then");
ba115175 3892 ERROR("please create an aufs or overlay clone first, snapshot that");
8c39f7a4
SH
3893 ERROR("and keep the original container pristine.");
3894 flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
3895 }
858377e4 3896 c2 = do_lxcapi_clone(c, newname, snappath, flags, NULL, NULL, 0, NULL);
f5dd1d53 3897 if (!c2) {
959aee9c 3898 ERROR("clone of %s:%s failed", c->config_path, c->name);
f5dd1d53
SH
3899 return -1;
3900 }
3901
3902 lxc_container_put(c2);
3903
1a0e70ac 3904 /* Now write down the creation time. */
f5dd1d53
SH
3905 time_t timer;
3906 char buffer[25];
3907 struct tm* tm_info;
025ed0f3 3908 FILE *f;
f5dd1d53
SH
3909
3910 time(&timer);
3911 tm_info = localtime(&timer);
3912
3913 strftime(buffer, 25, "%Y:%m:%d %H:%M:%S", tm_info);
3914
3915 char *dfnam = alloca(strlen(snappath) + strlen(newname) + 5);
3916 sprintf(dfnam, "%s/%s/ts", snappath, newname);
025ed0f3 3917 f = fopen(dfnam, "w");
f5dd1d53 3918 if (!f) {
959aee9c 3919 ERROR("Failed to open %s", dfnam);
f5dd1d53
SH
3920 return -1;
3921 }
3922 if (fprintf(f, "%s", buffer) < 0) {
3923 SYSERROR("Writing timestamp");
3924 fclose(f);
3925 return -1;
3926 }
025ed0f3 3927 ret = fclose(f);
025ed0f3 3928 if (ret != 0) {
f5dd1d53
SH
3929 SYSERROR("Writing timestamp");
3930 return -1;
3931 }
3932
3933 if (commentfile) {
1a0e70ac 3934 /* $p / $name / comment \0 */
f5dd1d53
SH
3935 int len = strlen(snappath) + strlen(newname) + 10;
3936 char *path = alloca(len);
3937 sprintf(path, "%s/%s/comment", snappath, newname);
3938 return copy_file(commentfile, path) < 0 ? -1 : i;
3939 }
3940
3941 return i;
3942}
3943
858377e4
SH
3944WRAP_API_1(int, lxcapi_snapshot, const char *)
3945
f5dd1d53
SH
3946static void lxcsnap_free(struct lxc_snapshot *s)
3947{
f10fad2f
ME
3948 free(s->name);
3949 free(s->comment_pathname);
3950 free(s->timestamp);
3951 free(s->lxcpath);
f5dd1d53
SH
3952}
3953
3954static char *get_snapcomment_path(char* snappath, char *name)
3955{
1a0e70ac 3956 /* $snappath/$name/comment */
f5dd1d53
SH
3957 int ret, len = strlen(snappath) + strlen(name) + 10;
3958 char *s = malloc(len);
3959
3960 if (s) {
3961 ret = snprintf(s, len, "%s/%s/comment", snappath, name);
3962 if (ret < 0 || ret >= len) {
3963 free(s);
3964 s = NULL;
3965 }
3966 }
3967 return s;
3968}
3969
3970static char *get_timestamp(char* snappath, char *name)
3971{
3972 char path[MAXPATHLEN], *s = NULL;
3973 int ret, len;
3974 FILE *fin;
3975
3976 ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name);
3977 if (ret < 0 || ret >= MAXPATHLEN)
3978 return NULL;
025ed0f3 3979 fin = fopen(path, "r");
025ed0f3 3980 if (!fin)
f5dd1d53
SH
3981 return NULL;
3982 (void) fseek(fin, 0, SEEK_END);
3983 len = ftell(fin);
3984 (void) fseek(fin, 0, SEEK_SET);
3985 if (len > 0) {
3986 s = malloc(len+1);
3987 if (s) {
3988 s[len] = '\0';
3989 if (fread(s, 1, len, fin) != len) {
3990 SYSERROR("reading timestamp");
3991 free(s);
3992 s = NULL;
3993 }
3994 }
3995 }
3996 fclose(fin);
3997 return s;
3998}
3999
858377e4 4000static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **ret_snaps)
f5dd1d53
SH
4001{
4002 char snappath[MAXPATHLEN], path2[MAXPATHLEN];
18aa217b 4003 int count = 0, ret;
74f96976 4004 struct dirent *direntp;
f5dd1d53
SH
4005 struct lxc_snapshot *snaps =NULL, *nsnaps;
4006 DIR *dir;
4007
4008 if (!c || !lxcapi_is_defined(c))
4009 return -1;
c868b261 4010
18aa217b 4011 if (!get_snappath_dir(c, snappath)) {
f5dd1d53
SH
4012 ERROR("path name too long");
4013 return -1;
4014 }
025ed0f3 4015 dir = opendir(snappath);
025ed0f3 4016 if (!dir) {
f5dd1d53
SH
4017 INFO("failed to open %s - assuming no snapshots", snappath);
4018 return 0;
4019 }
4020
74f96976 4021 while ((direntp = readdir(dir))) {
f5dd1d53
SH
4022 if (!direntp)
4023 break;
4024
4025 if (!strcmp(direntp->d_name, "."))
4026 continue;
4027
4028 if (!strcmp(direntp->d_name, ".."))
4029 continue;
4030
4031 ret = snprintf(path2, MAXPATHLEN, "%s/%s/config", snappath, direntp->d_name);
4032 if (ret < 0 || ret >= MAXPATHLEN) {
4033 ERROR("pathname too long");
4034 goto out_free;
4035 }
4036 if (!file_exists(path2))
4037 continue;
4038 nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps));
4039 if (!nsnaps) {
4040 SYSERROR("Out of memory");
4041 goto out_free;
4042 }
4043 snaps = nsnaps;
4044 snaps[count].free = lxcsnap_free;
4045 snaps[count].name = strdup(direntp->d_name);
4046 if (!snaps[count].name)
4047 goto out_free;
4048 snaps[count].lxcpath = strdup(snappath);
4049 if (!snaps[count].lxcpath) {
4050 free(snaps[count].name);
4051 goto out_free;
4052 }
4053 snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name);
4054 snaps[count].timestamp = get_timestamp(snappath, direntp->d_name);
4055 count++;
4056 }
4057
4058 if (closedir(dir))
4059 WARN("failed to close directory");
4060
4061 *ret_snaps = snaps;
4062 return count;
4063
4064out_free:
4065 if (snaps) {
4066 int i;
4067 for (i=0; i<count; i++)
4068 lxcsnap_free(&snaps[i]);
4069 free(snaps);
4070 }
9baa57bd
SH
4071 if (closedir(dir))
4072 WARN("failed to close directory");
f5dd1d53
SH
4073 return -1;
4074}
4075
858377e4
SH
4076WRAP_API_1(int, lxcapi_snapshot_list, struct lxc_snapshot **)
4077
4078static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snapname, const char *newname)
f5dd1d53
SH
4079{
4080 char clonelxcpath[MAXPATHLEN];
18aa217b 4081 int flags = 0;
f5dd1d53 4082 struct lxc_container *snap, *rest;
10bc1861 4083 struct lxc_storage *bdev;
f5dd1d53
SH
4084 bool b = false;
4085
4086 if (!c || !c->name || !c->config_path)
4087 return false;
4088
18aa217b
SH
4089 if (has_fs_snapshots(c)) {
4090 ERROR("container rootfs has dependent snapshots");
4091 return false;
4092 }
4093
8a388ed4 4094 bdev = storage_init(c->lxc_conf);
f5dd1d53
SH
4095 if (!bdev) {
4096 ERROR("Failed to find original backing store type");
4097 return false;
4098 }
4099
17a367d8
CB
4100 /* For an overlay container the rootfs is considered immutable
4101 * and cannot be removed when restoring from a snapshot. We pass this
4102 * internal flag along to communicate this to various parts of the
4103 * codebase.
4104 */
4105 if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs"))
4106 bdev->flags |= LXC_STORAGE_INTERNAL_OVERLAY_RESTORE;
4107
f5dd1d53
SH
4108 if (!newname)
4109 newname = c->name;
7e36f87e 4110
18aa217b 4111 if (!get_snappath_dir(c, clonelxcpath)) {
10bc1861 4112 storage_put(bdev);
f5dd1d53
SH
4113 return false;
4114 }
1a0e70ac 4115 /* how should we lock this? */
f5dd1d53
SH
4116
4117 snap = lxc_container_new(snapname, clonelxcpath);
4118 if (!snap || !lxcapi_is_defined(snap)) {
4119 ERROR("Could not open snapshot %s", snapname);
17a367d8
CB
4120 if (snap)
4121 lxc_container_put(snap);
10bc1861 4122 storage_put(bdev);
f5dd1d53
SH
4123 return false;
4124 }
4125
17a367d8
CB
4126 if (!strcmp(c->name, newname)) {
4127 if (!container_destroy(c, bdev)) {
7e36f87e
ÇO
4128 ERROR("Could not destroy existing container %s", newname);
4129 lxc_container_put(snap);
10bc1861 4130 storage_put(bdev);
7e36f87e
ÇO
4131 return false;
4132 }
4133 }
4134
de269ee8
SH
4135 if (strcmp(bdev->type, "dir") != 0 && strcmp(bdev->type, "loop") != 0)
4136 flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
17a367d8
CB
4137
4138 if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs"))
4139 flags |= LXC_STORAGE_INTERNAL_OVERLAY_RESTORE;
09f6f8c4
CB
4140 rest = lxcapi_clone(snap, newname, c->config_path, flags, bdev->type,
4141 NULL, 0, NULL);
10bc1861 4142 storage_put(bdev);
f5dd1d53
SH
4143 if (rest && lxcapi_is_defined(rest))
4144 b = true;
4145 if (rest)
4146 lxc_container_put(rest);
17a367d8 4147
f5dd1d53
SH
4148 lxc_container_put(snap);
4149 return b;
4150}
4151
858377e4
SH
4152WRAP_API_2(bool, lxcapi_snapshot_restore, const char *, const char *)
4153
18aa217b 4154static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
771d96b3 4155{
771d96b3 4156 struct lxc_container *snap = NULL;
18aa217b 4157 bool bret = false;
771d96b3
ÇO
4158
4159 snap = lxc_container_new(snapname, clonelxcpath);
18aa217b 4160 if (!snap) {
771d96b3
ÇO
4161 ERROR("Could not find snapshot %s", snapname);
4162 goto err;
4163 }
4164
858377e4 4165 if (!do_lxcapi_destroy(snap)) {
771d96b3
ÇO
4166 ERROR("Could not destroy snapshot %s", snapname);
4167 goto err;
4168 }
18aa217b 4169 bret = true;
771d96b3 4170
771d96b3
ÇO
4171err:
4172 if (snap)
4173 lxc_container_put(snap);
18aa217b
SH
4174 return bret;
4175}
4176
4177static bool remove_all_snapshots(const char *path)
4178{
4179 DIR *dir;
74f96976 4180 struct dirent *direntp;
18aa217b
SH
4181 bool bret = true;
4182
4183 dir = opendir(path);
4184 if (!dir) {
4185 SYSERROR("opendir on snapshot path %s", path);
4186 return false;
4187 }
74f96976 4188 while ((direntp = readdir(dir))) {
18aa217b
SH
4189 if (!strcmp(direntp->d_name, "."))
4190 continue;
4191 if (!strcmp(direntp->d_name, ".."))
4192 continue;
4193 if (!do_snapshot_destroy(direntp->d_name, path)) {
4194 bret = false;
4195 continue;
4196 }
4197 }
4198
4199 closedir(dir);
4200
4201 if (rmdir(path))
4202 SYSERROR("Error removing directory %s", path);
4203
4204 return bret;
4205}
4206
858377e4 4207static bool do_lxcapi_snapshot_destroy(struct lxc_container *c, const char *snapname)
18aa217b
SH
4208{
4209 char clonelxcpath[MAXPATHLEN];
4210
4211 if (!c || !c->name || !c->config_path || !snapname)
4212 return false;
4213
4214 if (!get_snappath_dir(c, clonelxcpath))
4215 return false;
4216
4217 return do_snapshot_destroy(snapname, clonelxcpath);
4218}
4219
858377e4
SH
4220WRAP_API_1(bool, lxcapi_snapshot_destroy, const char *)
4221
4222static bool do_lxcapi_snapshot_destroy_all(struct lxc_container *c)
18aa217b
SH
4223{
4224 char clonelxcpath[MAXPATHLEN];
4225
4226 if (!c || !c->name || !c->config_path)
4227 return false;
4228
4229 if (!get_snappath_dir(c, clonelxcpath))
4230 return false;
4231
4232 return remove_all_snapshots(clonelxcpath);
771d96b3
ÇO
4233}
4234
858377e4
SH
4235WRAP_API(bool, lxcapi_snapshot_destroy_all)
4236
4237static bool do_lxcapi_may_control(struct lxc_container *c)
b494d2dd
SH
4238{
4239 return lxc_try_cmd(c->name, c->config_path) == 0;
4240}
4241
858377e4
SH
4242WRAP_API(bool, lxcapi_may_control)
4243
d5aa23e6 4244static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
b69dfc9f 4245 struct stat *st)
d5aa23e6 4246{
b69dfc9f
CB
4247 int ret;
4248 char *tmp;
4249 pid_t pid;
d5aa23e6
SH
4250 char chrootpath[MAXPATHLEN];
4251 char *directory_path = NULL;
d5aa23e6 4252
b69dfc9f
CB
4253 pid = fork();
4254 if (pid < 0) {
4255 SYSERROR("Failed to fork()");
d5aa23e6
SH
4256 return false;
4257 }
b69dfc9f 4258
d5aa23e6 4259 if (pid) {
b69dfc9f
CB
4260 ret = wait_for_pid(pid);
4261 if (ret != 0) {
4262 ERROR("Failed to create device node");
d5aa23e6
SH
4263 return false;
4264 }
b69dfc9f 4265
d5aa23e6
SH
4266 return true;
4267 }
4268
4269 /* prepare the path */
4270 ret = snprintf(chrootpath, MAXPATHLEN, "/proc/%d/root", init_pid);
4271 if (ret < 0 || ret >= MAXPATHLEN)
4272 return false;
4273
b69dfc9f
CB
4274 ret = chroot(chrootpath);
4275 if (ret < 0)
a7764ce7 4276 _exit(EXIT_FAILURE);
b69dfc9f
CB
4277
4278 ret = chdir("/");
4279 if (ret < 0)
a7764ce7 4280 _exit(EXIT_FAILURE);
b69dfc9f 4281
d5aa23e6 4282 /* remove path if it exists */
b69dfc9f
CB
4283 ret = faccessat(AT_FDCWD, path, F_OK, AT_SYMLINK_NOFOLLOW);
4284 if(ret == 0) {
4285 ret = unlink(path);
c7d76c09
CB
4286 if (ret < 0) {
4287 ERROR("%s - Failed to remove \"%s\"", strerror(errno), path);
a7764ce7 4288 _exit(EXIT_FAILURE);
c7d76c09 4289 }
d5aa23e6 4290 }
b69dfc9f 4291
d5aa23e6 4292 if (!add)
a7764ce7 4293 _exit(EXIT_SUCCESS);
d5aa23e6
SH
4294
4295 /* create any missing directories */
b69dfc9f
CB
4296 tmp = strdup(path);
4297 if (!tmp)
a7764ce7 4298 _exit(EXIT_FAILURE);
b69dfc9f
CB
4299
4300 directory_path = dirname(tmp);
4301 ret = mkdir_p(directory_path, 0755);
4302 if (ret < 0 && errno != EEXIST) {
c7d76c09 4303 ERROR("%s - Failed to create path \"%s\"", strerror(errno), directory_path);
b69dfc9f 4304 free(tmp);
a7764ce7 4305 _exit(EXIT_FAILURE);
d5aa23e6
SH
4306 }
4307
4308 /* create the device node */
b69dfc9f
CB
4309 ret = mknod(path, st->st_mode, st->st_rdev);
4310 free(tmp);
c7d76c09
CB
4311 if (ret < 0) {
4312 ERROR("%s - Failed to create device node at \"%s\"", strerror(errno), path);
a7764ce7 4313 _exit(EXIT_FAILURE);
c7d76c09 4314 }
d5aa23e6 4315
a7764ce7 4316 _exit(EXIT_SUCCESS);
d5aa23e6
SH
4317}
4318
f0ca2726 4319static bool add_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path, bool add)
a9a0ed90
ÇO
4320{
4321 int ret;
4322 struct stat st;
238b3e5e 4323 char value[LXC_MAX_BUFFER];
f0ca2726 4324 const char *p;
a9a0ed90
ÇO
4325
4326 /* make sure container is running */
858377e4 4327 if (!do_lxcapi_is_running(c)) {
a9a0ed90 4328 ERROR("container is not running");
d5aa23e6 4329 return false;
a9a0ed90
ÇO
4330 }
4331
4332 /* use src_path if dest_path is NULL otherwise use dest_path */
4333 p = dest_path ? dest_path : src_path;
4334
a9a0ed90
ÇO
4335 /* make sure we can access p */
4336 if(access(p, F_OK) < 0 || stat(p, &st) < 0)
d5aa23e6 4337 return false;
a9a0ed90
ÇO
4338
4339 /* continue if path is character device or block device */
c6a9b0d7 4340 if (S_ISCHR(st.st_mode))
238b3e5e 4341 ret = snprintf(value, LXC_MAX_BUFFER, "c %d:%d rwm", major(st.st_rdev), minor(st.st_rdev));
c6a9b0d7 4342 else if (S_ISBLK(st.st_mode))
238b3e5e 4343 ret = snprintf(value, LXC_MAX_BUFFER, "b %d:%d rwm", major(st.st_rdev), minor(st.st_rdev));
a9a0ed90 4344 else
d5aa23e6 4345 return false;
a9a0ed90
ÇO
4346
4347 /* check snprintf return code */
238b3e5e 4348 if (ret < 0 || ret >= LXC_MAX_BUFFER)
d5aa23e6 4349 return false;
a9a0ed90 4350
858377e4 4351 if (!do_add_remove_node(do_lxcapi_init_pid(c), p, add, &st))
d5aa23e6 4352 return false;
a9a0ed90 4353
d5aa23e6 4354 /* add or remove device to/from cgroup access list */
a9a0ed90 4355 if (add) {
858377e4 4356 if (!do_lxcapi_set_cgroup_item(c, "devices.allow", value)) {
a9a0ed90 4357 ERROR("set_cgroup_item failed while adding the device node");
d5aa23e6 4358 return false;
a9a0ed90
ÇO
4359 }
4360 } else {
858377e4 4361 if (!do_lxcapi_set_cgroup_item(c, "devices.deny", value)) {
a9a0ed90 4362 ERROR("set_cgroup_item failed while removing the device node");
d5aa23e6 4363 return false;
a9a0ed90
ÇO
4364 }
4365 }
d5aa23e6 4366
a9a0ed90 4367 return true;
a9a0ed90
ÇO
4368}
4369
858377e4 4370static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
a9a0ed90 4371{
e0010464 4372 // cannot mknod if we're not privileged wrt init_user_ns
5384e99d 4373 if (am_host_unpriv()) {
238b3e5e 4374 ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
c868b261
ÇO
4375 return false;
4376 }
a9a0ed90
ÇO
4377 return add_remove_device_node(c, src_path, dest_path, true);
4378}
4379
858377e4
SH
4380WRAP_API_2(bool, lxcapi_add_device_node, const char *, const char *)
4381
4382static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
a9a0ed90 4383{
e0010464 4384 if (am_guest_unpriv()) {
238b3e5e 4385 ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
c868b261
ÇO
4386 return false;
4387 }
a9a0ed90
ÇO
4388 return add_remove_device_node(c, src_path, dest_path, false);
4389}
4390
858377e4
SH
4391WRAP_API_2(bool, lxcapi_remove_device_node, const char *, const char *)
4392
c7d76c09
CB
4393static bool do_lxcapi_attach_interface(struct lxc_container *c,
4394 const char *ifname,
4395 const char *dst_ifname)
e58fae8f 4396{
c7d76c09 4397 pid_t init_pid;
e58fae8f 4398 int ret = 0;
c7d76c09 4399
e0010464 4400 if (am_guest_unpriv()) {
238b3e5e 4401 ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
e58fae8f
DY
4402 return false;
4403 }
4404
4405 if (!ifname) {
4406 ERROR("No source interface name given");
4407 return false;
4408 }
4409
4410 ret = lxc_netdev_isup(ifname);
e5848d39
SH
4411 if (ret > 0) {
4412 /* netdev of ifname is up. */
e58fae8f
DY
4413 ret = lxc_netdev_down(ifname);
4414 if (ret)
4415 goto err;
4416 }
4417
c7d76c09
CB
4418 init_pid = do_lxcapi_init_pid(c);
4419 ret = lxc_netdev_move_by_name(ifname, init_pid, dst_ifname);
e58fae8f
DY
4420 if (ret)
4421 goto err;
4422
c7d76c09 4423 INFO("Moved network device \"%s\" to network namespace of %d", ifname, init_pid);
e58fae8f 4424 return true;
e5848d39 4425
e58fae8f 4426err:
e58fae8f
DY
4427 return false;
4428}
4429
858377e4
SH
4430WRAP_API_2(bool, lxcapi_attach_interface, const char *, const char *)
4431
c7d76c09
CB
4432static bool do_lxcapi_detach_interface(struct lxc_container *c,
4433 const char *ifname,
4434 const char *dst_ifname)
e58fae8f 4435{
c7d76c09 4436 int ret;
e58fae8f
DY
4437 pid_t pid, pid_outside;
4438
e0010464
SH
4439 /*
4440 * TODO - if this is a physical device, then we need am_host_unpriv.
4441 * But for other types guest privilege suffices.
4442 */
4443 if (am_guest_unpriv()) {
238b3e5e 4444 ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
e58fae8f
DY
4445 return false;
4446 }
4447
4448 if (!ifname) {
4449 ERROR("No source interface name given");
4450 return false;
4451 }
4452
0059379f 4453 pid_outside = lxc_raw_getpid();
e58fae8f
DY
4454 pid = fork();
4455 if (pid < 0) {
c7d76c09 4456 ERROR("Failed to fork");
e58fae8f
DY
4457 return false;
4458 }
4459
1a0e70ac 4460 if (pid == 0) { /* child */
acbfeda8
CB
4461 pid_t init_pid;
4462
4463 init_pid = do_lxcapi_init_pid(c);
4464 if (!switch_to_ns(init_pid, "net")) {
4465 ERROR("Failed to enter network namespace");
8d7b6c25 4466 _exit(EXIT_FAILURE);
e58fae8f
DY
4467 }
4468
4469 ret = lxc_netdev_isup(ifname);
c7d76c09
CB
4470 if (ret < 0) {
4471 ERROR("Failed to determine whether network device \"%s\" is up", ifname);
8d7b6c25 4472 _exit(EXIT_FAILURE);
c7d76c09 4473 }
e58fae8f
DY
4474
4475 /* netdev of ifname is up. */
4476 if (ret) {
4477 ret = lxc_netdev_down(ifname);
c7d76c09
CB
4478 if (ret) {
4479 ERROR("Failed to set network device \"%s\" down", ifname);
8d7b6c25 4480 _exit(EXIT_FAILURE);
c7d76c09 4481 }
e58fae8f
DY
4482 }
4483
4484 ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname);
c7d76c09
CB
4485 /* -EINVAL means there is no netdev named as ifname. */
4486 if (ret < 0) {
4487 if (ret == -EINVAL)
4488 ERROR("Network device \"%s\" not found", ifname);
4489 else
4490 ERROR("Failed to remove network device \"%s\"", ifname);
8d7b6c25 4491 _exit(EXIT_FAILURE);
e58fae8f 4492 }
c7d76c09 4493
8d7b6c25 4494 _exit(EXIT_SUCCESS);
e58fae8f
DY
4495 }
4496
c7d76c09
CB
4497 ret = wait_for_pid(pid);
4498 if (ret != 0)
e58fae8f
DY
4499 return false;
4500
c7d76c09 4501 INFO("Moved network device \"%s\" to network namespace of %d", ifname, pid_outside);
e58fae8f
DY
4502 return true;
4503}
4504
858377e4
SH
4505WRAP_API_2(bool, lxcapi_detach_interface, const char *, const char *)
4506
aef3d51e
TA
4507static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
4508 struct migrate_opts *opts, unsigned int size)
bbd4e13e 4509{
6b9be523 4510 int ret = -1;
2cb80427 4511 struct migrate_opts *valid_opts = opts;
b5b12b9e 4512 uint64_t features_to_check = 0;
85c50991 4513
aef3d51e
TA
4514 /* If the caller has a bigger (newer) struct migrate_opts, let's make
4515 * sure that the stuff on the end is zero, i.e. that they didn't ask us
4516 * to do anything special.
4517 */
4518 if (size > sizeof(*opts)) {
4519 unsigned char *addr;
4520 unsigned char *end;
4521
4522 addr = (void *)opts + sizeof(*opts);
4523 end = (void *)opts + size;
4524 for (; addr < end; addr++) {
4525 if (*addr) {
4526 return -E2BIG;
4527 }
4528 }
85c50991
TA
4529 }
4530
2cb80427
TA
4531 /* If the caller has a smaller struct, let's zero out the end for them
4532 * so we don't accidentally use bits of it that they didn't know about
4533 * to initialize.
4534 */
4535 if (size < sizeof(*opts)) {
4536 valid_opts = malloc(sizeof(*opts));
4537 if (!valid_opts)
4538 return -ENOMEM;
4539
4540 memset(valid_opts, 0, sizeof(*opts));
4541 memcpy(valid_opts, opts, size);
4542 }
4543
aef3d51e
TA
4544 switch (cmd) {
4545 case MIGRATE_PRE_DUMP:
7ad13c91
TA
4546 if (!do_lxcapi_is_running(c)) {
4547 ERROR("container is not running");
6b9be523 4548 goto on_error;
7ad13c91 4549 }
2cb80427 4550 ret = !__criu_pre_dump(c, valid_opts);
aef3d51e
TA
4551 break;
4552 case MIGRATE_DUMP:
7ad13c91
TA
4553 if (!do_lxcapi_is_running(c)) {
4554 ERROR("container is not running");
6b9be523 4555 goto on_error;
7ad13c91 4556 }
2cb80427 4557 ret = !__criu_dump(c, valid_opts);
aef3d51e
TA
4558 break;
4559 case MIGRATE_RESTORE:
7ad13c91
TA
4560 if (do_lxcapi_is_running(c)) {
4561 ERROR("container is already running");
6b9be523 4562 goto on_error;
7ad13c91 4563 }
2cb80427 4564 ret = !__criu_restore(c, valid_opts);
aef3d51e 4565 break;
b5b12b9e
AR
4566 case MIGRATE_FEATURE_CHECK:
4567 features_to_check = valid_opts->features_to_check;
4568 ret = !__criu_check_feature(&features_to_check);
4569 if (ret) {
4570 /* Something went wrong. Let's let the caller
4571 * know which feature checks failed. */
4572 valid_opts->features_to_check = features_to_check;
4573 }
4574 break;
aef3d51e
TA
4575 default:
4576 ERROR("invalid migrate command %u", cmd);
4577 ret = -EINVAL;
4578 }
735f2c6e 4579
6b9be523 4580on_error:
f686506d
TA
4581 if (size < sizeof(*opts))
4582 free(valid_opts);
4583
aef3d51e
TA
4584 return ret;
4585}
735f2c6e 4586
aef3d51e 4587WRAP_API_3(int, lxcapi_migrate, unsigned int, struct migrate_opts *, unsigned int)
735f2c6e 4588
aef3d51e
TA
4589static bool do_lxcapi_checkpoint(struct lxc_container *c, char *directory, bool stop, bool verbose)
4590{
ebb088e1
AR
4591 struct migrate_opts opts;
4592
4593 memset(&opts, 0, sizeof(opts));
4594
4595 opts.directory = directory;
4596 opts.stop = stop;
4597 opts.verbose = verbose;
735f2c6e 4598
aef3d51e 4599 return !do_lxcapi_migrate(c, MIGRATE_DUMP, &opts, sizeof(opts));
735f2c6e
TA
4600}
4601
858377e4
SH
4602WRAP_API_3(bool, lxcapi_checkpoint, char *, bool, bool)
4603
4604static bool do_lxcapi_restore(struct lxc_container *c, char *directory, bool verbose)
c9d8f2ee 4605{
ebb088e1
AR
4606 struct migrate_opts opts;
4607
4608 memset(&opts, 0, sizeof(opts));
4609
4610 opts.directory = directory;
4611 opts.verbose = verbose;
c9d8f2ee 4612
aef3d51e 4613 return !do_lxcapi_migrate(c, MIGRATE_RESTORE, &opts, sizeof(opts));
735f2c6e
TA
4614}
4615
858377e4
SH
4616WRAP_API_2(bool, lxcapi_restore, char *, bool)
4617
a0e93eeb
CS
4618static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...)
4619{
4620 va_list ap;
4621 const char **argv;
4622 int ret;
4623
4624 if (!c)
4625 return -1;
4626
858377e4
SH
4627 current_config = c->lxc_conf;
4628
a0e93eeb
CS
4629 va_start(ap, arg);
4630 argv = lxc_va_arg_list_to_argv_const(ap, 1);
4631 va_end(ap);
4632
4633 if (!argv) {
4634 ERROR("Memory allocation error.");
858377e4
SH
4635 ret = -1;
4636 goto out;
a0e93eeb
CS
4637 }
4638 argv[0] = arg;
4639
858377e4 4640 ret = do_lxcapi_attach_run_wait(c, options, program, (const char * const *)argv);
a0e93eeb 4641 free((void*)argv);
858377e4
SH
4642out:
4643 current_config = NULL;
a0e93eeb
CS
4644 return ret;
4645}
4646
afeecbba 4647struct lxc_container *lxc_container_new(const char *name, const char *configpath)
72d0e1cb
SG
4648{
4649 struct lxc_container *c;
72d0e1cb 4650
18aa217b
SH
4651 if (!name)
4652 return NULL;
4653
72d0e1cb
SG
4654 c = malloc(sizeof(*c));
4655 if (!c) {
e9e29a33 4656 fprintf(stderr, "Failed to allocate memory for %s\n", name);
72d0e1cb
SG
4657 return NULL;
4658 }
4659 memset(c, 0, sizeof(*c));
4660
afeecbba
SH
4661 if (configpath)
4662 c->config_path = strdup(configpath);
4663 else
593e8478 4664 c->config_path = strdup(lxc_global_config_value("lxc.lxcpath"));
afeecbba 4665
2a59a681 4666 if (!c->config_path) {
e9e29a33 4667 fprintf(stderr, "Failed to allocate memory for %s\n", name);
2a59a681
SH
4668 goto err;
4669 }
4670
f5dd1d53 4671 remove_trailing_slashes(c->config_path);
72d0e1cb
SG
4672 c->name = malloc(strlen(name)+1);
4673 if (!c->name) {
e9e29a33 4674 fprintf(stderr, "Failed to allocate memory for %s\n", name);
72d0e1cb
SG
4675 goto err;
4676 }
4677 strcpy(c->name, name);
4678
4679 c->numthreads = 1;
e9e29a33
CB
4680 c->slock = lxc_newlock(c->config_path, name);
4681 if (!c->slock) {
4682 fprintf(stderr, "Failed to create lock for %s\n", name);
72d0e1cb
SG
4683 goto err;
4684 }
4685
e9e29a33
CB
4686 c->privlock = lxc_newlock(NULL, NULL);
4687 if (!c->privlock) {
4688 fprintf(stderr, "Failed to create private lock for %s\n", name);
72d0e1cb
SG
4689 goto err;
4690 }
4691
afeecbba 4692 if (!set_config_filename(c)) {
e9e29a33 4693 fprintf(stderr, "Failed to create config file name for %s\n", name);
72d0e1cb
SG
4694 goto err;
4695 }
72d0e1cb 4696
e9e29a33
CB
4697 if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) {
4698 fprintf(stderr, "Failed to load config for %s\n", name);
bac806d1 4699 goto err;
e9e29a33 4700 }
72d0e1cb 4701
3e625e2d 4702 if (ongoing_create(c) == 2) {
e9e29a33 4703 ERROR("Failed to complete container creation for %s", c->name);
17a367d8 4704 container_destroy(c, NULL);
4df7f012 4705 lxcapi_clear_config(c);
3e625e2d 4706 }
a2739df5 4707 c->daemonize = true;
72cf75fa 4708 c->pidfile = NULL;
3e625e2d 4709
1a0e70ac 4710 /* Assign the member functions. */
72d0e1cb
SG
4711 c->is_defined = lxcapi_is_defined;
4712 c->state = lxcapi_state;
4713 c->is_running = lxcapi_is_running;
4714 c->freeze = lxcapi_freeze;
4715 c->unfreeze = lxcapi_unfreeze;
0115f8fd 4716 c->console = lxcapi_console;
b5159817 4717 c->console_getfd = lxcapi_console_getfd;
72d0e1cb
SG
4718 c->init_pid = lxcapi_init_pid;
4719 c->load_config = lxcapi_load_config;
4720 c->want_daemonize = lxcapi_want_daemonize;
130a1888 4721 c->want_close_all_fds = lxcapi_want_close_all_fds;
72d0e1cb
SG
4722 c->start = lxcapi_start;
4723 c->startl = lxcapi_startl;
4724 c->stop = lxcapi_stop;
4725 c->config_file_name = lxcapi_config_file_name;
4726 c->wait = lxcapi_wait;
4727 c->set_config_item = lxcapi_set_config_item;
4728 c->destroy = lxcapi_destroy;
18aa217b 4729 c->destroy_with_snapshots = lxcapi_destroy_with_snapshots;
06e5650e 4730 c->rename = lxcapi_rename;
72d0e1cb
SG
4731 c->save_config = lxcapi_save_config;
4732 c->get_keys = lxcapi_get_keys;
4733 c->create = lxcapi_create;
4734 c->createl = lxcapi_createl;
4735 c->shutdown = lxcapi_shutdown;
3e625e2d 4736 c->reboot = lxcapi_reboot;
d39b10eb 4737 c->reboot2 = lxcapi_reboot2;
4df7f012 4738 c->clear_config = lxcapi_clear_config;
72d0e1cb
SG
4739 c->clear_config_item = lxcapi_clear_config_item;
4740 c->get_config_item = lxcapi_get_config_item;
8ac18377 4741 c->get_running_config_item = lxcapi_get_running_config_item;
794dd120
SH
4742 c->get_cgroup_item = lxcapi_get_cgroup_item;
4743 c->set_cgroup_item = lxcapi_set_cgroup_item;
2a59a681
SH
4744 c->get_config_path = lxcapi_get_config_path;
4745 c->set_config_path = lxcapi_set_config_path;
9be53773 4746 c->clone = lxcapi_clone;
799f29ab 4747 c->get_interfaces = lxcapi_get_interfaces;
9c83a661 4748 c->get_ips = lxcapi_get_ips;
a0e93eeb
CS
4749 c->attach = lxcapi_attach;
4750 c->attach_run_wait = lxcapi_attach_run_wait;
4751 c->attach_run_waitl = lxcapi_attach_run_waitl;
f5dd1d53
SH
4752 c->snapshot = lxcapi_snapshot;
4753 c->snapshot_list = lxcapi_snapshot_list;
4754 c->snapshot_restore = lxcapi_snapshot_restore;
771d96b3 4755 c->snapshot_destroy = lxcapi_snapshot_destroy;
18aa217b 4756 c->snapshot_destroy_all = lxcapi_snapshot_destroy_all;
b494d2dd 4757 c->may_control = lxcapi_may_control;
a9a0ed90
ÇO
4758 c->add_device_node = lxcapi_add_device_node;
4759 c->remove_device_node = lxcapi_remove_device_node;
e58fae8f
DY
4760 c->attach_interface = lxcapi_attach_interface;
4761 c->detach_interface = lxcapi_detach_interface;
735f2c6e
TA
4762 c->checkpoint = lxcapi_checkpoint;
4763 c->restore = lxcapi_restore;
aef3d51e 4764 c->migrate = lxcapi_migrate;
191d43cc 4765 c->console_log = lxcapi_console_log;
72d0e1cb 4766
72d0e1cb
SG
4767 return c;
4768
4769err:
4770 lxc_container_free(c);
4771 return NULL;
4772}
4773
4a7c7daa 4774int lxc_get_wait_states(const char **states)
72d0e1cb
SG
4775{
4776 int i;
4777
4778 if (states)
4779 for (i=0; i<MAX_STATE; i++)
4780 states[i] = lxc_state2str(i);
4781 return MAX_STATE;
4782}
a41f104b 4783
a41f104b
SH
4784/*
4785 * These next two could probably be done smarter with reusing a common function
4786 * with different iterators and tests...
4787 */
4788int list_defined_containers(const char *lxcpath, char ***names, struct lxc_container ***cret)
4789{
4790 DIR *dir;
4791 int i, cfound = 0, nfound = 0;
74f96976 4792 struct dirent *direntp;
a41f104b
SH
4793 struct lxc_container *c;
4794
4795 if (!lxcpath)
593e8478 4796 lxcpath = lxc_global_config_value("lxc.lxcpath");
a41f104b 4797
a41f104b 4798 dir = opendir(lxcpath);
a41f104b
SH
4799 if (!dir) {
4800 SYSERROR("opendir on lxcpath");
4801 return -1;
4802 }
4803
4804 if (cret)
4805 *cret = NULL;
4806 if (names)
4807 *names = NULL;
4808
74f96976 4809 while ((direntp = readdir(dir))) {
a41f104b
SH
4810 if (!direntp)
4811 break;
e4ebeab1 4812
1a0e70ac 4813 /* Ignore '.', '..' and any hidden directory. */
e4ebeab1 4814 if (!strncmp(direntp->d_name, ".", 1))
a41f104b
SH
4815 continue;
4816
4817 if (!config_file_exists(lxcpath, direntp->d_name))
4818 continue;
4819
4820 if (names) {
9c88ff1f 4821 if (!add_to_array(names, direntp->d_name, cfound))
a41f104b
SH
4822 goto free_bad;
4823 }
4824 cfound++;
4825
4826 if (!cret) {
4827 nfound++;
4828 continue;
4829 }
4830
4831 c = lxc_container_new(direntp->d_name, lxcpath);
4832 if (!c) {
4833 INFO("Container %s:%s has a config but could not be loaded",
4834 lxcpath, direntp->d_name);
4835 if (names)
9c88ff1f
ÇO
4836 if(!remove_from_array(names, direntp->d_name, cfound--))
4837 goto free_bad;
a41f104b
SH
4838 continue;
4839 }
858377e4 4840 if (!do_lxcapi_is_defined(c)) {
a41f104b
SH
4841 INFO("Container %s:%s has a config but is not defined",
4842 lxcpath, direntp->d_name);
4843 if (names)
9c88ff1f
ÇO
4844 if(!remove_from_array(names, direntp->d_name, cfound--))
4845 goto free_bad;
a41f104b
SH
4846 lxc_container_put(c);
4847 continue;
4848 }
4849
2871830a 4850 if (!add_to_clist(cret, c, nfound, true)) {
a41f104b
SH
4851 lxc_container_put(c);
4852 goto free_bad;
4853 }
4854 nfound++;
4855 }
4856
a41f104b 4857 closedir(dir);
a41f104b
SH
4858 return nfound;
4859
4860free_bad:
4861 if (names && *names) {
4862 for (i=0; i<cfound; i++)
4863 free((*names)[i]);
4864 free(*names);
4865 }
4866 if (cret && *cret) {
4867 for (i=0; i<nfound; i++)
4868 lxc_container_put((*cret)[i]);
4869 free(*cret);
4870 }
a41f104b 4871 closedir(dir);
a41f104b
SH
4872 return -1;
4873}
4874
148a9d27
DE
4875int list_active_containers(const char *lxcpath, char ***nret,
4876 struct lxc_container ***cret)
a41f104b 4877{
148a9d27 4878 int i, ret = -1, cret_cnt = 0, ct_name_cnt = 0;
a41f104b
SH
4879 int lxcpath_len;
4880 char *line = NULL;
148a9d27 4881 char **ct_name = NULL;
a41f104b 4882 size_t len = 0;
97bc2422 4883 struct lxc_container *c = NULL;
88556fd7 4884 bool is_hashed;
a41f104b
SH
4885
4886 if (!lxcpath)
593e8478 4887 lxcpath = lxc_global_config_value("lxc.lxcpath");
a41f104b
SH
4888 lxcpath_len = strlen(lxcpath);
4889
4890 if (cret)
4891 *cret = NULL;
148a9d27
DE
4892 if (nret)
4893 *nret = NULL;
a41f104b 4894
a41f104b 4895 FILE *f = fopen("/proc/net/unix", "r");
a41f104b
SH
4896 if (!f)
4897 return -1;
4898
4899 while (getline(&line, &len, f) != -1) {
88556fd7 4900
0f8f9c8a 4901 char *p = strrchr(line, ' '), *p2;
a41f104b
SH
4902 if (!p)
4903 continue;
4904 p++;
4905 if (*p != 0x40)
4906 continue;
4907 p++;
88556fd7
ÇO
4908
4909 is_hashed = false;
4910 if (strncmp(p, lxcpath, lxcpath_len) == 0) {
4911 p += lxcpath_len;
4912 } else if (strncmp(p, "lxc/", 4) == 0) {
4913 p += 4;
4914 is_hashed = true;
4915 } else {
a41f104b 4916 continue;
88556fd7
ÇO
4917 }
4918
a41f104b
SH
4919 while (*p == '/')
4920 p++;
4921
1a0e70ac 4922 /* Now p is the start of lxc_name. */
46cd2845 4923 p2 = strchr(p, '/');
a41f104b
SH
4924 if (!p2 || strncmp(p2, "/command", 8) != 0)
4925 continue;
4926 *p2 = '\0';
4927
88556fd7 4928 if (is_hashed) {
899a9f55
CB
4929 char *recvpath = lxc_cmd_get_lxcpath(p);
4930 if (!recvpath)
4931 continue;
4932 if (strncmp(lxcpath, recvpath, lxcpath_len) != 0)
88556fd7
ÇO
4933 continue;
4934 p = lxc_cmd_get_name(p);
ee2d7093
L
4935 if (!p)
4936 continue;
88556fd7
ÇO
4937 }
4938
148a9d27 4939 if (array_contains(&ct_name, p, ct_name_cnt))
9c88ff1f
ÇO
4940 continue;
4941
148a9d27
DE
4942 if (!add_to_array(&ct_name, p, ct_name_cnt))
4943 goto free_cret_list;
9c88ff1f 4944
148a9d27 4945 ct_name_cnt++;
a41f104b 4946
148a9d27 4947 if (!cret)
a41f104b 4948 continue;
a41f104b
SH
4949
4950 c = lxc_container_new(p, lxcpath);
4951 if (!c) {
4952 INFO("Container %s:%s is running but could not be loaded",
4953 lxcpath, p);
148a9d27 4954 remove_from_array(&ct_name, p, ct_name_cnt--);
a41f104b
SH
4955 continue;
4956 }
4957
4958 /*
4959 * If this is an anonymous container, then is_defined *can*
4960 * return false. So we don't do that check. Count on the
4961 * fact that the command socket exists.
4962 */
4963
148a9d27 4964 if (!add_to_clist(cret, c, cret_cnt, true)) {
a41f104b 4965 lxc_container_put(c);
148a9d27 4966 goto free_cret_list;
a41f104b 4967 }
148a9d27 4968 cret_cnt++;
a41f104b
SH
4969 }
4970
97bc2422
CB
4971 if (nret && cret && cret_cnt != ct_name_cnt) {
4972 if (c)
4973 lxc_container_put(c);
4974 goto free_cret_list;
4975 }
4976
148a9d27
DE
4977 ret = ct_name_cnt;
4978 if (nret)
4979 *nret = ct_name;
4980 else
4981 goto free_ct_name;
4982 goto out;
a41f104b 4983
148a9d27 4984free_cret_list:
a41f104b 4985 if (cret && *cret) {
148a9d27 4986 for (i = 0; i < cret_cnt; i++)
a41f104b
SH
4987 lxc_container_put((*cret)[i]);
4988 free(*cret);
4989 }
148a9d27
DE
4990
4991free_ct_name:
4992 if (ct_name) {
4993 for (i = 0; i < ct_name_cnt; i++)
4994 free(ct_name[i]);
4995 free(ct_name);
4996 }
4997
4998out:
f10fad2f 4999 free(line);
e853a32d 5000
a41f104b 5001 fclose(f);
148a9d27 5002 return ret;
a41f104b 5003}
2871830a
DE
5004
5005int list_all_containers(const char *lxcpath, char ***nret,
5006 struct lxc_container ***cret)
5007{
5008 int i, ret, active_cnt, ct_cnt, ct_list_cnt;
5009 char **active_name;
5010 char **ct_name;
5011 struct lxc_container **ct_list = NULL;
5012
5013 ct_cnt = list_defined_containers(lxcpath, &ct_name, NULL);
5014 if (ct_cnt < 0)
5015 return ct_cnt;
5016
5017 active_cnt = list_active_containers(lxcpath, &active_name, NULL);
5018 if (active_cnt < 0) {
5019 ret = active_cnt;
5020 goto free_ct_name;
5021 }
5022
5023 for (i = 0; i < active_cnt; i++) {
5024 if (!array_contains(&ct_name, active_name[i], ct_cnt)) {
5025 if (!add_to_array(&ct_name, active_name[i], ct_cnt)) {
5026 ret = -1;
5027 goto free_active_name;
5028 }
5029 ct_cnt++;
5030 }
5031 free(active_name[i]);
5032 active_name[i] = NULL;
5033 }
5034 free(active_name);
5035 active_name = NULL;
5036 active_cnt = 0;
5037
5038 for (i = 0, ct_list_cnt = 0; i < ct_cnt && cret; i++) {
5039 struct lxc_container *c;
5040
5041 c = lxc_container_new(ct_name[i], lxcpath);
5042 if (!c) {
5043 WARN("Container %s:%s could not be loaded", lxcpath, ct_name[i]);
5044 remove_from_array(&ct_name, ct_name[i], ct_cnt--);
5045 continue;
5046 }
5047
5048 if (!add_to_clist(&ct_list, c, ct_list_cnt, false)) {
5049 lxc_container_put(c);
5050 ret = -1;
5051 goto free_ct_list;
5052 }
5053 ct_list_cnt++;
5054 }
5055
5056 if (cret)
5057 *cret = ct_list;
5058
5059 if (nret)
5060 *nret = ct_name;
5061 else {
5062 ret = ct_cnt;
5063 goto free_ct_name;
5064 }
5065 return ct_cnt;
5066
5067free_ct_list:
5068 for (i = 0; i < ct_list_cnt; i++) {
5069 lxc_container_put(ct_list[i]);
5070 }
f10fad2f 5071 free(ct_list);
2871830a
DE
5072
5073free_active_name:
5074 for (i = 0; i < active_cnt; i++) {
f10fad2f 5075 free(active_name[i]);
2871830a 5076 }
f10fad2f 5077 free(active_name);
2871830a
DE
5078
5079free_ct_name:
5080 for (i = 0; i < ct_cnt; i++) {
5081 free(ct_name[i]);
5082 }
5083 free(ct_name);
5084 return ret;
5085}
12461428
CB
5086
5087bool lxc_config_item_is_supported(const char *key)
5088{
300df83e 5089 return !!lxc_get_config(key);
12461428 5090}