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