├── config
├── etc
│ ├── default.conf.unknown
│ ├── default.conf.libvirt
│ ├── default.conf.lxcbr
│ └── meson.build
├── selinux
│ ├── lxc.if
│ └── meson.build
├── init
│ ├── module
│ │ ├── module.prop.in
│ │ ├── boot-completed.sh.in
│ │ ├── uninstall.sh.in
│ │ ├── meson.build
│ │ └── customize.sh.in
│ ├── systemd
│ │ ├── lxc-monitord.service.in
│ │ ├── lxc-net.service.in
│ │ ├── lxc@.service.in
│ │ ├── lxc.service.in
│ │ ├── lxc-apparmor-load
│ │ └── meson.build
│ ├── sysvinit
│ │ ├── meson.build
│ │ ├── lxc-net.in
│ │ └── lxc-containers.in
│ └── common
│ │ └── meson.build
├── apparmor
│ ├── usr.bin.lxc-copy
│ ├── usr.bin.lxc-start
│ ├── lxc-containers
│ ├── README
│ ├── profiles
│ │ ├── lxc-default
│ │ ├── lxc-default-with-mounting
│ │ ├── lxc-default-with-nesting
│ │ ├── lxc-default-cgns
│ │ └── meson.build
│ ├── container-rules.base
│ ├── abstractions
│ │ ├── meson.build
│ │ └── start-container.in
│ └── meson.build
├── templates
│ ├── oci.common.conf.in
│ ├── common.seccomp
│ ├── common.conf.d
│ │ ├── meson.build
│ │ └── README
│ ├── nesting.conf.in
│ ├── userns.conf.in
│ ├── meson.build
│ └── common.conf.in
├── yum
│ ├── meson.build
│ └── lxc-patch.py
├── sysconfig
│ ├── meson.build
│ └── lxc.in
└── bash
│ └── meson.build
├── .gitignore
├── doc
├── examples
│ ├── lxc-no-netns.conf.in
│ ├── lxc-empty-netns.conf.in
│ ├── lxc-macvlan.conf.in
│ ├── lxc-phys.conf.in
│ ├── lxc-vlan.conf.in
│ ├── seccomp-v2-denylist.conf
│ ├── lxc-veth.conf.in
│ ├── seccomp-v2.conf
│ ├── lxc-complex.conf.in
│ └── meson.build
├── rootfs
│ ├── README
│ └── meson.build
├── lxc.system.conf
├── FAQ.txt
├── ja
│ ├── FAQ.txt
│ ├── lxc-checkconfig.sgml.in
│ ├── meson.build
│ ├── lxc-unfreeze.sgml.in
│ └── lxc-freeze.sgml.in
├── ko
│ ├── FAQ.txt
│ ├── meson.build
│ ├── lxc-checkconfig.sgml.in
│ ├── lxc-unfreeze.sgml.in
│ └── lxc-freeze.sgml.in
├── lxc.container.conf
├── lxc-checkconfig.sgml.in
├── lxc-unfreeze.sgml.in
├── lxc-freeze.sgml.in
├── lxc-config.sgml.in
├── meson.build
└── see_also.sgml.in
├── AUTHORS
├── .github
├── dependabot.yml
├── workflows
│ ├── sync.yml
│ ├── commits.yml
│ ├── fuzzing.yml
│ ├── code-test.yml
│ └── coverity.yml
└── ISSUE_TEMPLATE.md
├── src
├── include
│ ├── strchrnul.h
│ ├── hasmntopt.h
│ ├── fexecve.h
│ ├── strlcpy.h
│ ├── strlcat.h
│ ├── pthread_ext.h
│ ├── strlcpy.c
│ ├── getgrgid_r.h
│ ├── strlcat.c
│ ├── hasmntopt.c
│ ├── pthread_setcancelstate.c
│ ├── fexecve.c
│ ├── meson.build
│ ├── bpf_common.h
│ └── netns_ifaddrs.h
├── lxc
│ ├── tools
│ │ ├── include
│ │ │ ├── getsubopt.h
│ │ │ ├── meson.build
│ │ │ └── getsubopt.c
│ │ ├── lxc_config.c
│ │ ├── meson.build
│ │ ├── lxc_freeze.c
│ │ └── lxc_unfreeze.c
│ ├── rexec.h
│ ├── lxc.functions.in
│ ├── version.h.in
│ ├── error.h
│ ├── criu.h
│ ├── attach.h
│ ├── pam
│ │ └── meson.build
│ ├── storage
│ │ ├── rsync.h
│ │ ├── dir.h
│ │ ├── rbd.h
│ │ ├── loop.h
│ │ ├── nbd.h
│ │ ├── zfs.h
│ │ ├── lvm.h
│ │ ├── storage_utils.h
│ │ └── overlay.h
│ ├── uuid.h
│ ├── state.h
│ ├── lsm
│ │ ├── lsm.c
│ │ ├── lsm.h
│ │ └── nop.c
│ ├── cgroups
│ │ ├── cgroup_utils.h
│ │ └── cgroup2_devices.h
│ ├── idmap_utils.h
│ ├── parse.h
│ ├── namespace.h
│ ├── error_utils.h
│ ├── error.c
│ ├── execute.c
│ ├── initutils.h
│ ├── sync.h
│ ├── rtnl.c
│ ├── api_extensions.h
│ ├── mainloop.h
│ ├── ringbuf.h
│ ├── freezer.c
│ └── monitor.h
└── tests
│ ├── lxc-test-createconfig
│ ├── basic.c
│ ├── may_control.c
│ ├── lxc-test-procsys
│ ├── fuzz-lxc-config-read.c
│ ├── lxc-test-exit-code
│ ├── fuzz-lxc-cgroup-init.c
│ ├── lxc-test-checkpoint-restore
│ ├── lxc-test-no-new-privs
│ ├── fuzz-lxc-define-load.c
│ ├── lxc-test-snapdeps
│ ├── lxctest.h
│ ├── lxc-test-apparmor-generated
│ ├── arch_parse.c
│ ├── lxc-test-rootfs
│ ├── lxcpath.c
│ ├── config_jump_table.c
│ ├── createtest.c
│ ├── destroytest.c
│ ├── lxc-test-autostart
│ ├── shutdowntest.c
│ ├── list.c
│ ├── device_add_remove.c
│ ├── criu_check_feature.c
│ └── saveconfig.c
├── coccinelle
├── while-true.cocci
├── exit.cocci
└── run-coccinelle.sh
├── COPYING
├── Makefile
├── hooks
├── clonehostname
├── squid-deb-proxy-client
├── mountecryptfsroot
└── meson.build
├── MAINTAINERS
├── templates
└── meson.build
└── aarch64-android-api30.txt
/config/etc/default.conf.unknown:
--------------------------------------------------------------------------------
1 | lxc.net.0.type = empty
2 |
--------------------------------------------------------------------------------
/config/selinux/lxc.if:
--------------------------------------------------------------------------------
1 | ## Policy for LXC containers
2 |
--------------------------------------------------------------------------------
/config/etc/default.conf.libvirt:
--------------------------------------------------------------------------------
1 | lxc.net.0.type = veth
2 | lxc.net.0.link = virbr0
3 | lxc.net.0.flags = up
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Temporarily files.
2 | *~
3 | *.swp
4 | *.orig
5 | *.rej
6 |
7 | # Release tarballs.
8 | lxc-*.tar.gz*
9 |
--------------------------------------------------------------------------------
/doc/examples/lxc-no-netns.conf.in:
--------------------------------------------------------------------------------
1 | # Container with non-virtualized network
2 | lxc.net.0.type = none
3 | lxc.uts.name = delta
4 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | The list of authors and contributors can be retrieved from the git
2 | commit history and in some cases, the file headers.
3 |
--------------------------------------------------------------------------------
/config/etc/default.conf.lxcbr:
--------------------------------------------------------------------------------
1 | lxc.net.0.type = veth
2 | lxc.net.0.link = lxcbr0
3 | lxc.net.0.flags = up
4 | lxc.net.0.hwaddr = 10:66:6a:xx:xx:xx
5 |
--------------------------------------------------------------------------------
/config/init/module/module.prop.in:
--------------------------------------------------------------------------------
1 | id=lxc
2 | name=LXC-Daemon
3 | version=1.0.0
4 | versionCode=10001
5 | author=@Container-On-Android
6 | description=description
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 |
--------------------------------------------------------------------------------
/doc/examples/lxc-empty-netns.conf.in:
--------------------------------------------------------------------------------
1 | # Container with new network without network devices
2 | lxc.uts.name = omega
3 | lxc.net.0.type = empty
4 | lxc.net.0.flags = up
5 |
--------------------------------------------------------------------------------
/src/include/strchrnul.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "../lxc/compiler.h"
4 |
5 | __hidden extern char *strchrnul(const char *s, int c_in);
6 |
--------------------------------------------------------------------------------
/config/apparmor/usr.bin.lxc-copy:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /usr/bin/lxc-copy flags=(attach_disconnected) {
4 | #include
5 | }
6 |
--------------------------------------------------------------------------------
/config/apparmor/usr.bin.lxc-start:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /usr/bin/lxc-start flags=(attach_disconnected) {
4 | #include
5 | }
6 |
--------------------------------------------------------------------------------
/coccinelle/while-true.cocci:
--------------------------------------------------------------------------------
1 | @@
2 | statement s;
3 | @@
4 | - while (true)
5 | + for (;;)
6 | s
7 | @@
8 | statement s;
9 | @@
10 | - while (1)
11 | + for (;;)
12 | s
13 |
--------------------------------------------------------------------------------
/config/templates/oci.common.conf.in:
--------------------------------------------------------------------------------
1 | # Uncomment the following if you want to use DHCP for OCI containers
2 | #lxc.hook.start-host = @LXCHOOKDIR@/dhclient
3 | #lxc.hook.stop = @LXCHOOKDIR@/dhclient
4 |
--------------------------------------------------------------------------------
/src/lxc/tools/include/getsubopt.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef _GETSUBOPT_H
4 | #define _GETSUBOPT_H
5 | int getsubopt (char **optionp, char *const *tokens, char **valuep);
6 | #endif
7 |
--------------------------------------------------------------------------------
/doc/rootfs/README:
--------------------------------------------------------------------------------
1 | This directory must exist, even though it may be empty.
2 | It is used to temporary mount the rootfs of lxc in a private
3 | mount namespace only visible by the processes running in the
4 | container.
5 |
--------------------------------------------------------------------------------
/src/lxc/tools/include/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if srcconf.get('HAVE_GETSUBOPT') == 0
4 | include_sources += files(
5 | 'getsubopt.c',
6 | 'getsubopt.h')
7 | endif
8 |
--------------------------------------------------------------------------------
/config/apparmor/lxc-containers:
--------------------------------------------------------------------------------
1 | # This file exists only to ensure that all per-container policies
2 | # listed under /etc/apparmor.d/lxc get loaded at boot. Please do
3 | # not edit this file.
4 |
5 | #include
6 |
7 | #include
8 |
--------------------------------------------------------------------------------
/doc/rootfs/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | rootfs_readme = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'README',
6 | output: 'README',
7 | install: true,
8 | install_dir: lxcrootfsmount)
9 |
--------------------------------------------------------------------------------
/coccinelle/exit.cocci:
--------------------------------------------------------------------------------
1 | @@
2 | @@
3 | - exit(0);
4 | + exit(EXIT_SUCCESS);
5 | @@
6 | @@
7 | - _exit(0);
8 | + _exit(EXIT_SUCCESS);
9 | @@
10 | @@
11 | - exit(1);
12 | + exit(EXIT_FAILURE);
13 | @@
14 | @@
15 | - _exit(1);
16 | + _exit(EXIT_FAILURE);
17 |
--------------------------------------------------------------------------------
/config/init/module/boot-completed.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export LD_LIBRARY_PATH=/system/lib64:/system/lib:@LIBDIR@:/data/sysroot/lib64:/data/sysroot/lib
4 |
5 | # lxc-autostart
6 | mkdir -p @LOCALSTATEDIR@/lock
7 | @LIBEXECDIR@/lxc/lxc-containers start
8 |
--------------------------------------------------------------------------------
/config/yum/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_patch = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'lxc-patch.py',
6 | output: 'lxc-patch.py',
7 | install: true,
8 | install_dir: lxcdatadir)
9 |
--------------------------------------------------------------------------------
/config/etc/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_system_config = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'default.conf.lxcbr',
6 | output: 'default.conf',
7 | install: true,
8 | install_dir: lxcconfdir)
9 |
--------------------------------------------------------------------------------
/config/templates/common.seccomp:
--------------------------------------------------------------------------------
1 | 2
2 | denylist
3 | reject_force_umount # comment this to allow umount -f; not recommended
4 | [all]
5 | kexec_load errno 1
6 | open_by_handle_at errno 1
7 | init_module errno 1
8 | finit_module errno 1
9 | delete_module errno 1
10 |
--------------------------------------------------------------------------------
/src/lxc/rexec.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_REXEC_H
4 | #define __LXC_REXEC_H
5 |
6 | #include "config.h"
7 |
8 | #include "compiler.h"
9 |
10 | __hidden extern int lxc_rexec(const char *memfd_name);
11 |
12 | #endif /* __LXC_REXEC_H */
13 |
--------------------------------------------------------------------------------
/config/templates/common.conf.d/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_conf_common_readme = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'README',
6 | output: 'README',
7 | install: true,
8 | install_dir: lxctemplateconfcommondir)
9 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | All source files have SPDX headers that declare what license applies.
2 | The applicable licenses are included in the code repository.
3 |
4 | For other files such as examples, config files, ... they can be assumed
5 | to be licensed the same way that the LXC library is, so under LGPLv2.1+.
6 |
--------------------------------------------------------------------------------
/config/sysconfig/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if distrosysconfdir != ''
4 | configure_file(
5 | configuration: conf,
6 | input: 'lxc.in',
7 | output: 'lxc',
8 | install: true,
9 | install_dir: distrosysconfdir)
10 | endif
11 |
--------------------------------------------------------------------------------
/config/init/systemd/lxc-monitord.service.in:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LXC Container Monitoring Daemon
3 | After=syslog.service network.target
4 | Documentation=man:lxc
5 |
6 | [Service]
7 | Type=simple
8 | ExecStart=@LIBEXECDIR@/lxc/lxc-monitord --daemon
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/config/init/module/uninstall.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export LD_LIBRARY_PATH=/system/lib64:/system/lib:@LIBDIR@:/data/sysroot/lib64:/data/sysroot/lib
4 |
5 | for container in $(lxc-ls); do
6 | echo "stopping: $container"
7 | lxc-stop -n "$container" 2>/dev/null || lxc-stop -n "$container" -k
8 | done
9 |
10 | rm -rf @PREFIXDIR@
--------------------------------------------------------------------------------
/config/apparmor/README:
--------------------------------------------------------------------------------
1 | The abstractions/container-base file installed is automatically
2 | generated. Its two source files are container-rules.base and
3 | abstractions/container-base.in. If container-rules.base is updated,
4 | generate a new container-rules file using
5 |
6 | ./lxc-generate-aa-rules.py container-rules.base > container-rules
7 |
--------------------------------------------------------------------------------
/doc/examples/lxc-macvlan.conf.in:
--------------------------------------------------------------------------------
1 | # Container with network virtualized using the macvlan device driver
2 | lxc.uts.name = alpha
3 | lxc.net.0.type = macvlan
4 | lxc.net.0.flags = up
5 | lxc.net.0.link = eth0
6 | lxc.net.0.hwaddr = 4a:49:43:49:79:bd
7 | lxc.net.0.ipv4.address = 10.2.3.4/24
8 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3596
9 |
--------------------------------------------------------------------------------
/config/templates/common.conf.d/README:
--------------------------------------------------------------------------------
1 | This directory can be used by packages and users to dump LXC
2 | configuration snippets which will then be used by all containers using
3 | the common.conf configuration file (directly or indirectly).
4 |
5 | Configuration files must end with the .conf suffix and LXC will include
6 | those in alphabetical order.
7 |
--------------------------------------------------------------------------------
/src/include/hasmntopt.h:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #ifndef _HASMNTOPT_H
9 | #define _HASMNTOPT_H
10 |
11 | #include "../lxc/compiler.h"
12 |
13 | __hidden extern char* hasmntopt(const struct mntent* mnt, const char* opt);
14 |
15 | #endif
--------------------------------------------------------------------------------
/src/include/fexecve.h:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+
4 | *
5 | */
6 |
7 | #ifndef _LXC_FEXECVE_H
8 | #define _LXC_FEXECVE_H
9 |
10 | #include "../lxc/compiler.h"
11 | #include
12 |
13 | __hidden extern int fexecve(int fd, char *const argv[], char *const envp[]);
14 |
15 | #endif /* _LXC_FEXECVE_H */
16 |
--------------------------------------------------------------------------------
/src/include/strlcpy.h:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #ifndef _STRLCPY_H
9 | #define _STRLCPY_H
10 |
11 | #include "../lxc/compiler.h"
12 | #include
13 |
14 | __hidden extern size_t strlcpy(char *, const char *, size_t);
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/config/templates/nesting.conf.in:
--------------------------------------------------------------------------------
1 | # Use a profile which allows nesting
2 | lxc.apparmor.profile = lxc-container-default-with-nesting
3 |
4 | # Add uncovered mounts of proc and sys, else unprivileged users
5 | # cannot remount those
6 |
7 | lxc.mount.entry = proc dev/.lxc/proc proc create=dir,optional 0 0
8 | lxc.mount.entry = sys dev/.lxc/sys sysfs create=dir,optional 0 0
9 |
--------------------------------------------------------------------------------
/doc/examples/lxc-phys.conf.in:
--------------------------------------------------------------------------------
1 | # Container with network virtualized using a physical network device with name
2 | # 'eth0'
3 | lxc.uts.name = gamma
4 | lxc.net.0.type = phys
5 | lxc.net.0.flags = up
6 | lxc.net.0.link = eth0
7 | lxc.net.0.hwaddr = 4a:49:43:49:79:ff
8 | lxc.net.0.ipv4.address = 10.2.3.6/24
9 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3297
10 |
--------------------------------------------------------------------------------
/doc/examples/lxc-vlan.conf.in:
--------------------------------------------------------------------------------
1 | # Container with network virtualized using the vlan device driver
2 | lxc.uts.name = alpha
3 | lxc.net.0.type = vlan
4 | lxc.net.0.vlan.id = 1234
5 | lxc.net.0.flags = up
6 | lxc.net.0.link = eth0
7 | lxc.net.0.hwaddr = 4a:49:43:49:79:bd
8 | lxc.net.0.ipv4.address = 10.2.3.4/24
9 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3596
10 |
--------------------------------------------------------------------------------
/src/include/strlcat.h:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #ifndef _STRLCAT_H
9 | #define _STRLCAT_H
10 |
11 | #include "../lxc/compiler.h"
12 | #include
13 |
14 | __hidden extern size_t strlcat(char *src, const char *append, size_t len);
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/src/include/pthread_ext.h:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | */
6 |
7 | #ifndef _PTHREAD_EXT_H
8 | #define _PTHREAD_EXT_H
9 |
10 | #include "../lxc/compiler.h"
11 |
12 | #ifndef PTHREAD_CANCELED
13 | #define PTHREAD_CANCELED ((void *)-1)
14 | #endif
15 |
16 | __hidden extern int pthread_setcancelstate(int, int *);
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | .PHONY: all
4 | all: meson
5 | ninja -C build
6 |
7 | .PHONY: meson
8 | meson:
9 | [ -d build ] || meson setup build/
10 |
11 | .PHONY: dist
12 | dist: meson
13 | meson dist -C build/ --formats=gztar
14 | cp build/meson-dist/*.tar.gz .
15 |
16 | .PHONY: install
17 | install:
18 | DESTDIR=$(DESTDIR) ninja -C build install
19 |
--------------------------------------------------------------------------------
/doc/examples/seccomp-v2-denylist.conf:
--------------------------------------------------------------------------------
1 | 2
2 | denylist
3 | # v2 allows comments after the second line, with '#' in first column,
4 | # denylist will allow syscalls by default
5 | # if 'errno 0' was not appended to 'mknod' below, then the task would
6 | # simply be killed when it tried to mknod. 'errno 0' means do not allow
7 | # the container to mknod, but immediately return 0.
8 | mknod errno 0
9 |
--------------------------------------------------------------------------------
/src/lxc/lxc.functions.in:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | # This file contains helpers for the various lxc shell scripts
4 |
5 | globalconf=@LXC_GLOBAL_CONF@
6 | bindir=@BINDIR@
7 | templatedir=@LXCTEMPLATEDIR@
8 | lxcinitdir=@LXCINITDIR@
9 |
10 | lxc_path=$(lxc-config lxc.lxcpath)
11 | lxc_vg=$(lxc-config lxc.bdev.lvm.vg)
12 | lxc_zfsroot=$(lxc-config lxc.bdev.zfs.root)
13 |
--------------------------------------------------------------------------------
/doc/examples/lxc-veth.conf.in:
--------------------------------------------------------------------------------
1 | # Container with network virtualized using a pre-configured bridge named br0 and
2 | # veth pair virtual network devices
3 | lxc.uts.name = beta
4 | lxc.net.0.type = veth
5 | lxc.net.0.flags = up
6 | lxc.net.0.link = br0
7 | lxc.net.0.hwaddr = 4a:49:43:49:79:bf
8 | lxc.net.0.ipv4.address = 10.2.3.5/24
9 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3597
10 |
--------------------------------------------------------------------------------
/config/init/systemd/lxc-net.service.in:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LXC network bridge setup
3 | After=network-online.target
4 | Before=lxc.service
5 | Documentation=man:lxc
6 | ConditionVirtualization=!lxc
7 |
8 | [Service]
9 | Type=oneshot
10 | RemainAfterExit=yes
11 | ExecStart=@LIBEXECDIR@/lxc/lxc-net start
12 | ExecStop=@LIBEXECDIR@/lxc/lxc-net stop
13 |
14 | [Install]
15 | WantedBy=multi-user.target
16 |
--------------------------------------------------------------------------------
/src/lxc/version.h.in:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_VERSION_H
4 | #define __LXC_VERSION_H
5 |
6 | #define LXC_DEVEL @LXC_DEVEL@
7 | #define LXC_VERSION_MAJOR @LXC_VERSION_MAJOR@
8 | #define LXC_VERSION_MINOR @LXC_VERSION_MINOR@
9 | #define LXC_VERSION_MICRO @LXC_VERSION_MICRO@
10 | #define LXC_VERSION_ABI "@LXC_ABI@"
11 | #define LXC_VERSION "@LXC_VERSION@"
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/src/lxc/error.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_ERROR_H
4 | #define __LXC_ERROR_H
5 |
6 | #define LXC_CLONE_ERROR "Failed to clone a new set of namespaces"
7 | #define LXC_UNPRIV_EOPNOTSUPP "the requested function %s is not currently supported with unprivileged containers"
8 |
9 | #include "compiler.h"
10 |
11 | __hidden extern int lxc_error_set_and_log(int pid, int status);
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/src/include/strlcpy.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #include
9 |
10 | size_t strlcpy(char *dest, const char *src, size_t size)
11 | {
12 | size_t ret = strlen(src);
13 |
14 | if (size) {
15 | size_t len = (ret >= size) ? size - 1 : ret;
16 | memcpy(dest, src, len);
17 | dest[len] = '\0';
18 | }
19 |
20 | return ret;
21 | }
22 |
--------------------------------------------------------------------------------
/config/selinux/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_selinux_if = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'lxc.if',
6 | output: 'lxc.if',
7 | install: libselinux.found(),
8 | install_dir: lxcselinuxdir)
9 |
10 | lxc_selinux_te = configure_file(
11 | configuration: dummy_config_data,
12 | input: 'lxc.te',
13 | output: 'lxc.te',
14 | install: libselinux.found(),
15 | install_dir: lxcselinuxdir)
16 |
--------------------------------------------------------------------------------
/src/include/getgrgid_r.h:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #ifndef _GETGRGID_R_H
9 | #define _GETGRGID_R_H
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include "../lxc/compiler.h"
16 |
17 | __hidden extern int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size,
18 | struct group **res);
19 |
20 | #endif /* _GETGRGID_R_H */
21 |
--------------------------------------------------------------------------------
/hooks/clonehostname:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # SPDX-License-Identifier: GPL-2.0-only
4 | #
5 | # Update the hostname in the cloned container's scripts
6 |
7 | # Note that /etc/hostname is updated by lxc itself
8 | for file in \
9 | $LXC_ROOTFS_MOUNT/etc/sysconfig/network \
10 | $LXC_ROOTFS_MOUNT/etc/sysconfig/network-scripts/ifcfg-* \
11 | $LXC_ROOTFS_MOUNT/etc/hosts ;
12 | do
13 | if [ -f $file ]; then
14 | sed -i "s|$LXC_SRC_NAME|$LXC_NAME|" $file
15 | fi
16 | done
17 |
18 | exit 0
19 |
--------------------------------------------------------------------------------
/config/init/systemd/lxc@.service.in:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LXC Container: %i
3 | # This pulls in apparmor, dev-setup, lxc-net
4 | After=lxc.service
5 | Wants=lxc.service
6 | Documentation=man:lxc-start man:lxc
7 |
8 | [Service]
9 | Type=simple
10 | KillMode=mixed
11 | TimeoutStopSec=120s
12 | ExecStart=@BINDIR@/lxc-start -F -n %i
13 | ExecStop=@BINDIR@/lxc-stop -n %i
14 | # Environment=BOOTUP=serial
15 | # Environment=CONSOLETYPE=serial
16 | StateDirectory=lxc
17 | Delegate=yes
18 |
19 | [Install]
20 | WantedBy=multi-user.target
21 |
--------------------------------------------------------------------------------
/doc/lxc.system.conf:
--------------------------------------------------------------------------------
1 | # LVM: volume group to use for new containers
2 | lxc.bdev.lvm.vg = lxc
3 |
4 | # LVM: thin pool to use for new containers
5 | lxc.bdev.lvm.thin_pool = lxc
6 |
7 | # ZFS: Root path
8 | lxc.bdev.zfs.root = lxc
9 |
10 | # Path to the containers
11 | lxc.lxcpath = /var/lib/lxc/
12 |
13 | # Path to the default configuration file
14 | lxc.default_config = /etc/lxc/default.conf
15 |
16 | # Pattern to use for the cgroup path
17 | lxc.cgroup.pattern = lxc/%n
18 |
19 | # List of cgroups to use
20 | lxc.cgroup.use =
21 |
--------------------------------------------------------------------------------
/config/apparmor/profiles/lxc-default:
--------------------------------------------------------------------------------
1 | # Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which
2 | # will source all profiles under /etc/apparmor.d/lxc
3 |
4 | profile lxc-container-default flags=(attach_disconnected,mediate_deleted) {
5 | #include
6 |
7 | # the container may never be allowed to mount devpts. If it does, it
8 | # will remount the host's devpts. We could allow it to do it with
9 | # the newinstance option (but, right now, we don't).
10 | deny mount fstype=devpts,
11 | }
12 |
--------------------------------------------------------------------------------
/config/init/sysvinit/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if 'sysvinit' in init_script
4 | configure_file(
5 | configuration: conf,
6 | input: 'lxc-containers.in',
7 | output: 'lxc-containers',
8 | install: true,
9 | install_dir: join_paths(sysconfdir, 'init.d'))
10 |
11 | configure_file(
12 | configuration: conf,
13 | input: 'lxc-net.in',
14 | output: 'lxc-net',
15 | install: true,
16 | install_dir: join_paths(sysconfdir, 'init.d'))
17 | endif
18 |
--------------------------------------------------------------------------------
/config/apparmor/container-rules.base:
--------------------------------------------------------------------------------
1 | # Run lxc-generate-aa-rules.py on this file after any modification, to generate
2 | # the container-rules file which is appended to container-base.in to create the
3 | # final abstractions/container-base.
4 |
5 | block /sys
6 | allow /sys/fs/cgroup/**
7 | allow /sys/devices/virtual/net/**
8 | allow /sys/class/net/**
9 | block /proc/sys
10 | allow /proc/sys/kernel/shm*
11 | allow /proc/sys/kernel/sem*
12 | allow /proc/sys/kernel/msg*
13 | allow /proc/sys/kernel/hostname
14 | allow /proc/sys/kernel/domainname
15 | allow /proc/sys/net/**
16 |
--------------------------------------------------------------------------------
/src/lxc/criu.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_CRIU_H
4 | #define __LXC_CRIU_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 |
10 | #include "lxc.h"
11 |
12 | __hidden extern bool __criu_pre_dump(struct lxc_container *c, struct migrate_opts *opts);
13 | __hidden extern bool __criu_dump(struct lxc_container *c, struct migrate_opts *opts);
14 | __hidden extern bool __criu_restore(struct lxc_container *c, struct migrate_opts *opts);
15 | __hidden extern bool __criu_check_feature(uint64_t *features_to_check);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/src/include/strlcat.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #if !HAVE_STRLCPY
13 | #include "strlcpy.h"
14 | #endif
15 |
16 | size_t strlcat(char *src, const char *append, size_t len)
17 | {
18 | size_t src_len;
19 |
20 | src_len = strnlen(src, len);
21 | if (src_len == len)
22 | return src_len + strlen(append);
23 |
24 | return src_len + strlcpy(src + src_len, append, len - src_len);
25 | }
26 |
--------------------------------------------------------------------------------
/MAINTAINERS:
--------------------------------------------------------------------------------
1 | Before submitting your patches, check they are signed-off-by
2 | conforming with the DCO contained in the ./CONTRIBUTING file.
3 |
4 | Maintainer
5 | ----------
6 |
7 | Committers : Serge Hallyn, Stéphane Graber, Christian Brauner and Wolfgang Bumiller
8 | Mail patches to : lxc-devel@lists.linuxcontainers.org
9 | Send pull requests at : https://github.com/lxc/lxc
10 | Mailing lists : lxc-devel@lists.linuxcontainers.org, lxc-users@lists.linuxcontainers.org
11 | Web page : https://linuxcontainers.org/lxc
12 | Git location : https://github.com/lxc/lxc
13 |
--------------------------------------------------------------------------------
/config/apparmor/profiles/lxc-default-with-mounting:
--------------------------------------------------------------------------------
1 | # Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which
2 | # will source all profiles under /etc/apparmor.d/lxc
3 |
4 | profile lxc-container-default-with-mounting flags=(attach_disconnected,mediate_deleted) {
5 | #include
6 |
7 | # allow standard blockdevtypes.
8 | # The concern here is in-kernel superblock parsers bringing down the
9 | # host with bad data. However, we continue to disallow proc, sys, securityfs,
10 | # etc to nonstandard locations.
11 | mount fstype=ext*,
12 | mount fstype=xfs,
13 | mount fstype=btrfs,
14 | }
15 |
--------------------------------------------------------------------------------
/config/init/common/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_containers = configure_file(
4 | configuration: conf,
5 | input: 'lxc-containers.in',
6 | output: 'lxc-containers',
7 | install: true,
8 | install_dir: lxclibexec)
9 |
10 | lxc_net = configure_file(
11 | configuration: conf,
12 | input: 'lxc-net.in',
13 | output: 'lxc-net',
14 | install: true,
15 | install_dir: lxclibexec)
16 |
17 | lxc_net_builtin = configure_file(
18 | configuration: conf,
19 | input: 'lxc-net-builtin.in',
20 | output: 'lxc-net-builtin',
21 | install: true,
22 | install_dir: lxclibexec)
23 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-createconfig:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 | #
7 | # This is a test script for the lxc-user-nic program
8 |
9 | set -e
10 |
11 | s=$(mktemp -d /tmp/lxctest-XXXXXX)
12 | f="$s/in.conf"
13 |
14 | cleanup() {
15 | lxc-destroy -n lxctestc || true
16 | rm -rf $s
17 | }
18 |
19 | trap cleanup EXIT
20 |
21 | cat > $f << EOF
22 | lxc.net.0.type = veth
23 | lxc.net.0.hwaddr = 10:66:6a:xx:xx:xx
24 | EOF
25 | lxc-create -t busybox -f $f -n lxctestc
26 | grep -q "xx:xx" /var/lib/lxc/lxctestc/config && { echo "hwaddr not expanded"; exit 1; }
27 | echo "Success"
28 |
--------------------------------------------------------------------------------
/.github/workflows/sync.yml:
--------------------------------------------------------------------------------
1 | name: Sync Fork
2 |
3 | on:
4 | schedule:
5 | - cron: '20 4 * * 5' # every Friday 12:20 (UTC/GMT+08:00 Shanghai)
6 | workflow_dispatch: # on button click
7 |
8 | jobs:
9 | sync:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: tgymnich/fork-sync@v2.0.10
15 | with:
16 | owner: Container-On-Android
17 | base: main
18 | head: main
19 | pr_title: "Merge upstream branch 'main'"
20 | pr_message: "Merge branch 'lxc:main' into main"
21 | auto_merge: false
22 | merge_method: rebase
23 | ignore_fail: true
24 |
--------------------------------------------------------------------------------
/src/include/hasmntopt.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This function has been copied from musl.
6 | */
7 |
8 | #include
9 |
10 | struct mntent {
11 | char* mnt_fsname;
12 | char* mnt_dir;
13 | char* mnt_type;
14 | char* mnt_opts;
15 | int mnt_freq;
16 | int mnt_passno;
17 | };
18 |
19 | char *hasmntopt(const struct mntent *mnt, const char *opt)
20 | {
21 | size_t l = strlen(opt);
22 | char *p = mnt->mnt_opts;
23 | for (;;) {
24 | if (!strncmp(p, opt, l) && (!p[l] || p[l]==',' || p[l]=='='))
25 | return p;
26 | p = strchr(p, ',');
27 | if (!p) return 0;
28 | p++;
29 | }
30 | }
--------------------------------------------------------------------------------
/config/init/systemd/lxc.service.in:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LXC Container Initialization and Autoboot Code
3 | After=network.target lxc-net.service remote-fs.target
4 | Wants=lxc-net.service
5 | Documentation=man:lxc-autostart man:lxc
6 |
7 | [Service]
8 | Type=oneshot
9 | RemainAfterExit=yes
10 | ExecStartPre=@LIBEXECDIR@/lxc/lxc-apparmor-load
11 | ExecStart=@LIBEXECDIR@/lxc/lxc-containers start
12 | ExecStop=@LIBEXECDIR@/lxc/lxc-containers stop
13 | ExecReload=@LIBEXECDIR@/lxc/lxc-apparmor-load
14 | # Environment=BOOTUP=serial
15 | # Environment=CONSOLETYPE=serial
16 | StateDirectory=lxc
17 | Delegate=yes
18 |
19 | [Install]
20 | WantedBy=multi-user.target
21 |
--------------------------------------------------------------------------------
/src/lxc/attach.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_ATTACH_H
4 | #define __LXC_ATTACH_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "lxc.h"
12 |
13 | #include "compiler.h"
14 | #include "namespace.h"
15 |
16 | struct lxc_conf;
17 | struct lxc_container;
18 |
19 | __hidden extern int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
20 | void *exec_payload, lxc_attach_options_t *options,
21 | pid_t *attached_process);
22 |
23 | __hidden extern int lxc_attach_remount_sys_proc(void);
24 |
25 | #endif /* __LXC_ATTACH_H */
26 |
--------------------------------------------------------------------------------
/config/apparmor/profiles/lxc-default-with-nesting:
--------------------------------------------------------------------------------
1 | # Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which
2 | # will source all profiles under /etc/apparmor.d/lxc
3 |
4 | profile lxc-container-default-with-nesting flags=(attach_disconnected,mediate_deleted) {
5 | #include
6 | #include
7 |
8 | deny /dev/.lxc/proc/** rw,
9 | deny /dev/.lxc/sys/** rw,
10 | mount fstype=proc -> /var/cache/lxc/**,
11 | mount fstype=sysfs -> /var/cache/lxc/**,
12 | mount options=(rw,bind),
13 | mount fstype=cgroup -> /sys/fs/cgroup/**,
14 | mount fstype=cgroup2 -> /sys/fs/cgroup/**,
15 | }
16 |
--------------------------------------------------------------------------------
/config/apparmor/abstractions/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if libapparmor.found()
4 | configure_file(
5 | command: ['cat', '@INPUT@'],
6 | capture: true,
7 | input: ['container-base.in', '../container-rules'],
8 | output: 'container-base',
9 | install: true,
10 | install_dir: join_paths(sysconfdir, 'apparmor.d', 'abstractions', 'lxc'))
11 |
12 | configure_file(
13 | configuration: conf,
14 | input: 'start-container.in',
15 | output: 'start-container',
16 | install: true,
17 | install_dir: join_paths(sysconfdir, 'apparmor.d', 'abstractions', 'lxc'))
18 | endif
19 |
--------------------------------------------------------------------------------
/config/apparmor/profiles/lxc-default-cgns:
--------------------------------------------------------------------------------
1 | # Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which
2 | # will source all profiles under /etc/apparmor.d/lxc
3 |
4 | profile lxc-container-default-cgns flags=(attach_disconnected,mediate_deleted) {
5 | #include
6 |
7 | # the container may never be allowed to mount devpts. If it does, it
8 | # will remount the host's devpts. We could allow it to do it with
9 | # the newinstance option (but, right now, we don't).
10 | deny mount fstype=devpts,
11 | mount fstype=cgroup -> /sys/fs/cgroup/**,
12 | mount fstype=cgroup2 -> /sys/fs/cgroup/**,
13 | mount fstype=overlay,
14 | }
15 |
--------------------------------------------------------------------------------
/src/lxc/pam/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | pam_cgfs_sources = files(
4 | 'pam_cgfs.c',
5 | '../file_utils.c',
6 | '../file_utils.h',
7 | '../macro.h',
8 | '../memory_utils.h',
9 | '../open_utils.h',
10 | '../string_utils.c',
11 | '../string_utils.h') + include_sources
12 |
13 | if want_pam_cgroup
14 | pam_cgfs = shared_module(
15 | 'pam_cgfs',
16 | include_directories: liblxc_includes,
17 | sources: pam_cgfs_sources,
18 | dependencies: [pkgconfig_libs],
19 | name_prefix: '',
20 | install_mode: 'rw-r--r--', # 644
21 | install: true,
22 | install_dir: pam_security)
23 | endif
24 |
--------------------------------------------------------------------------------
/config/templates/userns.conf.in:
--------------------------------------------------------------------------------
1 | # CAP_SYS_ADMIN in init-user-ns is required for cgroup.devices
2 | #
3 | # Default legacy cgroup configuration
4 | #
5 | lxc.cgroup.devices.deny =
6 | lxc.cgroup.devices.allow =
7 |
8 | # Default unified cgroup configuration
9 | #
10 | lxc.cgroup2.devices.deny =
11 | lxc.cgroup2.devices.allow =
12 |
13 | # Start with a full set of capabilities in user namespaces.
14 | lxc.cap.drop =
15 | lxc.cap.keep =
16 |
17 | # We can't move bind-mounts, so don't use /dev/lxc/
18 | lxc.tty.dir =
19 |
20 | # Setup the default mounts
21 | lxc.mount.auto = sys:rw
22 |
23 | # Lastly, include all the configs from @LXCTEMPLATECONFIG@/userns.conf.d/
24 | lxc.include = @LXCTEMPLATECONFIG@/userns.conf.d/
25 |
--------------------------------------------------------------------------------
/src/lxc/storage/rsync.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_RSYNC_H
4 | #define __LXC_RSYNC_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 |
10 | #include "compiler.h"
11 |
12 | struct rsync_data {
13 | struct lxc_storage *orig;
14 | struct lxc_storage *new;
15 | };
16 |
17 | struct rsync_data_char {
18 | char *src;
19 | char *dest;
20 | };
21 |
22 | /* new helpers */
23 | __hidden extern int lxc_rsync_exec_wrapper(void *data);
24 | __hidden extern int lxc_storage_rsync_exec_wrapper(void *data);
25 | __hidden extern int lxc_rsync_exec(const char *src, const char *dest);
26 | __hidden extern int lxc_rsync(struct rsync_data *data);
27 |
28 | #endif /* __LXC_RSYNC_H */
29 |
--------------------------------------------------------------------------------
/src/tests/basic.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include "lxctest.h"
15 |
16 | int main(int argc, char *argv[])
17 | {
18 | int ret;
19 | struct lxc_container *c;
20 |
21 | c = lxc_container_new("init-pid", NULL);
22 | if (!c)
23 | exit(EXIT_FAILURE);
24 |
25 | ret = c->init_pid(c);
26 | c->destroy(c);
27 | lxc_container_put(c);
28 | /* Return value needs to be -1. Any other negative error code is to be
29 | * considered invalid.
30 | */
31 | if (ret != -1)
32 | exit(EXIT_FAILURE);
33 |
34 | exit(EXIT_SUCCESS);
35 | }
36 |
--------------------------------------------------------------------------------
/config/init/systemd/lxc-apparmor-load:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # lxc-apparmor-load: Load AppArmor profiles, if supported by the system
3 |
4 | set -eu
5 |
6 | # don't load profiles if mount mediation is not supported
7 | SYSF=/sys/kernel/security/apparmor/features/mount/mask
8 | if [ -f $SYSF ]; then
9 | if [ -x /lib/apparmor/profile-load ]; then
10 | /lib/apparmor/profile-load usr.bin.lxc-copy
11 | /lib/apparmor/profile-load usr.bin.lxc-start
12 | /lib/apparmor/profile-load lxc-containers
13 | elif [ -x /lib/init/apparmor-profile-load ]; then
14 | /lib/init/apparmor-profile-load usr.bin.lxc-copy
15 | /lib/init/apparmor-profile-load usr.bin.lxc-start
16 | /lib/init/apparmor-profile-load lxc-containers
17 | fi
18 | fi
19 |
--------------------------------------------------------------------------------
/src/lxc/uuid.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_UUID_H
4 | #define __LXC_UUID_H
5 |
6 | #ifndef _GNU_SOURCE
7 | #define _GNU_SOURCE 1
8 | #endif
9 | #define __STDC_FORMAT_MACROS
10 | #include
11 |
12 | #include "compiler.h"
13 |
14 | typedef union lxc_id128 lxc_id128_t;
15 |
16 | union lxc_id128 {
17 | uint8_t bytes[16];
18 | uint64_t qwords[2];
19 | };
20 |
21 | __hidden extern int lxc_id128_randomize(lxc_id128_t *ret);
22 | __hidden extern int lxc_id128_write(const char *p, lxc_id128_t id);
23 | __hidden extern int lxc_id128_write_fd(int fd, lxc_id128_t id);
24 | __hidden extern char *id128_to_uuid_string(lxc_id128_t id, char s[37]);
25 |
26 | #endif /* __LXC_UUID_H */
27 |
--------------------------------------------------------------------------------
/src/include/pthread_setcancelstate.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+ *
4 | *
5 | * This is not a standard implementation.
6 | * It only protects getgrgid_r().
7 | */
8 |
9 | #include
10 | #include "pthread_ext.h"
11 |
12 | static const int signals[] = {
13 | SIGINT,
14 | SIGTERM,
15 | SIGQUIT,
16 | };
17 |
18 | int pthread_setcancelstate(int state, int *oldstate)
19 | {
20 | sigset_t signal_set;
21 | sigset_t old_mask;
22 | sigemptyset(&signal_set);
23 |
24 | for (size_t i = 0; i < sizeof(signals)/sizeof(signals[0]); i++)
25 | sigaddset(&signal_set, signals[i]);
26 |
27 | int operation = (state == 1) ? SIG_UNBLOCK : SIG_BLOCK;
28 | return pthread_sigmask(operation, &signal_set, &old_mask);
29 | }
30 |
--------------------------------------------------------------------------------
/doc/examples/seccomp-v2.conf:
--------------------------------------------------------------------------------
1 | 2
2 | allowlist trap
3 | # 'allowlist' would normally mean kill a task doing any syscall which is not
4 | # allowlisted below. By appending 'trap' to the line, we will cause a SIGSYS
5 | # to be sent to the task instead. 'errno 0' would mean don't allow the system
6 | # call but immediately return 0. 'errno 22' would mean return EINVAL immediately.
7 | [x86_64]
8 | open
9 | close
10 | read
11 | write
12 | mount
13 | umount2
14 | # Since we are listing system calls by name, we can also ask to have them resolved
15 | # for another arch, i.e. for 32/64-bit versions.
16 | [x86]
17 | open
18 | close
19 | read
20 | write
21 | mount
22 | umount2
23 | # Do note that this policy does not allowlist enough system calls to allow a
24 | # system container to boot.
25 |
--------------------------------------------------------------------------------
/src/tests/may_control.c:
--------------------------------------------------------------------------------
1 | /* control.c
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | static void usage(const char *me)
14 | {
15 | printf("Usage: %s name [lxcpath]\n", me);
16 | exit(EXIT_SUCCESS);
17 | }
18 |
19 | int main(int argc, char *argv[])
20 | {
21 | const char *lxcpath = NULL, *name;
22 | bool may = false;
23 | struct lxc_container *c;
24 |
25 | if (argc < 2)
26 | usage(argv[0]);
27 |
28 | name = argv[1];
29 |
30 | if (argc == 3)
31 | lxcpath = argv[2];
32 |
33 | c = lxc_container_new(name, lxcpath);
34 | if (c)
35 | may = c->may_control(c);
36 |
37 | printf("You may%s control %s\n", may ? "" : " not", name);
38 | exit(may ? 0 : 1);
39 | }
40 |
--------------------------------------------------------------------------------
/config/init/module/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: MIT
2 |
3 | if 'module' in init_script
4 | configured_files = []
5 |
6 | foreach module_files: [
7 | 'boot-completed.sh.in',
8 | 'customize.sh.in',
9 | 'module.prop.in',
10 | 'service.sh.in',
11 | 'uninstall.sh.in',
12 | ]
13 | configured_file = configure_file(
14 | input: module_files,
15 | output: '@BASENAME@',
16 | configuration: conf,
17 | )
18 | configured_files += configured_file
19 | endforeach
20 |
21 | configure_file(
22 | command: [zip, '-rj', '@OUTPUT@', '@INPUT@'],
23 | input: configured_files,
24 | output: 'lxc-module.zip',
25 | install: true,
26 | install_dir: project_source_root)
27 |
28 | endif
29 |
--------------------------------------------------------------------------------
/config/apparmor/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if libapparmor.found()
4 | configure_file(
5 | configuration: dummy_config_data,
6 | input: 'lxc-containers',
7 | output: 'lxc-containers',
8 | install: true,
9 | install_dir: join_paths(sysconfdir, 'apparmor.d'))
10 |
11 | configure_file(
12 | configuration: dummy_config_data,
13 | input: 'usr.bin.lxc-start',
14 | output: 'usr.bin.lxc-start',
15 | install: true,
16 | install_dir: join_paths(sysconfdir, 'apparmor.d'))
17 |
18 | configure_file(
19 | configuration: dummy_config_data,
20 | input: 'usr.bin.lxc-copy',
21 | output: 'usr.bin.lxc-copy',
22 | install: true,
23 | install_dir: join_paths(sysconfdir, 'apparmor.d'))
24 | endif
25 |
--------------------------------------------------------------------------------
/doc/examples/lxc-complex.conf.in:
--------------------------------------------------------------------------------
1 | # Container with network a complex network mixing macvlan, veth and
2 | # physical network devices
3 | lxc.uts.name = complex
4 | lxc.net.0.type = veth
5 | lxc.net.0.flags = up
6 | lxc.net.0.link = br0
7 | lxc.net.0.hwaddr = 4a:49:43:49:79:bf
8 | lxc.net.0.ipv4.address = 10.2.3.5/24
9 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3597
10 |
11 | lxc.net.0.type = macvlan
12 | lxc.net.0.flags = up
13 | lxc.net.0.link = eth0
14 | lxc.net.0.hwaddr = 4a:49:43:49:79:bd
15 | lxc.net.0.ipv4.address = 10.2.3.4/24
16 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3596
17 |
18 | lxc.net.0.type = phys
19 | lxc.net.0.flags = up
20 | lxc.net.0.link = random0
21 | lxc.net.0.hwaddr = 4a:49:43:49:79:ff
22 | lxc.net.0.ipv4.address = 10.2.3.6/24
23 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3297
24 |
--------------------------------------------------------------------------------
/templates/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | template_scripts = configure_file(
4 | configuration: conf,
5 | input: 'lxc-busybox.in',
6 | output: 'lxc-busybox',
7 | install: true,
8 | install_dir: lxctemplatedir)
9 |
10 | template_scripts = configure_file(
11 | configuration: conf,
12 | input: 'lxc-download.in',
13 | output: 'lxc-download',
14 | install: true,
15 | install_dir: lxctemplatedir)
16 |
17 | template_scripts = configure_file(
18 | configuration: conf,
19 | input: 'lxc-local.in',
20 | output: 'lxc-local',
21 | install: true,
22 | install_dir: lxctemplatedir)
23 |
24 | template_scripts = configure_file(
25 | configuration: conf,
26 | input: 'lxc-oci.in',
27 | output: 'lxc-oci',
28 | install: true,
29 | install_dir: lxctemplatedir)
30 |
--------------------------------------------------------------------------------
/coccinelle/run-coccinelle.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | top="$(git rev-parse --show-toplevel)"
4 | files="$(git ls-files ':/*.[ch]')"
5 | args=
6 |
7 | case "$1" in
8 | -i)
9 | args="$args --in-place"
10 | shift
11 | ;;
12 | esac
13 |
14 | if ! parallel -h >/dev/null; then
15 | echo 'Please install GNU parallel (package "parallel")'
16 | exit 1
17 | fi
18 |
19 | for SCRIPT in ${@-$top/coccinelle/*.cocci} ; do
20 | echo "--x-- Processing $SCRIPT --x--"
21 | TMPFILE=$(mktemp)
22 | echo "+ spatch --sp-file $SCRIPT $args ..."
23 | parallel --halt now,fail=1 --keep-order --noswap --max-args=20 \
24 | spatch --sp-file $SCRIPT $args ::: $files \
25 | 2>"$TMPFILE" || cat "$TMPFILE"
26 | echo -e "--x-- Processed $SCRIPT --x--\n"
27 | done
28 |
--------------------------------------------------------------------------------
/src/lxc/state.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_STATE_H
4 | #define __LXC_STATE_H
5 |
6 | #include "config.h"
7 |
8 | #include "compiler.h"
9 |
10 | #define MAX_STATE_LENGTH (8 + 1)
11 |
12 | typedef enum {
13 | STOPPED,
14 | STARTING,
15 | RUNNING,
16 | STOPPING,
17 | ABORTING,
18 | FREEZING,
19 | FROZEN,
20 | THAWED,
21 | MAX_STATE,
22 | } lxc_state_t;
23 |
24 | enum {
25 | REBOOT_NONE,
26 | REBOOT_REQ,
27 | REBOOT_INIT
28 | };
29 |
30 | __hidden extern lxc_state_t lxc_getstate(const char *name, const char *lxcpath, int timeout);
31 |
32 | __hidden extern lxc_state_t lxc_str2state(const char *state);
33 | __hidden extern const char *lxc_state2str(lxc_state_t state);
34 | __hidden extern int lxc_wait(const char *lxcname, const char *states, int timeout,
35 | const char *lxcpath);
36 |
37 | #endif /* __LXC_STATE_H */
38 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | The template below is mostly useful for bug reports and support questions.
2 | Feel free to remove anything which doesn't apply to you and add more information where it makes sense.
3 |
4 | # Required information
5 |
6 | * Distribution:
7 | * Distribution version:
8 | * The output of
9 | * `lxc-start --version`
10 | * `lxc-checkconfig`
11 | * `uname -a`
12 | * `cat /proc/self/cgroup`
13 | * `cat /proc/1/mounts`
14 |
15 | # Issue description
16 |
17 | A brief description of what failed or what could be improved.
18 |
19 | # Steps to reproduce
20 |
21 | 1. Step one
22 | 2. Step two
23 | 3. Step three
24 |
25 | # Information to attach
26 |
27 | - [ ] any relevant kernel output (`dmesg`)
28 | - [ ] container log (The file from running `lxc-start -n -l TRACE -o `)
29 | - [ ] the containers configuration file
30 |
--------------------------------------------------------------------------------
/src/include/fexecve.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+
4 | *
5 | */
6 |
7 | #ifndef _GNU_SOURCE
8 | #define _GNU_SOURCE 1
9 | #endif
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include "config.h"
17 | #include "macro.h"
18 | #include "process_utils.h"
19 |
20 | int fexecve(int fd, char *const argv[], char *const envp[])
21 | {
22 | char procfd[LXC_PROC_PID_FD_LEN];
23 | int ret;
24 |
25 | if (fd < 0 || !argv || !envp) {
26 | errno = EINVAL;
27 | return -1;
28 | }
29 |
30 | execveat(fd, "", argv, envp, AT_EMPTY_PATH);
31 | if (errno != ENOSYS)
32 | return -1;
33 |
34 | ret = snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", fd);
35 | if (ret < 0 || (size_t)ret >= sizeof(procfd)) {
36 | errno = ENAMETOOLONG;
37 | return -1;
38 | }
39 |
40 | execve(procfd, argv, envp);
41 | return -1;
42 | }
43 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-procsys:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 |
7 | # Ensure that when /proc and/or /sys do not exist in the container,
8 | # it is started successfully anyway.
9 |
10 | set -ex
11 | FAIL() {
12 | echo -n "Failed " >&2
13 | echo "$*" >&2
14 | lxc-destroy -n lxc-test-procsys -f
15 | exit 1
16 | }
17 |
18 | lxc-destroy -n lxc-test-procsys -f || :
19 | lxc-create -t busybox -n lxc-test-procsys
20 | rmdir /var/lib/lxc/lxc-test-procsys/rootfs/{proc,sys}
21 |
22 | lxc-start -n lxc-test-procsys
23 | lxc-wait -n lxc-test-procsys -s RUNNING || FAIL "waiting for busybox container to run"
24 |
25 | lxc-attach -n lxc-test-procsys -- sh -c 'test -f /proc/version' || FAIL "/proc/version not found"
26 | lxc-attach -n lxc-test-procsys -- sh -c 'test -d /sys/fs' || FAIL "/sys/fs not found"
27 |
28 | lxc-destroy -n lxc-test-procsys -f
29 | exit 0
30 |
--------------------------------------------------------------------------------
/config/bash/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | bash_completion = configure_file(
4 | configuration: conf,
5 | input: '_lxc.in',
6 | output: '_lxc',
7 | install: true,
8 | install_dir: bashcompletiondir)
9 |
10 |
11 | foreach cmd: [
12 | 'lxc-attach',
13 | 'lxc-autostart',
14 | 'lxc-cgroup',
15 | 'lxc-checkpoint',
16 | 'lxc-config',
17 | 'lxc-console',
18 | 'lxc-copy',
19 | 'lxc-create',
20 | 'lxc-destroy',
21 | 'lxc-device',
22 | 'lxc-execute',
23 | 'lxc-freeze',
24 | 'lxc-info',
25 | 'lxc-ls',
26 | 'lxc-monitor',
27 | 'lxc-snapshot',
28 | 'lxc-start',
29 | 'lxc-stop',
30 | 'lxc-top',
31 | 'lxc-unfreeze',
32 | 'lxc-unshare',
33 | 'lxc-usernsexec',
34 | 'lxc-wait',
35 | ]
36 | install_symlink(cmd,
37 | pointing_to: '_lxc',
38 | install_dir: bashcompletiondir)
39 | endforeach
40 |
--------------------------------------------------------------------------------
/aarch64-android-api30.txt:
--------------------------------------------------------------------------------
1 | [binaries]
2 | c = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang'
3 | cpp = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang++'
4 | ar = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar'
5 | as = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-as'
6 | ld = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ld'
7 | strip = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip'
8 | ranlib = 'android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib'
9 | pkgconfig = '/usr/bin/pkg-config'
10 | cmake = '/usr/bin/cmake'
11 |
12 | [host_machine]
13 | system = 'linux'
14 | cpu_family = 'x86_64'
15 | cpu = 'x86_64'
16 | endian = 'little'
17 |
18 | [target_machine]
19 | system = 'linux'
20 | cpu_family = 'aarch64'
21 | cpu = 'aarch64'
22 | endian = 'little'
23 |
--------------------------------------------------------------------------------
/src/lxc/lsm/lsm.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 | #include "conf.h"
13 | #include "log.h"
14 | #include "lsm.h"
15 |
16 | lxc_log_define(lsm, lxc);
17 |
18 | __hidden extern struct lsm_ops *lsm_apparmor_ops_init(void);
19 | __hidden extern struct lsm_ops *lsm_selinux_ops_init(void);
20 | __hidden extern struct lsm_ops *lsm_nop_ops_init(void);
21 |
22 | struct lsm_ops *lsm_init_static(void)
23 | {
24 | struct lsm_ops *ops = NULL;
25 |
26 | #if HAVE_APPARMOR
27 | ops = lsm_apparmor_ops_init();
28 | #endif
29 |
30 | #if HAVE_SELINUX
31 | if (!ops)
32 | ops = lsm_selinux_ops_init();
33 | #endif
34 |
35 | if (!ops)
36 | ops = lsm_nop_ops_init();
37 |
38 | INFO("Initialized LSM security driver %s", ops->name);
39 | return ops;
40 | }
41 |
--------------------------------------------------------------------------------
/src/lxc/cgroups/cgroup_utils.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_CGROUP_UTILS_H
4 | #define __LXC_CGROUP_UTILS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 | #include "file_utils.h"
13 |
14 | __hidden extern bool unified_cgroup_fd(int fd);
15 |
16 | static inline bool cgns_supported(void)
17 | {
18 | static int supported = -1;
19 |
20 | if (supported == -1)
21 | supported = file_exists("/proc/self/ns/cgroup");
22 |
23 | return supported == 1;
24 | }
25 |
26 | __hidden extern int cgroup_tree_prune(int dfd, const char *path);
27 |
28 | /*
29 | * This function can only be called on information parsed from
30 | * /proc//cgroup or on absolute paths and it will verify the latter and
31 | * return NULL if a relative path is passed.
32 | */
33 | __hidden extern char *prune_init_scope(char *path);
34 |
35 | #endif /* __LXC_CGROUP_UTILS_H */
36 |
--------------------------------------------------------------------------------
/src/tests/fuzz-lxc-config-read.c:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: LGPL-2.1+
3 | */
4 |
5 | #include "config.h"
6 |
7 | #include
8 | #include
9 |
10 | #include "conf.h"
11 | #include "confile.h"
12 | #include "lxctest.h"
13 | #include "utils.h"
14 |
15 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
16 | int fd = -1;
17 | char tmpf[] = "/tmp/fuzz-lxc-config-read-XXXXXX";
18 | struct lxc_conf *conf = NULL;
19 |
20 | /*
21 | * 100Kb should probably be enough to trigger all the issues
22 | * we're interested in without any timeouts
23 | */
24 | if (size > 102400)
25 | return 0;
26 |
27 | fd = lxc_make_tmpfile(tmpf, false);
28 | lxc_test_assert_abort(fd >= 0);
29 | lxc_write_nointr(fd, data, size);
30 | close(fd);
31 |
32 | conf = lxc_conf_init();
33 | lxc_test_assert_abort(conf);
34 | lxc_config_read(tmpf, conf, false);
35 | lxc_conf_free(conf);
36 |
37 | (void) unlink(tmpf);
38 | return 0;
39 | }
40 |
--------------------------------------------------------------------------------
/doc/FAQ.txt:
--------------------------------------------------------------------------------
1 |
2 | Troubleshooting:
3 | ===============
4 |
5 |
6 | Error:
7 | ------
8 |
9 | error while loading shared libraries reported after sudo make install
10 | and when trying to run lxc-execute.
11 |
12 | "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash"
13 |
14 | /usr/local/bin/lxc-execute: error while loading shared libraries:
15 | liblxc-0.5.0.so: cannot open shared object file: No such file or
16 | directory
17 |
18 | Answer:
19 | -------
20 | update the ld cache by running ldconfig.
21 |
22 |
23 |
24 | Error:
25 | ------
26 |
27 | error when starting a container.
28 |
29 | "lxc-start Invalid argument"
30 |
31 | "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash"
32 | "[syserr] lxc_start:96: Invalid argument - failed to fork into a new
33 | namespace"
34 |
35 | Answer:
36 | -------
37 |
38 | read the lxc man page about kernel version prereq :) most probably
39 | your kernel is not configured to support the container options you
40 | want to use.
41 |
--------------------------------------------------------------------------------
/doc/ja/FAQ.txt:
--------------------------------------------------------------------------------
1 |
2 | Troubleshooting:
3 | ===============
4 |
5 |
6 | Error:
7 | ------
8 |
9 | error while loading shared libraries reported after sudo make install
10 | and when trying to run lxc-execute.
11 |
12 | "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash"
13 |
14 | /usr/local/bin/lxc-execute: error while loading shared libraries:
15 | liblxc-0.5.0.so: cannot open shared object file: No such file or
16 | directory
17 |
18 | Answer:
19 | -------
20 | update the ld cache by running ldconfig.
21 |
22 |
23 |
24 | Error:
25 | ------
26 |
27 | error when starting a container.
28 |
29 | "lxc-start Invalid argument"
30 |
31 | "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash"
32 | "[syserr] lxc_start:96: Invalid argument - failed to fork into a new
33 | namespace"
34 |
35 | Answer:
36 | -------
37 |
38 | read the lxc man page about kernel version prereq :) most probably
39 | your kernel is not configured to support the container options you
40 | want to use.
41 |
--------------------------------------------------------------------------------
/doc/ko/FAQ.txt:
--------------------------------------------------------------------------------
1 |
2 | Troubleshooting:
3 | ===============
4 |
5 |
6 | Error:
7 | ------
8 |
9 | error while loading shared libraries reported after sudo make install
10 | and when trying to run lxc-execute.
11 |
12 | "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash"
13 |
14 | /usr/local/bin/lxc-execute: error while loading shared libraries:
15 | liblxc-0.5.0.so: cannot open shared object file: No such file or
16 | directory
17 |
18 | Answer:
19 | -------
20 | update the ld cache by running ldconfig.
21 |
22 |
23 |
24 | Error:
25 | ------
26 |
27 | error when starting a container.
28 |
29 | "lxc-start Invalid argument"
30 |
31 | "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash"
32 | "[syserr] lxc_start:96: Invalid argument - failed to fork into a new
33 | namespace"
34 |
35 | Answer:
36 | -------
37 |
38 | read the lxc man page about kernel version prereq :) most probably
39 | your kernel is not configured to support the container options you
40 | want to use.
41 |
--------------------------------------------------------------------------------
/src/lxc/storage/dir.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_DIR_H
4 | #define __LXC_DIR_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 |
13 | struct lxc_storage;
14 |
15 | struct bdev_specs;
16 |
17 | struct lxc_conf;
18 |
19 | __hidden extern int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
20 | const char *oldname, const char *cname, const char *oldpath,
21 | const char *lxcpath, int snap, uint64_t newsize,
22 | struct lxc_conf *conf);
23 | __hidden extern int dir_create(struct lxc_storage *bdev, const char *dest, const char *n,
24 | struct bdev_specs *specs, const struct lxc_conf *conf);
25 | __hidden extern int dir_destroy(struct lxc_storage *orig);
26 | __hidden extern bool dir_detect(const char *path);
27 | __hidden extern int dir_mount(struct lxc_storage *bdev);
28 | __hidden extern int dir_umount(struct lxc_storage *bdev);
29 |
30 | #endif /* __LXC_DIR_H */
31 |
--------------------------------------------------------------------------------
/src/lxc/storage/rbd.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_RDB_H
4 | #define __LXC_RDB_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 |
13 | struct lxc_storage;
14 |
15 | struct bdev_specs;
16 |
17 | struct lxc_conf;
18 |
19 | __hidden extern int rbd_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
20 | const char *oldname, const char *cname, const char *oldpath,
21 | const char *lxcpath, int snap, uint64_t newsize,
22 | struct lxc_conf *conf);
23 | __hidden extern int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
24 | struct bdev_specs *specs, const struct lxc_conf *conf);
25 | __hidden extern int rbd_destroy(struct lxc_storage *orig);
26 | __hidden extern bool rbd_detect(const char *path);
27 | __hidden extern int rbd_mount(struct lxc_storage *bdev);
28 | __hidden extern int rbd_umount(struct lxc_storage *bdev);
29 |
30 | #endif /* __LXC_RDB_H */
31 |
--------------------------------------------------------------------------------
/src/lxc/storage/loop.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_LOOP_H
4 | #define __LXC_LOOP_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 |
13 | struct lxc_storage;
14 |
15 | struct bdev_specs;
16 |
17 | struct lxc_conf;
18 |
19 | __hidden extern int loop_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
20 | const char *oldname, const char *cname, const char *oldpath,
21 | const char *lxcpath, int snap, uint64_t newsize,
22 | struct lxc_conf *conf);
23 | __hidden extern int loop_create(struct lxc_storage *bdev, const char *dest, const char *n,
24 | struct bdev_specs *specs, const struct lxc_conf *conf);
25 | __hidden extern int loop_destroy(struct lxc_storage *orig);
26 | __hidden extern bool loop_detect(const char *path);
27 | __hidden extern int loop_mount(struct lxc_storage *bdev);
28 | __hidden extern int loop_umount(struct lxc_storage *bdev);
29 |
30 | #endif /* __LXC_LOOP_H */
31 |
--------------------------------------------------------------------------------
/config/sysconfig/lxc.in:
--------------------------------------------------------------------------------
1 | # LXC_AUTO - whether or not to start containers at boot
2 | LXC_AUTO="true"
3 |
4 | # BOOTGROUPS - What groups should start on bootup?
5 | # Comma separated list of groups.
6 | # Leading comma, trailing comma or embedded double
7 | # comma indicates when the NULL group should be run.
8 | # Example (default): boot the onboot group first then the NULL group
9 | BOOTGROUPS="onboot,"
10 |
11 | # SHUTDOWNDELAY - Wait time for a container to shut down.
12 | # Container shutdown can result in lengthy system
13 | # shutdown times. Even 5 seconds per container can be
14 | # too long.
15 | SHUTDOWNDELAY=5
16 |
17 | # OPTIONS can be used for anything else.
18 | # If you want to boot everything then
19 | # options can be "-a" or "-a -A".
20 | OPTIONS=
21 |
22 | # STOPOPTS are stop options. The can be used for anything else to stop.
23 | # If you want to kill containers fast, use -k
24 | STOPOPTS="-a -A -s"
25 |
26 | USE_LXC_BRIDGE="false"
27 |
28 | [ ! -f @LXC_DISTRO_SYSCONF@/lxc-net ] || . @LXC_DISTRO_SYSCONF@/lxc-net
29 |
--------------------------------------------------------------------------------
/src/lxc/idmap_utils.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_IDMAP_UTILS_H
4 | #define __LXC_IDMAP_UTILS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include "compiler.h"
17 | #include "conf.h"
18 |
19 | __hidden extern int lxc_map_ids(struct list_head *idmap, pid_t pid);
20 | __hidden extern int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype);
21 | __hidden extern int mapped_hostid(unsigned id, const struct lxc_conf *conf, enum idtype idtype);
22 | __hidden extern struct id_map *mapped_hostid_add(const struct lxc_conf *conf, uid_t id,
23 | enum idtype type);
24 | __hidden extern struct id_map *mapped_nsid_add(const struct lxc_conf *conf, unsigned id,
25 | enum idtype idtype);
26 |
27 | __hidden extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, size_t buf_size)
28 | __access_r(3, 4);
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-exit-code:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 |
7 | set -e
8 |
9 | FAIL() {
10 | echo -n "Failed " >&2
11 | echo "$*" >&2
12 | lxc-destroy -n busy -f
13 | exit 1
14 | }
15 |
16 | # Create a container
17 | lxc-create -t busybox -n busy || FAIL "creating busybox container"
18 |
19 | # Run lxc-execute to make sure it fails when the command fails, and
20 | # succeed when the command succeeds.
21 | lxc-execute -n busy -- sh -c 'exit 1' && FAIL "should be failing" || true
22 | lxc-execute -n busy -- sh -c 'exit 0' || FAIL "should be succeeding"
23 |
24 | # Now, start the container and wait for it to be in running state.
25 | lxc-start -n busy -d || FAIL "starting busybox container"
26 | lxc-wait -n busy -s RUNNING || FAIL "waiting for busybox container to run"
27 |
28 | # And run the same tests on lxc-attach.
29 | lxc-attach -n busy -- sh -c 'exit 1' && FAIL "should be failing" || true
30 | lxc-attach -n busy -- sh -c 'exit 0' || FAIL "should be succeeding"
31 |
32 | lxc-destroy -n busy -f
33 |
34 | exit 0
35 |
--------------------------------------------------------------------------------
/src/lxc/parse.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_PARSE_H
4 | #define __LXC_PARSE_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 |
13 | typedef int (*lxc_dir_cb)(const char *name, const char *directory,
14 | const char *file, void *data);
15 |
16 | typedef int (*lxc_file_cb)(char *buffer, void *data);
17 |
18 | __hidden __hot extern int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data);
19 |
20 | __hidden __hot extern int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback,
21 | void *data);
22 |
23 | /* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that
24 | * normal string-handling functions can be used on the buffer. */
25 | __hidden extern void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
26 | off_t offset);
27 | /* munmap() wrapper. Use it to free memory mmap()ed with lxc_strmmap(). */
28 | __hidden extern int lxc_strmunmap(void *addr, size_t length);
29 |
30 | #endif /* __LXC_PARSE_H */
31 |
--------------------------------------------------------------------------------
/config/templates/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_conf_common_seccomp = configure_file(
4 | configuration: conf,
5 | input: 'common.seccomp',
6 | output: 'common.seccomp',
7 | install: true,
8 | install_dir: lxctemplateconfdir)
9 |
10 | lxc_conf_common_main = configure_file(
11 | configuration: conf,
12 | input: 'common.conf.in',
13 | output: 'common.conf',
14 | install: true,
15 | install_dir: lxctemplateconfdir)
16 |
17 | lxc_conf_common_nesting = configure_file(
18 | configuration: conf,
19 | input: 'nesting.conf.in',
20 | output: 'nesting.conf',
21 | install: true,
22 | install_dir: lxctemplateconfdir)
23 |
24 | lxc_conf_common_oci = configure_file(
25 | configuration: conf,
26 | input: 'oci.common.conf.in',
27 | output: 'oci.common.conf',
28 | install: true,
29 | install_dir: lxctemplateconfdir)
30 |
31 | lxc_conf_common_userns = configure_file(
32 | configuration: conf,
33 | input: 'userns.conf.in',
34 | output: 'userns.conf',
35 | install: true,
36 | install_dir: lxctemplateconfdir)
37 |
--------------------------------------------------------------------------------
/.github/workflows/commits.yml:
--------------------------------------------------------------------------------
1 | name: Commits
2 | on:
3 | - pull_request
4 |
5 | permissions:
6 | contents: read
7 |
8 | jobs:
9 | dco-check:
10 | permissions:
11 | pull-requests: read # for tim-actions/get-pr-commits to get list of commits from the PR
12 | name: Signed-off-by (DCO)
13 | runs-on: ubuntu-24.04
14 | steps:
15 | - name: Get PR Commits
16 | id: 'get-pr-commits'
17 | uses: tim-actions/get-pr-commits@master
18 | with:
19 | token: ${{ secrets.GITHUB_TOKEN }}
20 |
21 | - name: Check that all commits are signed-off
22 | uses: tim-actions/dco@master
23 | with:
24 | commits: ${{ steps.get-pr-commits.outputs.commits }}
25 |
26 | target-branch:
27 | permissions:
28 | contents: none
29 | name: Branch target
30 | runs-on: ubuntu-24.04
31 | steps:
32 | - name: Check branch target
33 | env:
34 | TARGET: ${{ github.event.pull_request.base.ref }}
35 | run: |
36 | set -x
37 | [ "${TARGET}" = "main" ] && exit 0
38 |
39 | echo "Invalid branch target: ${TARGET}"
40 | exit 1
41 |
--------------------------------------------------------------------------------
/src/lxc/namespace.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_NAMESPACE_H
4 | #define __LXC_NAMESPACE_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #include "compiler.h"
13 |
14 | typedef enum lxc_namespace_t {
15 | LXC_NS_USER = 0,
16 | LXC_NS_MNT = 1,
17 | LXC_NS_PID = 2,
18 | LXC_NS_UTS = 3,
19 | LXC_NS_IPC = 4,
20 | LXC_NS_NET = 5,
21 | LXC_NS_CGROUP = 6,
22 | LXC_NS_TIME = 7,
23 | LXC_NS_MAX = 8
24 | } lxc_namespace_t;
25 |
26 | __hidden extern const struct ns_info {
27 | #define MAX_NS_PROC_NAME 6
28 | const char proc_name[MAX_NS_PROC_NAME + 1];
29 | const char *proc_path;
30 | int clone_flag;
31 | const char *flag_name;
32 | const char *env_name;
33 | } ns_info[LXC_NS_MAX];
34 |
35 | __hidden extern int lxc_namespace_2_cloneflag(const char *namespace);
36 | __hidden extern int lxc_namespace_2_ns_idx(const char *namespace);
37 | __hidden extern int lxc_namespace_2_std_identifiers(char *namespaces);
38 | __hidden extern int lxc_fill_namespace_flags(char *flaglist, int *flags);
39 |
40 | #endif /* __LXC_NAMESPACE_H */
41 |
--------------------------------------------------------------------------------
/config/apparmor/profiles/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if libapparmor.found()
4 | configure_file(
5 | configuration: dummy_config_data,
6 | input: 'lxc-default',
7 | output: 'lxc-default',
8 | install: true,
9 | install_dir: join_paths(sysconfdir, 'apparmor.d', 'lxc'))
10 |
11 | configure_file(
12 | configuration: dummy_config_data,
13 | input: 'lxc-default-cgns',
14 | output: 'lxc-default-cgns',
15 | install: true,
16 | install_dir: join_paths(sysconfdir, 'apparmor.d', 'lxc'))
17 |
18 | configure_file(
19 | configuration: dummy_config_data,
20 | input: 'lxc-default-with-mounting',
21 | output: 'lxc-default-with-mounting',
22 | install: true,
23 | install_dir: join_paths(sysconfdir, 'apparmor.d', 'lxc'))
24 |
25 | configure_file(
26 | configuration: dummy_config_data,
27 | input: 'lxc-default-with-nesting',
28 | output: 'lxc-default-with-nesting',
29 | install: true,
30 | install_dir: join_paths(sysconfdir, 'apparmor.d', 'lxc'))
31 | endif
32 |
--------------------------------------------------------------------------------
/src/lxc/error_utils.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_ERROR_UTILS_H
4 | #define __LXC_ERROR_UTILS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 |
10 | #include "macro.h"
11 |
12 | #define MAX_ERRNO 4095
13 |
14 | #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
15 |
16 | static inline void *ERR_PTR(long error)
17 | {
18 | return (void *)error;
19 | }
20 |
21 | static inline long PTR_ERR(const void *ptr)
22 | {
23 | return (long)ptr;
24 | }
25 |
26 | static inline long IS_ERR(const void *ptr)
27 | {
28 | return IS_ERR_VALUE((unsigned long)ptr);
29 | }
30 |
31 | static inline long IS_ERR_OR_NULL(const void *ptr)
32 | {
33 | return !ptr || IS_ERR_VALUE((unsigned long)ptr);
34 | }
35 |
36 | static inline void *ERR_CAST(const void *ptr)
37 | {
38 | return (void *)ptr;
39 | }
40 |
41 | static inline int PTR_RET(const void *ptr)
42 | {
43 | if (IS_ERR(ptr))
44 | return PTR_ERR(ptr);
45 | else
46 | return 0;
47 | }
48 |
49 | static inline bool ERRNO_IS_NOT_SUPPORTED(int r) {
50 | int x = abs(r);
51 | return x == EOPNOTSUPP || x == ENOSYS;
52 | }
53 |
54 | #endif /* __LXC_ERROR_UTILS_H */
55 |
--------------------------------------------------------------------------------
/src/lxc/error.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | #include "error.h"
10 | #include "log.h"
11 | #include "process_utils.h"
12 |
13 | lxc_log_define(error, lxc);
14 |
15 | /*---------------------------------------------------------------------------*/
16 | /* lxc_error_set_and_log
17 | * function is here to convert
18 | * the reported status to an exit code as detailed here:
19 | *
20 | * 0-126 exit code of the application
21 | * 128+n signal n received by the application
22 | * 255 lxc error
23 | */
24 | int lxc_error_set_and_log(int pid, int status)
25 | {
26 | int ret = 0;
27 |
28 | if (WIFEXITED(status)) {
29 | ret = WEXITSTATUS(status);
30 | if (ret)
31 | INFO("Child <%d> ended on error (%d)", pid, ret);
32 | } else if (WIFSIGNALED(status)) {
33 | int signal_nr = WTERMSIG(status);
34 | INFO("Child <%d> ended on signal %s(%d)", pid, signal_name(signal_nr), signal_nr);
35 | ret = 128 + signal_nr;
36 | } else {
37 | ERROR("Invalid exit status (%d)", status);
38 | }
39 |
40 | return ret;
41 | }
42 |
--------------------------------------------------------------------------------
/src/lxc/storage/nbd.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_NBD_H
4 | #define __LXC_NBD_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 |
13 | struct lxc_storage;
14 |
15 | struct bdev_specs;
16 |
17 | struct lxc_conf;
18 |
19 | __hidden extern int nbd_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
20 | const char *oldname, const char *cname, const char *oldpath,
21 | const char *lxcpath, int snap, uint64_t newsize,
22 | struct lxc_conf *conf);
23 | __hidden extern int nbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
24 | struct bdev_specs *specs, const struct lxc_conf *conf);
25 | __hidden extern int nbd_destroy(struct lxc_storage *orig);
26 | __hidden extern bool nbd_detect(const char *path);
27 | __hidden extern int nbd_mount(struct lxc_storage *bdev);
28 | __hidden extern int nbd_umount(struct lxc_storage *bdev);
29 | __hidden extern bool attach_nbd(char *src, struct lxc_conf *conf);
30 | __hidden extern void detach_nbd_idx(int idx);
31 | __hidden extern bool requires_nbd(const char *path);
32 |
33 | #endif /* __LXC_NBD_H */
34 |
--------------------------------------------------------------------------------
/config/yum/lxc-patch.py:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 | #
3 | # Yum plugin to re-patch container rootfs after a yum update is done
4 |
5 | import os
6 | from fnmatch import fnmatch
7 | from yum.plugins import TYPE_INTERACTIVE
8 |
9 | requires_api_version = '2.0'
10 | plugin_type = (TYPE_INTERACTIVE,)
11 |
12 | def posttrans_hook(conduit):
13 | pkgs = []
14 | patch_required = False
15 |
16 | # If we aren't root, we can't have updated anything
17 | if os.geteuid():
18 | return
19 |
20 | # See what packages have files that were patched
21 | confpkgs = conduit.confString('main', 'packages')
22 | if not confpkgs:
23 | return
24 |
25 | tmp = confpkgs.split(",")
26 | for confpkg in tmp:
27 | pkgs.append(confpkg.strip())
28 |
29 | conduit.info(2, "lxc-patch: checking if updated pkgs need patching...")
30 | ts = conduit.getTsInfo()
31 | for tsmem in ts.getMembers():
32 | for pkg in pkgs:
33 | if fnmatch(pkg, tsmem.po.name):
34 | patch_required = True
35 | if patch_required:
36 | conduit.info(2, "lxc-patch: patching container...")
37 | os.spawnlp(os.P_WAIT, "lxc-patch", "lxc-patch", "--patch", "/")
38 |
--------------------------------------------------------------------------------
/src/include/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | include_sources = files(
4 | 'bpf.h',
5 | 'bpf_common.h')
6 |
7 | netns_ifaddrs_sources = files(
8 | 'netns_ifaddrs.c',
9 | 'netns_ifaddrs.h')
10 |
11 | if srcconf.get('HAVE_FEXECVE') == 0
12 | include_sources += files(
13 | 'fexecve.c',
14 | 'fexecve.h')
15 | endif
16 |
17 |
18 | if srcconf.get('HAVE_GETGRGID_R') == 0
19 | include_sources += files(
20 | 'getgrgid_r.c',
21 | 'getgrgid_r.h')
22 | endif
23 |
24 | if srcconf.get('HAVE_STRLCPY') == 0
25 | include_sources += files(
26 | 'strlcpy.c',
27 | 'strlcpy.h')
28 | endif
29 |
30 | if srcconf.get('HAVE_STRLCAT') == 0
31 | include_sources += files(
32 | 'strlcat.c',
33 | 'strlcat.h')
34 | endif
35 |
36 | if srcconf.get('HAVE_STRCHRNUL') == 0
37 | include_sources += files(
38 | 'strchrnul.c',
39 | 'strchrnul.h')
40 | endif
41 |
42 | if srcconf.get('HAVE_HASMNTOPT') == 0
43 | include_sources += files(
44 | 'hasmntopt.c',
45 | 'hasmntopt.h')
46 | endif
47 |
48 | if srcconf.get('HAVE_PTHREAD_SETCANCELSTATE') == 0
49 | include_sources += files(
50 | 'pthread_setcancelstate.c',
51 | 'pthread_ext.h')
52 | endif
53 |
--------------------------------------------------------------------------------
/src/tests/fuzz-lxc-cgroup-init.c:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: LGPL-2.1+
3 | */
4 |
5 | #include "config.h"
6 |
7 | #include
8 | #include
9 |
10 | #include "cgroups/cgroup.h"
11 | #include "conf.h"
12 | #include "confile.h"
13 | #include "lxctest.h"
14 | #include "utils.h"
15 |
16 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
17 | int fd = -1;
18 | char tmpf[] = "/tmp/fuzz-lxc-cgroup-init-XXXXXX";
19 | struct lxc_conf *conf = NULL;
20 | int ret;
21 | struct cgroup_ops *ops;
22 |
23 | /*
24 | * 100Kb should probably be enough to trigger all the issues
25 | * we're interested in without any timeouts
26 | */
27 | if (size > 102400)
28 | return 0;
29 |
30 | fd = lxc_make_tmpfile(tmpf, false);
31 | lxc_test_assert_abort(fd >= 0);
32 | lxc_write_nointr(fd, data, size);
33 | close(fd);
34 |
35 | conf = lxc_conf_init();
36 | lxc_test_assert_abort(conf);
37 |
38 | /* Test cgroup_init() with valid config. */
39 | ops = cgroup_init(conf);
40 | cgroup_exit(ops);
41 |
42 | ret = lxc_config_read(tmpf, conf, false);
43 | if (ret == 0) {
44 | /* Test cgroup_init() with likely garbage config. */
45 | ops = cgroup_init(conf);
46 | cgroup_exit(ops);
47 | }
48 | lxc_conf_free(conf);
49 |
50 | (void) unlink(tmpf);
51 |
52 | return 0;
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/src/lxc/storage/zfs.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_ZFS_H
4 | #define __LXC_ZFS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #include "compiler.h"
13 |
14 | struct lxc_storage;
15 |
16 | struct bdev_specs;
17 |
18 | struct lxc_conf;
19 |
20 | __hidden extern int zfs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
21 | const char *oldname, const char *cname, const char *oldpath,
22 | const char *lxcpath, int snap, uint64_t newsize,
23 | struct lxc_conf *conf);
24 | __hidden extern int zfs_create(struct lxc_storage *bdev, const char *dest, const char *n,
25 | struct bdev_specs *specs, const struct lxc_conf *conf);
26 | __hidden extern int zfs_destroy(struct lxc_storage *orig);
27 | __hidden extern bool zfs_detect(const char *path);
28 | __hidden extern int zfs_mount(struct lxc_storage *bdev);
29 | __hidden extern int zfs_umount(struct lxc_storage *bdev);
30 | __hidden extern bool zfs_copy(struct lxc_conf *conf, struct lxc_storage *orig,
31 | struct lxc_storage *new, uint64_t newsize);
32 | __hidden extern bool zfs_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
33 | struct lxc_storage *new, uint64_t newsize);
34 |
35 | #endif /* __LXC_ZFS_H */
36 |
--------------------------------------------------------------------------------
/.github/workflows/fuzzing.yml:
--------------------------------------------------------------------------------
1 | name: Fuzzing
2 | on:
3 | push:
4 | branches:
5 |
6 | permissions:
7 | contents: read
8 |
9 | jobs:
10 | fuzzing:
11 | name: OSS-Fuzz
12 | runs-on: ubuntu-24.04
13 | if: github.repository == 'lxc/lxc'
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | sanitizer:
18 | - address
19 | - undefined
20 | - memory
21 | steps:
22 | - name: Build Fuzzers (${{ matrix.sanitizer }})
23 | id: build
24 | uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
25 | with:
26 | oss-fuzz-project-name: 'lxc'
27 | dry-run: false
28 | allowed-broken-targets-percentage: 0
29 | sanitizer: ${{ matrix.sanitizer }}
30 |
31 | - name: Run Fuzzers (${{ matrix.sanitizer }})
32 | uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
33 | with:
34 | oss-fuzz-project-name: 'lxc'
35 | fuzz-seconds: 360
36 | dry-run: false
37 | sanitizer: ${{ matrix.sanitizer }}
38 |
39 | - name: Upload Crash
40 | uses: actions/upload-artifact@v6
41 | if: failure() && steps.build.outcome == 'success'
42 | with:
43 | name: ${{ matrix.sanitizer }}-artifacts
44 | path: ./out/artifacts
45 |
--------------------------------------------------------------------------------
/hooks/squid-deb-proxy-client:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # SPDX-License-Identifier: GPL-2.0-only
4 | #
5 | # Make the cloned container aware of squid-deb-proxy settings at start.
6 |
7 | # When starting a container, inject the squid-deb-proxy-client proxy
8 | # address in the container's apt configuration.
9 | # This script should be added to templates as a pre-start script, such as:
10 | #lxc.hook.pre-start=/usr/share/lxc/hooks/squid-deb-proxy-client
11 |
12 | discovery_script=/usr/share/squid-deb-proxy-client/apt-avahi-discover
13 | proxy_file=/etc/apt/apt.conf.d/50squid-deb-proxy
14 | container_proxy_file=$LXC_ROOTFS_PATH$proxy_file
15 |
16 | if [ -f $proxy_file ]; then
17 | # The host has a proxy file - let's propagate the config to the guest.
18 | cat $proxy_file > $container_proxy_file
19 | exit 0
20 | fi
21 |
22 | if [ ! -f $discovery_script ]; then
23 | # There is no squid-deb-proxy-client package installed. Do nothing.
24 | exit 0
25 | fi
26 |
27 | proxy_line=$($discovery_script) #XXX: Could be multiline?
28 |
29 | if [ -n "$proxy_line" ]; then
30 | doc="# Detected at container start from the host's squid-deb-proxy-client"
31 | echo "Acquire::http::proxy \"$proxy_line\"; $doc" > $container_proxy_file
32 | else
33 | if [ -f $proxy_file ]; then
34 | rm $proxy_file
35 | fi
36 | fi
37 | exit 0
38 |
--------------------------------------------------------------------------------
/src/lxc/lsm/lsm.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_LSM_H
4 | #define __LXC_LSM_H
5 |
6 | #include "config.h"
7 |
8 | struct lxc_conf;
9 |
10 | #include
11 |
12 | #include "compiler.h"
13 | #include "macro.h"
14 | #include "utils.h"
15 |
16 | struct lsm_ops {
17 | const char *name;
18 |
19 | /* AppArmor specific fields. */
20 | int aa_enabled;
21 | int aa_parser_available;
22 | int aa_supports_unix;
23 | int aa_can_stack;
24 | int aa_is_stacked;
25 | int aa_admin;
26 | int aa_mount_features_enabled;
27 |
28 | int (*enabled)(struct lsm_ops *ops);
29 | char *(*process_label_get)(struct lsm_ops *ops, pid_t pid);
30 | int (*process_label_set)(struct lsm_ops *ops, const char *label, struct lxc_conf *conf, bool on_exec);
31 | int (*keyring_label_set)(struct lsm_ops *ops, const char *label);
32 | int (*prepare)(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath);
33 | void (*cleanup)(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath);
34 | int (*process_label_fd_get)(struct lsm_ops *ops, pid_t pid, bool on_exec);
35 | char *(*process_label_get_at)(struct lsm_ops *ops, int fd_pid);
36 | int (*process_label_set_at)(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec);
37 | };
38 |
39 | __hidden extern struct lsm_ops *lsm_init_static(void);
40 |
41 | #endif /* __LXC_LSM_H */
42 |
--------------------------------------------------------------------------------
/config/init/systemd/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | lxc_apparmor_load = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'lxc-apparmor-load',
6 | output: 'lxc-apparmor-load',
7 | install: true,
8 | install_dir: lxclibexec)
9 |
10 | if 'systemd' in init_script
11 | systemd_system_unit_dir = get_option('systemd-unitdir')
12 | if systemd_system_unit_dir == ''
13 | systemd = dependency('systemd')
14 | systemd_system_unit_dir = systemd.get_variable('systemdsystemunitdir')
15 | endif
16 |
17 | configure_file(
18 | configuration: conf,
19 | input: 'lxc-monitord.service.in',
20 | output: 'lxc-monitord.service',
21 | install: true,
22 | install_dir: systemd_system_unit_dir)
23 |
24 | configure_file(
25 | configuration: conf,
26 | input: 'lxc-net.service.in',
27 | output: 'lxc-net.service',
28 | install: true,
29 | install_dir: systemd_system_unit_dir)
30 |
31 | configure_file(
32 | configuration: conf,
33 | input: 'lxc.service.in',
34 | output: 'lxc.service',
35 | install: true,
36 | install_dir: systemd_system_unit_dir)
37 |
38 | configure_file(
39 | configuration: conf,
40 | input: 'lxc@.service.in',
41 | output: 'lxc@.service',
42 | install: true,
43 | install_dir: systemd_system_unit_dir)
44 | endif
45 |
--------------------------------------------------------------------------------
/src/lxc/execute.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "conf.h"
13 | #include "log.h"
14 | #include "start.h"
15 | #include "process_utils.h"
16 | #include "utils.h"
17 | #include "initutils.h"
18 |
19 | lxc_log_define(execute, start);
20 |
21 | static int execute_start(struct lxc_handler *handler, void* data)
22 | {
23 | int argc = 0;
24 | struct execute_args *my_args = data;
25 |
26 | while (my_args->argv[argc++]);
27 |
28 | lxc_container_init(argc, my_args->argv, my_args->quiet);
29 | }
30 |
31 | static int execute_post_start(struct lxc_handler *handler, void* data)
32 | {
33 | struct execute_args *my_args = data;
34 | NOTICE("'%s' started with pid '%d'", my_args->argv[0], handler->pid);
35 | return 0;
36 | }
37 |
38 | static struct lxc_operations execute_start_ops = {
39 | .start = execute_start,
40 | .post_start = execute_post_start
41 | };
42 |
43 | int lxc_execute(const char *name, char *const argv[], int quiet,
44 | struct lxc_handler *handler, const char *lxcpath,
45 | bool daemonize, int *error_num)
46 | {
47 | struct execute_args args = {.argv = argv, .quiet = quiet};
48 |
49 | TRACE("Doing lxc_execute");
50 | handler->conf->is_execute = true;
51 | return __lxc_start(handler, &execute_start_ops, &args, lxcpath,
52 | daemonize, error_num);
53 | }
54 |
--------------------------------------------------------------------------------
/src/lxc/initutils.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_INITUTILS_H
4 | #define __LXC_INITUTILS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "compiler.h"
22 | #include "string_utils.h"
23 |
24 | #define DEFAULT_VG "lxc"
25 | #define DEFAULT_THIN_POOL "lxc"
26 | #define DEFAULT_ZFSROOT "lxc"
27 | #define DEFAULT_RBDPOOL "lxc"
28 | #define DEFAULT_RBDUSER NULL
29 |
30 | #ifndef PR_SET_MM
31 | #define PR_SET_MM 35
32 | #endif
33 |
34 | #ifndef PR_SET_MM_MAP
35 | #define PR_SET_MM_MAP 14
36 |
37 | struct prctl_mm_map {
38 | uint64_t start_code;
39 | uint64_t end_code;
40 | uint64_t start_data;
41 | uint64_t end_data;
42 | uint64_t start_brk;
43 | uint64_t brk;
44 | uint64_t start_stack;
45 | uint64_t arg_start;
46 | uint64_t arg_end;
47 | uint64_t env_start;
48 | uint64_t env_end;
49 | uint64_t *auxv;
50 | uint32_t auxv_size;
51 | uint32_t exe_fd;
52 | };
53 | #endif
54 |
55 | __hidden extern const char *lxc_global_config_value(const char *option_name);
56 |
57 | __hidden extern int setproctitle(char *title);
58 |
59 | __hidden __noreturn int lxc_container_init(int argc, char *const *argv, bool quiet);
60 |
61 | #endif /* __LXC_INITUTILS_H */
62 |
--------------------------------------------------------------------------------
/config/init/sysvinit/lxc-net.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh -
2 | #
3 | # lxc-net Start/Stop LXC Networking
4 | #
5 | # chkconfig: 345 98 01
6 | # description: Starts/Stops LXC Network Bridge
7 | #
8 | ### BEGIN INIT INFO
9 | # Provides: lxc-net
10 | # Required-Start: $syslog $remote_fs
11 | # Required-Stop: $syslog $remote_fs
12 | # Should-Start:
13 | # Should-Stop:
14 | # Default-Start: 2 3 4 5
15 | # Default-Stop: 0 1 6
16 | # Short-Description: Bring up/down LXC Network Bridge
17 | # Description: Bring up/down LXC Network Bridge
18 | ### END INIT INFO
19 |
20 | # To be replaced by LSB functions, if they can be found
21 | # Defined here for distributions that don't have log_daemon_msg
22 | log_daemon_msg () {
23 | echo $@
24 | }
25 |
26 | # Try to source LSB init functions to define LSB log_* functions.
27 | test ! -r /lib/lsb/init-functions ||
28 | . /lib/lsb/init-functions
29 |
30 | start() {
31 | log_daemon_msg "Starting LXC network bridge: "
32 | @LIBEXECDIR@/lxc/lxc-net start
33 | }
34 |
35 | stop() {
36 | log_daemon_msg "Stopping LXC network bridge: "
37 | @LIBEXECDIR@/lxc/lxc-net stop
38 | }
39 |
40 | # See how we were called.
41 | case "$1" in
42 | start)
43 | start
44 | ;;
45 |
46 | stop)
47 | stop
48 | ;;
49 |
50 | restart|reload|force-reload)
51 | $0 stop
52 | $0 start
53 | ;;
54 |
55 | *)
56 | echo "Usage: $0 {start|stop|restart|reload|force-reload}"
57 | exit 2
58 | ;;
59 | esac
60 |
61 | exit $?
62 |
--------------------------------------------------------------------------------
/doc/lxc.container.conf:
--------------------------------------------------------------------------------
1 | # the fstab mount file
2 | lxc.mount.fstab = ./fstab
3 |
4 | # the hostname to be set into the container
5 | lxc.utsname = virtnode
6 |
7 | # The network has several of kind of configuration:
8 | #
9 | # * veth : the network will use the veth virtual device, the specified
10 | # link must be a bridge
11 | # * macvlan : the network will use the macvlan device, the specified link
12 | # should be an existing interface, usually it is eth0
13 | # * phys : the network will use a physical network device, the specified
14 | # link should be an existing interface
15 | lxc.net.0.type = macvlan
16 |
17 | # specify the flags to be used for the network, actually only is allowed
18 | # which mean the network should be set up when created. If the network is set
19 | # up, the loopback is automatically set up too.
20 | lxc.net.0.flags = up
21 |
22 | # specify the physical network device which will communicate with the
23 | # outside world
24 | lxc.net.0.link = eth0
25 |
26 | # NIC ethernet mac address
27 | lxc.net.0.hwaddr = 4a:49:43:49:79:bd
28 |
29 | # specify the ipv4 address of the container. Several lines are allowed and
30 | # will mean several addresses will be assigned to the interface
31 | lxc.net.0.ipv4.address = 1.2.3.5/24
32 |
33 | # specify the ipv6 address of the container. Several lines are allowed and
34 | # will mean several addresses will be assigned to the interface
35 | lxc.net.0.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3596
36 |
37 |
--------------------------------------------------------------------------------
/src/lxc/storage/lvm.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_LVM_H
4 | #define __LXC_LVM_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "compiler.h"
12 |
13 | struct lxc_storage;
14 |
15 | struct bdev_specs;
16 |
17 | struct lxc_conf;
18 |
19 | __hidden extern bool lvm_detect(const char *path);
20 | __hidden extern int lvm_mount(struct lxc_storage *bdev);
21 | __hidden extern int lvm_umount(struct lxc_storage *bdev);
22 | __hidden extern int lvm_compare_lv_attr(const char *path, int pos, const char expected);
23 | __hidden extern int lvm_is_thin_volume(const char *path);
24 | __hidden extern int lvm_is_thin_pool(const char *path);
25 | __hidden extern int lvm_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
26 | const char *oldname, const char *cname, const char *oldpath,
27 | const char *lxcpath, int snap, uint64_t newsize,
28 | struct lxc_conf *conf);
29 | __hidden extern int lvm_destroy(struct lxc_storage *orig);
30 | __hidden extern int lvm_create(struct lxc_storage *bdev, const char *dest, const char *n,
31 | struct bdev_specs *specs, const struct lxc_conf *conf);
32 | __hidden extern bool lvm_create_clone(struct lxc_conf *conf, struct lxc_storage *orig,
33 | struct lxc_storage *new, uint64_t newsize);
34 | __hidden extern bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
35 | struct lxc_storage *new, uint64_t newsize);
36 |
37 | #endif /* __LXC_LVM_H */
38 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-checkpoint-restore:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # Do an end to end checkpoint and restore with criu.
6 |
7 | set -e
8 |
9 | FAIL() {
10 | echo -n "Failed " >&2
11 | echo "$*" >&2
12 | exit 1
13 | }
14 |
15 | cleanup() {
16 | set +e
17 | lxc-stop -n $name -k
18 | lxc-destroy -f -n $name
19 | }
20 |
21 | if [ "$(id -u)" != "0" ]; then
22 | echo "ERROR: Must run as root."
23 | exit 1
24 | fi
25 |
26 | verlte() {
27 | ! [ "$1" = "$(printf "$1\n$2" | sort -V | tail -n1)" ]
28 | }
29 |
30 | criu_version="$(criu --version | head -n1 | cut -d' ' -f 2)"
31 |
32 | if verlte "$criu_version" "1.3.1"; then
33 | echo "SKIP: skipping test because no (or wrong) criu installed."
34 | exit 0
35 | fi
36 |
37 | name=lxc-test-criu
38 | trap cleanup EXIT HUP INT TERM
39 | lxc-create -t busybox -n $name || FAIL "creating container"
40 |
41 | cat >> "$(lxc-config lxc.lxcpath)/$name/config" < /etc/lxc/default.conf << EOF
27 | lxc.net.0.type = veth
28 | lxc.net.0.link = lxcbr0
29 | EOF
30 | fi
31 |
32 | lxc-create -t busybox -n c1
33 | echo "lxc.no_new_privs = 1" >> /var/lib/lxc/c1/config
34 |
35 | lxc-start -n c1
36 | p1=$(lxc-info -n c1 -p -H)
37 | [ "$p1" != "-1" ] || { echo "Failed to start container c1"; false; }
38 |
39 | lxc-attach -n c1 --clear-env -- mkdir -p /home/ubuntu
40 | lxc-attach -n c1 --clear-env -- /bin/sh -c "cat <> /etc/passwd
41 | ubuntu:x:1000:1000:ubuntu:/home/ubuntu:/bin/sh
42 | EOF"
43 |
44 | # Check that lxc-attach obeys PR_SET_NO_NEW_PRIVS when it is set.
45 | ! lxc-attach -n c1 --clear-env --uid 1000 --gid 1000 -- ping -c 1 127.0.0.1 || { echo "Managed to ping localhost"; false; }
46 | lxc-stop -n c1 -k
47 |
48 | # Check that lxc-attach obeys PR_SET_NO_NEW_PRIVS when it is not set.
49 | sed -i 's/lxc.no_new_privs = 1/lxc.no_new_privs = 0/' /var/lib/lxc/c1/config
50 | lxc-start -n c1
51 | lxc-attach -n c1 --clear-env --uid 1000 --gid 1000 -- ping -c 1 127.0.0.1 || { echo "Managed to ping localhost"; false; }
52 | lxc-stop -n c1 -k
53 |
54 | DONE=1
55 |
--------------------------------------------------------------------------------
/src/lxc/sync.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_SYNC_H
4 | #define __LXC_SYNC_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 |
10 | #include "compiler.h"
11 |
12 | struct lxc_handler;
13 |
14 | enum /* generic */ {
15 | SYNC_ERROR = -1 /* Used to report errors from another process */
16 | };
17 |
18 | enum /* start */ {
19 | START_SYNC_STARTUP = 0,
20 | START_SYNC_CONFIGURE = 1,
21 | START_SYNC_POST_CONFIGURE = 2,
22 | START_SYNC_IDMAPPED_MOUNTS = 3,
23 | START_SYNC_CGROUP_LIMITS = 4,
24 | START_SYNC_FDS = 5,
25 | START_SYNC_READY_START = 6,
26 | START_SYNC_RESTART = 7,
27 | START_SYNC_POST_RESTART = 8,
28 | };
29 |
30 | enum /* attach */ {
31 | ATTACH_SYNC_CGROUP = 0,
32 | };
33 |
34 | __hidden extern bool lxc_sync_init(struct lxc_handler *handler);
35 | __hidden extern void lxc_sync_fini(struct lxc_handler *);
36 | __hidden extern void lxc_sync_fini_parent(struct lxc_handler *);
37 | __hidden extern void lxc_sync_fini_child(struct lxc_handler *);
38 | __hidden extern bool lxc_sync_wake_child(struct lxc_handler *, int);
39 | __hidden extern bool lxc_sync_wait_child(struct lxc_handler *, int);
40 | __hidden extern bool lxc_sync_wake_parent(struct lxc_handler *, int);
41 | __hidden extern bool lxc_sync_wait_parent(struct lxc_handler *, int);
42 | __hidden extern bool lxc_sync_barrier_parent(struct lxc_handler *, int);
43 | __hidden extern bool lxc_sync_barrier_child(struct lxc_handler *, int);
44 | __hidden extern bool sync_wait(int fd, int sequence);
45 | __hidden extern bool sync_wake(int fd, int sequence);
46 |
47 | #endif /* __LXC_SYNC_H */
48 |
--------------------------------------------------------------------------------
/config/init/sysvinit/lxc-containers.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # lxc Start/Stop LXC autoboot containers
4 | #
5 | # chkconfig: 345 99 01
6 | # description: Starts/Stops all LXC containers configured for autostart.
7 | #
8 | ### BEGIN INIT INFO
9 | # Provides: lxc
10 | # Required-Start: $syslog $remote_fs
11 | # Required-Stop: $syslog $remote_fs
12 | # Should-Start: cgroupfs-mount
13 | # Should-Stop: cgroupfs-mount
14 | # Default-Start: 2 3 4 5
15 | # Default-Stop: 0 1 6
16 | # Short-Description: Bring up/down LXC autostart containers
17 | # Description: Bring up/down LXC autostart containers
18 | ### END INIT INFO
19 |
20 | # To be replaced by LSB functions, if they can be found
21 | # Defined here for distributions that don't have log_daemon_msg
22 | log_daemon_msg () {
23 | echo $@
24 | }
25 |
26 | # Try to source LSB init functions to define LSB log_* functions.
27 | test ! -r /lib/lsb/init-functions ||
28 | . /lib/lsb/init-functions
29 |
30 | start() {
31 | # Setup host /dev for autodev containers.
32 | log_daemon_msg "Starting LXC autoboot containers: "
33 | @LIBEXECDIR@/lxc/lxc-containers start
34 | }
35 |
36 | stop() {
37 | log_daemon_msg "Stopping LXC containers: "
38 | @LIBEXECDIR@/lxc/lxc-containers stop
39 | }
40 |
41 | # See how we were called.
42 | case "$1" in
43 | start)
44 | start
45 | ;;
46 |
47 | stop)
48 | stop
49 | ;;
50 |
51 | restart|reload|force-reload)
52 | $0 stop
53 | $0 start
54 | ;;
55 |
56 | *)
57 | echo "Usage: $0 {start|stop|restart|reload|force-reload}"
58 | exit 2
59 | ;;
60 | esac
61 |
62 | exit $?
63 |
--------------------------------------------------------------------------------
/src/include/bpf_common.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2 | #ifndef _UAPI__LINUX_BPF_COMMON_H__
3 | #define _UAPI__LINUX_BPF_COMMON_H__
4 |
5 | /* Instruction classes */
6 | #define BPF_CLASS(code) ((code) & 0x07)
7 | #define BPF_LD 0x00
8 | #define BPF_LDX 0x01
9 | #define BPF_ST 0x02
10 | #define BPF_STX 0x03
11 | #define BPF_ALU 0x04
12 | #define BPF_JMP 0x05
13 | #define BPF_RET 0x06
14 | #define BPF_MISC 0x07
15 |
16 | /* ld/ldx fields */
17 | #define BPF_SIZE(code) ((code) & 0x18)
18 | #define BPF_W 0x00 /* 32-bit */
19 | #define BPF_H 0x08 /* 16-bit */
20 | #define BPF_B 0x10 /* 8-bit */
21 | /* eBPF BPF_DW 0x18 64-bit */
22 | #define BPF_MODE(code) ((code) & 0xe0)
23 | #define BPF_IMM 0x00
24 | #define BPF_ABS 0x20
25 | #define BPF_IND 0x40
26 | #define BPF_MEM 0x60
27 | #define BPF_LEN 0x80
28 | #define BPF_MSH 0xa0
29 |
30 | /* alu/jmp fields */
31 | #define BPF_OP(code) ((code) & 0xf0)
32 | #define BPF_ADD 0x00
33 | #define BPF_SUB 0x10
34 | #define BPF_MUL 0x20
35 | #define BPF_DIV 0x30
36 | #define BPF_OR 0x40
37 | #define BPF_AND 0x50
38 | #define BPF_LSH 0x60
39 | #define BPF_RSH 0x70
40 | #define BPF_NEG 0x80
41 | #define BPF_MOD 0x90
42 | #define BPF_XOR 0xa0
43 |
44 | #define BPF_JA 0x00
45 | #define BPF_JEQ 0x10
46 | #define BPF_JGT 0x20
47 | #define BPF_JGE 0x30
48 | #define BPF_JSET 0x40
49 | #define BPF_SRC(code) ((code) & 0x08)
50 | #define BPF_K 0x00
51 | #define BPF_X 0x08
52 |
53 | #ifndef BPF_MAXINSNS
54 | #define BPF_MAXINSNS 4096
55 | #endif
56 |
57 | #endif /* _UAPI__LINUX_BPF_COMMON_H__ */
58 |
--------------------------------------------------------------------------------
/src/lxc/rtnl.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "nl.h"
15 | #include "rtnl.h"
16 |
17 | int rtnetlink_open(struct rtnl_handler *handler)
18 | {
19 | return netlink_open(&handler->nlh, NETLINK_ROUTE);
20 | }
21 |
22 | void rtnetlink_close(struct rtnl_handler *handler)
23 | {
24 | netlink_close(&handler->nlh);
25 | }
26 |
27 | #pragma GCC diagnostic push
28 | #pragma GCC diagnostic ignored "-Wcast-align"
29 |
30 | int rtnetlink_rcv(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg)
31 | {
32 | return netlink_rcv(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr);
33 | }
34 |
35 | int rtnetlink_send(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg)
36 | {
37 |
38 | return netlink_send(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr);
39 | }
40 |
41 | int rtnetlink_transaction(struct rtnl_handler *handler, struct rtnlmsg *request,
42 | struct rtnlmsg *answer)
43 | {
44 | return netlink_transaction(&handler->nlh,
45 | (struct nlmsg *)&request->nlmsghdr,
46 | (struct nlmsg *)&answer->nlmsghdr);
47 | }
48 |
49 | #pragma GCC diagnostic pop
50 |
51 | struct rtnlmsg *rtnlmsg_alloc(size_t size)
52 | {
53 | /*
54 | size_t len;
55 |
56 | len = NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct rtnlmsghdr))) + size;
57 | return (struct rtnlmsg *)nlmsg_alloc(len);
58 | */
59 |
60 | return NULL;
61 | }
62 |
63 | void rtnlmsg_free(struct rtnlmsg *rtnlmsg) { free(rtnlmsg); }
64 |
--------------------------------------------------------------------------------
/src/lxc/api_extensions.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_API_EXTENSIONS_H
4 | #define __LXC_API_EXTENSIONS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | /*
12 | * api_extensions is the list of all API extensions in the order they were
13 | * added.
14 |
15 | The following kind of changes come with a new extensions:
16 |
17 | - New public functions
18 | - New configuration key
19 | - New valid values for a configuration key
20 | */
21 | static char *api_extensions[] = {
22 | "lxc_log",
23 | "lxc_config_item_is_supported",
24 | "console_log",
25 | "reboot2",
26 | "mount_injection",
27 | "cgroup_relative",
28 | "mount_injection_file",
29 | "seccomp_allow_nesting",
30 | #ifdef HAVE_DECL_SECCOMP_NOTIFY_FD
31 | "seccomp_notify",
32 | #endif /* HAVE_DECL_SECCOMP_NOTIFY_FD */
33 | "network_veth_routes",
34 | "network_ipvlan",
35 | "network_l2proxy",
36 | "network_gateway_device_route",
37 | "network_phys_macvlan_mtu",
38 | "network_veth_router",
39 | "cgroup2_devices",
40 | "cgroup2",
41 | "pidfd",
42 | "cgroup_advanced_isolation",
43 | "network_bridge_vlan",
44 | "time_namespace",
45 | "seccomp_allow_deny_syntax",
46 | "devpts_fd",
47 | #ifdef HAVE_DECL_SECCOMP_NOTIFY_FD
48 | "seccomp_notify_fd_active",
49 | "seccomp_proxy_send_notify_fd",
50 | #endif /* HAVE_DECL_SECCOMP_NOTIFY_FD */
51 | "idmapped_mounts",
52 | "idmapped_mounts_v2",
53 | "core_scheduling",
54 | "cgroup2_auto_mounting",
55 | "environment_runtime_hooks",
56 | };
57 |
58 | static size_t nr_api_extensions = sizeof(api_extensions) / sizeof(*api_extensions);
59 |
60 | #endif /* __LXC_API_EXTENSIONS_H */
61 |
--------------------------------------------------------------------------------
/src/tests/fuzz-lxc-define-load.c:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: LGPL-2.1+
3 | */
4 |
5 | #include "config.h"
6 |
7 | #include
8 | #include
9 |
10 | #include "conf.h"
11 | #include "confile.h"
12 | #include "lxctest.h"
13 | #include "utils.h"
14 |
15 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
16 | __do_free char *new_str = NULL;
17 | struct lxc_container *c = NULL;
18 | struct lxc_list defines;
19 | struct lxc_list *it;
20 | __do_close int devnull_fd = -EBADF;
21 |
22 | if (size > 102400)
23 | return 0;
24 |
25 | c = lxc_container_new("FUZZ", NULL);
26 | lxc_test_assert_abort(c);
27 |
28 | new_str = (char *)malloc(size+1);
29 | lxc_test_assert_abort(new_str);
30 | memcpy(new_str, data, size);
31 | new_str[size] = '\0';
32 |
33 | lxc_list_init(&defines);
34 |
35 | if (lxc_config_define_add(&defines, new_str) < 0)
36 | goto out;
37 |
38 | if (!lxc_config_define_load(&defines, c))
39 | goto out;
40 |
41 | devnull_fd = open_devnull();
42 | lxc_test_assert_abort(devnull_fd >= 0);
43 |
44 | lxc_list_for_each(it, &defines) {
45 | __do_free char *val = NULL;
46 | struct new_config_item *config_item = it->elem;
47 | int len;
48 |
49 | len = c->get_config_item(c, config_item->key, NULL, 0);
50 | if (len < 0)
51 | continue;
52 |
53 | val = (char *)malloc(len + 1);
54 | lxc_test_assert_abort(val);
55 |
56 | if (c->get_config_item(c, config_item->key, val, len + 1) != len)
57 | continue;
58 |
59 | if (len > 0)
60 | dprintf(devnull_fd, "[%s/%s]\n", config_item->key, val);
61 | }
62 |
63 | out:
64 | lxc_container_put(c);
65 | lxc_config_define_free(&defines);
66 |
67 | return 0;
68 | }
69 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-snapdeps:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 | #
7 | # This is a test for dependency between snapshots
8 | #
9 | # When container c2 is created as an overlayfs clone of c1, then
10 | # we record it as such, because c1 cannot be deleted until c2 is
11 | # deleted. Once c2 is deleted, c1 should be delete-able.
12 |
13 | # This test assumes an Ubuntu host
14 |
15 | set -e
16 |
17 | modprobe -v overlay || true
18 | if ! grep -q overlay /proc/filesystems; then
19 | echo "Not running this test as overlay is not available"
20 | exit 0
21 | fi
22 |
23 | cleanup() {
24 | for i in $(seq 1 20); do
25 | lxc-destroy -n snapdeptest$i > /dev/null 2>&1 || true
26 | done
27 | lxc-destroy -n snapdeptest > /dev/null 2>&1 || true
28 | }
29 |
30 | verify_deps() {
31 | n=$1
32 | m=$(wc -l /var/lib/lxc/snapdeptest/lxc_snapshots | awk '{ print $1 }')
33 | [ $((n*2)) -eq $m ]
34 | }
35 |
36 | cleanup
37 |
38 | trap cleanup EXIT SIGHUP SIGINT SIGTERM
39 |
40 | lxc-create -t busybox -n snapdeptest
41 | lxc-copy -s -n snapdeptest -N snapdeptest1
42 | fail=0
43 | lxc-destroy -n snapdeptest || fail=1
44 | if [ $fail -eq 0 ]; then
45 | echo "FAIL: clone did not prevent deletion"
46 | false
47 | fi
48 |
49 | for i in $(seq 2 20); do
50 | lxc-copy -s -n snapdeptest -N snapdeptest$i
51 | done
52 |
53 | verify_deps 20
54 |
55 | lxc-destroy -n snapdeptest1
56 |
57 | verify_deps 19
58 |
59 | lxc-destroy -n snapdeptest20
60 |
61 | verify_deps 18
62 |
63 | for i in $(seq 2 19); do
64 | lxc-destroy -n snapdeptest$i
65 | done
66 |
67 | lxc-destroy -n snapdeptest
68 |
69 | echo "Snapshot clone dependency test passed"
70 | exit 0
71 |
--------------------------------------------------------------------------------
/src/tests/lxctest.h:
--------------------------------------------------------------------------------
1 | /* lxc: linux Container library
2 | *
3 | * SPDX-License-Identifier: LGPL-2.1+
4 | *
5 | */
6 |
7 | #ifndef __LXC_TEST_H_
8 | #define __LXC_TEST_H_
9 |
10 | #include "config.h"
11 |
12 | #include
13 | #include
14 | #include
15 |
16 | #define lxc_debug_stream(stream, format, ...) \
17 | do { \
18 | fprintf(stream, "%s: %d: %s: " format "\n", __FILE__, \
19 | __LINE__, __func__, ##__VA_ARGS__); \
20 | } while (false)
21 |
22 | #define lxc_error(format, ...) lxc_debug_stream(stderr, format, ##__VA_ARGS__)
23 | #define lxc_debug(format, ...) lxc_debug_stream(stdout, format, ##__VA_ARGS__)
24 |
25 | #define lxc_test_assert_stringify(expression, stringify_expression) \
26 | do { \
27 | if (!(expression)) { \
28 | fprintf(stderr, "%s: %s: %d: %s\n", __FILE__, \
29 | __func__, __LINE__, stringify_expression); \
30 | abort(); \
31 | } \
32 | } while (false)
33 |
34 | #define lxc_test_assert_abort(expression) lxc_test_assert_stringify(expression, #expression)
35 |
36 | #define test_error_ret(__ret__, format, ...) \
37 | ({ \
38 | typeof(__ret__) __internal_ret__ = (__ret__); \
39 | fprintf(stderr, format, ##__VA_ARGS__); \
40 | __internal_ret__; \
41 | })
42 |
43 | #endif /* __LXC_TEST_H */
44 |
--------------------------------------------------------------------------------
/src/include/netns_ifaddrs.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef _LXC_NETNS_IFADDRS_H
4 | #define _LXC_NETNS_IFADDRS_H
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "../lxc/compiler.h"
18 | #include "../lxc/memory_utils.h"
19 |
20 | struct netns_ifaddrs {
21 | struct netns_ifaddrs *ifa_next;
22 |
23 | /* Can - but shouldn't be - NULL. */
24 | char *ifa_name;
25 |
26 | /* This field is not present struct ifaddrs. */
27 | int ifa_ifindex;
28 |
29 | unsigned ifa_flags;
30 |
31 | /* This field is not present struct ifaddrs. */
32 | int ifa_mtu;
33 |
34 | /* This field is not present struct ifaddrs. */
35 | int ifa_prefixlen;
36 |
37 | struct sockaddr *ifa_addr;
38 | struct sockaddr *ifa_netmask;
39 | union {
40 | struct sockaddr *ifu_broadaddr;
41 | struct sockaddr *ifu_dstaddr;
42 | } ifa_ifu;
43 |
44 | /* These fields are not present struct ifaddrs. */
45 | int ifa_stats_type;
46 | #if HAVE_STRUCT_RTNL_LINK_STATS64
47 | struct rtnl_link_stats64 ifa_stats;
48 | #else
49 | struct rtnl_link_stats ifa_stats;
50 | #endif
51 | };
52 |
53 | #define __ifa_broadaddr ifa_ifu.ifu_broadaddr
54 | #define __ifa_dstaddr ifa_ifu.ifu_dstaddr
55 |
56 | __hidden extern void netns_freeifaddrs(struct netns_ifaddrs *);
57 | define_cleanup_function(struct netns_ifaddrs *, netns_freeifaddrs);
58 | __hidden extern int netns_getifaddrs(struct netns_ifaddrs **ifap, __s32 netns_id,
59 | bool *netnsid_aware);
60 |
61 | #ifdef __cplusplus
62 | }
63 | #endif
64 |
65 | #endif /* _LXC_NETNS_IFADDRS_H */
66 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-apparmor-generated:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 |
7 | # This is a test script for generated apparmor profiles
8 |
9 | if ! command -v apparmor_parser >/dev/null 2>&1; then
10 | echo 'SKIP: test for generated apparmor profiles: apparmor_parser missing'
11 | exit 0
12 | fi
13 |
14 | DONE=0
15 | LOGFILE="/tmp/lxc-test-$$.log"
16 | cleanup() {
17 | lxc-destroy -n $CONTAINER_NAME >/dev/null 2>&1 || true
18 |
19 | if [ $DONE -eq 0 ]; then
20 | [ -f "$LOGFILE" ] && cat "$LOGFILE" >&2
21 | rm -f "$LOGFILE"
22 | echo "FAIL"
23 | exit 1
24 | fi
25 | rm -f "$LOGFILE"
26 | echo "PASS"
27 | }
28 |
29 | trap cleanup EXIT HUP INT TERM
30 | set -eu
31 |
32 | # Create a container
33 | CONTAINER_NAME=lxc-test-apparmor-generated
34 |
35 | lxc-create -t busybox -n $CONTAINER_NAME -B dir
36 | CONTAINER_PATH=$(dirname $(lxc-info -n $CONTAINER_NAME -c lxc.rootfs.path -H) | sed -e 's/dir://')
37 | cp $CONTAINER_PATH/config $CONTAINER_PATH/config.bak
38 |
39 | # Set the profile to be auto-generated
40 | echo "lxc.apparmor.profile = generated" >> $CONTAINER_PATH/config
41 |
42 | # Start it
43 | lxc-start -n $CONTAINER_NAME -lDEBUG -o "$LOGFILE"
44 | lxc-wait -n $CONTAINER_NAME -t 5 -s RUNNING || (echo "Container didn't start" && exit 1)
45 | pid=$(lxc-info -p -H -n $CONTAINER_NAME)
46 | profile=$(cat /proc/$pid/attr/current)
47 | expected_profile="lxc-${CONTAINER_NAME}_//&:lxc-${CONTAINER_NAME}_<-var-lib-lxc>:unconfined (enforce)"
48 | lxc-stop -n $CONTAINER_NAME -k
49 | if [ "x$profile" != "x$expected_profile" ]; then
50 | echo "FAIL: container was in profile $profile" >&2
51 | echo "expected profile: $expected_profile" >&2
52 | exit 1
53 | fi
54 |
55 | DONE=1
56 |
--------------------------------------------------------------------------------
/src/lxc/storage/storage_utils.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_STORAGE_UTILS_H
4 | #define __LXC_STORAGE_UTILS_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "compiler.h"
14 | #include "conf.h"
15 | #include "macro.h"
16 |
17 | #define LXC_OVERLAY_PRIVATE_DIR "overlay"
18 | #define LXC_OVERLAY_DELTA_DIR "delta"
19 | #define LXC_OVERLAY_WORK_DIR "work"
20 | #define LXC_OVERLAY_DELTA_PATH LXC_OVERLAY_PRIVATE_DIR "/" LXC_OVERLAY_DELTA_DIR
21 | #define LXC_OVERLAY_WORK_PATH LXC_OVERLAY_PRIVATE_DIR "/" LXC_OVERLAY_WORK_DIR
22 | #define LXC_OVERLAY_PATH_LEN \
23 | (STRLITERALLEN(LXC_OVERLAY_PRIVATE_DIR) + STRLITERALLEN("/") + 256 + 1)
24 |
25 | struct lxc_storage;
26 | struct lxc_conf;
27 |
28 | __hidden extern bool attach_block_device(struct lxc_conf *conf);
29 | __hidden extern void detach_block_device(struct lxc_conf *conf);
30 | __hidden extern int blk_getsize(struct lxc_storage *bdev, uint64_t *size);
31 | __hidden extern int detect_fs(struct lxc_storage *bdev, char *type, int len);
32 | __hidden extern int do_mkfs_exec_wrapper(void *args);
33 | __hidden extern int is_blktype(struct lxc_storage *b);
34 | __hidden extern int mount_unknown_fs(const char *rootfs, const char *target, const char *options);
35 | __hidden extern int find_fstype_cb(char *buffer, void *data);
36 | __hidden extern const char *linkderef(const char *path, char *dest);
37 | __hidden extern bool unpriv_snap_allowed(struct lxc_storage *b, const char *t, bool snap,
38 | bool maybesnap);
39 | extern bool lxc_is_valid_storage_type(const char *type);
40 | __hidden extern int storage_destroy_wrapper(void *data);
41 |
42 | #endif /* __LXC_STORAGE_UTILS_H */
43 |
--------------------------------------------------------------------------------
/src/lxc/tools/include/getsubopt.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 |
4 | #include
5 | #include
6 |
7 | #include "config.h"
8 |
9 | #if !HAVE_STRCHRNUL
10 | #include "strchrnul.h"
11 | #endif
12 |
13 | /* Parse comma separated suboption from *OPTIONP and match against
14 | strings in TOKENS. If found return index and set *VALUEP to
15 | optional value introduced by an equal sign. If the suboption is
16 | not part of TOKENS return in *VALUEP beginning of unknown
17 | suboption. On exit *OPTIONP is set to the beginning of the next
18 | token or at the terminating NUL character. */
19 | int
20 | getsubopt (char **optionp, char *const *tokens, char **valuep)
21 | {
22 | char *endp, *vstart;
23 | int cnt;
24 |
25 | if (**optionp == '\0')
26 | return -1;
27 |
28 | /* Find end of next token. */
29 | endp = strchrnul (*optionp, ',');
30 |
31 | /* Find start of value. */
32 | vstart = memchr (*optionp, '=', endp - *optionp);
33 | if (vstart == NULL)
34 | vstart = endp;
35 |
36 | /* Try to match the characters between *OPTIONP and VSTART against
37 | one of the TOKENS. */
38 | for (cnt = 0; tokens[cnt] != NULL; ++cnt)
39 | if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0
40 | && tokens[cnt][vstart - *optionp] == '\0')
41 | {
42 | /* We found the current option in TOKENS. */
43 | *valuep = vstart != endp ? vstart + 1 : NULL;
44 |
45 | if (*endp != '\0')
46 | *endp++ = '\0';
47 | *optionp = endp;
48 |
49 | return cnt;
50 | }
51 |
52 | /* The current suboption does not match any option. */
53 | *valuep = *optionp;
54 |
55 | if (*endp != '\0')
56 | *endp++ = '\0';
57 | *optionp = endp;
58 |
59 | return -1;
60 | }
61 |
--------------------------------------------------------------------------------
/src/tests/arch_parse.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "lxc/lxccontainer.h"
18 |
19 | #include "lxctest.h"
20 | #include "../lxc/lxc.h"
21 | #include "../lxc/memory_utils.h"
22 |
23 | #if !HAVE_STRLCPY
24 | #include "strlcpy.h"
25 | #endif
26 |
27 | static const char *const arches[] = {
28 | "arm", "armel", "armhf", "armv7l", "athlon", "i386", "i486",
29 | "i586", "i686", "linux32", "mips", "mipsel", "ppc", "powerpc",
30 | "x86", "aarch64", "amd64", "arm64", "linux64", "loongarch64", "loong64",
31 | "mips64", "mips64el", "ppc64", "ppc64el", "ppc64le", "powerpc64", "riscv64",
32 | "s390x", "x86_64",
33 | };
34 |
35 | static bool parse_valid_architectures(void)
36 | {
37 | __put_lxc_container struct lxc_container *c = NULL;
38 |
39 | c = lxc_container_new("parse-arch", NULL);
40 | if (!c)
41 | return test_error_ret(false, "Failed to create container \"parse_arch\"");
42 |
43 | for (size_t i = 0; i < ARRAY_SIZE(arches); i++) {
44 | const char *arch = arches[i];
45 |
46 | if (!c->set_config_item(c, "lxc.arch", arch))
47 | return test_error_ret(false, "Failed to set \"lxc.arch=%s\"", arch);
48 |
49 | if (!c->clear_config_item(c, "lxc.arch"))
50 | return test_error_ret(false, "Failed to clear \"lxc.arch=%s\"", arch);
51 | }
52 |
53 | return true;
54 | }
55 |
56 | int main(int argc, char *argv[])
57 | {
58 | if (!parse_valid_architectures())
59 | exit(EXIT_FAILURE);
60 |
61 | exit(EXIT_SUCCESS);
62 | }
63 |
--------------------------------------------------------------------------------
/doc/lxc-checkconfig.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | ]>
7 |
8 |
9 |
10 | @LXC_GENERATE_DATE@
11 |
12 |
13 | lxc-checkconfig
14 | 1
15 |
16 |
17 |
18 | lxc-checkconfig
19 |
20 |
21 | check the current kernel for lxc support
22 |
23 |
24 |
25 |
26 |
27 | lxc-checkconfig
28 |
29 |
30 |
31 |
32 | Description
33 |
34 | lxc-checkconfig check the current kernel for
35 | lxc support
36 |
37 |
38 |
39 |
40 | Examples
41 |
42 |
43 | lxc-checkconfig
44 |
45 |
46 | check the current kernel.
47 | CONFIG can be set in the environment to an alternate location.
48 |
49 |
50 |
51 |
52 |
53 |
54 | &seealso;
55 |
56 |
57 |
73 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-rootfs:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 |
7 | set -ex
8 |
9 | cleanup() {
10 | set +e
11 | lxc-destroy -n lxc-test-rootfs -f
12 | sed -i '/^root:910000:10000/d' /etc/subuid /etc/subgid
13 | if [ $PHASE != "done" ]; then
14 | echo "rootfs test failed at $PHASE"
15 | exit 1
16 | fi
17 | echo "rootfs test passed"
18 | exit 0
19 | }
20 |
21 | PHASE=setup
22 | trap cleanup EXIT
23 |
24 | lxc-destroy -n lxc-test-rootfs -f || true
25 | lxc-create -t busybox -n lxc-test-rootfs
26 |
27 | PHASE=ro_rootfs
28 | echo "Starting phase $PHASE"
29 | config=/var/lib/lxc/lxc-test-rootfs/config
30 | sed -i '/lxc.rootfs.options/d' $config
31 | echo "lxc.rootfs.options = ro" >> $config
32 |
33 | lxc-start -n lxc-test-rootfs
34 | pid=$(lxc-info -n lxc-test-rootfs -p -H)
35 | ro=0
36 | mkdir /proc/$pid/root/rotest || ro=1
37 | [ $ro -ne 0 ]
38 |
39 | lxc-stop -n lxc-test-rootfs -k
40 | PHASE=rw_rootfs
41 | echo "Starting phase $PHASE"
42 | sed -i '/lxc.rootfs.options/d' $config
43 | echo "lxc.rootfs.options = rw" >> $config
44 | lxc-start -n lxc-test-rootfs
45 | pid=$(lxc-info -n lxc-test-rootfs -p -H)
46 | ro=0
47 | mkdir /proc/$pid/root/rwtest || ro=1
48 | [ $ro -ne 1 ]
49 | rmdir /proc/$pid/root/rwtest
50 | ro=0
51 |
52 | lxc-stop -n lxc-test-rootfs -k
53 | PHASE=idmapped_rootfs
54 | echo "Starting phase $PHASE"
55 | usermod -v 910000-919999 -w 910000-919999 root
56 | sed -i '/lxc.rootfs.options/d' $config
57 | echo "lxc.idmap = u 0 910000 9999" >> $config
58 | echo "lxc.idmap = g 0 910000 9999" >> $config
59 | echo "lxc.rootfs.options = idmap=container" >> $config
60 | lxc-start -n lxc-test-rootfs
61 | pid=$(lxc-info -n lxc-test-rootfs -p -H)
62 | ro=0
63 | lxc-attach -n lxc-test-rootfs -- mkdir /rwtest || ro=1
64 | [ $ro -ne 1 ]
65 | rmdir /proc/$pid/root/rwtest
66 | ro=0
67 |
68 | PHASE=done
69 |
--------------------------------------------------------------------------------
/src/lxc/tools/lxc_config.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 |
8 | #include "lxc.h"
9 |
10 | struct lxc_config_items {
11 | char *name;
12 | };
13 |
14 | static struct lxc_config_items items[] =
15 | {
16 | { .name = "lxc.default_config", },
17 | { .name = "lxc.lxcpath", },
18 | { .name = "lxc.bdev.lvm.vg", },
19 | { .name = "lxc.bdev.lvm.thin_pool", },
20 | { .name = "lxc.bdev.zfs.root", },
21 | { .name = "lxc.cgroup.use", },
22 | { .name = "lxc.cgroup.pattern", },
23 | { .name = NULL, },
24 | };
25 |
26 | static void usage(char *me)
27 | {
28 | printf("Usage: %s -l: list all available configuration items\n", me);
29 | printf(" %s item: print configuration item\n", me);
30 | exit(EXIT_SUCCESS);
31 | }
32 |
33 | static void list_config_items(void)
34 | {
35 | struct lxc_config_items *i;
36 |
37 | for (i = &items[0]; i->name; i++)
38 | printf("%s\n", i->name);
39 |
40 | exit(EXIT_SUCCESS);
41 | }
42 |
43 | int __attribute__((weak, alias("lxc_config_main"))) main(int argc, char *argv[]);
44 | int lxc_config_main(int argc, char *argv[])
45 | {
46 | struct lxc_config_items *i;
47 | const char *value;
48 |
49 | if (argc < 2 || strncmp(argv[1], "-h", strlen(argv[1])) == 0 ||
50 | strncmp(argv[1], "--help", strlen(argv[1])) == 0)
51 | usage(argv[0]);
52 |
53 | if (strncmp(argv[1], "-l", strlen(argv[1])) == 0)
54 | list_config_items();
55 |
56 | for (i = &items[0]; i->name; i++) {
57 | if (strncmp(argv[1], i->name, strlen(argv[1])) == 0) {
58 | value = lxc_get_global_config_item(i->name);
59 | if (value)
60 | printf("%s\n", value);
61 | else
62 | printf("%s is not set.\n", argv[1]);
63 |
64 | exit(EXIT_SUCCESS);
65 | }
66 | }
67 |
68 | printf("Unknown configuration item: %s\n", argv[1]);
69 | exit(EXIT_FAILURE);
70 | }
71 |
--------------------------------------------------------------------------------
/config/init/module/customize.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ui_print "- [I] Checking env..."
4 |
5 | if [ -n $KSU ]; then
6 | ui_print "- [D] Su manager is KernelSU."
7 | fi
8 |
9 | if [ $ARCH = "arm64" ]; then
10 | continue
11 | else
12 | abort "- [E] Unsupported arch: $ARCH."
13 | fi
14 |
15 | if [ $API -ge 30 ]; then
16 | continue
17 | else
18 | ui_print "- [W] Func memfd_create() required API 30(R)."
19 | fi
20 |
21 | ui_print "- [D] Fetching download link..."
22 |
23 | DOWNLOAD_URLS=$(curl -s https://api.github.com/repos/Container-On-Android/lxc/releases/latest | grep browser_download_url | cut -d'"' -f4 | grep -E 'gz$')
24 |
25 | URL_LXC=$(echo "$DOWNLOAD_URLS" | sed -n '1p')
26 | URL_SYSROOT=$(echo "$DOWNLOAD_URLS" | sed -n '2p')
27 |
28 | if [ -z $URL_LXC ] && [ -z $URL_SHARE ]; then
29 | abort "- [E] Error: URL_LXC: $URL_LXC URL_SHARE: $URL_SHARE."
30 | else
31 | ui_print "- [D] Fetch ok..."
32 | fi
33 |
34 | ui_print "- [I] Downloading lxc..."
35 |
36 | wget -q $URL_LXC -O /data/local/tmp/lxc.tar.gz
37 |
38 | if [ $? -eq 0 ]; then
39 | ui_print "- [I] Download lxc ok..."
40 | else
41 | rm /data/local/tmp/lxc.tar.gz
42 | abort "- [E] Failed to download lxc. ($URL_LXC)"
43 | fi
44 |
45 | ui_print "- [I] Downloading lxc-sysroot..."
46 |
47 | wget -q $URL_SYSROOT -O /data/local/tmp/lxc-sysroot.tar.gz
48 |
49 | if [ $? -eq 0 ]; then
50 | ui_print "- [D] Download lxc-sysroot ok..."
51 | else
52 | rm /data/local/tmp/lxc-sysroot.tar.gz
53 | abort "- [E] Failed to download lxc-sysroot. ($URL_SYSROOT)"
54 | fi
55 |
56 | ui_print "- [I] Installing lxc..."
57 | mkdir -p @PREFIXDIR@
58 | mkdir -p /data/sysroot
59 | tar zxf /data/local/tmp/lxc.tar.gz -C @PREFIXDIR@
60 | tar zxf /data/local/tmp/lxc-sysroot.tar.gz -C /data/sysroot
61 | ui_print "- [I] OK!"
62 |
63 | ui_print "- [I] Clean!"
64 | rm /data/local/tmp/lxc.tar.gz
65 | rm /data/local/tmp/lxc-sysroot.tar.gz
--------------------------------------------------------------------------------
/src/tests/lxcpath.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "memory_utils.h"
21 |
22 | #define MYNAME "lxctest1"
23 |
24 | #define TSTERR(x) do { \
25 | fprintf(stderr, "%d: %s\n", __LINE__, x); \
26 | } while (0)
27 |
28 | int main(int argc, char *argv[])
29 | {
30 | struct lxc_container *c;
31 | const char *p1;
32 | __do_free char *p2 = NULL;
33 | int retval = -1;
34 |
35 | c = lxc_container_new(MYNAME, NULL);
36 | if (!c) {
37 | TSTERR("create using default path");
38 | goto err;
39 | }
40 |
41 | p1 = c->get_config_path(c);
42 | p2 = c->config_file_name(c);
43 | if (!p1 || !p2 || strncmp(p1, p2, strlen(p1))) {
44 | TSTERR("Bad result for path names");
45 | goto err;
46 | }
47 |
48 | #define CPATH "/boo"
49 | #define FPATH "/boo/lxctest1/config"
50 | if (!c->set_config_path(c, "/boo")) {
51 | TSTERR("Error setting custom path");
52 | goto err;
53 | }
54 |
55 | p1 = c->get_config_path(c);
56 | free(p2);
57 | p2 = c->config_file_name(c);
58 | if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) {
59 | TSTERR("Bad result for path names after set_config_path()");
60 | goto err;
61 | }
62 | lxc_container_put(c);
63 |
64 | c = lxc_container_new(MYNAME, CPATH);
65 | if (!c) {
66 | TSTERR("create using custom path");
67 | goto err;
68 | }
69 |
70 | p1 = c->get_config_path(c);
71 | free(p2);
72 | p2 = c->config_file_name(c);
73 | if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) {
74 | TSTERR("Bad result for path names after create with custom path");
75 | goto err;
76 | }
77 |
78 | retval = 0;
79 |
80 | err:
81 | lxc_container_put(c);
82 | return retval;
83 | }
84 |
--------------------------------------------------------------------------------
/src/tests/config_jump_table.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #include "confile.h"
23 | #include "state.h"
24 | #include "lxctest.h"
25 |
26 | int main(int argc, char *argv[])
27 | {
28 | int fulllen = 0, inlen = 0, ret = EXIT_FAILURE;
29 | char *key, *keys, *saveptr = NULL;
30 |
31 | fulllen = lxc_list_config_items(NULL, inlen);
32 |
33 | keys = malloc(sizeof(char) * fulllen + 1);
34 | if (!keys) {
35 | lxc_error("%s\n", "failed to allocate memory");
36 | exit(ret);
37 | }
38 |
39 | if (lxc_list_config_items(keys, fulllen) != fulllen) {
40 | lxc_error("%s\n", "failed to retrieve configuration keys");
41 | goto on_error;
42 | }
43 |
44 | for (key = strtok_r(keys, "\n", &saveptr); key != NULL;
45 | key = strtok_r(NULL, "\n", &saveptr)) {
46 | struct lxc_config_t *config;
47 |
48 | config = lxc_get_config(key);
49 | if (!config) {
50 | lxc_error("configuration key \"%s\" not implemented in "
51 | "jump table",
52 | key);
53 | goto on_error;
54 | }
55 |
56 | if (!config->set) {
57 | lxc_error("configuration key \"%s\" has no set method "
58 | "in jump table",
59 | key);
60 | goto on_error;
61 | }
62 |
63 | if (!config->get) {
64 | lxc_error("configuration key \"%s\" has no get method "
65 | "in jump table",
66 | key);
67 | goto on_error;
68 | }
69 |
70 | if (!config->clr) {
71 | lxc_error("configuration key \"%s\" has no clr (clear) "
72 | "method in jump table",
73 | key);
74 | goto on_error;
75 | }
76 | }
77 |
78 | ret = EXIT_SUCCESS;
79 |
80 | on_error:
81 | free(keys);
82 |
83 | exit(ret);
84 | }
85 |
--------------------------------------------------------------------------------
/src/lxc/lsm/nop.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 |
7 | #include "lsm/lsm.h"
8 |
9 | static char *nop_process_label_get(struct lsm_ops *ops, pid_t pid)
10 | {
11 | return NULL;
12 | }
13 |
14 | static char *nop_process_label_get_at(struct lsm_ops *ops, int fd_pid)
15 | {
16 | return NULL;
17 | }
18 |
19 | static int nop_process_label_set(struct lsm_ops *ops, const char *label, struct lxc_conf *conf,
20 | bool on_exec)
21 | {
22 | return 0;
23 | }
24 |
25 | static int nop_enabled(struct lsm_ops *ops)
26 | {
27 | return 0;
28 | }
29 |
30 | static int nop_keyring_label_set(struct lsm_ops *ops, const char *label)
31 | {
32 | return 0;
33 | }
34 |
35 | static int nop_prepare(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath)
36 | {
37 | return 0;
38 | }
39 |
40 | static void nop_cleanup(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath)
41 | {
42 | }
43 |
44 | static int nop_process_label_fd_get(struct lsm_ops *ops, pid_t pid, bool on_exec)
45 | {
46 | return 0;
47 | }
48 |
49 | static int nop_process_label_set_at(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec)
50 | {
51 | return 0;
52 | }
53 |
54 | static struct lsm_ops nop_ops = {
55 | .name = "nop",
56 | .aa_admin = -1,
57 | .aa_can_stack = -1,
58 | .aa_enabled = -1,
59 | .aa_is_stacked = -1,
60 | .aa_mount_features_enabled = -1,
61 | .aa_parser_available = -1,
62 | .aa_supports_unix = -1,
63 | .cleanup = nop_cleanup,
64 | .enabled = nop_enabled,
65 | .keyring_label_set = nop_keyring_label_set,
66 | .prepare = nop_prepare,
67 | .process_label_fd_get = nop_process_label_fd_get,
68 | .process_label_get = nop_process_label_get,
69 | .process_label_set = nop_process_label_set,
70 | .process_label_get_at = nop_process_label_get_at,
71 | .process_label_set_at = nop_process_label_set_at,
72 | };
73 |
74 | struct lsm_ops *lsm_nop_ops_init(void)
75 | {
76 | return &nop_ops;
77 | }
78 |
--------------------------------------------------------------------------------
/config/apparmor/abstractions/start-container.in:
--------------------------------------------------------------------------------
1 | network,
2 | capability,
3 | file,
4 |
5 | # The following 3 entries are only supported by recent apparmor versions.
6 | # Comment them if the apparmor parser doesn't recognize them.
7 | dbus,
8 | signal,
9 | ptrace,
10 |
11 | # currently blocked by apparmor bug
12 | mount -> /usr/lib*/*/lxc/{**,},
13 | mount -> /usr/lib*/lxc/{**,},
14 | mount -> @LXCROOTFSMOUNT@/{,**},
15 | mount fstype=devpts -> /dev/pts/,
16 | mount options=bind /dev/pts/ptmx/ -> /dev/ptmx/,
17 | mount options=bind /dev/pts/** -> /dev/**,
18 | mount options=(rw, make-slave) -> /{,**},
19 | mount options=(rw, make-rslave) -> /{,**},
20 | mount options=(rw, make-shared) -> /{,**},
21 | mount options=(rw, make-rshared) -> /{,**},
22 | mount fstype=debugfs,
23 | mount fstype=fuse.*,
24 | # allow pre-mount hooks to stage mounts under /var/lib/lxc//
25 | mount -> /var/lib/lxc/{**,},
26 |
27 | mount /dev/.lxc-boot-id -> /proc/sys/kernel/random/boot_id,
28 | mount options=(ro, nosuid, nodev, noexec, remount, bind) -> /proc/sys/kernel/random/boot_id,
29 |
30 | # required for some pre-mount hooks
31 | mount fstype=overlayfs,
32 | mount fstype=aufs,
33 | mount fstype=ecryptfs,
34 |
35 | # all umounts are under the original root's /mnt, but right now we
36 | # can't allow those umounts after pivot_root. So allow all umounts
37 | # right now. They'll be restricted for the container at least.
38 | umount,
39 | #umount /mnt/{**,},
40 |
41 | # This may look a bit redundant, however it appears we need all of
42 | # them if we want things to work properly on all combinations of kernel
43 | # and userspace parser...
44 | pivot_root /usr/lib*/lxc/,
45 | pivot_root /usr/lib*/*/lxc/,
46 | pivot_root /usr/lib*/lxc/**,
47 | pivot_root /usr/lib*/*/lxc/**,
48 | pivot_root @LXCROOTFSMOUNT@/{,**},
49 |
50 | change_profile -> lxc-*,
51 | change_profile -> lxc-**,
52 | change_profile -> unconfined,
53 | change_profile -> :lxc-*:unconfined,
54 |
--------------------------------------------------------------------------------
/hooks/mountecryptfsroot:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # SPDX-License-Identifier: LGPL-2.1+
4 | #
5 | # This hook can be used to mount an ecryptfs filesystem as a container's
6 | # rootfs.
7 | # To use this hook, assuming your container is called q1,
8 | # 1. add 'lxc.hook.pre-mount = /usr/share/lxc/hooks/mountecryptfsroot' to
9 | # the container's configuration file
10 | # 2. Create /var/lib/lxc/q1/ecryptfs-root
11 | # a. mkdir /var/lib/lxc/q1/ecryptfs-root
12 | # 3. convert your container's root filesystem to be ecryptfs-backed. Assuming
13 | # your container is called 'q1', do
14 | # a. c=q1
15 | # b. mv /var/lib/lxc/$c/rootfs /var/lib/lxc/$c/rootfs.plain
16 | # c. mkdir /var/lib/lxc/$c/rootfs{,.crypt}
17 | # d. sig=$(echo none | ecryptfs-add-passphrase | grep -v Passphrase | cut -d[ -f 2 | cut -d] -f 1)
18 | # e. echo $sig > /var/lib/lxc/$c/sig
19 | # f. mount -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,ecryptfs_sig=${sig},sig=${sig},verbosity=0 /var/lib/lxc/$c/rootfs.crypt /var/lib/lxc/$c/rootfs
20 | # g. rsync -va /var/lib/lxc/$c/rootfs.plain/ /var/lib/lxc/$c/rootfs/
21 | # h. umount /var/lib/lxc/$c/rootfs
22 | # i. rm -rf /var/lib/lxc/$c/rootfs.plain
23 | # 4. Now you can start your container by adding the passphrase to your
24 | # in-kernel keyring using 'ecryptfs-add-passphrase', then starting your
25 | # container as normal.
26 | # a. echo none | ecryptfs-add-passphrase
27 | # b. lxc-start -n q1
28 | # Note that you may well want to use a wrapped passphrase (see the ecryptfs-wrap-passphrase(1) manual page).
29 |
30 | set -e
31 | ecryptfs_crypt=$(echo $LXC_ROOTFS_PATH | sed 's/rootfs$/rootfs.crypt/')
32 | sigfile=$(echo $LXC_CONFIG_FILE | sed 's/config$/sig/')
33 |
34 | sig=$(cat $sigfile)
35 | mount -n -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,ecryptfs_sig=${sig},sig=${sig},verbosity=0 $ecryptfs_crypt $LXC_ROOTFS_PATH
36 | exit 0
37 |
--------------------------------------------------------------------------------
/.github/workflows/code-test.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 | on:
3 | - pull_request
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | name: Build test
9 | steps:
10 | - uses: actions/checkout@v4
11 |
12 | - name: Set up Android NDK
13 | uses: nttld/setup-ndk@v1
14 | with:
15 | ndk-version: r27c
16 |
17 | - name: Install dependencies
18 | run: |
19 | sudo apt-get install -y -qq build-essential pipx python3-venv pkg-config cmake docbook2x \
20 | python3-pip pipx
21 | pipx ensurepath
22 | pipx install meson==0.61
23 | pipx install ninja
24 |
25 | - name: Test build
26 | run: |
27 | sed -i "s|android-ndk-r27c|$ANDROID_NDK_HOME|g" aarch64-android-api30.txt
28 |
29 | meson setup build \
30 | -Dprefix=/data/share \
31 | -Dinit-script=module \
32 | -Druntime-path=/data/share/tmp \
33 | -Dstrip=true \
34 | -Dd_lto=true \
35 | -Db_pie=false \
36 | -Dlog-path=log/lxc \
37 | -Ddata-path=lib/lxc \
38 | --localstatedir=/data/share/var \
39 | -Dmemfd-rexec=true \
40 | --buildtype debug \
41 | -Dcapabilities=false \
42 | -Dseccomp=false \
43 | -Dselinux=false \
44 | -Dapparmor=false \
45 | -Dopenssl=false \
46 | -Ddbus=false \
47 | -Dandroid-log=true \
48 | -Dlandlock-monitor=true \
49 | --cross-file aarch64-android-api30.txt
50 |
51 | meson compile -C build
52 | sudo /usr/local/bin/ninja -C build install
53 |
54 | - name: Upload artifacts lxc
55 | uses: actions/upload-artifact@v4.3.1
56 | with:
57 | name: android-aarch64-lxc-shared-api30
58 | path: /data/share/*
59 |
60 | - name: Upload artifacts lxc-module
61 | uses: actions/upload-artifact@v4.3.1
62 | with:
63 | name: android-lxc-module
64 | path: lxc-module.zip
65 |
--------------------------------------------------------------------------------
/.github/workflows/coverity.yml:
--------------------------------------------------------------------------------
1 | name: Coverity
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | permissions:
8 | contents: read
9 |
10 | jobs:
11 | coverity:
12 | name: Build and upload
13 | runs-on: ubuntu-24.04
14 | if: github.repository == 'lxc/lxc'
15 | steps:
16 | - name: Checkout code
17 | uses: actions/checkout@v6
18 |
19 | - name: Download Coverity Build Tool
20 | run: |
21 | wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=lxc/lxc" -O cov-analysis-linux64.tar.gz
22 | mkdir cov-analysis-linux64
23 | tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
24 | env:
25 | TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
26 |
27 | - name: Install dependencies
28 | run: |
29 | sudo apt-get update -qq
30 | sudo apt-get install -qq gcc clang meson
31 | sudo apt-get install -qq libapparmor-dev libcap-dev libseccomp-dev libselinux1-dev linux-libc-dev libpam0g-dev docbook2x libdbus-1-dev
32 |
33 | - name: Run coverity
34 | run: |
35 | # Configure
36 | export PATH="$(pwd)/cov-analysis-linux64/bin:${PATH}"
37 | export CFLAGS="-Wall -Werror"
38 | export LDFLAGS="-pthread -lpthread"
39 |
40 | BUILD="$(pwd)/build"
41 | meson setup -Dtests=true -Dpam-cgroup=true -Dcoverity-build=true build/
42 |
43 | # Build
44 | cov-build --dir cov-int ninja -C ${BUILD}
45 | tar czvf upload.tgz cov-int
46 |
47 | # Submit the results
48 | curl \
49 | --form project=lxc/lxc \
50 | --form token=${TOKEN} \
51 | --form email=lxc-devel@lists.linuxcontainers.org \
52 | --form file=@upload.tgz \
53 | --form version=main \
54 | --form description="${GITHUB_SHA}" \
55 | https://scan.coverity.com/builds?project=lxc/lxc
56 | env:
57 | TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
58 |
--------------------------------------------------------------------------------
/doc/lxc-unfreeze.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | ]>
8 |
9 |
10 |
11 | @LXC_GENERATE_DATE@
12 |
13 |
14 | lxc-unfreeze
15 | 1
16 |
17 |
18 |
19 | lxc-unfreeze
20 |
21 |
22 | thaw all the container's processes
23 |
24 |
25 |
26 |
27 |
28 | lxc-unfreeze
29 | -n name
30 |
31 |
32 |
33 |
34 | Description
35 |
36 |
37 | lxc-unfreeze will thaw all the processes
38 | previously frozen by the lxc-freeze command.
39 |
40 |
41 |
42 |
43 | &commonoptions;
44 |
45 |
46 | Diagnostic
47 |
48 |
49 |
50 |
51 | The container was not found
52 |
53 |
54 | The specified container was not created before with
55 | the lxc-create command.
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | &seealso;
66 |
67 |
68 |
69 |
85 |
--------------------------------------------------------------------------------
/hooks/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | hooks_unmount_namespace_sources = files('unmount-namespace.c')
4 |
5 | hook_programs += executable(
6 | 'unmount-namespace',
7 | hooks_unmount_namespace_sources,
8 | include_directories: liblxc_includes,
9 | install: true,
10 | install_dir: join_paths(lxclibexec, 'hooks'))
11 |
12 | hook_programs = configure_file(
13 | configuration: dummy_config_data,
14 | input: 'clonehostname',
15 | output: 'clonehostname')
16 | install_data(join_paths(project_build_root, 'hooks/clonehostname'), install_dir: lxchookdir)
17 |
18 | hook_programs = configure_file(
19 | configuration: dummy_config_data,
20 | input: 'dhclient-script',
21 | output: 'dhclient-script')
22 | install_data(join_paths(project_build_root, 'hooks/dhclient-script'), install_dir: lxchookdir)
23 |
24 | hook_programs = configure_file(
25 | configuration: conf,
26 | input: 'dhclient.in',
27 | output: 'dhclient')
28 | install_data(join_paths(project_build_root, 'hooks/dhclient'), install_dir: lxchookdir)
29 |
30 | hook_programs = configure_file(
31 | configuration: dummy_config_data,
32 | input: 'mountecryptfsroot',
33 | output: 'mountecryptfsroot')
34 | install_data(join_paths(project_build_root, 'hooks/mountecryptfsroot'), install_dir: lxchookdir)
35 |
36 | hook_programs = configure_file(
37 | configuration: dummy_config_data,
38 | input: 'nvidia',
39 | output: 'nvidia')
40 | install_data(join_paths(project_build_root, 'hooks/nvidia'), install_dir: lxchookdir)
41 |
42 | hook_programs = configure_file(
43 | configuration: dummy_config_data,
44 | input: 'squid-deb-proxy-client',
45 | output: 'squid-deb-proxy-client')
46 | install_data(join_paths(project_build_root, 'hooks/squid-deb-proxy-client'), install_dir: lxchookdir)
47 |
48 | hook_programs = configure_file(
49 | configuration: dummy_config_data,
50 | input: 'ubuntu-cloud-prep',
51 | output: 'ubuntu-cloud-prep')
52 | install_data(join_paths(project_build_root, 'hooks/ubuntu-cloud-prep'), install_dir: lxchookdir)
53 |
--------------------------------------------------------------------------------
/src/tests/createtest.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #define MYNAME "lxctest1"
20 |
21 | int main(int argc, char *argv[])
22 | {
23 | struct lxc_container *c;
24 | int ret = 1;
25 |
26 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
27 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
28 | ret = 1;
29 | goto out;
30 | }
31 |
32 | if (c->is_defined(c)) {
33 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
34 | goto out;
35 | }
36 |
37 | if (!c->set_config_item(c, "lxc.net.0.type", "veth")) {
38 | fprintf(stderr, "%d: failed to set network type\n", __LINE__);
39 | goto out;
40 | }
41 |
42 | c->set_config_item(c, "lxc.net.0.link", "lxcbr0");
43 | c->set_config_item(c, "lxc.net.0.flags", "up");
44 |
45 | if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
46 | fprintf(stderr, "%d: failed to create a container\n", __LINE__);
47 | goto out;
48 | }
49 |
50 | if (!c->is_defined(c)) {
51 | fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
52 | goto out;
53 | }
54 |
55 | c->clear_config(c);
56 | c->load_config(c, NULL);
57 | c->want_daemonize(c, true);
58 |
59 | if (!c->startl(c, 0, NULL)) {
60 | fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME);
61 | goto out;
62 | }
63 |
64 | if (!c->stop(c)) {
65 | fprintf(stderr, "%d: failed to stop %s\n", __LINE__, MYNAME);
66 | goto out;
67 | }
68 |
69 | if (!c->destroy(c)) {
70 | fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME);
71 | goto out;
72 | }
73 |
74 | if (c->is_defined(c)) {
75 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
76 | goto out;
77 | }
78 |
79 | fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
80 | ret = 0;
81 |
82 | out:
83 | lxc_container_put(c);
84 | exit(ret);
85 | }
86 |
--------------------------------------------------------------------------------
/doc/ko/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if want_mans
4 | PAGES = [
5 | ['lxc', '7'],
6 | ['lxc.conf', '5'],
7 | ['lxc.container.conf', '5'],
8 | ['lxc.system.conf', '5'],
9 | ['lxc-usernet', '5'],
10 | ['lxc-user-nic', '1'],
11 | ['lxc-usernsexec', '1'],
12 | ]
13 |
14 | if want_tools
15 | PAGES += [
16 | ['lxc-attach', '1'],
17 | ['lxc-autostart', '1'],
18 | ['lxc-cgroup', '1'],
19 | ['lxc-checkconfig', '1'],
20 | ['lxc-checkpoint', '1'],
21 | ['lxc-config', '1'],
22 | ['lxc-console', '1'],
23 | ['lxc-copy', '1'],
24 | ['lxc-create', '1'],
25 | ['lxc-destroy', '1'],
26 | ['lxc-device', '1'],
27 | ['lxc-execute', '1'],
28 | ['lxc-freeze', '1'],
29 | ['lxc-info', '1'],
30 | ['lxc-ls', '1'],
31 | ['lxc-monitor', '1'],
32 | ['lxc-snapshot', '1'],
33 | ['lxc-start', '1'],
34 | ['lxc-stop', '1'],
35 | ['lxc-top', '1'],
36 | ['lxc-unfreeze', '1'],
37 | ['lxc-unshare', '1'],
38 | ['lxc-wait', '1'],
39 | ]
40 | endif
41 |
42 | # Common files.
43 | configure_file(
44 | configuration: docconf,
45 | input: 'common_options.sgml.in',
46 | output: 'common_options.sgml')
47 |
48 | configure_file(
49 | configuration: docconf,
50 | input: 'see_also.sgml.in',
51 | output: 'see_also.sgml')
52 |
53 | # Initial templating.
54 | foreach page : PAGES
55 | sgml = configure_file(
56 | configuration: docconf,
57 | input: page[0] + '.sgml.in',
58 | output: page[0] + '.sgml')
59 |
60 | configure_file(
61 | input: sgml,
62 | output: page[0] + '.' + page[1],
63 | command: [sgml2man, '--encoding=UTF-8', page[0] + '.sgml'],
64 | install: true,
65 | install_dir: join_paths(mandir, 'ko', 'man' + page[1]))
66 | endforeach
67 | endif
68 |
--------------------------------------------------------------------------------
/src/lxc/mainloop.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_MAINLOOP_H
4 | #define __LXC_MAINLOOP_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 |
10 | #include "compiler.h"
11 | #include "hlist.h"
12 | #include "memory_utils.h"
13 |
14 | #define LXC_MAINLOOP_ERROR -1
15 | #define LXC_MAINLOOP_CONTINUE 0
16 | #define LXC_MAINLOOP_CLOSE 1
17 | #define LXC_MAINLOOP_DISARM 2
18 |
19 | typedef enum {
20 | LXC_MAINLOOP_EPOLL = 1,
21 | LXC_MAINLOOP_IO_URING = 2,
22 | } async_descr_t;
23 |
24 | struct lxc_async_descr {
25 | async_descr_t type;
26 | union {
27 | int epfd;
28 | #if HAVE_LIBURING
29 | struct io_uring *ring;
30 | #endif
31 | };
32 | struct list_head handlers;
33 | };
34 |
35 | static inline int default_cleanup_handler(int fd, void *data)
36 | {
37 | return 0;
38 | }
39 |
40 | typedef int (*lxc_mainloop_callback_t)(int fd, uint32_t event, void *data,
41 | struct lxc_async_descr *descr);
42 |
43 | typedef int (*lxc_mainloop_cleanup_t)(int fd, void *data);
44 |
45 | __hidden extern int lxc_mainloop(struct lxc_async_descr *descr, int timeout_ms);
46 |
47 | __hidden extern int lxc_mainloop_add_handler_events(struct lxc_async_descr *descr, int fd, int events,
48 | lxc_mainloop_callback_t callback,
49 | lxc_mainloop_cleanup_t cleanup,
50 | void *data, const char *name);
51 | __hidden extern int lxc_mainloop_add_handler(struct lxc_async_descr *descr, int fd,
52 | lxc_mainloop_callback_t callback,
53 | lxc_mainloop_cleanup_t cleanup,
54 | void *data, const char *name);
55 | __hidden extern int lxc_mainloop_add_oneshot_handler(struct lxc_async_descr *descr, int fd,
56 | lxc_mainloop_callback_t callback,
57 | lxc_mainloop_cleanup_t cleanup,
58 | void *data, const char *name);
59 |
60 | __hidden extern int lxc_mainloop_del_handler(struct lxc_async_descr *descr, int fd);
61 |
62 | __hidden extern int lxc_mainloop_open(struct lxc_async_descr *descr);
63 |
64 | __hidden extern void lxc_mainloop_close(struct lxc_async_descr *descr);
65 |
66 | define_cleanup_function(struct lxc_async_descr *, lxc_mainloop_close);
67 |
68 | #endif
69 |
--------------------------------------------------------------------------------
/doc/ja/lxc-checkconfig.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | ]>
7 |
8 |
9 |
10 | @LXC_GENERATE_DATE@
11 |
12 |
13 | lxc-checkconfig
14 | 1
15 |
16 |
17 |
18 | lxc-checkconfig
19 |
20 |
21 |
24 | 現在のカーネルが lxc に必要な機能をサポートしているかのチェック
25 |
26 |
27 |
28 |
29 |
30 | lxc-checkconfig
31 |
32 |
33 |
34 |
35 | 説明
36 |
37 |
41 | lxc-checkconfig は、現在のカーネルが lxc に必要な機能をサポートしているかをチェックします。
42 |
43 |
44 |
45 |
46 | 例
47 |
48 |
49 | lxc-checkconfig
50 |
51 |
52 |
56 | 現在のカーネルをチェックします。
57 | CONFIG 環境変数に別の場所を設定することも可能です。
58 | (訳注: カーネルビルド時の設定オプションのファイルの位置を指定します。デフォルトは /proc/config.gz です。)
59 |
60 |
61 |
62 |
63 |
64 |
65 | &seealso;
66 |
67 |
68 |
84 |
--------------------------------------------------------------------------------
/doc/ko/lxc-checkconfig.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | ]>
7 |
8 |
9 |
10 | @LXC_GENERATE_DATE@
11 |
12 |
13 | lxc-checkconfig
14 | 1
15 |
16 |
17 |
18 | lxc-checkconfig
19 |
20 |
21 |
24 | 현재 커널의 lxc 지원 여부 검사
25 |
26 |
27 |
28 |
29 |
30 | lxc-checkconfig
31 |
32 |
33 |
34 |
35 | 설명
36 |
37 |
41 | lxc-checkconfig는 현재 커널이 lxc를 지원하는지 검사한다.
42 |
43 |
44 |
45 |
46 | 예제
47 |
48 |
49 | lxc-checkconfig
50 |
51 |
52 |
56 | 현재 커널을 검사한다.
57 | CONFIG 환경 변수를 이용하여 다른 위치를 설정할 수 있다.
58 | (역주 : 기본값은 /proc/config.gz 이다. Kernel compile option에서 Enable access to .config through /proc/config.gz를 체크하여야 한다)
59 |
60 |
61 |
62 |
63 |
64 |
65 | &seealso;
66 |
67 |
68 |
84 |
--------------------------------------------------------------------------------
/doc/lxc-freeze.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | ]>
8 |
9 |
10 |
11 | @LXC_GENERATE_DATE@
12 |
13 |
14 | lxc-freeze
15 | 1
16 |
17 |
18 |
19 | lxc-freeze
20 |
21 |
22 | freeze all the container's processes
23 |
24 |
25 |
26 |
27 |
28 | lxc-freeze
29 | -n name
30 |
31 |
32 |
33 |
34 | Description
35 |
36 |
37 | lxc-freeze freezes all the processes running
38 | inside the container. The processes will be blocked until they
39 | are explicitly thawed by the lxc-unfreeze
40 | command. This command is useful for batch managers to schedule a
41 | group of processes.
42 |
43 |
44 |
45 |
46 | &commonoptions;
47 |
48 |
49 | Diagnostic
50 |
51 |
52 |
53 |
54 | The container was not found
55 |
56 |
57 | The specified container was not created before with
58 | the lxc-create command.
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | &seealso;
69 |
70 |
71 |
72 |
88 |
--------------------------------------------------------------------------------
/doc/ja/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if want_mans
4 | PAGES = [
5 | ['lxc', '7'],
6 | ['lxc.conf', '5'],
7 | ['lxc.container.conf', '5'],
8 | ['lxc.system.conf', '5'],
9 | ['lxc-update-config', '1'],
10 | ['lxc-usernet', '5'],
11 | ['lxc-user-nic', '1'],
12 | ['lxc-usernsexec', '1'],
13 | ]
14 |
15 | if want_tools
16 | PAGES += [
17 | ['lxc-attach', '1'],
18 | ['lxc-autostart', '1'],
19 | ['lxc-cgroup', '1'],
20 | ['lxc-checkconfig', '1'],
21 | ['lxc-checkpoint', '1'],
22 | ['lxc-config', '1'],
23 | ['lxc-console', '1'],
24 | ['lxc-copy', '1'],
25 | ['lxc-create', '1'],
26 | ['lxc-destroy', '1'],
27 | ['lxc-device', '1'],
28 | ['lxc-execute', '1'],
29 | ['lxc-freeze', '1'],
30 | ['lxc-info', '1'],
31 | ['lxc-ls', '1'],
32 | ['lxc-monitor', '1'],
33 | ['lxc-snapshot', '1'],
34 | ['lxc-start', '1'],
35 | ['lxc-stop', '1'],
36 | ['lxc-top', '1'],
37 | ['lxc-unfreeze', '1'],
38 | ['lxc-unshare', '1'],
39 | ['lxc-wait', '1'],
40 | ]
41 | endif
42 |
43 | if want_pam_cgroup
44 | PAGES += [
45 | ['pam_cgfs', '8'],
46 | ]
47 | endif
48 |
49 | # Common files.
50 | configure_file(
51 | configuration: docconf,
52 | input: 'common_options.sgml.in',
53 | output: 'common_options.sgml')
54 |
55 | configure_file(
56 | configuration: docconf,
57 | input: 'see_also.sgml.in',
58 | output: 'see_also.sgml')
59 |
60 | # Initial templating.
61 | foreach page : PAGES
62 | sgml = configure_file(
63 | configuration: docconf,
64 | input: page[0] + '.sgml.in',
65 | output: page[0] + '.sgml')
66 |
67 | configure_file(
68 | input: sgml,
69 | output: page[0] + '.' + page[1],
70 | command: [sgml2man, '--encoding=UTF-8', page[0] + '.sgml'],
71 | install: true,
72 | install_dir: join_paths(mandir, 'ja', 'man' + page[1]))
73 | endforeach
74 | endif
75 |
--------------------------------------------------------------------------------
/src/tests/destroytest.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #define MYNAME "lxctest1"
20 |
21 | static int create_container(void)
22 | {
23 | int status, ret;
24 | pid_t pid = fork();
25 |
26 | if (pid < 0) {
27 | perror("fork");
28 | return -1;
29 | }
30 |
31 | if (pid == 0) {
32 | execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
33 | exit(EXIT_FAILURE);
34 | }
35 |
36 | again:
37 | ret = waitpid(pid, &status, 0);
38 | if (ret == -1) {
39 | if (errno == EINTR)
40 | goto again;
41 |
42 | perror("waitpid");
43 | return -1;
44 | }
45 |
46 | if (ret != pid)
47 | goto again;
48 |
49 | if (!WIFEXITED(status)) { // did not exit normally
50 | fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__);
51 | return -1;
52 | }
53 |
54 | return WEXITSTATUS(status);
55 | }
56 |
57 | int main(int argc, char *argv[])
58 | {
59 | struct lxc_container *c;
60 | int ret = 1;
61 |
62 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
63 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
64 | ret = 1;
65 | goto out;
66 | }
67 |
68 | if (c->is_defined(c)) {
69 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
70 | goto out;
71 | }
72 |
73 | if (create_container()) {
74 | fprintf(stderr, "%d: failed to create a container\n", __LINE__);
75 | goto out;
76 | }
77 |
78 | if (!c->is_defined(c)) {
79 | fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
80 | goto out;
81 | }
82 |
83 | if (!c->destroy(c)) {
84 | fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME);
85 | goto out;
86 | }
87 |
88 | if (c->is_defined(c)) {
89 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
90 | goto out;
91 | }
92 |
93 | fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
94 | ret = 0;
95 |
96 | out:
97 | lxc_container_put(c);
98 | exit(ret);
99 | }
100 |
--------------------------------------------------------------------------------
/src/lxc/tools/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | tools_common_sources = files('arguments.c', 'arguments.h') + include_sources
4 | tools_common_sources_for_dynamic_link = tools_common_sources + netns_ifaddrs_sources
5 |
6 | tools_commands_dynamic_link = ['attach', 'autostart', 'cgroup', 'checkpoint', 'config',
7 | 'console', 'copy', 'create', 'destroy', 'device', 'execute', 'freeze',
8 | 'info', 'ls', 'snapshot', 'start', 'stop', 'top', 'unfreeze',
9 | 'unshare', 'wait']
10 |
11 | tools_commands_static_link = ['monitor']
12 |
13 | tools_commands = tools_commands_dynamic_link + tools_commands_static_link
14 |
15 | if want_tools
16 | foreach cmd : tools_commands_dynamic_link
17 | public_programs += executable(
18 | 'lxc-' + cmd,
19 | files('lxc_' + cmd + '.c') + tools_common_sources_for_dynamic_link + liblxc_ext_sources,
20 | dependencies: liblxc_dependencies,
21 | include_directories: liblxc_includes,
22 | c_args: ['-DNO_LXC_CONF'],
23 | link_with: [liblxc],
24 | install: true)
25 | endforeach
26 |
27 | foreach cmd : tools_commands_static_link
28 | public_programs += executable(
29 | 'lxc-' + cmd,
30 | files('lxc_' + cmd + '.c') + files('arguments.c', 'arguments.h'),
31 | dependencies: liblxc_dependencies,
32 | include_directories: liblxc_includes,
33 | link_whole: [liblxc_static],
34 | install: true)
35 | endforeach
36 | endif
37 |
38 | if want_tools_multicall
39 | tools_all_sources = files('lxc_multicall.c') + files('arguments.c', 'arguments.h')
40 | foreach cmd : tools_commands
41 | tools_all_sources += files('lxc_' + cmd + '.c')
42 | endforeach
43 |
44 | public_programs += executable(
45 | 'lxc',
46 | tools_all_sources,
47 | include_directories: liblxc_includes,
48 | dependencies: liblxc_dependencies,
49 | link_whole: [liblxc_static],
50 | install: true)
51 |
52 | if want_tools == false
53 | foreach cmd : tools_commands
54 | public_programs += install_symlink(
55 | 'lxc-' + cmd,
56 | pointing_to: 'lxc',
57 | install_dir: get_option('bindir'))
58 | endforeach
59 | endif
60 | endif
61 |
--------------------------------------------------------------------------------
/src/tests/lxc-test-autostart:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # SPDX-License-Identifier: LGPL-2.1+
4 |
5 | # lxc: linux Container library
6 |
7 | DONE=0
8 | cleanup() {
9 | lxc-destroy -n $CONTAINER_NAME >/dev/null 2>&1 || true
10 |
11 | if [ $DONE -eq 0 ]; then
12 | echo "FAIL"
13 | exit 1
14 | fi
15 | echo "PASS"
16 | }
17 |
18 | trap cleanup EXIT HUP INT TERM
19 | set -eu
20 |
21 | # Create a container
22 | CONTAINER_NAME=lxc-test-auto
23 |
24 | lxc-create -t busybox -n $CONTAINER_NAME -B dir
25 | CONTAINER_PATH=$(dirname $(lxc-info -n $CONTAINER_NAME -c lxc.rootfs.path -H) | sed -e 's/dir://')
26 | cp $CONTAINER_PATH/config $CONTAINER_PATH/config.bak
27 |
28 | # Ensure it's not in lxc-autostart
29 | lxc-autostart -L | grep -q $CONTAINER_NAME && \
30 | (echo "Container shouldn't be auto-started" && exit 1)
31 |
32 | # Mark it as auto-started and re-check
33 | echo "lxc.start.auto = 1" >> $CONTAINER_PATH/config
34 | lxc-autostart -L | grep -q $CONTAINER_NAME || \
35 | (echo "Container should be auto-started" && exit 1)
36 |
37 | # Put it in a test group and set a delay
38 | echo "lxc.group = lxc-auto-test" >> $CONTAINER_PATH/config
39 | echo "lxc.start.delay = 5" >> $CONTAINER_PATH/config
40 |
41 | # Check that everything looks good
42 | if [ "$(lxc-autostart -L -g lxc-auto-test | grep $CONTAINER_NAME)" != "$CONTAINER_NAME 5" ]; then
43 | echo "Invalid autostart setting" && exit 1
44 | fi
45 |
46 | # Start it
47 | lxc-autostart -g lxc-auto-test
48 | lxc-wait -n $CONTAINER_NAME -t 5 -s RUNNING || (echo "Container didn't start" && exit 1)
49 | sleep 5
50 |
51 | # Restart it
52 | lxc-autostart -g lxc-auto-test -r
53 | lxc-wait -n $CONTAINER_NAME -t 5 -s RUNNING || (echo "Container didn't restart" && exit 1)
54 | sleep 5
55 |
56 | # When shutting down, the container calls sync. If the machine running
57 | # the test has a massive backlog, it can take minutes for the sync call to
58 | # finish, causing a test failure.
59 | # So try to reduce that by flushing everything to disk before we attempt
60 | # a container shutdown.
61 | sync
62 |
63 | # Shut it down
64 | lxc-autostart -g lxc-auto-test -s -t 120
65 | lxc-wait -n $CONTAINER_NAME -t 120 -s STOPPED || (echo "Container didn't stop" && exit 1)
66 |
67 | # Kill it
68 | lxc-autostart -g lxc-auto-test -k
69 | lxc-wait -n $CONTAINER_NAME -t 60 -s STOPPED || (echo "Container didn't die" && exit 1)
70 |
71 | DONE=1
72 |
--------------------------------------------------------------------------------
/doc/ja/lxc-unfreeze.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | ]>
8 |
9 |
10 |
11 | @LXC_GENERATE_DATE@
12 |
13 |
14 | lxc-unfreeze
15 | 1
16 |
17 |
18 |
19 | lxc-unfreeze
20 |
21 |
22 |
25 | 全てのコンテナのプロセスの解凍
26 |
27 |
28 |
29 |
30 |
31 | lxc-unfreeze
32 | -n name
33 |
34 |
35 |
36 |
37 | 説明
38 |
39 |
40 |
44 | lxc-unfreeze は、先に lxc-freeze を使って凍結した全てのプロセスを解凍します。
45 |
46 |
47 |
48 |
49 | &commonoptions;
50 |
51 |
52 | 診断
53 |
54 |
55 |
56 |
57 | The container was not found
58 |
59 |
60 |
64 | 指定したコンテナが lxc-create で作成されておらず存在しません。
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | &seealso;
75 |
76 |
77 |
78 |
94 |
--------------------------------------------------------------------------------
/doc/examples/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | example_lxc_complex = configure_file(
4 | configuration: dummy_config_data,
5 | input: 'lxc-complex.conf.in',
6 | output: 'lxc-complex.conf',
7 | install: want_examples,
8 | install_dir: lxcexamplesdir)
9 |
10 | example_lxc_empty_netns = configure_file(
11 | configuration: dummy_config_data,
12 | input: 'lxc-empty-netns.conf.in',
13 | output: 'lxc-empty-netns.conf',
14 | install: want_examples,
15 | install_dir: lxcexamplesdir)
16 |
17 | example_lxc_macvlan = configure_file(
18 | configuration: dummy_config_data,
19 | input: 'lxc-macvlan.conf.in',
20 | output: 'lxc-macvlan.conf',
21 | install: want_examples,
22 | install_dir: lxcexamplesdir)
23 |
24 | example_lxc_no_netns = configure_file(
25 | configuration: dummy_config_data,
26 | input: 'lxc-no-netns.conf.in',
27 | output: 'lxc-no-netns.conf',
28 | install: want_examples,
29 | install_dir: lxcexamplesdir)
30 |
31 | example_lxc_phys = configure_file(
32 | configuration: dummy_config_data,
33 | input: 'lxc-phys.conf.in',
34 | output: 'lxc-phys.conf',
35 | install: want_examples,
36 | install_dir: lxcexamplesdir)
37 |
38 | example_lxc_veth = configure_file(
39 | configuration: dummy_config_data,
40 | input: 'lxc-veth.conf.in',
41 | output: 'lxc-veth.conf',
42 | install: want_examples,
43 | install_dir: lxcexamplesdir)
44 |
45 | example_lxc_vlan = configure_file(
46 | configuration: dummy_config_data,
47 | input: 'lxc-vlan.conf.in',
48 | output: 'lxc-vlan.conf',
49 | install: want_examples,
50 | install_dir: lxcexamplesdir)
51 |
52 | example_lxc_seccomp_v1 = configure_file(
53 | configuration: dummy_config_data,
54 | input: 'seccomp-v1.conf',
55 | output: 'seccomp-v1.conf',
56 | install: want_examples,
57 | install_dir: lxcexamplesdir)
58 |
59 | example_lxc_seccomp_v2 = configure_file(
60 | configuration: dummy_config_data,
61 | input: 'seccomp-v2.conf',
62 | output: 'seccomp-v2.conf',
63 | install: want_examples,
64 | install_dir: lxcexamplesdir)
65 |
66 | example_lxc_seccomp_v2 = configure_file(
67 | configuration: dummy_config_data,
68 | input: 'seccomp-v2-denylist.conf',
69 | output: 'seccomp-v2-denylist.conf',
70 | install: want_examples,
71 | install_dir: lxcexamplesdir)
72 |
--------------------------------------------------------------------------------
/src/tests/shutdowntest.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #define MYNAME "lxctest1"
20 |
21 | int main(int argc, char *argv[])
22 | {
23 | struct lxc_container *c;
24 | int ret = 1;
25 |
26 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
27 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
28 | ret = 1;
29 | goto out;
30 | }
31 |
32 | if (c->is_defined(c)) {
33 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
34 | goto out;
35 | }
36 |
37 | if (!c->set_config_item(c, "lxc.net.0.type", "veth")) {
38 | fprintf(stderr, "%d: failed to set network type\n", __LINE__);
39 | goto out;
40 | }
41 |
42 | c->set_config_item(c, "lxc.net.0.link", "lxcbr0");
43 | c->set_config_item(c, "lxc.net.0.flags", "up");
44 |
45 | if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
46 | fprintf(stderr, "%d: failed to create a container\n", __LINE__);
47 | goto out;
48 | }
49 |
50 | if (!c->is_defined(c)) {
51 | fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
52 | goto out;
53 | }
54 |
55 | c->clear_config(c);
56 | c->load_config(c, NULL);
57 | c->want_daemonize(c, true);
58 |
59 | if (!c->startl(c, 0, NULL)) {
60 | fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME);
61 | goto out;
62 | }
63 |
64 | /* Wait for init to be ready for SIGPWR */
65 | sleep(20);
66 |
67 | if (!c->shutdown(c, 120)) {
68 | fprintf(stderr, "%d: failed to shut down %s\n", __LINE__, MYNAME);
69 | if (!c->stop(c))
70 | fprintf(stderr, "%d: failed to kill %s\n", __LINE__, MYNAME);
71 |
72 | goto out;
73 | }
74 |
75 | if (!c->destroy(c)) {
76 | fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME);
77 | goto out;
78 | }
79 |
80 | if (c->is_defined(c)) {
81 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
82 | goto out;
83 | }
84 |
85 | fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
86 | ret = 0;
87 |
88 | out:
89 | if (c && c->is_defined(c))
90 | c->destroy(c);
91 |
92 | lxc_container_put(c);
93 | exit(ret);
94 | }
95 |
--------------------------------------------------------------------------------
/doc/ko/lxc-unfreeze.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | ]>
8 |
9 |
10 |
11 | @LXC_GENERATE_DATE@
12 |
13 |
14 | lxc-unfreeze
15 | 1
16 |
17 |
18 |
19 | lxc-unfreeze
20 |
21 |
22 |
25 | 컨테이너의 모든 프로세스를 동결해제
26 |
27 |
28 |
29 |
30 |
31 | lxc-unfreeze
32 | -n name
33 |
34 |
35 |
36 |
37 | 설명
38 |
39 |
40 |
44 | lxc-unfreeze는 이전에 lxc-freeze로 동결 시켰던 모든 프로세스들을 동결해제한다.
45 |
46 |
47 |
48 |
49 | &commonoptions;
50 |
51 |
52 | 진단
53 |
54 |
55 |
56 |
57 | The container was not found
58 |
59 |
60 |
64 | 지정한 컨테이너가 lxc-create로 생성된 적이 없다.
65 | 컨테이너가 존재하지 않는다.
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | &seealso;
76 |
77 |
78 |
79 |
95 |
--------------------------------------------------------------------------------
/src/tests/list.c:
--------------------------------------------------------------------------------
1 | /* list.c
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | static void test_list_func(const char *lxcpath, const char *type,
15 | int (*func)(const char *path, char ***names,
16 | struct lxc_container ***cret))
17 | {
18 | int i, n, n2;
19 | struct lxc_container **clist;
20 | char **names;
21 |
22 | printf("%-10s Counting containers\n", type);
23 |
24 | n = func(lxcpath, NULL, NULL);
25 | printf("%-10s Counted %d containers\n", type, n);
26 | printf("%-10s Get container struct only\n", type);
27 |
28 | n2 = func(lxcpath, NULL, &clist);
29 | if (n2 != n)
30 | printf("Warning: first call returned %d, second %d\n", n, n2);
31 |
32 | for (i = 0; i < n2; i++) {
33 | struct lxc_container *c = clist[i];
34 | printf("%-10s Got container struct %s\n", type, c->name);
35 | lxc_container_put(c);
36 | }
37 |
38 | if (n2 > 0) {
39 | free(clist);
40 | clist = NULL;
41 | }
42 |
43 | printf("%-10s Get names only\n", type);
44 | n2 = func(lxcpath, &names, NULL);
45 | if (n2 != n)
46 | printf("Warning: first call returned %d, second %d\n", n, n2);
47 |
48 | for (i = 0; i < n2; i++) {
49 | printf("%-10s Got container name %s\n", type, names[i]);
50 | free(names[i]);
51 | }
52 |
53 | if (n2 > 0) {
54 | free(names);
55 | names = NULL;
56 | }
57 |
58 | printf("%-10s Get names and containers\n", type);
59 | n2 = func(lxcpath, &names, &clist);
60 | if (n2 != n)
61 | printf("Warning: first call returned %d, second %d\n", n, n2);
62 |
63 | for (i = 0; i < n2; i++) {
64 | struct lxc_container *c = clist[i];
65 | printf("%-10s Got container struct %s, name %s\n", type, c->name, names[i]);
66 |
67 | if (strcmp(c->name, names[i]))
68 | fprintf(stderr, "ERROR: name mismatch!\n");
69 |
70 | free(names[i]);
71 | lxc_container_put(c);
72 | }
73 |
74 | if (n2 > 0) {
75 | free(names);
76 | free(clist);
77 | }
78 | }
79 |
80 | int main(int argc, char *argv[])
81 | {
82 | const char *lxcpath = NULL;
83 |
84 | if (argc > 1)
85 | lxcpath = argv[1];
86 |
87 | test_list_func(lxcpath, "Defined:", list_defined_containers);
88 | test_list_func(lxcpath, "Active:", list_active_containers);
89 | test_list_func(lxcpath, "All:", list_all_containers);
90 |
91 | exit(EXIT_SUCCESS);
92 | }
93 |
--------------------------------------------------------------------------------
/src/lxc/storage/overlay.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_OVERLAY_H
4 | #define __LXC_OVERLAY_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include "compiler.h"
16 | #include "storage.h"
17 |
18 | struct lxc_storage;
19 |
20 | struct bdev_specs;
21 |
22 | struct lxc_conf;
23 |
24 | struct lxc_rootfs;
25 |
26 | __hidden extern int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
27 | const char *oldname, const char *cname, const char *oldpath,
28 | const char *lxcpath, int snap, uint64_t newsize,
29 | struct lxc_conf *conf);
30 | __hidden extern int ovl_create(struct lxc_storage *bdev, const char *dest, const char *n,
31 | struct bdev_specs *specs, const struct lxc_conf *conf);
32 | __hidden extern int ovl_destroy(struct lxc_storage *orig);
33 | __hidden extern bool ovl_detect(const char *path);
34 | __hidden extern int ovl_mount(struct lxc_storage *bdev);
35 | __hidden extern int ovl_umount(struct lxc_storage *bdev);
36 |
37 | /* To be called from lxcapi_clone() in lxccontainer.c: When we clone a container
38 | * with overlay lxc.mount.entry entries we need to update absolute paths for
39 | * upper- and workdir. This update is done in two locations:
40 | * lxc_conf->unexpanded_config and lxc_conf->mount_entries. Both updates are
41 | * done independent of each other since lxc_conf->mountlist may container more
42 | * mount entries (e.g. from other included files) than
43 | * lxc_conf->unexpanded_config .
44 | */
45 | __hidden extern int ovl_update_abs_paths(struct lxc_conf *lxc_conf, const char *lxc_path,
46 | const char *lxc_name, const char *newpath,
47 | const char *newname);
48 |
49 | /* To be called from functions in lxccontainer.c: Get lower directory for
50 | * overlay rootfs.
51 | */
52 | __hidden extern const char *ovl_get_lower(const char *rootfs_path);
53 |
54 | /* Get rootfs path for overlay backed containers. Allocated memory must be freed
55 | * by caller.
56 | */
57 | __hidden extern char *ovl_get_rootfs(const char *rootfs_path, size_t *rootfslen);
58 |
59 | /* Create upper- and workdirs for overlay mounts.
60 | */
61 | __hidden extern int ovl_mkdir(const struct mntent *mntent, const struct lxc_rootfs *rootfs,
62 | const char *lxc_name, const char *lxc_path);
63 |
64 | #endif /* __LXC_OVERLAY_H */
65 |
--------------------------------------------------------------------------------
/src/lxc/ringbuf.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_RINGBUF_H
4 | #define __LXC_RINGBUF_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "compiler.h"
14 |
15 | /**
16 | * lxc_ringbuf - Implements a simple and efficient memory mapped ringbuffer.
17 | * - The "addr" field of struct lxc_ringbuf is considered immutable. Instead the
18 | * read and write offsets r_off and w_off are used to calculate the current
19 | * read and write addresses. There should never be a need to use any of those
20 | * fields directly. Instead use the appropriate helpers below.
21 | * - Callers are expected to synchronize read and write accesses to the
22 | * ringbuffer.
23 | */
24 | struct lxc_ringbuf {
25 | char *addr; /* start address of the ringbuffer */
26 | uint64_t size; /* total size of the ringbuffer in bytes */
27 | uint64_t r_off; /* read offset */
28 | uint64_t w_off; /* write offset */
29 | };
30 |
31 | /**
32 | * lxc_ringbuf_create - Initialize a new ringbuffer.
33 | *
34 | * @param[in] size Size of the new ringbuffer as a power of 2.
35 | */
36 | __hidden extern int lxc_ringbuf_create(struct lxc_ringbuf *buf, size_t size);
37 | __hidden extern void lxc_ringbuf_move_read_addr(struct lxc_ringbuf *buf, size_t len);
38 | __hidden extern int lxc_ringbuf_write(struct lxc_ringbuf *buf, const char *msg, size_t len);
39 | __hidden extern int lxc_ringbuf_read(struct lxc_ringbuf *buf, char *out, size_t *len);
40 |
41 | static inline void lxc_ringbuf_release(struct lxc_ringbuf *buf)
42 | {
43 | if (buf->addr)
44 | munmap(buf->addr, buf->size * 2);
45 | }
46 |
47 | static inline void lxc_ringbuf_clear(struct lxc_ringbuf *buf)
48 | {
49 | buf->r_off = 0;
50 | buf->w_off = 0;
51 | }
52 |
53 | static inline uint64_t lxc_ringbuf_used(struct lxc_ringbuf *buf)
54 | {
55 | return buf->w_off - buf->r_off;
56 | }
57 |
58 | static inline uint64_t lxc_ringbuf_free(struct lxc_ringbuf *buf)
59 | {
60 | return buf->size - lxc_ringbuf_used(buf);
61 | }
62 |
63 | static inline char *lxc_ringbuf_get_read_addr(struct lxc_ringbuf *buf)
64 | {
65 | return buf->addr + buf->r_off;
66 | }
67 |
68 | static inline char *lxc_ringbuf_get_write_addr(struct lxc_ringbuf *buf)
69 | {
70 | return buf->addr + buf->w_off;
71 | }
72 |
73 | static inline void lxc_ringbuf_move_write_addr(struct lxc_ringbuf *buf, size_t len)
74 | {
75 | buf->w_off += len;
76 | }
77 |
78 | #endif /* __LXC_RINGBUF_H */
79 |
--------------------------------------------------------------------------------
/src/lxc/freezer.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "attach_options.h"
15 | #include "cgroups/cgroup.h"
16 | #include "cgroups/cgroup_utils.h"
17 | #include "commands.h"
18 | #include "commands_utils.h"
19 | #include "error.h"
20 | #include "log.h"
21 | #include "lxc.h"
22 | #include "monitor.h"
23 | #include "state.h"
24 | #include "string_utils.h"
25 |
26 | lxc_log_define(freezer, lxc);
27 |
28 | static int do_freeze_thaw(bool freeze, struct lxc_conf *conf, const char *name,
29 | const char *lxcpath)
30 | {
31 | call_cleaner(cgroup_exit) struct cgroup_ops *cgroup_ops = NULL;
32 | lxc_state_t new_state = freeze ? FROZEN : THAWED;
33 | int ret;
34 | const char *state;
35 | size_t state_len;
36 |
37 | state = lxc_state2str(new_state);
38 | state_len = strlen(state);
39 |
40 | cgroup_ops = cgroup_init(conf);
41 | if (!cgroup_ops)
42 | return -1;
43 |
44 | ret = cgroup_ops->set(cgroup_ops, "freezer.state", state, name, lxcpath);
45 | if (ret < 0)
46 | return log_error(-1, "Failed to %s %s",
47 | freeze ? "freeze" : "unfreeze", name);
48 |
49 | for (;;) {
50 | char cur_state[MAX_STATE_LENGTH] = "";
51 |
52 | ret = cgroup_ops->get(cgroup_ops, "freezer.state", cur_state,
53 | sizeof(cur_state), name, lxcpath);
54 | if (ret < 0)
55 | return log_error(-1, "Failed to get freezer state of %s", name);
56 |
57 | cur_state[lxc_char_right_gc(cur_state, strlen(cur_state))] = '\0';
58 | if (strnequal(cur_state, state, state_len)) {
59 | lxc_cmd_notify_state_listeners(name, lxcpath, new_state);
60 | return 0;
61 | }
62 |
63 | sleep(1);
64 | }
65 |
66 | return 0;
67 | }
68 |
69 | int lxc_freeze(struct lxc_conf *conf, const char *name, const char *lxcpath)
70 | {
71 | int ret;
72 |
73 | lxc_cmd_notify_state_listeners(name, lxcpath, FREEZING);
74 | ret = do_freeze_thaw(true, conf, name, lxcpath);
75 | lxc_cmd_notify_state_listeners(name, lxcpath, !ret ? FROZEN : RUNNING);
76 | return ret;
77 | }
78 |
79 | int lxc_unfreeze(struct lxc_conf *conf, const char *name, const char *lxcpath)
80 | {
81 | int ret;
82 |
83 | lxc_cmd_notify_state_listeners(name, lxcpath, THAWED);
84 | ret = do_freeze_thaw(false, conf, name, lxcpath);
85 | lxc_cmd_notify_state_listeners(name, lxcpath, !ret ? RUNNING : FROZEN);
86 | return ret;
87 | }
88 |
--------------------------------------------------------------------------------
/doc/lxc-config.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | ]>
7 |
8 |
9 | @LXC_GENERATE_DATE@
10 |
11 | lxc-config
12 | 1
13 |
14 |
15 |
16 | lxc-config
17 |
18 |
19 | query LXC system configuration
20 |
21 |
22 |
23 |
24 |
25 | lxc-config
26 | -l
27 | item
28 |
29 |
30 |
31 |
32 | Description
33 |
34 |
35 | lxc-config queries the lxc system
36 | configuration and lets you list all valid keys or query
37 | individual keys for their value.
38 |
39 |
40 |
41 |
42 | Options
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | List all supported keys.
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Query the value of the specified key.
62 |
63 |
64 |
65 |
66 |
67 |
68 | &seealso;
69 |
70 |
71 |
87 |
--------------------------------------------------------------------------------
/src/lxc/tools/lxc_freeze.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "lxc.h"
12 |
13 | #include "arguments.h"
14 | #include "log.h"
15 |
16 | lxc_log_define(lxc_freeze, lxc);
17 |
18 | static const struct option my_longopts[] = {
19 | LXC_COMMON_OPTIONS
20 | };
21 |
22 | static struct lxc_arguments my_args = {
23 | .progname = "lxc-freeze",
24 | .help = "\
25 | --name=NAME\n\
26 | \n\
27 | lxc-freeze freezes a container with the identifier NAME\n\
28 | \n\
29 | Options :\n\
30 | -n, --name=NAME NAME of the container\n\
31 | --rcfile=FILE Load configuration file FILE\n",
32 | .options = my_longopts,
33 | .parser = NULL,
34 | .checker = NULL,
35 | .log_priority = "ERROR",
36 | .log_file = "none",
37 | };
38 |
39 | int __attribute__((weak, alias("lxc_freeze_main"))) main(int argc, char *argv[]);
40 | int lxc_freeze_main(int argc, char *argv[])
41 | {
42 | struct lxc_container *c;
43 | struct lxc_log log;
44 |
45 | if (lxc_arguments_parse(&my_args, argc, argv))
46 | exit(EXIT_FAILURE);
47 |
48 | log.name = my_args.name;
49 | log.file = my_args.log_file;
50 | log.level = my_args.log_priority;
51 | log.prefix = my_args.progname;
52 | log.quiet = my_args.quiet;
53 | log.lxcpath = my_args.lxcpath[0];
54 |
55 | if (lxc_log_init(&log))
56 | exit(EXIT_FAILURE);
57 |
58 | c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
59 | if (!c) {
60 | ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
61 | exit(EXIT_FAILURE);
62 | }
63 |
64 | if (my_args.rcfile) {
65 | c->clear_config(c);
66 |
67 | if (!c->load_config(c, my_args.rcfile)) {
68 | ERROR("Failed to load rcfile");
69 | lxc_container_put(c);
70 | exit(EXIT_FAILURE);
71 | }
72 |
73 | c->configfile = strdup(my_args.rcfile);
74 | if (!c->configfile) {
75 | ERROR("Out of memory setting new config filename");
76 | lxc_container_put(c);
77 | exit(EXIT_FAILURE);
78 | }
79 | }
80 |
81 | if (!c->may_control(c)) {
82 | ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
83 | lxc_container_put(c);
84 | exit(EXIT_FAILURE);
85 | }
86 |
87 | if (!c->freeze(c)) {
88 | ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name);
89 | lxc_container_put(c);
90 | exit(EXIT_FAILURE);
91 | }
92 |
93 | lxc_container_put(c);
94 |
95 | exit(EXIT_SUCCESS);
96 | }
97 |
--------------------------------------------------------------------------------
/src/lxc/tools/lxc_unfreeze.c:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #include "config.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "lxc.h"
12 |
13 | #include "arguments.h"
14 | #include "log.h"
15 |
16 | lxc_log_define(lxc_unfreeze, lxc);
17 |
18 | static const struct option my_longopts[] = {
19 | LXC_COMMON_OPTIONS
20 | };
21 |
22 | static struct lxc_arguments my_args = {
23 | .progname = "lxc-unfreeze",
24 | .help = "\
25 | --name=NAME\n\
26 | \n\
27 | lxc-unfreeze unfreezes a container with the identifier NAME\n\
28 | \n\
29 | Options :\n\
30 | -n, --name=NAME NAME of the container\n\
31 | --rcfile=FILE Load configuration file FILE\n",
32 | .options = my_longopts,
33 | .parser = NULL,
34 | .checker = NULL,
35 | .log_priority = "ERROR",
36 | .log_file = "none",
37 | };
38 |
39 | int __attribute__((weak, alias("lxc_unfreeze_main"))) main(int argc, char *argv[]);
40 | int lxc_unfreeze_main(int argc, char *argv[])
41 | {
42 | struct lxc_container *c;
43 | struct lxc_log log;
44 |
45 | if (lxc_arguments_parse(&my_args, argc, argv))
46 | exit(EXIT_FAILURE);
47 |
48 | log.name = my_args.name;
49 | log.file = my_args.log_file;
50 | log.level = my_args.log_priority;
51 | log.prefix = my_args.progname;
52 | log.quiet = my_args.quiet;
53 | log.lxcpath = my_args.lxcpath[0];
54 |
55 | if (lxc_log_init(&log))
56 | exit(EXIT_FAILURE);
57 |
58 | c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
59 | if (!c) {
60 | ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
61 | exit(EXIT_FAILURE);
62 | }
63 |
64 | if (!c->may_control(c)) {
65 | ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
66 | lxc_container_put(c);
67 | exit(EXIT_FAILURE);
68 | }
69 |
70 | if (my_args.rcfile) {
71 | c->clear_config(c);
72 |
73 | if (!c->load_config(c, my_args.rcfile)) {
74 | ERROR("Failed to load rcfile");
75 | lxc_container_put(c);
76 | exit(EXIT_FAILURE);
77 | }
78 |
79 | c->configfile = strdup(my_args.rcfile);
80 | if (!c->configfile) {
81 | ERROR("Out of memory setting new config filename");
82 | lxc_container_put(c);
83 | exit(EXIT_FAILURE);
84 | }
85 | }
86 |
87 | if (!c->unfreeze(c)) {
88 | ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name);
89 | lxc_container_put(c);
90 | exit(EXIT_FAILURE);
91 | }
92 |
93 | lxc_container_put(c);
94 |
95 | exit(EXIT_SUCCESS);
96 | }
97 |
--------------------------------------------------------------------------------
/doc/ja/lxc-freeze.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | ]>
8 |
9 |
10 |
11 | @LXC_GENERATE_DATE@
12 |
13 |
14 | lxc-freeze
15 | 1
16 |
17 |
18 |
19 | lxc-freeze
20 |
21 |
22 |
25 | コンテナ内のプロセス全ての凍結
26 |
27 |
28 |
29 |
30 |
31 | lxc-freeze
32 | -n name
33 |
34 |
35 |
36 |
37 | 説明
38 |
39 |
40 |
47 | lxc-freeze は、コンテナ内部で実行中のプロセスを全て凍結します。
48 | プロセスは lxc-unfreeze コマンドによって明示的に解凍されるまでブロックされます。
49 | このコマンドはプロセスのグループをスケジューリングするバッチマネージャに便利なコマンドです。
50 |
51 |
52 |
53 |
54 | &commonoptions;
55 |
56 |
57 | 診断
58 |
59 |
60 |
61 |
62 | The container was not found
63 |
64 |
65 |
69 | 指定したコンテナが lxc-create で作成されておらず存在しません。
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | &seealso;
80 |
81 |
82 |
83 |
99 |
--------------------------------------------------------------------------------
/doc/meson.build:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: LGPL-2.1+
2 |
3 | if want_mans
4 | PAGES = [
5 | ['lxc', '7'],
6 | ['lxc.conf', '5'],
7 | ['lxc.container.conf', '5'],
8 | ['lxc.system.conf', '5'],
9 | ['lxc-update-config', '1'],
10 | ['lxc-usernet', '5'],
11 | ['lxc-user-nic', '1'],
12 | ['lxc-usernsexec', '1'],
13 | ]
14 |
15 | if want_tools
16 | PAGES += [
17 | ['lxc-attach', '1'],
18 | ['lxc-autostart', '1'],
19 | ['lxc-cgroup', '1'],
20 | ['lxc-checkconfig', '1'],
21 | ['lxc-checkpoint', '1'],
22 | ['lxc-config', '1'],
23 | ['lxc-console', '1'],
24 | ['lxc-copy', '1'],
25 | ['lxc-create', '1'],
26 | ['lxc-destroy', '1'],
27 | ['lxc-device', '1'],
28 | ['lxc-execute', '1'],
29 | ['lxc-freeze', '1'],
30 | ['lxc-info', '1'],
31 | ['lxc-ls', '1'],
32 | ['lxc-monitor', '1'],
33 | ['lxc-snapshot', '1'],
34 | ['lxc-start', '1'],
35 | ['lxc-stop', '1'],
36 | ['lxc-top', '1'],
37 | ['lxc-unfreeze', '1'],
38 | ['lxc-unshare', '1'],
39 | ['lxc-wait', '1'],
40 | ]
41 | endif
42 |
43 | if want_pam_cgroup
44 | PAGES += [
45 | ['pam_cgfs', '8'],
46 | ]
47 | endif
48 |
49 | # Common files.
50 | configure_file(
51 | configuration: docconf,
52 | input: 'common_options.sgml.in',
53 | output: 'common_options.sgml')
54 |
55 | configure_file(
56 | configuration: docconf,
57 | input: 'see_also.sgml.in',
58 | output: 'see_also.sgml')
59 |
60 | # Initial templating.
61 | foreach page : PAGES
62 | sgml = configure_file(
63 | configuration: docconf,
64 | input: page[0] + '.sgml.in',
65 | output: page[0] + '.sgml')
66 |
67 | configure_file(
68 | input: sgml,
69 | output: page[0] + '.' + page[1],
70 | command: [sgml2man, '--encoding=UTF-8', page[0] + '.sgml'],
71 | install: true,
72 | install_dir: join_paths(mandir, 'man' + page[1]))
73 | endforeach
74 | endif
75 |
76 | # API Docs (Doxygen)
77 | if want_api_docs
78 | doxygen = find_program('doxygen', required: true)
79 |
80 | api_docs = custom_target(
81 | 'api-docs',
82 | input: files('api/Doxyfile'),
83 | output: 'api-docs.stamp',
84 | command: [doxygen, '@INPUT@'],
85 | build_by_default: true
86 | )
87 | endif
--------------------------------------------------------------------------------
/config/templates/common.conf.in:
--------------------------------------------------------------------------------
1 | # Default configuration shared by all containers
2 |
3 | # Setup the LXC devices in /dev/lxc/
4 | lxc.tty.dir = lxc
5 |
6 | # Allow for 1024 pseudo terminals
7 | lxc.pty.max = 1024
8 |
9 | # Setup 4 tty devices
10 | lxc.tty.max = 4
11 |
12 | # Drop some harmful capabilities
13 | lxc.cap.drop = mac_admin mac_override sys_time sys_module sys_rawio
14 |
15 | # Ensure hostname is changed on clone
16 | lxc.hook.clone = @LXCHOOKDIR@/clonehostname
17 |
18 | # Default legacy cgroup configuration
19 | #
20 | # CGroup allowlist
21 | lxc.cgroup.devices.deny = a
22 | ## Allow any mknod (but not reading/writing the node)
23 | lxc.cgroup.devices.allow = c *:* m
24 | lxc.cgroup.devices.allow = b *:* m
25 | ## Allow specific devices
26 | ### /dev/null
27 | lxc.cgroup.devices.allow = c 1:3 rwm
28 | ### /dev/zero
29 | lxc.cgroup.devices.allow = c 1:5 rwm
30 | ### /dev/full
31 | lxc.cgroup.devices.allow = c 1:7 rwm
32 | ### /dev/tty
33 | lxc.cgroup.devices.allow = c 5:0 rwm
34 | ### /dev/console
35 | lxc.cgroup.devices.allow = c 5:1 rwm
36 | ### /dev/ptmx
37 | lxc.cgroup.devices.allow = c 5:2 rwm
38 | ### /dev/random
39 | lxc.cgroup.devices.allow = c 1:8 rwm
40 | ### /dev/urandom
41 | lxc.cgroup.devices.allow = c 1:9 rwm
42 | ### /dev/pts/*
43 | lxc.cgroup.devices.allow = c 136:* rwm
44 | ### fuse
45 | lxc.cgroup.devices.allow = c 10:229 rwm
46 |
47 | # Default unified cgroup configuration
48 | #
49 | # CGroup allowlist
50 | lxc.cgroup2.devices.deny = a
51 | ## Allow any mknod (but not reading/writing the node)
52 | lxc.cgroup2.devices.allow = c *:* m
53 | lxc.cgroup2.devices.allow = b *:* m
54 | ## Allow specific devices
55 | ### /dev/null
56 | lxc.cgroup2.devices.allow = c 1:3 rwm
57 | ### /dev/zero
58 | lxc.cgroup2.devices.allow = c 1:5 rwm
59 | ### /dev/full
60 | lxc.cgroup2.devices.allow = c 1:7 rwm
61 | ### /dev/tty
62 | lxc.cgroup2.devices.allow = c 5:0 rwm
63 | ### /dev/console
64 | lxc.cgroup2.devices.allow = c 5:1 rwm
65 | ### /dev/ptmx
66 | lxc.cgroup2.devices.allow = c 5:2 rwm
67 | ### /dev/random
68 | lxc.cgroup2.devices.allow = c 1:8 rwm
69 | ### /dev/urandom
70 | lxc.cgroup2.devices.allow = c 1:9 rwm
71 | ### /dev/pts/*
72 | lxc.cgroup2.devices.allow = c 136:* rwm
73 | ### fuse
74 | lxc.cgroup2.devices.allow = c 10:229 rwm
75 |
76 | # Setup the default mounts
77 | lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
78 | lxc.mount.entry = /sys/fs/fuse/connections sys/fs/fuse/connections none bind,optional 0 0
79 |
80 | # Block some syscalls which are not safe in privileged
81 | # containers
82 | lxc.seccomp.profile = @LXCTEMPLATECONFIG@/common.seccomp
83 |
84 | # Lastly, include all the configs from @LXCTEMPLATECONFIG@/common.conf.d/
85 | lxc.include = @LXCTEMPLATECONFIG@/common.conf.d/
86 |
--------------------------------------------------------------------------------
/src/lxc/cgroups/cgroup2_devices.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | /* Parts of this taken from systemd's implementation. */
4 |
5 | #ifndef __LXC_CGROUP2_DEVICES_H
6 | #define __LXC_CGROUP2_DEVICES_H
7 |
8 | #include "config.h"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "cgroup.h"
21 | #include "compiler.h"
22 | #include "conf.h"
23 | #include "list.h"
24 | #include "macro.h"
25 | #include "memory_utils.h"
26 | #include "syscall_numbers.h"
27 |
28 | #include "bpf.h"
29 | #include "bpf_common.h"
30 |
31 | #if !HAVE_BPF
32 | static inline int bpf_lxc(int cmd, union bpf_attr *attr, size_t size)
33 | {
34 | return syscall(__NR_bpf, cmd, attr, size);
35 | }
36 | #define bpf bpf_lxc
37 | #endif /* HAVE_BPF */
38 |
39 | struct bpf_program {
40 | int device_list_type;
41 | int kernel_fd;
42 | __u32 prog_type;
43 |
44 | size_t n_instructions;
45 | struct bpf_insn *instructions;
46 |
47 | int fd_cgroup;
48 | int attached_type;
49 | __u32 attached_flags;
50 | };
51 |
52 | __hidden extern struct bpf_program *bpf_program_new(__u32 prog_type);
53 | __hidden extern int bpf_program_init(struct bpf_program *prog);
54 | __hidden extern int bpf_program_append_device(struct bpf_program *prog, struct device_item *device);
55 | __hidden extern int bpf_program_finalize(struct bpf_program *prog);
56 | __hidden extern int bpf_program_cgroup_detach(struct bpf_program *prog);
57 | __hidden extern void bpf_device_program_free(struct cgroup_ops *ops);
58 | __hidden extern bool bpf_devices_cgroup_supported(void);
59 |
60 | /*
61 | * Note that bpf_list_add_device() returns 1 if it altered the device list and
62 | * 0 if it didn't; both return values indicate success. Only a negative return
63 | * value indicates an error.
64 | */
65 | __hidden extern int bpf_list_add_device(struct bpf_devices *bpf_devices,
66 | struct device_item *device);
67 | __hidden extern bool bpf_cgroup_devices_attach(struct cgroup_ops *ops,
68 | struct bpf_devices *bpf_devices);
69 | __hidden extern bool bpf_cgroup_devices_update(struct cgroup_ops *ops,
70 | struct bpf_devices *bpf_devices,
71 | struct device_item *device);
72 |
73 | static inline void bpf_program_free(struct bpf_program *prog)
74 | {
75 | if (prog) {
76 | (void)bpf_program_cgroup_detach(prog);
77 | free(prog->instructions);
78 | free(prog);
79 | }
80 | }
81 | define_cleanup_function(struct bpf_program *, bpf_program_free);
82 | #define __do_bpf_program_free call_cleaner(bpf_program_free)
83 |
84 | #endif /* __LXC_CGROUP2_DEVICES_H */
85 |
--------------------------------------------------------------------------------
/src/tests/device_add_remove.c:
--------------------------------------------------------------------------------
1 | /* DEVICE_add_remove.c
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #include "lxctest.h"
14 | #include "memory_utils.h"
15 | #include "utils.h"
16 |
17 | #if !HAVE_STRLCPY
18 | #include "strlcpy.h"
19 | #endif
20 |
21 | #define NAME "device_add_remove_test"
22 | #define DEVICE "/dev/loop-control"
23 |
24 | int main(int argc, char *argv[])
25 | {
26 | __do_close int fd_log = -EBADF;
27 | int ret = 1;
28 | struct lxc_log log = {};
29 | struct lxc_container *c = NULL;
30 | char template[sizeof(P_tmpdir"/attach_XXXXXX")];
31 |
32 | (void)strlcpy(template, P_tmpdir"/attach_XXXXXX", sizeof(template));
33 |
34 | fd_log = lxc_make_tmpfile(template, false);
35 | if (fd_log < 0) {
36 | lxc_error("Failed to create temporary log file for container %s\n", NAME);
37 | exit(EXIT_FAILURE);
38 | }
39 | log.name = NAME;
40 | log.file = template;
41 | log.level = "TRACE";
42 | log.prefix = "device_add_remove";
43 | log.quiet = false;
44 | log.lxcpath = NULL;
45 | if (lxc_log_init(&log))
46 | goto out;
47 |
48 | c = lxc_container_new(NAME, NULL);
49 | if (!c) {
50 | fprintf(stderr, "Unable to instantiate container (%s)...\n", NAME);
51 | goto out;
52 | }
53 |
54 | if (!c->create(c, "busybox", NULL, NULL, 1, NULL)) {
55 | fprintf(stderr, "Creating the container (%s) failed...\n", NAME);
56 | goto out;
57 | }
58 |
59 | c->want_daemonize(c, true);
60 |
61 | if (!c->start(c, false, NULL)) {
62 | fprintf(stderr, "Starting the container (%s) failed...\n", NAME);
63 | goto out;
64 | }
65 |
66 | if (!c->add_device_node(c, DEVICE, DEVICE)) {
67 | fprintf(stderr, "Adding %s to the container (%s) failed...\n", DEVICE, NAME);
68 | goto out;
69 | }
70 |
71 | if (!c->remove_device_node(c, DEVICE, DEVICE)) {
72 | fprintf(stderr, "Removing %s from the container (%s) failed...\n", DEVICE, NAME);
73 | goto out;
74 | }
75 |
76 | if (!c->stop(c)) {
77 | fprintf(stderr, "Stopping the container (%s) failed...\n", NAME);
78 | goto out;
79 | }
80 |
81 | if (!c->destroy(c)) {
82 | fprintf(stderr, "Destroying the container (%s) failed...\n", NAME);
83 | goto out;
84 | }
85 |
86 | ret = 0;
87 |
88 | out:
89 | if (ret != 0) {
90 | char buf[4096];
91 | ssize_t buflen;
92 | while ((buflen = read(fd_log, buf, 1024)) > 0) {
93 | buflen = write(STDERR_FILENO, buf, buflen);
94 | if (buflen <= 0)
95 | break;
96 | }
97 | }
98 | (void)unlink(template);
99 |
100 | if (c)
101 | lxc_container_put(c);
102 | return ret;
103 | }
104 |
--------------------------------------------------------------------------------
/src/lxc/monitor.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: LGPL-2.1+ */
2 |
3 | #ifndef __LXC_MONITOR_H
4 | #define __LXC_MONITOR_H
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "compiler.h"
14 |
15 | typedef enum {
16 | lxc_msg_state,
17 | lxc_msg_priority,
18 | lxc_msg_exit_code,
19 | } lxc_msg_type_t;
20 |
21 | struct lxc_msg {
22 | lxc_msg_type_t type;
23 | char name[NAME_MAX + 1];
24 | int value;
25 | };
26 |
27 | __hidden extern int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr);
28 | __hidden extern int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path_sz,
29 | int do_mkdirp);
30 | __hidden extern void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath);
31 | __hidden extern void lxc_monitor_send_exit_code(const char *name, int exit_code, const char *lxcpath);
32 | __hidden extern int lxc_monitord_spawn(const char *lxcpath);
33 |
34 | /*
35 | * Open the monitoring mechanism for a specific container
36 | * The function will return an fd corresponding to the events
37 | * Returns a file descriptor on success, < 0 otherwise
38 | */
39 | __hidden extern int lxc_monitor_open(const char *lxcpath);
40 |
41 | /*
42 | * Blocking read for the next container state change
43 | * @fd : the file descriptor provided by lxc_monitor_open
44 | * @msg : the variable which will be filled with the state
45 | * Returns 0 if the monitored container has exited, > 0 if
46 | * data was read, < 0 otherwise
47 | */
48 | __hidden extern int lxc_monitor_read(int fd, struct lxc_msg *msg);
49 |
50 | /*
51 | * Blocking read for the next container state change with timeout
52 | * @fd : the file descriptor provided by lxc_monitor_open
53 | * @msg : the variable which will be filled with the state
54 | * @timeout : the timeout in seconds to wait for a state change
55 | * Returns 0 if the monitored container has exited, > 0 if
56 | * data was read, < 0 otherwise
57 | */
58 | __hidden extern int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout);
59 |
60 | /*
61 | * Blocking read from multiple monitors for the next container state
62 | * change with timeout
63 | * @fds : struct pollfd describing the fds to use
64 | * @nfds : the number of entries in fds
65 | * @msg : the variable which will be filled with the state
66 | * @timeout : the timeout in seconds to wait for a state change
67 | * Returns 0 if the monitored container has exited, > 0 if
68 | * data was read, < 0 otherwise
69 | */
70 | __hidden extern int lxc_monitor_read_fdset(struct pollfd *fds, nfds_t nfds, struct lxc_msg *msg,
71 | int timeout);
72 |
73 | #endif /* __LXC_MONITOR_H */
74 |
--------------------------------------------------------------------------------
/src/tests/criu_check_feature.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 | #include
11 |
12 | #include "lxc/lxccontainer.h"
13 | #include "lxctest.h"
14 |
15 | int main(int argc, char *argv[])
16 | {
17 | struct lxc_container *c;
18 | struct migrate_opts m_opts;
19 | int ret = EXIT_FAILURE;
20 |
21 | /* Test the feature check interface,
22 | * we actually do not need a container. */
23 | c = lxc_container_new("check_feature", NULL);
24 | if (!c) {
25 | lxc_error("%s", "Failed to create container \"check_feature\"");
26 | exit(ret);
27 | }
28 |
29 | if (c->is_defined(c)) {
30 | lxc_error("%s\n", "Container \"check_feature\" is defined");
31 | goto on_error_put;
32 | }
33 |
34 | /* check the migrate API call with wrong 'cmd' */
35 | if (!c->migrate(c, UINT_MAX, &m_opts, sizeof(struct migrate_opts))) {
36 | /* This should failed */
37 | lxc_error("%s\n", "Migrate API calls with command UINT_MAX did not fail");
38 | goto on_error_put;
39 | }
40 |
41 | /* do the actual feature check for memory tracking */
42 | m_opts.features_to_check = FEATURE_MEM_TRACK;
43 | if (c->migrate(c, MIGRATE_FEATURE_CHECK, &m_opts, sizeof(struct migrate_opts))) {
44 | lxc_debug("%s\n", "System does not support \"FEATURE_MEM_TRACK\".");
45 | }
46 |
47 | /* check for lazy pages */
48 | m_opts.features_to_check = FEATURE_LAZY_PAGES;
49 | if (c->migrate(c, MIGRATE_FEATURE_CHECK, &m_opts, sizeof(struct migrate_opts))) {
50 | lxc_debug("%s\n", "System does not support \"FEATURE_LAZY_PAGES\".");
51 | }
52 |
53 | /* check for lazy pages and memory tracking */
54 | m_opts.features_to_check = FEATURE_LAZY_PAGES | FEATURE_MEM_TRACK;
55 | if (c->migrate(c, MIGRATE_FEATURE_CHECK, &m_opts, sizeof(struct migrate_opts))) {
56 | if (m_opts.features_to_check == FEATURE_LAZY_PAGES)
57 | lxc_debug("%s\n", "System does not support \"FEATURE_MEM_TRACK\"");
58 | else if (m_opts.features_to_check == FEATURE_MEM_TRACK)
59 | lxc_debug("%s\n", "System does not support \"FEATURE_LAZY_PAGES\"");
60 | else
61 | lxc_debug("%s\n", "System does not support \"FEATURE_MEM_TRACK\" "
62 | "and \"FEATURE_LAZY_PAGES\"");
63 | }
64 |
65 | /* test for unknown feature; once there are 64 features to test
66 | * this will be valid... */
67 | m_opts.features_to_check = -1ULL;
68 | if (!c->migrate(c, MIGRATE_FEATURE_CHECK, &m_opts, sizeof(struct migrate_opts))) {
69 | lxc_error("%s\n", "Unsupported feature supported, which is strange.");
70 | goto on_error_put;
71 | }
72 |
73 | ret = EXIT_SUCCESS;
74 |
75 | on_error_put:
76 | lxc_container_put(c);
77 | if (ret == EXIT_SUCCESS)
78 | lxc_debug("%s\n", "All criu feature check tests passed");
79 |
80 | exit(ret);
81 | }
82 |
--------------------------------------------------------------------------------
/src/tests/saveconfig.c:
--------------------------------------------------------------------------------
1 | /* liblxcapi
2 | *
3 | * SPDX-License-Identifier: GPL-2.0-only
4 | *
5 | */
6 |
7 | #include "config.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #define MYNAME "lxctest1"
20 |
21 | static int create_container(void)
22 | {
23 | int status, ret;
24 | pid_t pid = fork();
25 |
26 | if (pid < 0) {
27 | perror("fork");
28 | return -1;
29 | }
30 |
31 | if (pid == 0) {
32 | execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
33 | exit(EXIT_FAILURE);
34 | }
35 |
36 | again:
37 | ret = waitpid(pid, &status, 0);
38 | if (ret == -1) {
39 | if (errno == EINTR)
40 | goto again;
41 |
42 | perror("waitpid");
43 | return -1;
44 | }
45 |
46 | if (ret != pid)
47 | goto again;
48 |
49 | if (!WIFEXITED(status)) { // did not exit normally
50 | fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__);
51 | return -1;
52 | }
53 |
54 | return WEXITSTATUS(status);
55 | }
56 |
57 | int main(int argc, char *argv[])
58 | {
59 | struct lxc_container *c;
60 | int ret = 1;
61 |
62 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
63 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
64 | ret = 1;
65 | goto out;
66 | }
67 |
68 | if (c->is_defined(c)) {
69 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
70 | goto out;
71 | }
72 |
73 | if (create_container()) {
74 | fprintf(stderr, "%d: failed to create a container\n", __LINE__);
75 | goto out;
76 | }
77 |
78 | if (!c->is_defined(c)) {
79 | fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
80 | goto out;
81 | }
82 |
83 | c->load_config(c, NULL);
84 | unlink("/tmp/lxctest1");
85 | if (!c->save_config(c, "/tmp/lxctest1")) {
86 | fprintf(stderr, "%d: failed writing config file /tmp/lxctest1\n", __LINE__);
87 | goto out;
88 | }
89 |
90 | rename(LXCPATH "/" MYNAME "/config", LXCPATH "/" MYNAME "/config.bak");
91 | if (!c->save_config(c, NULL)) {
92 | fprintf(stderr, "%d: failed writing config file\n", __LINE__);
93 | goto out;
94 | }
95 |
96 | if (!c->destroy(c)) {
97 | fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME);
98 | goto out;
99 | }
100 |
101 | if (c->is_defined(c)) {
102 | fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
103 | goto out;
104 | }
105 |
106 | fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
107 | ret = 0;
108 |
109 | out:
110 | lxc_container_put(c);
111 | exit(ret);
112 | }
113 |
--------------------------------------------------------------------------------
/doc/ko/lxc-freeze.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | ]>
8 |
9 |
10 |
11 | @LXC_GENERATE_DATE@
12 |
13 |
14 | lxc-freeze
15 | 1
16 |
17 |
18 |
19 | lxc-freeze
20 |
21 |
22 |
25 | 컨테이너의 모든 프로세스를 동결
26 |
27 |
28 |
29 |
30 |
31 | lxc-freeze
32 | -n name
33 |
34 |
35 |
36 |
37 | 설명
38 |
39 |
40 |
47 | lxc-freeze는 컨테이너 내부에서 실행되는 모든 프로세스를 동결시킨다.
48 | 프로세스는 lxc-unfreeze 명령어를 이용하여 명시적으로 동결 해제시킬 때까지 블로킹 된다.
49 | 이 명령어는 프로세스 그룹들을 스케줄링하여 일괄처리하는 데 유용하다.
50 |
51 |
52 |
53 |
54 | &commonoptions;
55 |
56 |
57 | 진단
58 |
59 |
60 |
61 |
62 | The container was not found
63 |
64 |
65 |
69 | 지정한 컨테이너가 lxc-create로 생성된 적이 없다.
70 | 컨테이너가 존재하지 않는다.
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | &seealso;
81 |
82 |
83 |
84 |
100 |
--------------------------------------------------------------------------------
/doc/see_also.sgml.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | See Also
5 |
6 |
7 |
8 | lxc
9 | 7
10 | ,
11 |
12 |
13 | lxc-create
14 | 1
15 | ,
16 |
17 |
18 | lxc-copy
19 | 1
20 | ,
21 |
22 |
23 | lxc-destroy
24 | 1
25 | ,
26 |
27 |
28 | lxc-start
29 | 1
30 | ,
31 |
32 |
33 | lxc-stop
34 | 1
35 | ,
36 |
37 |
38 | lxc-execute
39 | 1
40 | ,
41 |
42 |
43 | lxc-console
44 | 1
45 | ,
46 |
47 |
48 | lxc-monitor
49 | 1
50 | ,
51 |
52 |
53 | lxc-wait
54 | 1
55 | ,
56 |
57 |
58 | lxc-cgroup
59 | 1
60 | ,
61 |
62 |
63 | lxc-ls
64 | 1
65 | ,
66 |
67 |
68 | lxc-info
69 | 1
70 | ,
71 |
72 |
73 | lxc-freeze
74 | 1
75 | ,
76 |
77 |
78 | lxc-unfreeze
79 | 1
80 | ,
81 |
82 |
83 | lxc-attach
84 | 1
85 | ,
86 |
87 |
88 | lxc.conf
89 | 5
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------