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