lxc_monitor_SOURCES = tools/lxc_monitor.c tools/arguments.c tools/tool_utils.c
lxc_ls_SOURCES = tools/lxc_ls.c tools/arguments.c tools/tool_utils.c
lxc_copy_SOURCES = tools/lxc_copy.c tools/arguments.c tools/tool_utils.c
-lxc_start_SOURCES = tools/lxc_start.c tools/arguments.c tools/tool_utils.c
+lxc_start_SOURCES = tools/lxc_start.c tools/arguments.c
lxc_stop_SOURCES = tools/lxc_stop.c tools/arguments.c tools/tool_utils.c
lxc_top_SOURCES = tools/lxc_top.c tools/arguments.c tools/tool_utils.c
lxc_unfreeze_SOURCES = tools/lxc_unfreeze.c tools/arguments.c tools/tool_utils.c
return ret;
}
-static int lxc_config_readline(char *buffer, struct lxc_conf *conf)
-{
- struct parse_line_conf c;
-
- c.conf = conf;
- c.from_include = false;
-
- return parse_line(buffer, &c);
-}
-
int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include)
{
int ret;
return 0;
}
-int lxc_config_define_load(struct lxc_list *defines, struct lxc_conf *conf)
+bool lxc_config_define_load(struct lxc_list *defines, struct lxc_container *c)
{
- struct lxc_list *it, *next;
- int ret = 0;
+ struct lxc_list *it;
+ bool bret = true;
lxc_list_for_each(it, defines) {
- ret = lxc_config_readline(it->elem, conf);
- if (ret)
+ struct new_config_item *new_item = it->elem;
+ bret = c->set_config_item(c, new_item->key, new_item->val);
+ if (!bret)
break;
}
+ lxc_config_define_free(defines);
+ return bret;
+}
+
+void lxc_config_define_free(struct lxc_list *defines)
+{
+ struct lxc_list *it, *next;
+
lxc_list_for_each_safe(it, defines, next) {
+ struct new_config_item *new_item = it->elem;
+ free(new_item->key);
+ free(new_item->val);
lxc_list_del(it);
free(it);
}
-
- return ret;
}
signed long lxc_config_parse_arch(const char *arch)
return -1;
}
+int lxc_fill_elevated_privileges(char *flaglist, int *flags)
+{
+ char *token, *saveptr = NULL;
+ int i, aflag;
+ struct {
+ const char *token;
+ int flag;
+ } all_privs[] = {
+ { "CGROUP", LXC_ATTACH_MOVE_TO_CGROUP },
+ { "CAP", LXC_ATTACH_DROP_CAPABILITIES },
+ { "LSM", LXC_ATTACH_LSM_EXEC },
+ { NULL, 0 }
+ };
+
+ if (!flaglist) {
+ /* For the sake of backward compatibility, drop all privileges
+ * if none is specified.
+ */
+ for (i = 0; all_privs[i].token; i++)
+ *flags |= all_privs[i].flag;
+
+ return 0;
+ }
+
+ token = strtok_r(flaglist, "|", &saveptr);
+ while (token) {
+ aflag = -1;
+
+ for (i = 0; all_privs[i].token; i++)
+ if (!strcmp(all_privs[i].token, token))
+ aflag = all_privs[i].flag;
+
+ if (aflag < 0)
+ return -1;
+
+ *flags |= aflag;
+
+ token = strtok_r(NULL, "|", &saveptr);
+ }
+
+ return 0;
+}
+
/* Write out a configuration file. */
int write_config(int fd, const struct lxc_conf *conf)
{
config_clr_cb clr;
};
+struct new_config_item {
+ char *key;
+ char *val;
+};
+
/* Get the jump table entry for the given configuration key. */
extern struct lxc_config_t *lxc_get_config(const char *key);
extern int lxc_config_define_add(struct lxc_list *defines, char* arg);
-extern int lxc_config_define_load(struct lxc_list *defines,
- struct lxc_conf *conf);
+extern bool lxc_config_define_load(struct lxc_list *defines,
+ struct lxc_container *c);
+
+extern void lxc_config_define_free(struct lxc_list *defines);
/* needed for lxc-attach */
extern signed long lxc_config_parse_arch(const char *arch);
+extern int lxc_fill_elevated_privileges(char *flaglist, int *flags);
+
extern int lxc_clear_config_item(struct lxc_conf *c, const char *key);
extern int write_config(int fd, const struct lxc_conf *conf);
extern bool lxc_setup_shared_ns(struct lxc_arguments *args, struct lxc_container *c);
-/* Helper macro to define errno string. */
-#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE) || IS_BIONIC
-#define lxc_log_strerror_r \
- char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \
- char *ptr = errno_buf; \
- { \
- (void)strerror_r(errno, errno_buf, sizeof(errno_buf)); \
- }
-#else
-#define lxc_log_strerror_r \
- char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \
- char *ptr; \
- { \
- ptr = strerror_r(errno, errno_buf, sizeof(errno_buf)); \
- if (!ptr) \
- ptr = errno_buf; \
- }
-#endif
-
#define lxc_info(arg, fmt, args...) \
do { \
if (!(arg)->quiet) { \
#define lxc_sys_error(arg, fmt, args...) \
do { \
if (!(arg)->quiet) { \
- lxc_log_strerror_r \
- fprintf(stderr, "%s: %s - " fmt "\n", (arg)->progname, ptr, ##args); \
+ fprintf(stderr, "%s: " fmt "\n", (arg)->progname, ##args); \
} \
} while (0)
#include <lxc/lxccontainer.h>
#include "arguments.h"
-#include "tool_list.h"
-#include "tool_utils.h"
+#include "caps.h"
+#include "confile.h"
+#include "log.h"
static struct lxc_list defines;
+lxc_log_define(lxc_start, lxc);
+
static int ensure_path(struct lxc_arguments *args, char **confpath, const char *path)
{
int err = -1, fd;
if (access(path, W_OK)) {
fd = creat(path, 0600);
if (fd < 0 && errno != EEXIST) {
- lxc_error(args, "Failed to create '%s'", path);
+ ERROR("Failed to create '%s'", path);
goto err;
}
fullpath = realpath(path, NULL);
if (!fullpath) {
- lxc_error(args, "Failed to get the real path of '%s'", path);
+ ERROR("Failed to get the real path of '%s'", path);
goto err;
}
lxcpath = my_args.lxcpath[0];
if (access(lxcpath, O_RDONLY) < 0) {
- lxc_error(&my_args, "You lack access to %s", lxcpath);
+ ERROR("You lack access to %s", lxcpath);
exit(err);
}
c = lxc_container_new(my_args.name, lxcpath);
if (!c) {
- lxc_error(&my_args, "Failed to create lxc_container");
+ ERROR("Failed to create lxc_container");
exit(err);
}
c->clear_config(c);
if (!c->load_config(c, rcfile)) {
- lxc_error(&my_args, "Failed to load rcfile");
+ ERROR("Failed to load rcfile");
lxc_container_put(c);
exit(err);
}
c->configfile = strdup(my_args.rcfile);
if (!c->configfile) {
- lxc_error(&my_args, "Out of memory setting new config filename");
+ ERROR("Out of memory setting new config filename");
goto out;
}
} else {
rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name);
if (rc == -1) {
- lxc_error(&my_args, "Failed to allocate memory");
+ ERROR("Failed to allocate memory");
exit(err);
}
c = lxc_container_new(my_args.name, lxcpath);
if (!c) {
- lxc_error(&my_args, "Failed to create lxc_container");
+ ERROR("Failed to create lxc_container");
exit(err);
}
}
* file as argument and start the container right away.
*/
if (!c->may_control(c)) {
- lxc_error(&my_args, "Insufficent privileges to control %s", c->name);
+ ERROR("Insufficent privileges to control %s", c->name);
goto out;
}
if (c->is_running(c)) {
- lxc_error(&my_args, "Container is already running.");
+ ERROR("Container is already running.");
err = EXIT_SUCCESS;
goto out;
}
* unset c->lxc_conf for us and let us not use lxc_config_define_load()
*/
if (!c->lxc_conf) {
- lxc_error(&my_args, "No container config specified");
+ ERROR("No container config specified");
goto out;
}
goto out;
if (!rcfile && !strcmp("/sbin/init", args[0])) {
- lxc_error(&my_args, "Executing '/sbin/init' with no configuration file may crash the host");
+ ERROR("Executing '/sbin/init' with no configuration file may crash the host");
goto out;
}
if (my_args.pidfile != NULL) {
if (ensure_path(&my_args, &c->pidfile, my_args.pidfile) < 0) {
- lxc_error(&my_args, "Failed to ensure pidfile '%s'", my_args.pidfile);
+ ERROR("Failed to ensure pidfile '%s'", my_args.pidfile);
goto out;
}
}
else
err = c->start(c, 0, args) ? EXIT_SUCCESS : EXIT_FAILURE;
if (err) {
- lxc_error(&my_args, "The container failed to start.");
+ ERROR("The container failed to start.");
if (my_args.daemonize)
- lxc_error(&my_args, "To get more details, run the container in foreground mode.");
+ ERROR("To get more details, run the container in foreground mode.");
- lxc_error(&my_args, "Additional information can be obtained by setting the "
- "--logfile and --logpriority options.\n");
+ ERROR("Additional information can be obtained by setting the "
+ "--logfile and --logpriority options.");
err = c->error_num;
lxc_container_put(c);