Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
mv ../lxc_* out/

- name: Upload resulting build
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
continue-on-error: true
with:
name: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fuzzing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
sanitizer: ${{ matrix.sanitizer }}

- name: Upload Crash
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
if: failure() && steps.build.outcome == 'success'
with:
name: ${{ matrix.sanitizer }}-artifacts
Expand Down
1 change: 1 addition & 0 deletions doc/lxc-create.sgml.in
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
You can specify the following options :
<replaceable>--rbdname RBDNAME</replaceable> will create a blockdevice named RBDNAME rather than the default, which is the container name.
<replaceable>--rbdpool POOL</replaceable> will create the blockdevice in the pool named POOL, rather than the default, which is 'lxc'.
<replaceable>--rbduser RBDUSER</replaceable> will specify the ceph user RBDUSER creating the blockdevice, rather than the default, which is 'admin'.
</para>
<para>
If backingstore is 'best', then lxc will try, in order, btrfs,
Expand Down
15 changes: 15 additions & 0 deletions doc/lxc.sgml.in
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,21 @@ rootfs
</para>
</refsect2>

<refsect2>
<title>Unprivileged containers</title>
<para>
Unprivileged LXC containers run without root host-level privileges in a
user namespace, mapping container UID 0 to a non-root host ID, which
strictly limits the accessible devices and filesystems of the
container. In order to mount a rootfs in an unprivileged container, the
mapped host user must have execute permissions for all directories
along the path to and including the rootfs. Additionally, all files and
directories under the rootfs must be owned by the correct user ID and
group ID. The correct user ID and group ID are the host IDs mapped to
the container root(UID 0) in lxc.idmap.
</para>
</refsect2>

<refsect2>
<title>Creating / Destroying containers</title>
<para>
Expand Down
13 changes: 13 additions & 0 deletions doc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,16 @@ if want_mans
install_dir: join_paths(mandir, 'man' + page[1]))
endforeach
endif

# API Docs (Doxygen)
if want_api_docs
doxygen = find_program('doxygen', required: true)

api_docs = custom_target(
'api-docs',
input: files('api/Doxyfile'),
output: 'api-docs.stamp',
command: [doxygen, '@INPUT@'],
build_by_default: true
)
endif
7 changes: 7 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ want_install_init = get_option('install-init-files')
want_io_uring = get_option('io-uring-event-loop')
want_pam_cgroup = get_option('pam-cgroup')
want_mans = get_option('man')
want_api_docs = get_option('api-docs')
want_tests = get_option('tests')
want_tools = get_option('tools')
want_tools_multicall = get_option('tools-multicall')
Expand Down Expand Up @@ -341,6 +342,12 @@ if not sgml2man.found()
endif
endif

## API Docs.
doxygen = find_program('doxygen', required: false)
if not doxygen.found() and want_api_docs
error('missing required doxygen dependency')
endif

