#include "conf.h"
#include "config.h"
#include "confile.h"
-#include "confile_legacy.h"
#include "confile_utils.h"
#include "log.h"
#include "lxcseccomp.h"
#include <sys/personality.h>
#endif
+#ifndef HAVE_STRLCPY
+#include "include/strlcpy.h"
+#endif
+
lxc_log_define(lxc_confile, lxc);
#define lxc_config_define(name) \
lxc_config_define(cap_drop);
lxc_config_define(cap_keep);
lxc_config_define(cgroup_controller);
+lxc_config_define(cgroup2_controller);
lxc_config_define(cgroup_dir);
-lxc_config_define(console_logfile);
-lxc_config_define(console_rotate);
-lxc_config_define(console_buffer_logfile);
lxc_config_define(console_buffer_size);
+lxc_config_define(console_logfile);
lxc_config_define(console_path);
+lxc_config_define(console_rotate);
+lxc_config_define(console_size);
lxc_config_define(environment);
lxc_config_define(ephemeral);
lxc_config_define(execute_cmd);
lxc_config_define(group);
lxc_config_define(hooks);
+lxc_config_define(hooks_version);
lxc_config_define(idmaps);
lxc_config_define(includefiles);
lxc_config_define(init_cmd);
lxc_config_define(mount);
lxc_config_define(mount_auto);
lxc_config_define(mount_fstab);
-lxc_config_define(namespace);
+lxc_config_define(namespace_clone);
+lxc_config_define(namespace_keep);
+lxc_config_define(namespace_share);
lxc_config_define(net);
lxc_config_define(net_flags);
lxc_config_define(net_hwaddr);
lxc_config_define(net_veth_pair);
lxc_config_define(net_vlan_id);
lxc_config_define(no_new_privs);
-lxc_config_define(noop);
lxc_config_define(personality);
lxc_config_define(prlimit);
lxc_config_define(pty_max);
-lxc_config_define(rootfs_backend);
lxc_config_define(rootfs_mount);
lxc_config_define(rootfs_options);
lxc_config_define(rootfs_path);
lxc_config_define(tty_dir);
lxc_config_define(uts_name);
lxc_config_define(sysctl);
+lxc_config_define(proc);
static struct lxc_config_t config[] = {
- /* REMOVE in LXC 3.0 */
- { "lxc.arch", false, set_config_personality, get_config_personality, clr_config_personality, },
- { "lxc.apparmor.profile", false, set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, },
- { "lxc.apparmor.allow_incomplete", false, set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, },
- { "lxc.autodev", false, set_config_autodev, get_config_autodev, clr_config_autodev, },
- { "lxc.cap.drop", false, set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, },
- { "lxc.cap.keep", false, set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, },
- { "lxc.cgroup.dir", false, set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, },
- { "lxc.cgroup", false, set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, },
- { "lxc.console.buffer.logfile", false, set_config_console_buffer_logfile, get_config_console_buffer_logfile, clr_config_console_buffer_logfile, },
- { "lxc.console.buffer.size", false, set_config_console_buffer_size, get_config_console_buffer_size, clr_config_console_buffer_size, },
- { "lxc.console.logfile", false, set_config_console_logfile, get_config_console_logfile, clr_config_console_logfile, },
- { "lxc.console.path", false, set_config_console_path, get_config_console_path, clr_config_console_path, },
- { "lxc.console.rotate", false, set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, },
- { "lxc.environment", false, set_config_environment, get_config_environment, clr_config_environment, },
- { "lxc.ephemeral", false, set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, },
- { "lxc.execute.cmd", false, set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, },
- { "lxc.group", false, set_config_group, get_config_group, clr_config_group, },
- { "lxc.hook.autodev", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.clone", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.destroy", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.mount", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.post-stop", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.start-host", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.pre-start", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.pre-mount", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.start", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook.stop", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.hook", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
- { "lxc.idmap", false, set_config_idmaps, get_config_idmaps, clr_config_idmaps, },
- { "lxc.include", false, set_config_includefiles, get_config_includefiles, clr_config_includefiles, },
- { "lxc.init.cmd", false, set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
- { "lxc.init.gid", false, set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
- { "lxc.init.uid", false, set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
- { "lxc.init.cwd", false, set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
- { "lxc.log.file", false, set_config_log_file, get_config_log_file, clr_config_log_file, },
- { "lxc.log.level", false, set_config_log_level, get_config_log_level, clr_config_log_level, },
- { "lxc.log.syslog", false, set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, },
- { "lxc.monitor.unshare", false, set_config_monitor, get_config_monitor, clr_config_monitor, },
- { "lxc.mount.auto", false, set_config_mount_auto, get_config_mount_auto, clr_config_mount_auto, },
- { "lxc.mount.entry", false, set_config_mount, get_config_mount, clr_config_mount, },
- { "lxc.mount.fstab", false, set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, },
- { "lxc.namespace", false, set_config_namespace, get_config_namespace, clr_config_namespace, },
-
- /* [START]: REMOVE IN LXC 3.0 */
- { "lxc.network.type", true, set_config_network_legacy_type, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.flags", true, set_config_network_legacy_flags, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.link", true, set_config_network_legacy_link, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.name", true, set_config_network_legacy_name, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.macvlan.mode", true, set_config_network_legacy_macvlan_mode, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.veth.pair", true, set_config_network_legacy_veth_pair, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.script.up", true, set_config_network_legacy_script_up, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.script.down", true, set_config_network_legacy_script_down, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.hwaddr", true, set_config_network_legacy_hwaddr, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.mtu", true, set_config_network_legacy_mtu, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.vlan.id", true, set_config_network_legacy_vlan_id, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.ipv4.gateway", true, set_config_network_legacy_ipv4_gateway, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.ipv4", true, set_config_network_legacy_ipv4, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.ipv6.gateway", true, set_config_network_legacy_ipv6_gateway, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.ipv6", true, set_config_network_legacy_ipv6, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network.", true, set_config_network_legacy_nic, get_config_network_legacy_item, clr_config_network_legacy_item, },
- { "lxc.network", true, set_config_network_legacy, get_config_network_legacy, clr_config_network_legacy, },
- /* [END]: REMOVE IN LXC 3.0 */
-
- { "lxc.net.flags", false, set_config_net_flags, get_config_net_flags, clr_config_net_flags, },
- { "lxc.net.hwaddr", false, set_config_net_hwaddr, get_config_net_hwaddr, clr_config_net_hwaddr, },
- { "lxc.net.ipv4.address", false, set_config_net_ipv4_address, get_config_net_ipv4_address, clr_config_net_ipv4_address, },
- { "lxc.net.ipv4.gateway", false, set_config_net_ipv4_gateway, get_config_net_ipv4_gateway, clr_config_net_ipv4_gateway, },
- { "lxc.net.ipv6.address", false, set_config_net_ipv6_address, get_config_net_ipv6_address, clr_config_net_ipv6_address, },
- { "lxc.net.ipv6.gateway", false, set_config_net_ipv6_gateway, get_config_net_ipv6_gateway, clr_config_net_ipv6_gateway, },
- { "lxc.net.link", false, set_config_net_link, get_config_net_link, clr_config_net_link, },
- { "lxc.net.macvlan.mode", false, set_config_net_macvlan_mode, get_config_net_macvlan_mode, clr_config_net_macvlan_mode, },
- { "lxc.net.mtu", false, set_config_net_mtu, get_config_net_mtu, clr_config_net_mtu, },
- { "lxc.net.name", false, set_config_net_name, get_config_net_name, clr_config_net_name, },
- { "lxc.net.script.down", false, set_config_net_script_down, get_config_net_script_down, clr_config_net_script_down, },
- { "lxc.net.script.up", false, set_config_net_script_up, get_config_net_script_up, clr_config_net_script_up, },
- { "lxc.net.type", false, set_config_net_type, get_config_net_type, clr_config_net_type, },
- { "lxc.net.vlan.id", false, set_config_net_vlan_id, get_config_net_vlan_id, clr_config_net_vlan_id, },
- { "lxc.net.veth.pair", false, set_config_net_veth_pair, get_config_net_veth_pair, clr_config_net_veth_pair, },
- { "lxc.net.", false, set_config_net_nic, get_config_net_nic, clr_config_net_nic, },
- { "lxc.net", false, set_config_net, get_config_net, clr_config_net, },
- { "lxc.no_new_privs", false, set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, },
- { "lxc.prlimit", false, set_config_prlimit, get_config_prlimit, clr_config_prlimit, },
- { "lxc.pty.max", false, set_config_pty_max, get_config_pty_max, clr_config_pty_max, },
- { "lxc.rootfs.mount", false, set_config_rootfs_mount, get_config_rootfs_mount, clr_config_rootfs_mount, },
- { "lxc.rootfs.options", false, set_config_rootfs_options, get_config_rootfs_options, clr_config_rootfs_options, },
- { "lxc.rootfs.path", false, set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, },
- { "lxc.seccomp.profile", false, set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, },
- { "lxc.selinux.context", false, set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, },
- { "lxc.signal.halt", false, set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, },
- { "lxc.signal.reboot", false, set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, },
- { "lxc.signal.stop", false, set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, },
- { "lxc.start.auto", false, set_config_start, get_config_start, clr_config_start, },
- { "lxc.start.delay", false, set_config_start, get_config_start, clr_config_start, },
- { "lxc.start.order", false, set_config_start, get_config_start, clr_config_start, },
- { "lxc.tty.dir", false, set_config_tty_dir, get_config_tty_dir, clr_config_tty_dir, },
- { "lxc.tty.max", false, set_config_tty_max, get_config_tty_max, clr_config_tty_max, },
- { "lxc.uts.name", false, set_config_uts_name, get_config_uts_name, clr_config_uts_name, },
- { "lxc.sysctl", false, set_config_sysctl, get_config_sysctl, clr_config_sysctl, },
-
- /* [START]: REMOVE IN LXC 3.0 */
- { "lxc.pts", true, set_config_pty_max, get_config_pty_max, clr_config_pty_max, },
- { "lxc.devttydir", true, set_config_tty_dir, get_config_tty_dir, clr_config_tty_dir, },
- { "lxc.tty", true, set_config_tty_max, get_config_tty_max, clr_config_tty_max, },
- { "lxc.aa_profile", true, set_config_lsm_aa_profile, get_config_lsm_aa_profile, clr_config_lsm_aa_profile, },
- { "lxc.aa_allow_incomplete", true, set_config_lsm_aa_incomplete, get_config_lsm_aa_incomplete, clr_config_lsm_aa_incomplete, },
- { "lxc.se_context", true, set_config_lsm_se_context, get_config_lsm_se_context, clr_config_lsm_se_context, },
- { "lxc.id_map", true, set_config_idmaps, get_config_idmaps, clr_config_idmaps, },
- { "lxc.mount", true, set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, },
- { "lxc.rootfs.backend", true, set_config_rootfs_backend, get_config_rootfs_backend, clr_config_rootfs_backend, },
- { "lxc.rootfs", true, set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, },
- { "lxc.utsname", true, set_config_uts_name, get_config_uts_name, clr_config_uts_name, },
- { "lxc.seccomp", true, set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, },
- { "lxc.console", true, set_config_console_path, get_config_console_path, clr_config_console_path, },
- { "lxc.haltsignal", true, set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, },
- { "lxc.rebootsignal", true, set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, },
- { "lxc.stopsignal", true, set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, },
- { "lxc.syslog", true, set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, },
- { "lxc.kmsg", true, set_config_noop, get_config_noop, clr_config_noop, },
- { "lxc.loglevel", true, set_config_log_level, get_config_log_level, clr_config_log_level, },
- { "lxc.logfile", true, set_config_log_file, get_config_log_file, clr_config_log_file, },
- { "lxc.init_cmd", true, set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
- { "lxc.init_uid", true, set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
- { "lxc.init_gid", true, set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
- { "lxc.limit", true, set_config_limit, get_config_limit, clr_config_limit, },
- { "lxc.pivotdir", true, set_config_noop, get_config_noop, clr_config_noop, },
- /* [END]: REMOVE IN LXC 3.0 */
+ { "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, },
+ { "lxc.apparmor.profile", set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, },
+ { "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, },
+ { "lxc.autodev", set_config_autodev, get_config_autodev, clr_config_autodev, },
+ { "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, },
+ { "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, },
+ { "lxc.cgroup2", set_config_cgroup2_controller, get_config_cgroup2_controller, clr_config_cgroup2_controller, },
+ { "lxc.cgroup.dir", set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, },
+ { "lxc.cgroup", set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, },
+ { "lxc.console.buffer.size", set_config_console_buffer_size, get_config_console_buffer_size, clr_config_console_buffer_size, },
+ { "lxc.console.logfile", set_config_console_logfile, get_config_console_logfile, clr_config_console_logfile, },
+ { "lxc.console.path", set_config_console_path, get_config_console_path, clr_config_console_path, },
+ { "lxc.console.rotate", set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, },
+ { "lxc.console.size", set_config_console_size, get_config_console_size, clr_config_console_size, },
+ { "lxc.environment", set_config_environment, get_config_environment, clr_config_environment, },
+ { "lxc.ephemeral", set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, },
+ { "lxc.execute.cmd", set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, },
+ { "lxc.group", set_config_group, get_config_group, clr_config_group, },
+ { "lxc.hook.autodev", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.clone", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.destroy", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.mount", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.post-stop", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.pre-mount", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.pre-start", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.start", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.start-host", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.stop", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.hook.version", set_config_hooks_version, get_config_hooks_version, clr_config_hooks_version, },
+ { "lxc.hook", set_config_hooks, get_config_hooks, clr_config_hooks, },
+ { "lxc.idmap", set_config_idmaps, get_config_idmaps, clr_config_idmaps, },
+ { "lxc.include", set_config_includefiles, get_config_includefiles, clr_config_includefiles, },
+ { "lxc.init.cmd", set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
+ { "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
+ { "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
+ { "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
+ { "lxc.log.file", set_config_log_file, get_config_log_file, clr_config_log_file, },
+ { "lxc.log.level", set_config_log_level, get_config_log_level, clr_config_log_level, },
+ { "lxc.log.syslog", set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, },
+ { "lxc.monitor.unshare", set_config_monitor, get_config_monitor, clr_config_monitor, },
+ { "lxc.mount.auto", set_config_mount_auto, get_config_mount_auto, clr_config_mount_auto, },
+ { "lxc.mount.entry", set_config_mount, get_config_mount, clr_config_mount, },
+ { "lxc.mount.fstab", set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, },
+ { "lxc.namespace.clone", set_config_namespace_clone, get_config_namespace_clone, clr_config_namespace_clone, },
+ { "lxc.namespace.keep", set_config_namespace_keep, get_config_namespace_keep, clr_config_namespace_keep, },
+ { "lxc.namespace.share", set_config_namespace_share, get_config_namespace_share, clr_config_namespace_share, },
+ { "lxc.net.flags", set_config_net_flags, get_config_net_flags, clr_config_net_flags, },
+ { "lxc.net.hwaddr", set_config_net_hwaddr, get_config_net_hwaddr, clr_config_net_hwaddr, },
+ { "lxc.net.ipv4.address", set_config_net_ipv4_address, get_config_net_ipv4_address, clr_config_net_ipv4_address, },
+ { "lxc.net.ipv4.gateway", set_config_net_ipv4_gateway, get_config_net_ipv4_gateway, clr_config_net_ipv4_gateway, },
+ { "lxc.net.ipv6.address", set_config_net_ipv6_address, get_config_net_ipv6_address, clr_config_net_ipv6_address, },
+ { "lxc.net.ipv6.gateway", set_config_net_ipv6_gateway, get_config_net_ipv6_gateway, clr_config_net_ipv6_gateway, },
+ { "lxc.net.link", set_config_net_link, get_config_net_link, clr_config_net_link, },
+ { "lxc.net.macvlan.mode", set_config_net_macvlan_mode, get_config_net_macvlan_mode, clr_config_net_macvlan_mode, },
+ { "lxc.net.mtu", set_config_net_mtu, get_config_net_mtu, clr_config_net_mtu, },
+ { "lxc.net.name", set_config_net_name, get_config_net_name, clr_config_net_name, },
+ { "lxc.net.script.down", set_config_net_script_down, get_config_net_script_down, clr_config_net_script_down, },
+ { "lxc.net.script.up", set_config_net_script_up, get_config_net_script_up, clr_config_net_script_up, },
+ { "lxc.net.type", set_config_net_type, get_config_net_type, clr_config_net_type, },
+ { "lxc.net.vlan.id", set_config_net_vlan_id, get_config_net_vlan_id, clr_config_net_vlan_id, },
+ { "lxc.net.veth.pair", set_config_net_veth_pair, get_config_net_veth_pair, clr_config_net_veth_pair, },
+ { "lxc.net.", set_config_net_nic, get_config_net_nic, clr_config_net_nic, },
+ { "lxc.net", set_config_net, get_config_net, clr_config_net, },
+ { "lxc.no_new_privs", set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, },
+ { "lxc.prlimit", set_config_prlimit, get_config_prlimit, clr_config_prlimit, },
+ { "lxc.pty.max", set_config_pty_max, get_config_pty_max, clr_config_pty_max, },
+ { "lxc.rootfs.mount", set_config_rootfs_mount, get_config_rootfs_mount, clr_config_rootfs_mount, },
+ { "lxc.rootfs.options", set_config_rootfs_options, get_config_rootfs_options, clr_config_rootfs_options, },
+ { "lxc.rootfs.path", set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, },
+ { "lxc.seccomp.profile", set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, },
+ { "lxc.selinux.context", set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, },
+ { "lxc.signal.halt", set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, },
+ { "lxc.signal.reboot", set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, },
+ { "lxc.signal.stop", set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, },
+ { "lxc.start.auto", set_config_start, get_config_start, clr_config_start, },
+ { "lxc.start.delay", set_config_start, get_config_start, clr_config_start, },
+ { "lxc.start.order", set_config_start, get_config_start, clr_config_start, },
+ { "lxc.tty.dir", set_config_tty_dir, get_config_tty_dir, clr_config_tty_dir, },
+ { "lxc.tty.max", set_config_tty_max, get_config_tty_max, clr_config_tty_max, },
+ { "lxc.uts.name", set_config_uts_name, get_config_uts_name, clr_config_uts_name, },
+ { "lxc.sysctl", set_config_sysctl, get_config_sysctl, clr_config_sysctl, },
+ { "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, },
};
struct signame {
/* No prefix specified, determine it from the network class. */
if (prefix) {
ret = lxc_safe_uint(prefix, &inetdev->prefix);
- if (ret < 0)
+ if (ret < 0) {
+ free(inetdev);
+ free(list);
+ free(addr);
return -1;
+ }
} else {
inetdev->prefix = config_ip_prefix(&inetdev->addr);
}
if (slash) {
*slash = '\0';
netmask = slash + 1;
- if (lxc_safe_uint(netmask, &inet6dev->prefix) < 0)
+ ret = lxc_safe_uint(netmask, &inet6dev->prefix);
+ if (ret < 0) {
+ free(list);
+ free(inet6dev);
+ free(valdup);
return -1;
+ }
}
ret = inet_pton(AF_INET6, valdup, &inet6dev->addr);
return -1;
}
+static int set_config_hooks_version(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ int ret;
+ unsigned int tmp;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_hooks_version(key, lxc_conf, NULL);
+
+ ret = lxc_safe_uint(value, &tmp);
+ if (ret < 0)
+ return -1;
+
+ if (tmp > 1) {
+ ERROR("Invalid hook version specified. Currently only 0 "
+ "(legacy) and 1 are supported");
+ return -1;
+ }
+
+ lxc_conf->hooks_version = tmp;
+ return 0;
+}
+
static int set_config_personality(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
static int set_config_pty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ int ret;
+ unsigned int max = 0;
+
if (lxc_config_value_empty(value)) {
- lxc_conf->pts = 0;
+ lxc_conf->pty_max = 0;
return 0;
}
- if (lxc_safe_uint(value, &lxc_conf->pts) < 0)
+ ret = lxc_safe_uint(value, &max);
+ if (ret < 0)
return -1;
+ lxc_conf->pty_max = max;
return 0;
}
if (!list_item)
goto on_error;
- list_item->elem = strdup(value);
+ if (!strchr(value, '=')) {
+ const char *env_val;
+ const char *env_key = value;
+ const char *env_var[3] = {0};
+
+ env_val = getenv(env_key);
+ if (!env_val)
+ goto on_error;
+
+ env_var[0] = env_key;
+ env_var[1] = env_val;
+ list_item->elem = lxc_string_join("=", env_var, false);
+ } else {
+ list_item->elem = strdup(value);
+ }
if (!list_item->elem)
goto on_error;
static int set_config_tty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ int ret;
+ unsigned int nbtty = 0;
+
if (lxc_config_value_empty(value)) {
- lxc_conf->tty = 0;
+ lxc_conf->ttys.max = 0;
return 0;
}
- return lxc_safe_uint(value, &lxc_conf->tty);
+ ret = lxc_safe_uint(value, &nbtty);
+ if (ret < 0)
+ return -1;
+
+ lxc_conf->ttys.max = nbtty;
+ return 0;
}
static int set_config_tty_dir(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- return set_config_string_item_max(&lxc_conf->ttydir, value,
+ return set_config_string_item_max(&lxc_conf->ttys.dir, value,
NAME_MAX + 1);
}
return 0;
}
-static int set_config_cgroup_controller(const char *key, const char *value,
- struct lxc_conf *lxc_conf, void *data)
+static int __set_config_cgroup_controller(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, int version)
{
- char *subkey;
- char *token = "lxc.cgroup.";
+ const char *subkey, *token;
+ size_t token_len;
struct lxc_list *cglist = NULL;
struct lxc_cgroup *cgelem = NULL;
if (lxc_config_value_empty(value))
- return lxc_clear_cgroups(lxc_conf, key);
-
- subkey = strstr(key, token);
- if (!subkey)
- return -1;
-
- if (!strlen(subkey))
- return -1;
+ return lxc_clear_cgroups(lxc_conf, key, version);
+
+ if (version == CGROUP2_SUPER_MAGIC) {
+ token = "lxc.cgroup2.";
+ token_len = 12;
+ } else if (version == CGROUP_SUPER_MAGIC) {
+ token = "lxc.cgroup.";
+ token_len = 11;
+ } else {
+ return -EINVAL;
+ }
- if (strlen(subkey) == strlen(token))
- return -1;
+ if (strncmp(key, token, token_len) != 0)
+ return -EINVAL;
- subkey += strlen(token);
+ subkey = key + token_len;
+ if (*subkey == '\0')
+ return -EINVAL;
cglist = malloc(sizeof(*cglist));
if (!cglist)
memset(cgelem, 0, sizeof(*cgelem));
cgelem->subsystem = strdup(subkey);
- cgelem->value = strdup(value);
+ if (!cgelem->subsystem)
+ goto out;
- if (!cgelem->subsystem || !cgelem->value)
+ cgelem->value = strdup(value);
+ if (!cgelem->value)
goto out;
- cglist->elem = cgelem;
+ cgelem->version = version;
+
+ lxc_list_add_elem(cglist, cgelem);
- lxc_list_add_tail(&lxc_conf->cgroup, cglist);
+ if (version == CGROUP2_SUPER_MAGIC)
+ lxc_list_add_tail(&lxc_conf->cgroup2, cglist);
+ else
+ lxc_list_add_tail(&lxc_conf->cgroup, cglist);
return 0;
return -1;
}
+static int set_config_cgroup_controller(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ return __set_config_cgroup_controller(key, value, lxc_conf,
+ CGROUP_SUPER_MAGIC);
+}
+
+static int set_config_cgroup2_controller(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ return __set_config_cgroup_controller(key, value, lxc_conf,
+ CGROUP2_SUPER_MAGIC);
+}
+
+
static int set_config_cgroup_dir(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
struct lxc_conf *lxc_conf, void *data)
{
struct lxc_list *iter;
+ char *replace_value = NULL;
struct lxc_list *sysctl_list = NULL;
struct lxc_sysctl *sysctl_elem = NULL;
- char *replace_value = NULL;
if (lxc_config_value_empty(value))
- return lxc_clear_sysctls(lxc_conf, key);
+ return clr_config_sysctl(key, lxc_conf, NULL);
if (strncmp(key, "lxc.sysctl.", sizeof("lxc.sysctl.") - 1) != 0)
return -1;
/* find existing list element */
lxc_list_for_each(iter, &lxc_conf->sysctls) {
sysctl_elem = iter->elem;
- if (strcmp(key, sysctl_elem->key) == 0) {
- replace_value = strdup(value);
- if (!replace_value)
- return -1;
- free(sysctl_elem->value);
- sysctl_elem->value = replace_value;
- return 0;
- }
+
+ if (strcmp(key, sysctl_elem->key) != 0)
+ continue;
+
+ replace_value = strdup(value);
+ if (!replace_value)
+ return -1;
+
+ free(sysctl_elem->value);
+ sysctl_elem->value = replace_value;
+ return 0;
}
/* allocate list element */
free(sysctl_elem);
}
return -1;
+}
+
+static int set_config_proc(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ const char *subkey;
+ struct lxc_list *proclist = NULL;
+ struct lxc_proc *procelem = NULL;
+ if (lxc_config_value_empty(value))
+ return clr_config_proc(key, lxc_conf, NULL);
+ if (strncmp(key, "lxc.proc.", sizeof("lxc.proc.") -1) != 0)
+ return -1;
+
+ subkey = key + sizeof("lxc.proc.") - 1;
+ if (*subkey == '\0')
+ return -EINVAL;
+
+ proclist = malloc(sizeof(*proclist));
+ if (!proclist)
+ goto on_error;
+
+ procelem = malloc(sizeof(*procelem));
+ if (!procelem)
+ goto on_error;
+ memset(procelem, 0, sizeof(*procelem));
+
+ procelem->filename = strdup(subkey);
+ procelem->value = strdup(value);
+
+ if (!procelem->filename || !procelem->value)
+ goto on_error;
+
+ proclist->elem = procelem;
+
+ lxc_list_add_tail(&lxc_conf->procs, proclist);
+
+ return 0;
+
+on_error:
+ free(proclist);
+ if (procelem) {
+ free(procelem->filename);
+ free(procelem->value);
+ free(procelem);
+ }
+
+ return -1;
}
static int set_config_idmaps(const char *key, const char *value,
memset(idmap, 0, sizeof(*idmap));
ret = parse_idmaps(value, &type, &nsid, &hostid, &range);
- if (ret < 0)
+ if (ret < 0) {
+ ERROR("Failed to parse id mappings");
goto on_error;
+ }
INFO("Read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, hostid, range);
if (type == 'u')
idmap->range = range;
idmaplist->elem = idmap;
lxc_list_add_tail(&lxc_conf->id_map, idmaplist);
+
+ if (!lxc_conf->root_nsuid_map && idmap->idtype == ID_TYPE_UID)
+ if (idmap->nsid == 0)
+ lxc_conf->root_nsuid_map = idmap;
+
+
+ if (!lxc_conf->root_nsgid_map && idmap->idtype == ID_TYPE_GID)
+ if (idmap->nsid == 0)
+ lxc_conf->root_nsgid_map = idmap;
+
idmap = NULL;
return 0;
int mask;
int flag;
} allowed_auto_mounts[] = {
- { "proc", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
- { "proc:mixed", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
- { "proc:rw", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW },
- { "sys", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
- { "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO },
- { "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
- { "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW },
- { "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC },
- { "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED },
- { "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO },
- { "cgroup:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW },
- { "cgroup-full", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC },
- { "cgroup-full:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED },
- { "cgroup-full:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO },
- { "cgroup-full:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW },
+ { "proc", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
+ { "proc:mixed", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
+ { "proc:rw", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW },
+ { "sys", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
+ { "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO },
+ { "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
+ { "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW },
+ { "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC },
+ { "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED },
+ { "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO },
+ { "cgroup:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW },
+ { "cgroup:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup-full", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC },
+ { "cgroup-full:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED },
+ { "cgroup-full:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO },
+ { "cgroup-full:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW },
+ { "cgroup-full:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup-full:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup-full:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO | LXC_AUTO_CGROUP_FORCE },
+ { "cgroup-full:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW | LXC_AUTO_CGROUP_FORCE },
/* For adding anything that is just a single on/off, but has no
- * options: keep mask and flag identical and just define the enum
- * value as an unused bit so far
+ * options: keep mask and flag identical and just define the enum
+ * value as an unused bit so far
*/
- { NULL, 0, 0 }
+ { NULL, 0, 0 }
};
if (lxc_config_value_empty(value)) {
return 0;
}
-static int set_config_console_buffer_logfile(const char *key, const char *value,
- struct lxc_conf *lxc_conf,
- void *data)
+static int set_config_console_size(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
{
- return set_config_path_item(&lxc_conf->console.buffer_log_file, value);
+ int ret;
+ int64_t size;
+ uint64_t log_size, pgsz;
+
+ if (lxc_config_value_empty(value)) {
+ lxc_conf->console.log_size = 0;
+ return 0;
+ }
+
+ /* If the user specified "auto" the default log size is 2^17 = 128 Kib */
+ if (!strcmp(value, "auto")) {
+ lxc_conf->console.log_size = 1 << 17;
+ return 0;
+ }
+
+ ret = parse_byte_size_string(value, &size);
+ if (ret < 0)
+ return -1;
+
+ if (size < 0)
+ return -EINVAL;
+
+ /* must be at least a page size */
+ pgsz = lxc_getpagesize();
+ if ((uint64_t)size < pgsz) {
+ NOTICE("Requested ringbuffer size for the console is %" PRId64
+ " but must be at least %" PRId64
+ " bytes. Setting ringbuffer size to %" PRId64 " bytes",
+ size, pgsz, pgsz);
+ size = pgsz;
+ }
+
+ log_size = lxc_find_next_power2((uint64_t)size);
+ if (log_size == 0)
+ return -EINVAL;
+
+ if (log_size != size)
+ NOTICE("Passed size was not a power of 2. Rounding log size to "
+ "next power of two: %" PRIu64 " bytes", log_size);
+
+ lxc_conf->console.log_size = log_size;
+ return 0;
}
int append_unexp_config_line(const char *line, struct lxc_conf *conf)
while ((direntp = readdir(dir))) {
const char *fnam;
- if (!direntp)
- break;
fnam = direntp->d_name;
if (!strcmp(fnam, "."))
static int set_config_rootfs_path(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- return set_config_path_item(&lxc_conf->rootfs.path, value);
+ int ret;
+ char *dup, *tmp;
+ const char *container_path;
+
+ if (lxc_config_value_empty(value)) {
+ free(lxc_conf->rootfs.path);
+ lxc_conf->rootfs.path = NULL;
+ return 0;
+ }
+
+ dup = strdup(value);
+ if (!dup)
+ return -1;
+
+ /* Split <storage type>:<container path> into <storage type> and
+ * <container path>. Set "rootfs.bdev_type" to <storage type> and
+ * "rootfs.path" to <container path>.
+ */
+ tmp = strchr(dup, ':');
+ if (tmp) {
+ *tmp = '\0';
+ ret = set_config_path_item(&lxc_conf->rootfs.bdev_type, dup);
+ if (ret < 0) {
+ free(dup);
+ return -1;
+ }
+ tmp++;
+ container_path = tmp;
+ } else {
+ container_path = value;
+ }
+
+ ret = set_config_path_item(&lxc_conf->rootfs.path, container_path);
+ free(dup);
+ return ret;
}
static int set_config_rootfs_mount(const char *key, const char *value,
return set_config_string_item(&lxc_conf->rootfs.options, value);
}
-static int set_config_rootfs_backend(const char *key, const char *value,
- struct lxc_conf *lxc_conf, void *data)
-{
- return 0;
-}
-
static int set_config_uts_name(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return -1;
}
- strcpy(utsname->nodename, value);
+ (void)strlcpy(utsname->nodename, value, sizeof(utsname->nodename));
free(lxc_conf->utsname);
lxc_conf->utsname = utsname;
return 0;
}
-static int set_config_namespace(const char *key, const char *value,
- struct lxc_conf *lxc_conf, void *data)
+static int set_config_namespace_clone(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ char *ns, *nsptr, *token;
+ int cloneflag = 0;
+ char *saveptr = NULL;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_namespace_clone(key, lxc_conf, data);
+
+ if (lxc_conf->ns_keep != 0) {
+ ERROR("%s - Cannot set both \"lxc.namespace.clone\" and "
+ "\"lxc.namespace.keep\"", strerror(EINVAL));
+ return -EINVAL;
+ }
+
+ ns = strdup(value);
+ if (!ns)
+ return -1;
+ nsptr = ns;
+
+ for (; (token = strtok_r(nsptr, " \t", &saveptr)); nsptr = NULL) {
+ token += lxc_char_left_gc(token, strlen(token));
+ token[lxc_char_right_gc(token, strlen(token))] = '\0';
+ cloneflag = lxc_namespace_2_cloneflag(token);
+ if (cloneflag < 0) {
+ free(ns);
+ return -EINVAL;
+ }
+ lxc_conf->ns_clone |= cloneflag;
+ }
+ free(ns);
+
+ return 0;
+}
+
+static int set_config_namespace_keep(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ char *ns, *nsptr, *token;
+ int cloneflag = 0;
+ char *saveptr = NULL;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_namespace_keep(key, lxc_conf, data);
+
+ if (lxc_conf->ns_clone != 0) {
+ ERROR("%s - Cannot set both \"lxc.namespace.clone\" and "
+ "\"lxc.namespace.keep\"", strerror(EINVAL));
+ return -EINVAL;
+ }
+
+ ns = strdup(value);
+ if (!ns)
+ return -1;
+ nsptr = ns;
+
+ for (; (token = strtok_r(nsptr, " \t", &saveptr)); nsptr = NULL) {
+ token += lxc_char_left_gc(token, strlen(token));
+ token[lxc_char_right_gc(token, strlen(token))] = '\0';
+ cloneflag = lxc_namespace_2_cloneflag(token);
+ if (cloneflag < 0) {
+ free(ns);
+ return -EINVAL;
+ }
+ lxc_conf->ns_keep |= cloneflag;
+ }
+ free(ns);
+
+ return 0;
+}
+
+static int set_config_namespace_share(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
{
int ns_idx;
const char *namespace;
if (lxc_config_value_empty(value))
- return clr_config_namespace(key, lxc_conf, data);
+ return clr_config_namespace_share(key, lxc_conf, data);
- namespace = key + sizeof("lxc.namespace.") - 1;
+ namespace = key + sizeof("lxc.namespace.share.") - 1;
ns_idx = lxc_namespace_2_ns_idx(namespace);
if (ns_idx < 0)
return ns_idx;
- return set_config_string_item(&lxc_conf->inherit_ns[ns_idx], value);
+ return set_config_string_item(&lxc_conf->ns_share[ns_idx], value);
}
struct parse_line_conf {
goto on_error;
}
- /* [START]: REMOVE IN LXC 3.0 */
- if (config->is_legacy_key && !plc->conf->contains_legacy_key) {
- plc->conf->contains_legacy_key = true;
- if (getenv("LXC_UPDATE_CONFIG_FORMAT")) {
- /* Warn the user once loud and clear that there is at
- * least one legacy configuration item in the
- * configuration file and then an update is required.
- */
- fprintf(stderr, "The configuration file contains "
- "legacy configuration keys.\nPlease "
- "update your configuration file!\nThe "
- "update script lxc-update-config -c "
- "<path-to-config> can be used for "
- "this.\n");
- }
- }
- /* [END]: REMOVE IN LXC 3.0 */
-
ret = config->set(key, value, plc->conf, NULL);
on_error:
if (!conf->rcfile)
conf->rcfile = strdup(file);
- return lxc_file_for_each_line(file, parse_line, &c);
+ return lxc_file_for_each_line_mmap(file, parse_line, &c);
}
int lxc_config_define_add(struct lxc_list *defines, char *arg)
char *name;
unsigned long per;
} pername[] = {
- { "x86", PER_LINUX32 },
- { "linux32", PER_LINUX32 },
+ { "arm", PER_LINUX32 },
+ { "armel", PER_LINUX32 },
+ { "armhf", PER_LINUX32 },
+ { "armv7l", PER_LINUX32 },
+ { "athlon", PER_LINUX32 },
{ "i386", PER_LINUX32 },
{ "i486", PER_LINUX32 },
{ "i586", PER_LINUX32 },
{ "i686", PER_LINUX32 },
- { "athlon", PER_LINUX32 },
+ { "linux32", PER_LINUX32 },
{ "mips", PER_LINUX32 },
{ "mipsel", PER_LINUX32 },
{ "ppc", PER_LINUX32 },
- { "arm", PER_LINUX32 },
- { "armv7l", PER_LINUX32 },
- { "armhf", PER_LINUX32 },
- { "armel", PER_LINUX32 },
{ "powerpc", PER_LINUX32 },
- { "linux64", PER_LINUX },
- { "x86_64", PER_LINUX },
+ { "x86", PER_LINUX32 },
{ "amd64", PER_LINUX },
+ { "arm64", PER_LINUX },
+ { "linux64", PER_LINUX },
{ "mips64", PER_LINUX },
{ "mips64el", PER_LINUX },
{ "ppc64", PER_LINUX },
- { "ppc64le", PER_LINUX },
{ "ppc64el", PER_LINUX },
+ { "ppc64le", PER_LINUX },
{ "powerpc64", PER_LINUX },
{ "s390x", PER_LINUX },
- { "aarch64", PER_LINUX },
- { "arm64", PER_LINUX },
+ { "x86_64", PER_LINUX },
};
size_t len = sizeof(pername) / sizeof(pername[0]);
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i++)
if (!strcmp(pername[i].name, arch))
return pername[i].per;
- }
#endif
return -1;
}
-int lxc_fill_elevated_privileges(char *flaglist, int *flags)
+/* Write out a configuration file. */
+int write_config(int fd, const struct lxc_conf *conf)
{
- 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;
+ int ret;
+ size_t len = conf->unexpanded_len;
+ if (len == 0)
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);
+ ret = lxc_write_nointr(fd, conf->unexpanded_config, len);
+ if (ret < 0) {
+ SYSERROR("Failed to write configuration file");
+ return -1;
}
return 0;
}
-/* Write out a configuration file. */
-void write_config(FILE *fout, struct lxc_conf *c)
-{
- int ret;
- size_t len = c->unexpanded_len;
-
- if (!len)
- return;
-
- ret = fwrite(c->unexpanded_config, 1, len, fout);
- if (ret != len)
- SYSERROR("Failed to write configuration file");
-}
-
bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
const char *v)
{
if (p >= lend)
goto next;
- /* Whenever an lxc.mount.entry entry is found in a line we check
- * if the substring " overlay" or the substring " aufs" is
- * present before doing any further work. We check for "
- * overlay" and " aufs" since both substrings need to have at
- * least one space before them in a valid overlay
+ /* Whenever a lxc.mount.entry entry is found in a line we check
+ * if the substring "overlay" is present before doing any
+ * further work. We check for "overlay" because substrings need
+ * to have at least one space before them in a valid overlay
* lxc.mount.entry (/A B overlay). When the space before is
* missing it is very likely that these substrings are part of a
* path or something else. (Checking q >= lend ensures that we
* only count matches in the current line.) */
- if ((!(q = strstr(p, " overlay")) || q >= lend) &&
- (!(q = strstr(p, " aufs")) || q >= lend))
+ q = strstr(p, " overlay");
+ if (!q || q >= lend)
goto next;
if (!(q = strstr(p, olddir)) || (q >= lend))
return 0;
}
-static int set_config_noop(const char *key, const char *value,
- struct lxc_conf *lxc_conf, void *data)
-{
- return 0;
-}
-
/* Callbacks to get configuration items. */
static int get_config_personality(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
static int get_config_pty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_int(c, retv, inlen, c->pts);
+ return lxc_get_conf_size_t(c, retv, inlen, c->pty_max);
}
static int get_config_tty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_int(c, retv, inlen, c->tty);
+ return lxc_get_conf_size_t(c, retv, inlen, c->ttys.max);
}
static int get_config_tty_dir(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_str(retv, inlen, c->ttydir);
+ return lxc_get_conf_str(retv, inlen, c->ttys.dir);
}
static int get_config_apparmor_profile(const char *key, char *retv, int inlen,
* If you ask for 'lxc.cgroup", then all cgroup entries will be printed, in
* 'lxc.cgroup.subsystem.key = value' format.
*/
-static int get_config_cgroup_controller(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
+static int __get_config_cgroup_controller(const char *key, char *retv,
+ int inlen, struct lxc_conf *c,
+ int version)
{
- struct lxc_list *it;
int len;
+ size_t namespaced_token_len;
+ char *global_token, *namespaced_token;
+ struct lxc_list *it;
int fulllen = 0;
bool get_all = false;
else
memset(retv, 0, inlen);
- if (!strcmp(key, "lxc.cgroup"))
+ if (version == CGROUP2_SUPER_MAGIC) {
+ global_token = "lxc.cgroup2";
+ namespaced_token = "lxc.cgroup2.";
+ namespaced_token_len = sizeof("lxc.cgroup2.") - 1;;
+ } else if (version == CGROUP_SUPER_MAGIC) {
+ global_token = "lxc.cgroup";
+ namespaced_token = "lxc.cgroup.";
+ namespaced_token_len = sizeof("lxc.cgroup.") - 1;;
+ } else {
+ return -1;
+ }
+
+ if (strcmp(key, global_token) == 0)
get_all = true;
- else if (!strncmp(key, "lxc.cgroup.", 11))
- key += 11;
+ else if (strncmp(key, namespaced_token, namespaced_token_len) == 0)
+ key += namespaced_token_len;
else
return -1;
struct lxc_cgroup *cg = it->elem;
if (get_all) {
- strprint(retv, inlen, "lxc.cgroup.%s = %s\n",
- cg->subsystem, cg->value);
+ if (version != cg->version)
+ continue;
+
+ strprint(retv, inlen, "%s.%s = %s\n",
+ global_token, cg->subsystem, cg->value);
} else if (!strcmp(cg->subsystem, key)) {
strprint(retv, inlen, "%s\n", cg->value);
}
return fulllen;
}
+static int get_config_cgroup_controller(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return __get_config_cgroup_controller(key, retv, inlen, c,
+ CGROUP_SUPER_MAGIC);
+}
+
+static int get_config_cgroup2_controller(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return __get_config_cgroup_controller(key, retv, inlen, c,
+ CGROUP2_SUPER_MAGIC);
+}
+
static int get_config_cgroup_dir(const char *key, char *retv, int inlen,
struct lxc_conf *lxc_conf, void *data)
{
return lxc_get_conf_str(retv, inlen, c->rootfs.options);
}
-static int get_config_rootfs_backend(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
-{
- return 0;
-}
-
static int get_config_uts_name(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return fulllen;
}
+static int get_config_hooks_version(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_int(c, retv, inlen, c->hooks_version);
+}
+
static int get_config_net(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
int inlen, struct lxc_conf *c,
void *data)
{
- return lxc_get_conf_uint64(c, retv, inlen, c->autodev);
+ return lxc_get_conf_uint64(c, retv, inlen, c->console.buffer_size);
}
-static int get_config_console_buffer_logfile(const char *key, char *retv,
- int inlen, struct lxc_conf *c,
- void *data)
+static int get_config_console_size(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
{
- return lxc_get_conf_str(retv, inlen, c->console.buffer_log_file);
+ return lxc_get_conf_uint64(c, retv, inlen, c->console.log_size);
}
+
static int get_config_seccomp_profile(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return fulllen;
}
-/* If you ask for a specific value, i.e. lxc.sysctl.net.ipv4.ip_forward, then just the value
- * will be printed. If you ask for 'lxc.sysctl', then all sysctl entries will be
- * printed, in 'lxc.sysctl.key = value' format.
+/* If you ask for a specific value, i.e. lxc.sysctl.net.ipv4.ip_forward, then
+ * just the value will be printed. If you ask for 'lxc.sysctl', then all sysctl
+ * entries will be printed, in 'lxc.sysctl.key = value' format.
*/
static int get_config_sysctl(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
return fulllen;
}
-static int get_config_noop(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
+static int get_config_proc(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
{
- return 0;
+ struct lxc_list *it;
+ int len;
+ int fulllen = 0;
+ bool get_all = false;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ if (strcmp(key, "lxc.proc") == 0)
+ get_all = true;
+ else if (strncmp(key, "lxc.proc.", sizeof("lxc.proc.") - 1) == 0)
+ key += sizeof("lxc.proc.") - 1;
+ else
+ return -1;
+
+ lxc_list_for_each(it, &c->procs) {
+ struct lxc_proc *proc = it->elem;
+
+ if (get_all) {
+ strprint(retv, inlen, "lxc.proc.%s = %s\n",
+ proc->filename, proc->value);
+ } else if (strcmp(proc->filename, key) == 0) {
+ strprint(retv, inlen, "%s", proc->value);
+ }
+ }
+
+ return fulllen;
}
-static int get_config_namespace(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
+static int get_config_namespace_clone(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int i, len;
+ int fulllen = 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ for (i = 0; i < LXC_NS_MAX; i++) {
+ if (c->ns_clone & ns_info[i].clone_flag)
+ strprint(retv, inlen, "%s\n", ns_info[i].proc_name);
+ }
+
+ return fulllen;
+}
+
+static int get_config_namespace_keep(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int i, len;
+ int fulllen = 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ for (i = 0; i < LXC_NS_MAX; i++) {
+ if (c->ns_keep & ns_info[i].clone_flag)
+ strprint(retv, inlen, "%s\n", ns_info[i].proc_name);
+ }
+
+ return fulllen;
+}
+
+static int get_config_namespace_share(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
{
int len, ns_idx;
const char *namespace;
else
memset(retv, 0, inlen);
- namespace = key + sizeof("lxc.namespace.") - 1;
+ namespace = key + sizeof("lxc.namespace.share.") - 1;
ns_idx = lxc_namespace_2_ns_idx(namespace);
if (ns_idx < 0)
return ns_idx;
- strprint(retv, inlen, "%s", c->inherit_ns[ns_idx]);
+ strprint(retv, inlen, "%s", c->ns_share[ns_idx]);
return fulllen;
}
static inline int clr_config_pty_max(const char *key, struct lxc_conf *c,
void *data)
{
- c->pts = 0;
+ c->pty_max = 0;
return 0;
}
static inline int clr_config_tty_max(const char *key, struct lxc_conf *c,
void *data)
{
- c->tty = 0;
+ c->ttys.tty = 0;
return 0;
}
static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c,
void *data)
{
- free(c->ttydir);
- c->ttydir = NULL;
+ free(c->ttys.dir);
+ c->ttys.dir = NULL;
return 0;
}
static inline int clr_config_cgroup_controller(const char *key,
struct lxc_conf *c, void *data)
{
- return lxc_clear_cgroups(c, key);
+ return lxc_clear_cgroups(c, key, CGROUP_SUPER_MAGIC);
+}
+
+static inline int clr_config_cgroup2_controller(const char *key,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_clear_cgroups(c, key, CGROUP2_SUPER_MAGIC);
}
static int clr_config_cgroup_dir(const char *key, struct lxc_conf *lxc_conf,
return 0;
}
-static inline int clr_config_rootfs_backend(const char *key, struct lxc_conf *c,
- void *data)
-{
- return 0;
-}
-
static inline int clr_config_uts_name(const char *key, struct lxc_conf *c,
void *data)
{
return lxc_clear_hooks(c, key);
}
+static inline int clr_config_hooks_version(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ /* default to legacy hooks version */
+ c->hooks_version = 0;
+ return 0;
+}
+
static inline int clr_config_net(const char *key, struct lxc_conf *c,
void *data)
{
return 0;
}
-static inline int clr_config_console_buffer_logfile(const char *key,
- struct lxc_conf *c,
- void *data)
+static inline int clr_config_console_size(const char *key, struct lxc_conf *c,
+ void *data)
{
- free(c->console.buffer_log_file);
- c->console.buffer_log_file = NULL;
+ c->console.log_size = 0;
return 0;
}
return lxc_clear_sysctls(c, key);
}
+static inline int clr_config_proc(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ return lxc_clear_procs(c, key);
+}
+
static inline int clr_config_includefiles(const char *key, struct lxc_conf *c,
void *data)
{
return 0;
}
-static inline int clr_config_noop(const char *key, struct lxc_conf *c,
- void *data)
+static int clr_config_namespace_clone(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
{
+ lxc_conf->ns_clone = 0;
return 0;
}
-static int clr_config_namespace(const char *key, struct lxc_conf *lxc_conf,
- void *data)
+static int clr_config_namespace_keep(const char *key, struct lxc_conf *lxc_conf,
+ void *data)
+{
+ lxc_conf->ns_keep = 0;
+ return 0;
+}
+
+static int clr_config_namespace_share(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
{
int ns_idx;
const char *namespace;
- namespace = key + sizeof("lxc.namespace.") - 1;
+ namespace = key + sizeof("lxc.namespace.share.") - 1;
ns_idx = lxc_namespace_2_ns_idx(namespace);
if (ns_idx < 0)
return ns_idx;
- free(lxc_conf->inherit_ns[ns_idx]);
- lxc_conf->inherit_ns[ns_idx] = NULL;
+ free(lxc_conf->ns_share[ns_idx]);
+ lxc_conf->ns_share[ns_idx] = NULL;
return 0;
}