]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/conf.h
github: Update for main branch
[mirror_lxc.git] / src / lxc / conf.h
index 4d13e90dcb84756414a0488a32f86dfdae9fd9d9..185e0b35db20a9b200fc5564e45eef492e3125aa 100644 (file)
@@ -3,9 +3,8 @@
 #ifndef __LXC_CONF_H
 #define __LXC_CONF_H
 
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
+#include "config.h"
+
 #include <linux/magic.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <sys/types.h>
 #include <sys/vfs.h>
 
+#include "attach_options.h"
 #include "caps.h"
 #include "compiler.h"
-#include "config.h"
+#include "hlist.h"
 #include "list.h"
 #include "lxcseccomp.h"
 #include "memory_utils.h"
+#include "mount_utils.h"
+#include "namespace.h"
 #include "ringbuf.h"
 #include "start.h"
+#include "state.h"
+#include "storage/storage.h"
 #include "string_utils.h"
+#include "syscall_wrappers.h"
 #include "terminal.h"
 
 #if HAVE_SYS_RESOURCE_H
@@ -34,6 +39,8 @@
 typedef void * scmp_filter_ctx;
 #endif
 
+typedef signed long personality_t;
+
 /* worth moving to configure.ac? */
 #define subuidfile "/etc/subuid"
 #define subgidfile "/etc/subgid"
@@ -68,8 +75,17 @@ struct lxc_cgroup {
                        char *container_dir;
                        char *namespace_dir;
                        bool relative;
+                       /* If an unpriv user in pure unified-only hierarchy
+                        * starts a container, then we ask systemd to create
+                        * a scope for us, and create the monitor and container
+                        * cgroups under that.
+                        * This will ignore the above things like monitor_dir
+                        */
+                       char *systemd_scope;
                };
        };
+
+       struct list_head head;
 };
 
 static void free_lxc_cgroup(struct lxc_cgroup *ptr)
@@ -87,6 +103,7 @@ define_cleanup_function(struct lxc_cgroup *, free_lxc_cgroup);
 struct rlimit {
        unsigned long rlim_cur;
        unsigned long rlim_max;
+       struct list_head head;
 };
 #endif
 