## Threads.
threads = dependency('threads')
liblxc_dependencies += threads
Expand Down
4 changes: 4 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ option('io-uring-event-loop', type: 'boolean', value: false,
option('man', type: 'boolean', value: true,
description: 'build and install manpages')

# was --{disable,enable}-api-docs in autotools
option('api-docs', type: 'boolean', value: false,
description: 'build and install API documentation (Doxygen)')

# was --{disable,enable}-pam in autotools
option('pam-cgroup', type: 'boolean', value: false,
description: 'build and install the pam cgroup module')
Expand Down
1 change: 1 addition & 0 deletions src/lxc/initutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const char *lxc_global_config_value(const char *option_name)
{ "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL },
{ "lxc.bdev.zfs.root", DEFAULT_ZFSROOT },
{ "lxc.bdev.rbd.rbdpool", DEFAULT_RBDPOOL },
{ "lxc.bdev.rbd.rbduser", DEFAULT_RBDUSER },
{ "lxc.lxcpath", NULL },
{ "lxc.default_config", NULL },
{ "lxc.cgroup.pattern", NULL },
Expand Down
1 change: 1 addition & 0 deletions src/lxc/initutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define DEFAULT_THIN_POOL "lxc"
#define DEFAULT_ZFSROOT "lxc"
#define DEFAULT_RBDPOOL "lxc"
#define DEFAULT_RBDUSER NULL

#ifndef PR_SET_MM
#define PR_SET_MM 35
Expand Down
4 changes: 4 additions & 0 deletions src/lxc/lxccontainer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3468,6 +3468,10 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
return;
}

if (!file_exists(path0)) {
return;
}

if (copy_file(path0, path1) < 0) {
INFO("Error copying reverse dependencies");
return;
Expand Down
1 change: 1 addition & 0 deletions src/lxc/lxccontainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ struct bdev_specs {
struct {
char *rbdname; /*!< RBD image name */
char *rbdpool; /*!< Ceph pool name */
char *rbduser; /*!< Ceph user name*/
} rbd;
};

Expand Down
15 changes: 7 additions & 8 deletions src/lxc/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,9 +1307,6 @@ static int do_start(void *data)
if (!handler->conf->root_nsgid_map)
nsgid = handler->conf->init_gid;

/* Drop groups only after we switched to a valid gid in the new
* user namespace.
*/
if (!lxc_drop_groups() &&
(handler->am_root || errno != EPERM))
goto out_warn_father;
Expand Down Expand Up @@ -1606,17 +1603,19 @@ static int do_start(void *data)
if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE))
#endif
{
if (handler->conf->init_groups.size > 0) {
if (!lxc_setgroups(handler->conf->init_groups.list,
handler->conf->init_groups.size))
goto out_warn_father;
} else {
if (handler->conf->init_groups.size == 0) {
if (!lxc_drop_groups())
goto out_warn_father;
}
}
}

if (handler->conf->init_groups.size > 0) {
if (!lxc_setgroups(handler->conf->init_groups.list,
handler->conf->init_groups.size))
goto out_warn_father;
}

if (!lxc_switch_uid_gid(new_uid, new_gid))
goto out_warn_father;

Expand Down
40 changes: 35 additions & 5 deletions src/lxc/storage/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ lxc_log_define(rbd, lxc);

