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