@@ -98,12 +115,13 @@ struct rlimit {
 struct lxc_limit {
        char *resource;
        struct rlimit limit;
+       struct list_head head;
 };
 
 static void free_lxc_limit(struct lxc_limit *ptr)
 {
        if (ptr) {
-               free(ptr->resource);
+               free_disarm(ptr->resource);
                free_disarm(ptr);
        }
 }
@@ -122,6 +140,7 @@ enum idtype {
 struct lxc_sysctl {
        char *key;
        char *value;
+       struct list_head head;
 };
 
 static void free_lxc_sysctl(struct lxc_sysctl *ptr)
@@ -142,6 +161,7 @@ define_cleanup_function(struct lxc_sysctl *, free_lxc_sysctl);
 struct lxc_proc {
        char *filename;
        char *value;
+       struct list_head head;
 };
 
 static void free_lxc_proc(struct lxc_proc *ptr)
@@ -167,6 +187,7 @@ define_cleanup_function(struct lxc_proc *, free_lxc_proc);
 struct id_map {
        enum idtype idtype;
        unsigned long hostid, nsid, range;
+       struct list_head head;
 };
 
 /* Defines the number of tty configured and contains the
@@ -180,66 +201,137 @@ struct lxc_tty_info {
        struct lxc_terminal_info *tty;
 };
 
+typedef enum lxc_mount_options_t {
+       LXC_MOUNT_CREATE_DIR    = 0,
+       LXC_MOUNT_CREATE_FILE   = 1,
+       LXC_MOUNT_OPTIONAL      = 2,
+       LXC_MOUNT_RELATIVE      = 3,
+       LXC_MOUNT_IDMAP         = 4,
+       LXC_MOUNT_MAX           = 5,
+} lxc_mount_options_t;
+
+__hidden extern const char *lxc_mount_options_info[LXC_MOUNT_MAX];
+
+struct lxc_mount_options {
+       unsigned int create_dir : 1;
+       unsigned int create_file : 1;
+       unsigned int optional : 1;
+       unsigned int relative : 1;
+       unsigned int bind_recursively : 1;
+       unsigned int propagate_recursively : 1;
+       unsigned int bind : 1;
+       char userns_path[PATH_MAX];
+       unsigned long mnt_flags;
+       unsigned long prop_flags;
+       char *data;
+       struct mount_attr attr;
+       char *raw_options;
+};
+
 /* Defines a structure to store the rootfs location, the
  * optionals pivot_root, rootfs mount paths
  * @path         : the rootfs source (directory or device)
  * @mount        : where it is mounted
  * @buf                 : static buffer to construct paths
- * @bev_type     : optional backing store type
- * @options      : mount options
- * @mountflags   : the portion of @options that are flags
- * @data         : the portion of @options that are not flags
+ * @bdev_type     : optional backing store type
  * @managed      : whether it is managed by LXC
  * @dfd_mnt     : fd for @mount
  * @dfd_dev : fd for /dev of the container
  */
 struct lxc_rootfs {
        int dfd_host;
-       int dfd_mnt;
-       int dfd_dev;
+
        char *path;
+       int fd_path_pin;
+       int dfd_idmapped;
+
+       int dfd_mnt;
        char *mount;
+
+       int dfd_dev;
+
        char buf[PATH_MAX];
        char *bdev_type;
-       char *options;
-       unsigned long mountflags;
-       char *data;
        bool managed;
+       struct lxc_mount_options mnt_opts;
+       struct lxc_storage *storage;
 };
 
 /*
  * Automatic mounts for LXC to perform inside the container
  */
 enum {
-       LXC_AUTO_PROC_RW              = 0x001, /* /proc read-write */
-       LXC_AUTO_PROC_MIXED           = 0x002, /* /proc/sys and /proc/sysrq-trigger read-only */
-       LXC_AUTO_PROC_MASK            = 0x003,
-
-       LXC_AUTO_SYS_RW               = 0x004, /* /sys */
-       LXC_AUTO_SYS_RO               = 0x008, /* /sys read-only */
-       LXC_AUTO_SYS_MIXED            = 0x00C, /* /sys read-only and /sys/class/net read-write */
-       LXC_AUTO_SYS_MASK             = 0x00C,
-
-       LXC_AUTO_CGROUP_RO            = 0x010, /* /sys/fs/cgroup (partial mount, read-only) */
-       LXC_AUTO_CGROUP_RW            = 0x020, /* /sys/fs/cgroup (partial mount, read-write) */
-       LXC_AUTO_CGROUP_MIXED         = 0x030, /* /sys/fs/cgroup (partial mount, paths r/o, cgroup r/w) */
-       LXC_AUTO_CGROUP_FULL_RO       = 0x040, /* /sys/fs/cgroup (full mount, read-only) */
-       LXC_AUTO_CGROUP_FULL_RW       = 0x050, /* /sys/fs/cgroup (full mount, read-write) */
-       LXC_AUTO_CGROUP_FULL_MIXED    = 0x060, /* /sys/fs/cgroup (full mount, parent r/o, own r/w) */
+       /* /proc read-write */
+       LXC_AUTO_PROC_RW              = BIT(0),
+       /* /proc/sys and /proc/sysrq-trigger read-only */
+       LXC_AUTO_PROC_MIXED           = BIT(1),
+       LXC_AUTO_PROC_MASK            = LXC_AUTO_PROC_RW |
+                                       LXC_AUTO_PROC_MIXED,
+       /* /sys read-write */
+       LXC_AUTO_SYS_RW               = BIT(2),
+       /* /sys read-only */
+       LXC_AUTO_SYS_RO               = BIT(3),
+       /* /sys read-only and /sys/class/net read-write */
+       LXC_AUTO_SYS_MIXED            = LXC_AUTO_SYS_RW |
+                                       LXC_AUTO_SYS_RO,
+       LXC_AUTO_SYS_MASK             = LXC_AUTO_SYS_MIXED,
+
+       /* /sys/fs/cgroup (partial mount, read-only) */
+       LXC_AUTO_CGROUP_RO            = BIT(4),
+       /* /sys/fs/cgroup (partial mount, read-write) */
+       LXC_AUTO_CGROUP_RW            = BIT(5),
+       /* /sys/fs/cgroup (partial mount, paths r/o, cgroup r/w) */
+       LXC_AUTO_CGROUP_MIXED         = LXC_AUTO_CGROUP_RO |
+                                       LXC_AUTO_CGROUP_RW,
+       /* /sys/fs/cgroup (full mount, read-only) */
+       LXC_AUTO_CGROUP_FULL_RO       = BIT(6),
+       /* /sys/fs/cgroup (full mount, read-write) */
+       LXC_AUTO_CGROUP_FULL_RW       = BIT(7),
+       /* /sys/fs/cgroup (full mount, parent r/o, own r/w) */
+       LXC_AUTO_CGROUP_FULL_MIXED    = LXC_AUTO_CGROUP_FULL_RO |
+                                       LXC_AUTO_CGROUP_FULL_RW,
+
+       /*
+        * Mount a pure read-write cgroup2 layout in the container independent
+        * of the cgroup layout used on the host.
+        */
+       LXC_AUTO_CGROUP2_RW           = BIT(8),
+       /*
+        * Mount a pure read-only cgroup2 layout in the container independent
+        * of the cgroup layout used on the host.
+        */
+       LXC_AUTO_CGROUP2_RO           = BIT(9),
+
        /*
         * These are defined in such a way as to retain binary compatibility
         * with earlier versions of this code. If the previous mask is applied,
         * both of these will default back to the _MIXED variants, which is
         * safe.
         */
-       LXC_AUTO_CGROUP_NOSPEC        = 0x0B0, /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */
-       LXC_AUTO_CGROUP_FULL_NOSPEC   = 0x0E0, /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */
-       LXC_AUTO_CGROUP_FORCE         = 0x100, /* mount cgroups even when cgroup namespaces are supported */
-       LXC_AUTO_CGROUP_MASK          = 0x1F0, /* all known cgroup options, doe not contain LXC_AUTO_CGROUP_FORCE */
-
-       LXC_AUTO_SHMOUNTS             = 0x200, /* shared mount point */
-       LXC_AUTO_SHMOUNTS_MASK        = 0x200, /* shared mount point mask */
-       LXC_AUTO_ALL_MASK             = 0x1FF, /* all known settings */
+       /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */
+       LXC_AUTO_CGROUP_NOSPEC        = 0x0B0,
+       /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */
+       LXC_AUTO_CGROUP_FULL_NOSPEC   = 0x0E0,
+       /* mount cgroups even when cgroup namespaces are supported */
+       LXC_AUTO_CGROUP_FORCE         = BIT(10),
+       /* all known cgroup options */
+       LXC_AUTO_CGROUP_MASK          = LXC_AUTO_CGROUP_MIXED |
+                                       LXC_AUTO_CGROUP_FULL_MIXED |
+                                       LXC_AUTO_CGROUP_NOSPEC |
+                                       LXC_AUTO_CGROUP_FULL_NOSPEC |
+                                       LXC_AUTO_CGROUP_FORCE |
+                                       LXC_AUTO_CGROUP2_RW |
+                                       LXC_AUTO_CGROUP2_RO,
+
+       /* shared mount point */
+       LXC_AUTO_SHMOUNTS             = BIT(11),
+       /* shared mount point mask */
+       LXC_AUTO_SHMOUNTS_MASK        = LXC_AUTO_SHMOUNTS,
+
+       /* all known settings */
+       LXC_AUTO_ALL_MASK             = LXC_AUTO_PROC_MASK |
+                                       LXC_AUTO_SYS_MASK |
+                                       LXC_AUTO_CGROUP_MASK,
 };
 
 enum lxchooks {
@@ -261,13 +353,13 @@ __hidden extern char *lxchook_names[NUM_LXC_HOOKS];
 struct lxc_state_client {
        int clientfd;
        lxc_state_t states[MAX_STATE];
+       struct list_head head;
 };
 
-enum {
-       LXC_BPF_DEVICE_CGROUP_LOCAL_RULE = -1,
-       LXC_BPF_DEVICE_CGROUP_ALLOWLIST  =  0,
-       LXC_BPF_DEVICE_CGROUP_DENYLIST  =  1,
-};
+typedef enum lxc_bpf_devices_rule_t {
+       LXC_BPF_DEVICE_CGROUP_ALLOWLIST         = 0,
+       LXC_BPF_DEVICE_CGROUP_DENYLIST          = 1,
+} lxc_bpf_devices_rule_t;
 
 struct device_item {
        char type;
@@ -275,12 +367,12 @@ struct device_item {
        int minor;
        char access[4];
        int allow;
-       /*
-        * LXC_BPF_DEVICE_CGROUP_LOCAL_RULE -> no global rule
-        * LXC_BPF_DEVICE_CGROUP_ALLOWLIST  -> allowlist (deny all)
-        * LXC_BPF_DEVICE_CGROUP_DENYLIST   -> denylist (allow all)
-        */
-       int global_rule;
+       struct list_head head;
+};
+
+struct bpf_devices {
+       lxc_bpf_devices_rule_t list_type;
+       struct list_head devices;
 };
 
 struct timens_offsets {
@@ -293,23 +385,44 @@ struct timens_offsets {
        int64_t ns_monotonic;
 };
 
+struct environment_entry {
+       char *key;
+       char *val;
+       struct list_head head;
+};
+
+struct cap_entry {
+       char *cap_name;
+       __u32 cap;
+       struct list_head head;
+};
+
+struct caps {
+       int keep;
+       struct list_head list;
+};
+
+struct string_entry {
+       char *val;
+       struct list_head head;
+};
+
 struct lxc_conf {
        /* Pointer to the name of the container. Do not free! */
        const char *name;
        bool is_execute;
        int reboot;
-       signed long personality;
+       personality_t personality;
        struct utsname *utsname;
 
        struct {
-               struct lxc_list cgroup;
-               struct lxc_list cgroup2;
-               /* This should be reimplemented as a hashmap. */
-               struct lxc_list devices;
+               struct list_head cgroup;
+               struct list_head cgroup2;
+               struct bpf_devices bpf_devices;
        };
 
        struct {
-               struct lxc_list id_map;
+               struct list_head id_map;
 
                /*
                 * Pointer to the idmap entry for the container's root uid in
@@ -324,16 +437,15 @@ struct lxc_conf {
                const struct id_map *root_nsgid_map;
        };
 
-       struct lxc_list network;
+       struct list_head netdevs;
 
        struct {
                char *fstab;
                int auto_mounts;
-               struct lxc_list mount_list;
+               struct list_head mount_entries;
        };
 
-       struct lxc_list caps;
-       struct lxc_list keepcaps;
+       struct caps caps;
 
        /* /dev/tty<idx> devices */
        struct lxc_tty_info ttys;
@@ -352,7 +464,7 @@ struct lxc_conf {
 
        struct {
                unsigned int hooks_version;
-               struct lxc_list hooks[NUM_LXC_HOOKS];
+               struct list_head hooks[NUM_LXC_HOOKS];
        };
 
        char *lsm_aa_profile;
@@ -360,7 +472,7 @@ struct lxc_conf {
        bool lsm_aa_profile_created;
        unsigned int lsm_aa_allow_nesting;
        unsigned int lsm_aa_allow_incomplete;
-       struct lxc_list lsm_aa_raw;
+       struct list_head lsm_aa_raw;
        char *lsm_se_context;
        char *lsm_se_keyring_context;
        bool keyring_disable_session;
@@ -386,21 +498,16 @@ struct lxc_conf {
        unsigned int start_auto;
        unsigned int start_delay;
        int start_order;
-       struct lxc_list groups;
+       struct list_head groups;
        int nbd_idx;
 
        /* unshare the mount namespace in the monitor */
        unsigned int monitor_unshare;
        unsigned int monitor_signal_pdeath;
 
-       /* list of included files */
-       struct lxc_list includes;
-       /* config entries which are not "lxc.*" are aliens */
-       struct lxc_list aliens;
-
        /* list of environment variables we'll add to the container when
         * started */
-       struct lxc_list environment;
+       struct list_head environment;
 
        /* text representation of the config file */
        char *unexpanded_config;
@@ -413,14 +520,12 @@ struct lxc_conf {
        /* init command */
        char *init_cmd;
 
-       /* if running in a new user namespace, the UID/GID that init and COMMAND
-        * should run under when using lxc-execute */
+       /* The uid to use for the container. */
        uid_t init_uid;
+       /* The gid to use for the container. */
        gid_t init_gid;
-       struct {
-               int size;
-               gid_t *list;
-       } init_groups;
+       /* The groups to use for the container. */
+       lxc_groups_t init_groups;
 
        /* indicator if the container will be destroyed on shutdown */
        unsigned int ephemeral;
@@ -433,7 +538,7 @@ struct lxc_conf {
        bool no_new_privs;
 
        /* RLIMIT_* limits */
-       struct lxc_list limits;
+       struct list_head limits;
 
        /* Contains generic info about the cgroup configuration for this
         * container. Note that struct lxc_cgroup contains a union. It is only
@@ -452,13 +557,13 @@ struct lxc_conf {
        char *init_cwd;
 
        /* A list of clients registered to be informed about a container state. */
-       struct lxc_list state_clients;
+       struct list_head state_clients;
 
        /* sysctls */
-       struct lxc_list sysctls;
+       struct list_head sysctls;
 
        /* procs */
-       struct lxc_list procs;
+       struct list_head procs;
 
        struct shmount {
                /* Absolute path to the shared mount point on the host */
@@ -468,26 +573,29 @@ struct lxc_conf {
        } shmount;
 
        struct timens_offsets timens;
+
+       bool sched_core;
+       __u64 sched_core_cookie;
 };
 
 __hidden extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, size_t buf_size)
     __access_r(3, 4);
 
-#ifdef HAVE_TLS
 extern thread_local struct lxc_conf *current_config;
-#else
-extern struct lxc_conf *current_config;
-#endif
 
 __hidden extern int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, char *argv[]);
 __hidden extern struct lxc_conf *lxc_conf_init(void);
 __hidden extern void lxc_conf_free(struct lxc_conf *conf);
-__hidden extern int pin_rootfs(const char *rootfs);
-__hidden extern int lxc_map_ids(struct lxc_list *idmap, pid_t pid);
+__hidden extern int lxc_storage_prepare(struct lxc_conf *conf);
+__hidden extern int lxc_rootfs_prepare(struct lxc_conf *conf, bool userns);
+__hidden extern void lxc_storage_put(struct lxc_conf *conf);
+__hidden extern int lxc_rootfs_init(struct lxc_conf *conf, bool userns);
+__hidden extern int lxc_rootfs_prepare_parent(struct lxc_handler *handler);
+__hidden extern int lxc_idmapped_mounts_parent(struct lxc_handler *handler);
+__hidden extern int lxc_map_ids(struct list_head *idmap, pid_t pid);
 __hidden extern int lxc_create_tty(const char *name, struct lxc_conf *conf);
 __hidden extern void lxc_delete_tty(struct lxc_tty_info *ttys);
 __hidden extern int lxc_clear_config_caps(struct lxc_conf *c);
-__hidden extern int lxc_clear_config_keepcaps(struct lxc_conf *c);
 __hidden extern int lxc_clear_cgroups(struct lxc_conf *c, const char *key, int version);
 __hidden extern int lxc_clear_mount_entries(struct lxc_conf *c);
 __hidden extern int lxc_clear_automounts(struct lxc_conf *c);
@@ -498,46 +606,48 @@ __hidden extern int lxc_clear_environment(struct lxc_conf *c);
 __hidden extern int lxc_clear_limits(struct lxc_conf *c, const char *key);
 __hidden extern int lxc_delete_autodev(struct lxc_handler *handler);
 __hidden extern int lxc_clear_autodev_tmpfs_size(struct lxc_conf *c);
-__hidden extern void lxc_clear_includes(struct lxc_conf *conf);
 __hidden extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, const char *name,
                                                  const char *lxcpath);
 __hidden extern int lxc_setup(struct lxc_handler *handler);
 __hidden extern int lxc_setup_parent(struct lxc_handler *handler);
-__hidden extern int setup_resource_limits(struct lxc_list *limits, pid_t pid);
+__hidden extern int setup_resource_limits(struct lxc_conf *conf, pid_t pid);
 __hidden extern int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype);
 __hidden extern int mapped_hostid(unsigned id, const struct lxc_conf *conf, enum idtype idtype);
 __hidden extern int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), void *data,
                                  const char *fn_name);
 __hidden extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data,
                                     const char *fn_name);
-__hidden extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata);
+__hidden extern int parse_mntopts_legacy(const char *mntopts, unsigned long *mntflags, char **mntdata);
 __hidden extern int parse_propagationopts(const char *mntopts, unsigned long *pflags);
+__hidden extern int parse_lxc_mount_attrs(struct lxc_mount_options *opts, char *mnt_opts);
+__hidden extern int parse_mount_attrs(struct lxc_mount_options *opts, const char *mntopts);
 __hidden extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
-__hidden extern void turn_into_dependent_mounts(void);
 __hidden extern void suggest_default_idmap(void);
-__hidden extern FILE *make_anonymous_mount_file(struct lxc_list *mount, bool include_nesting_helpers);
-__hidden extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings);
-__hidden extern unsigned long add_required_remount_flags(const char *s, const char *d,
-                                                        unsigned long flags);
+__hidden extern FILE *make_anonymous_mount_file(const struct list_head *mount,
+                                               bool include_nesting_helpers);
 __hidden extern int run_script(const char *name, const char *section, const char *script, ...);
 __hidden extern int run_script_argv(const char *name, unsigned int hook_version, const char *section,
                                    const char *script, const char *hookname, char **argsin);
-__hidden extern int in_caplist(int cap, struct lxc_list *caps);
 
-static inline bool lxc_wants_cap(int cap, struct lxc_conf *conf)
+__hidden extern bool has_cap(__u32 cap, struct lxc_conf *conf);
+static inline bool lxc_wants_cap(__u32 cap, struct lxc_conf *conf)
 {
-       if (lxc_caps_last_cap() < cap)
+       __u32 last_cap;
+       int ret;
+
+       ret = lxc_caps_last_cap(&last_cap);
+       if (ret)
                return false;
 
-       if (!lxc_list_empty(&conf->keepcaps))
-               return in_caplist(cap, &conf->keepcaps);
+       if (last_cap < cap)
+               return false;
 
-       return !in_caplist(cap, &conf->caps);
+       return has_cap(cap, conf);
 }
 
-__hidden extern int setup_sysctl_parameters(struct lxc_list *sysctls);
+__hidden extern int setup_sysctl_parameters(struct lxc_conf *conf);
 __hidden extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key);
-__hidden extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid);
+__hidden extern int setup_proc_filesystem(struct lxc_conf *conf, pid_t pid);
 __hidden extern int lxc_clear_procs(struct lxc_conf *c, const char *key);
 __hidden extern int lxc_clear_apparmor_raw(struct lxc_conf *c);
 __hidden extern int lxc_clear_namespace(struct lxc_conf *c);
@@ -551,7 +661,8 @@ static inline int chown_mapped_root(const char *path, const struct lxc_conf *con
        return userns_exec_mapped_root(path, -EBADF, conf);
 }
 
-__hidden int lxc_setup_devpts_parent(struct lxc_handler *handler);
+__hidden extern int lxc_sync_fds_parent(struct lxc_handler *handler);
+__hidden extern int lxc_sync_fds_child(struct lxc_handler *handler);
 
 static inline const char *get_rootfs_mnt(const struct lxc_rootfs *rootfs)
 {
@@ -560,4 +671,54 @@ static inline const char *get_rootfs_mnt(const struct lxc_rootfs *rootfs)
        return !is_empty_string(rootfs->path) ? rootfs->mount : s;
 }
 
+static inline void put_lxc_mount_options(struct lxc_mount_options *mnt_opts)
+{
+       mnt_opts->create_dir = 0;
+       mnt_opts->create_file = 0;
+       mnt_opts->optional = 0;
+       mnt_opts->relative = 0;
+       mnt_opts->userns_path[0] = '\0';
+       mnt_opts->mnt_flags = 0;
+       mnt_opts->prop_flags = 0;
+
+       free_disarm(mnt_opts->data);
+       free_disarm(mnt_opts->raw_options);
+}
+
+static inline void put_lxc_rootfs(struct lxc_rootfs *rootfs, bool unpin)
+{
+       if (rootfs) {
+               close_prot_errno_disarm(rootfs->dfd_host);
+               close_prot_errno_disarm(rootfs->dfd_mnt);
+               close_prot_errno_disarm(rootfs->dfd_dev);
+               if (unpin)
+                       close_prot_errno_disarm(rootfs->fd_path_pin);
+               close_prot_errno_disarm(rootfs->dfd_idmapped);
+               put_lxc_mount_options(&rootfs->mnt_opts);
+               storage_put(rootfs->storage);
+               rootfs->storage = NULL;
+       }
+}
+
+static inline void lxc_clear_cgroup2_devices(struct bpf_devices *bpf_devices)
+{
+       struct device_item *device, *n;
+
+       list_for_each_entry_safe(device, n, &bpf_devices->devices, head)
+               list_del(&device->head);
+
+       INIT_LIST_HEAD(&bpf_devices->devices);
+}
+
+static inline int lxc_personality(personality_t persona)
+{
+       if (persona < 0)
+               return ret_errno(EINVAL);
+
+       return personality(persona);
+}
+
+__hidden extern int lxc_set_environment(const struct lxc_conf *conf);
+__hidden extern int parse_cap(const char *cap_name, __u32 *cap);
+
 #endif /* __LXC_CONF_H */