struct rbd_args {
const char *osd_pool_name;
const char *rbd_user;
const char *rbd_name;
const char *size;
};
Expand All @@ -30,8 +31,14 @@ static int rbd_create_wrapper(void *data)
{
struct rbd_args *args = data;

execlp("rbd", "rbd", "create", "--pool", args->osd_pool_name,
if (args->rbd_user){
execlp("rbd", "rbd", "create", "--id", args->rbd_user, "--pool",
args->osd_pool_name, args->rbd_name, "--size", args->size,
(char *)NULL);
} else {
execlp("rbd", "rbd", "create", "--pool", args->osd_pool_name,
args->rbd_name, "--size", args->size, (char *)NULL);
}

return -1;
}
Expand All @@ -40,17 +47,27 @@ static int rbd_map_wrapper(void *data)
{
struct rbd_args *args = data;

execlp("rbd", "rbd", "map", "--pool", args->osd_pool_name,
if (args->rbd_user){
execlp("rbd", "rbd", "map", "--id", args->rbd_user, "--pool",
args->osd_pool_name, args->rbd_name, (char *)NULL);
} else {
execlp("rbd", "rbd", "map", "--pool", args->osd_pool_name,
args->rbd_name, (char *)NULL);

}
return -1;
}

static int rbd_unmap_wrapper(void *data)
{
struct rbd_args *args = data;

execlp("rbd", "rbd", "unmap", args->rbd_name, (char *)NULL);
if (args->rbd_user){
execlp("rbd", "rbd", "unmap", "--id", args->rbd_user, args->rbd_name,
(char *)NULL);
} else {
execlp("rbd", "rbd", "unmap", args->rbd_name, (char *)NULL);
}


return -1;
}
Expand All @@ -59,7 +76,12 @@ static int rbd_delete_wrapper(void *data)
{
struct rbd_args *args = data;

execlp("rbd", "rbd", "rm", args->rbd_name, (char *)NULL);
if (args->rbd_user){
execlp("rbd", "rbd", "rm", "--id", args->rbd_user, args->rbd_name,
(char *)NULL);
} else {
execlp("rbd", "rbd", "rm", args->rbd_name, (char *)NULL);
}

return -1;
}
Expand All @@ -83,6 +105,7 @@ int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
const char *cmd_args[2];
char cmd_output[PATH_MAX];
const char *rbdname = n;
const char *rbduser;
struct rbd_args args = {0};

if (!specs)
Expand All @@ -94,6 +117,10 @@ int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,

if (specs->rbd.rbdname)
rbdname = specs->rbd.rbdname;

rbduser = specs->rbd.rbduser;
if (!rbduser)
rbduser = lxc_global_config_value("lxc.bdev.rbd.rbduser");

/* source device /dev/rbd/lxc/ctn */
len = strlen(rbdpool) + strlen(rbdname) + 4 + 11;
Expand Down Expand Up @@ -123,6 +150,7 @@ int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,

args.osd_pool_name = rbdpool;
args.rbd_name = rbdname;
args.rbd_user = rbduser;
args.size = sz;
ret = run_command(cmd_output, sizeof(cmd_output), rbd_create_wrapper,
(void *)&args);
Expand Down Expand Up @@ -179,6 +207,8 @@ int rbd_destroy(struct lxc_storage *orig)
struct rbd_args args = {0};
size_t len;

args.rbd_user = lxc_global_config_value("lxc.bdev.rbd.rbduser");

src = lxc_storage_get_path(orig->src, orig->type);
if (file_exists(src)) {
args.rbd_name = src;
Expand Down
2 changes: 1 addition & 1 deletion src/lxc/tools/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct lxc_arguments {
char *fstype;
uint64_t fssize;
char *lvname, *vgname, *thinpool;
char *rbdname, *rbdpool;
char *rbdname, *rbdpool, *rbduser;
char *zfsroot, *lowerdir, *dir;

/* lxc-execute and lxc-unshare */
Expand Down
11 changes: 10 additions & 1 deletion src/lxc/tools/lxc_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static const struct option my_longopts[] = {
{"dir", required_argument, 0, '6'},
{"rbdname", required_argument, 0, '7'},
{"rbdpool", required_argument, 0, '8'},
{"rbduser", required_argument, 0, '9'},
LXC_COMMON_OPTIONS
};

Expand Down Expand Up @@ -67,6 +68,8 @@ Options :\n\
(Default: container name)\n\
--rbdpool=POOL Use Ceph RBD pool name POOL\n\
(Default: lxc)\n\
--rbduser=RBDUSER Use Ceph user RBDUSER for auth\n\
(Default: admin)\n\
\n\
BDEV option for ZFS (with -B/--bdev zfs) :\n\
--zfsroot=PATH Create zfs under given zfsroot\n\
Expand Down Expand Up @@ -128,6 +131,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
case '8':
args->rbdpool = arg;
break;
case '9':
args->rbduser = arg;
break;
}
return 0;
}
Expand Down Expand Up @@ -175,7 +181,7 @@ static bool validate_bdev_args(struct lxc_arguments *args)
}

if (strncmp(args->bdevtype, "rbd", strlen(args->bdevtype)) != 0)
if (args->rbdname || args->rbdpool) {
if (args->rbdname || args->rbdpool ) {
ERROR("--rbdname and --rbdpool are only valid with -B rbd");
return false;
}
Expand Down Expand Up @@ -303,6 +309,9 @@ int lxc_create_main(int argc, char *argv[])

if (my_args.rbdpool)
spec.rbd.rbdpool = my_args.rbdpool;

if(my_args.rbduser)
spec.rbd.rbduser = my_args.rbduser;
}

if (my_args.dir)
Expand Down