Skip to content

Commit

Permalink
Merge pull request #645 from mihalicyn/runtime_dir_override
Browse files Browse the repository at this point in the history
Allow overriding RUNTIME_DIR with a cli flag #2
  • Loading branch information
stgraber authored Jun 6, 2024
2 parents 9b873a1 + 5c42da9 commit 62c7230
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 35 deletions.
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ lxcmandir = join_paths(datadir, 'man')
conf.set_quoted('BINDIR', bindir)
conf.set_quoted('LIBDIR', libdir)
conf.set_quoted('LOCALSTATEDIR', localstatedir)
conf.set_quoted('RUNTIME_PATH', runtimepath)
conf.set_quoted('DEFAULT_RUNTIME_PATH', runtimepath)
conf.set_quoted('SYSCONFDIR', sysconfdir)

conf.set_quoted('LXCCONFDIR', lxcconfdir)
Expand Down
100 changes: 80 additions & 20 deletions src/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
#include <linux/limits.h>
#include <linux/magic.h>
#include <linux/sched.h>
#include <pthread.h>
Expand Down Expand Up @@ -40,15 +41,32 @@
#include "syscall_numbers.h"
#include "utils.h"

/* directory under which we mount the controllers - /run/lxcfs/controllers */
#define BASEDIR "/lxcfs/controllers"
#define ROOTDIR "/lxcfs/root"

static bool can_use_pidfd;
static bool can_use_swap;
static bool can_use_sys_cpu;
static bool has_versioned_opts;
static bool memory_is_cgroupv2;
static __u32 host_personality;
static char runtime_path[PATH_MAX] = DEFAULT_RUNTIME_PATH;


static volatile sig_atomic_t reload_successful;


static char *get_base_dir(void)
{
return must_make_path(runtime_path, BASEDIR, NULL);
}

static char *get_root_dir(void)
{
return must_make_path(runtime_path, ROOTDIR, NULL);
}

bool liblxcfs_functional(void)
{
return reload_successful != 0;
Expand Down Expand Up @@ -580,8 +598,9 @@ pid_t lookup_initpid_in_store(pid_t pid)

static bool umount_if_mounted(void)
{
if (umount2(BASEDIR, MNT_DETACH) < 0 && errno != EINVAL) {
lxcfs_error("Failed to unmount %s: %s.\n", BASEDIR, strerror(errno));
__do_free char *base_dir = get_base_dir();
if (umount2(base_dir, MNT_DETACH) < 0 && errno != EINVAL) {
lxcfs_error("Failed to unmount %s: %s.\n", base_dir, strerror(errno));
return false;
}
return true;
Expand Down Expand Up @@ -639,13 +658,14 @@ static bool is_on_ramfs(void)
static int pivot_enter(void)
{
__do_close int oldroot = -EBADF, newroot = -EBADF;
__do_free char *root_dir = get_root_dir();

oldroot = open("/", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (oldroot < 0)
return log_error_errno(-1, errno,
"Failed to open old root for fchdir");

newroot = open(ROOTDIR, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
newroot = open(root_dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (newroot < 0)
return log_error_errno(-1, errno,
"Failed to open new root for fchdir");
Expand All @@ -654,7 +674,7 @@ static int pivot_enter(void)
if (fchdir(newroot) < 0)
return log_error_errno(-1,
errno, "Failed to change directory to new rootfs: %s",
ROOTDIR);
root_dir);

/* pivot_root into our new root fs */
if (pivot_root(".", ".") < 0)
Expand All @@ -681,8 +701,10 @@ static int pivot_enter(void)

static int chroot_enter(void)
{
if (mount(ROOTDIR, "/", NULL, MS_REC | MS_BIND, NULL)) {
lxcfs_error("Failed to recursively bind-mount %s into /.", ROOTDIR);
__do_free char *root_dir = get_root_dir();

if (mount(root_dir, "/", NULL, MS_REC | MS_BIND, NULL)) {
lxcfs_error("Failed to recursively bind-mount %s into /.", root_dir);
return -1;
}

Expand Down Expand Up @@ -725,23 +747,33 @@ static int permute_and_enter(void)
/* Prepare our new clean root. */
static int permute_prepare(void)
{
if (mkdir(ROOTDIR, 0700) < 0 && errno != EEXIST) {
__do_free char *base_dir = get_base_dir();
__do_free char *root_dir = get_root_dir();
__do_free char *new_runtime = must_make_path(root_dir, runtime_path, NULL);
__do_free char *new_base_dir = must_make_path(root_dir, base_dir, NULL);

if (mkdir(root_dir, 0700) < 0 && errno != EEXIST) {
lxcfs_error("%s\n", "Failed to create directory for new root.");
return -1;
}

if (mount("/", ROOTDIR, NULL, MS_BIND, 0) < 0) {
if (mount("/", root_dir, NULL, MS_BIND, 0) < 0) {
lxcfs_error("Failed to bind-mount / for new root: %s.\n", strerror(errno));
return -1;
}

if (mount(RUNTIME_PATH, ROOTDIR RUNTIME_PATH, NULL, MS_BIND, 0) < 0) {
lxcfs_error("Failed to bind-mount /run into new root: %s.\n", strerror(errno));
if (!mkdir_p(new_runtime, 0700)) {
lxcfs_error("Failed to create dir %s\n", new_runtime);
return -1;
}

if (mount(runtime_path, new_runtime, NULL, MS_BIND, 0) < 0) {
lxcfs_error("Failed to bind-mount %s into new root: %s.\n", runtime_path, strerror(errno));
return -1;
}

if (mount(BASEDIR, ROOTDIR BASEDIR, NULL, MS_REC | MS_MOVE, 0) < 0) {
printf("Failed to move " BASEDIR " into new root: %s.\n", strerror(errno));
if (mount(base_dir, new_base_dir, NULL, MS_REC | MS_MOVE, 0) < 0) {
printf("Failed to move %s into new root: %s.\n", base_dir, strerror(errno));
return -1;
}

Expand All @@ -764,7 +796,9 @@ static bool permute_root(void)

static bool cgfs_prepare_mounts(void)
{
if (!mkdir_p(BASEDIR, 0700)) {
__do_free char *base_dir = get_base_dir();

if (!mkdir_p(base_dir, 0700)) {
lxcfs_error("%s\n", "Failed to create lxcfs cgroup mountpoint.");
return false;
}
Expand All @@ -790,7 +824,7 @@ static bool cgfs_prepare_mounts(void)
return false;
}

if (mount("tmpfs", BASEDIR, "tmpfs", 0, "size=100000,mode=700") < 0) {
if (mount("tmpfs", base_dir, "tmpfs", 0, "size=100000,mode=700") < 0) {
lxcfs_error("%s\n", "Failed to mount tmpfs over lxcfs cgroup mountpoint.");
return false;
}
Expand All @@ -800,14 +834,17 @@ static bool cgfs_prepare_mounts(void)

static bool cgfs_mount_hierarchies(void)
{
if (!mkdir_p(BASEDIR DEFAULT_CGROUP_MOUNTPOINT, 0755))
__do_free char *base_dir = get_base_dir();
__do_free char *base_dir_cgroup_mount = must_make_path(base_dir, DEFAULT_CGROUP_MOUNTPOINT, NULL);

if (!mkdir_p(base_dir_cgroup_mount, 0700))
return false;

if (!cgroup_ops->mount(cgroup_ops, BASEDIR))
if (!cgroup_ops->mount(cgroup_ops, base_dir))
return false;

for (struct hierarchy **h = cgroup_ops->hierarchies; h && *h; h++) {
__do_free char *path = must_make_path(BASEDIR, (*h)->mountpoint, NULL);
__do_free char *path = must_make_path(base_dir, (*h)->mountpoint, NULL);
(*h)->fd = open(path, O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
if ((*h)->fd < 0)
return false;
Expand Down Expand Up @@ -862,7 +899,19 @@ static void sigusr2_toggle_virtualization(int signo, siginfo_t *info, void *extr
return;
}

static void __attribute__((constructor)) lxcfs_init(void)
bool set_runtime_path(const char* new_path)
{
if (new_path && strlen(new_path) < PATH_MAX) {
strcpy(runtime_path, new_path);
lxcfs_info("Using runtime path %s", runtime_path);
return true;
} else {
lxcfs_error("%s\n", "Failed to overwrite the runtime path");
return false;
}
}

void lxcfslib_init(void)
{
__do_close int init_ns = -EBADF, root_fd = -EBADF,
pidfd = -EBADF;
Expand All @@ -871,7 +920,7 @@ static void __attribute__((constructor)) lxcfs_init(void)
pid_t pid;
struct hierarchy *hierarchy;

lxcfs_info("Running constructor %s to reload liblxcfs", __func__);
lxcfs_info("Running %s to reload liblxcfs", __func__);

cgroup_ops = cgroup_init();
if (!cgroup_ops) {
Expand Down Expand Up @@ -971,9 +1020,20 @@ static void __attribute__((destructor)) lxcfs_exit(void)
void *lxcfs_fuse_init(struct fuse_conn_info *conn, void *data)
{
struct fuse_context *fc = fuse_get_context();
struct lxcfs_opts *opts = fc ? fc->private_data : NULL;

#if HAVE_FUSE_RETURNS_DT_TYPE
can_use_sys_cpu = true;
#endif
has_versioned_opts = true;
return fc ? fc->private_data : NULL;

// We can read runtime_path as of opts version 2.
if (opts && opts->version >= 2) {
set_runtime_path(opts->runtime_path);
}

/* initialize the library */
lxcfslib_init();

return opts;
}
6 changes: 2 additions & 4 deletions src/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
#include "proc_loadavg.h"
#include "sysfs_fuse.h"

/* directory under which we mount the controllers - /run/lxcfs/controllers */
#define BASEDIR RUNTIME_PATH "/lxcfs/controllers"
#define ROOTDIR RUNTIME_PATH "/lxcfs/root"

/* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */
#define LXCFS_NUMSTRLEN64 21

Expand Down Expand Up @@ -116,6 +112,8 @@ struct lxcfs_opts {
* and the use of bool instead of explicited __u32 and __u64 we can't.
*/
__u32 version;
// As of opts version 2.
char runtime_path[PATH_MAX];
};

typedef enum lxcfs_opt_t {
Expand Down
34 changes: 25 additions & 9 deletions src/lxcfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
#include "macro.h"
#include "memory_utils.h"

#define PID_FILE "/lxcfs.pid"

void *dlopen_handle;
static char runtime_path[PATH_MAX] = DEFAULT_RUNTIME_PATH;


/* Functions to keep track of number of threads using the library */

Expand Down Expand Up @@ -146,7 +150,7 @@ static int stop_loadavg(void)

static volatile sig_atomic_t need_reload;

static int lxcfs_init_library(void)
static int do_lxcfs_fuse_init(void)
{
char *error;
void *(*__lxcfs_fuse_init)(struct fuse_conn_info * conn, void * cfg);
Expand Down Expand Up @@ -199,13 +203,12 @@ static void do_reload(bool reinit)

dlopen_handle = dlopen(lxcfs_lib_path, RTLD_LAZY);
if (!dlopen_handle)
log_exit("%s - Failed to open liblxcfs.so", dlerror());
log_exit("%s - Failed to open liblxcfs.so at %s", dlerror(), lxcfs_lib_path);
else
lxcfs_debug("Opened %s", lxcfs_lib_path);

good:
/* initialize the library */
if (reinit && lxcfs_init_library() < 0) {
if (reinit && do_lxcfs_fuse_init() < 0) {
log_exit("Failed to initialize liblxcfs.so");
}

Expand Down Expand Up @@ -1119,7 +1122,7 @@ static void *lxcfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
static void *lxcfs_init(struct fuse_conn_info *conn)
#endif
{
if (lxcfs_init_library() < 0)
if (do_lxcfs_fuse_init() < 0)
return NULL;

#if HAVE_FUSE3
Expand Down Expand Up @@ -1187,12 +1190,14 @@ static void usage(void)
lxcfs_info(" -l, --enable-loadavg Enable loadavg virtualization");
lxcfs_info(" -o Options to pass directly through fuse");
lxcfs_info(" -p, --pidfile=FILE Path to use for storing lxcfs pid");
lxcfs_info(" Default pidfile is %s/lxcfs.pid", RUNTIME_PATH);
lxcfs_info(" Default pidfile is %s/lxcfs.pid", DEFAULT_RUNTIME_PATH);
lxcfs_info(" -u, --disable-swap Disable swap virtualization");
lxcfs_info(" -v, --version Print lxcfs version");
lxcfs_info(" --enable-cfs Enable CPU virtualization via CPU shares");
lxcfs_info(" --enable-pidfd Use pidfd for process tracking");
lxcfs_info(" --enable-cgroup Enable cgroup emulation code");
lxcfs_info(" --runtime-dir=DIR Path to use as the runtime directory.");
lxcfs_info(" Default is %s", DEFAULT_RUNTIME_PATH);
exit(EXIT_FAILURE);
}

Expand Down Expand Up @@ -1244,6 +1249,7 @@ static const struct option long_options[] = {
{"enable-cgroup", no_argument, 0, 0 },

{"pidfile", required_argument, 0, 'p' },
{"runtime-dir", required_argument, 0, 0 },
{ },
};

Expand Down Expand Up @@ -1286,7 +1292,7 @@ int main(int argc, char *argv[])
int pidfile_fd = -EBADF;
int ret = EXIT_FAILURE;
char *pidfile = NULL, *token = NULL;
char pidfile_buf[STRLITERALLEN(RUNTIME_PATH) + STRLITERALLEN("/lxcfs.pid") + 1] = {};
char pidfile_buf[PATH_MAX + sizeof(PID_FILE)] = {};
bool debug = false, foreground = false;
#if !HAVE_FUSE3
bool nonempty = false;
Expand All @@ -1303,6 +1309,7 @@ int main(int argc, char *argv[])
char *new_fuse_opts = NULL;
char *const *new_argv;
struct lxcfs_opts *opts;
char *runtime_path_arg = NULL;

opts = malloc(sizeof(struct lxcfs_opts));
if (opts == NULL) {
Expand All @@ -1313,7 +1320,7 @@ int main(int argc, char *argv[])
opts->swap_off = false;
opts->use_pidfd = false;
opts->use_cfs = false;
opts->version = 1;
opts->version = 2;

while ((c = getopt_long(argc, argv, "dulfhvso:p:", long_options, &idx)) != -1) {
switch (c) {
Expand All @@ -1324,6 +1331,8 @@ int main(int argc, char *argv[])
opts->use_cfs = true;
else if (strcmp(long_options[idx].name, "enable-cgroup") == 0)
cgroup_is_enabled = true;
else if (strcmp(long_options[idx].name, "runtime-dir") == 0)
runtime_path_arg = optarg;
else
usage();
break;
Expand Down Expand Up @@ -1376,6 +1385,12 @@ int main(int argc, char *argv[])
goto out;
}

if (runtime_path_arg) {
strcpy(runtime_path, runtime_path_arg);
lxcfs_info("runtime path set to %s", runtime_path);
}
strcpy(opts->runtime_path, runtime_path);

fuse_argv[fuse_argc++] = argv[0];
if (debug)
fuse_argv[fuse_argc++] = "-d";
Expand Down Expand Up @@ -1467,6 +1482,7 @@ int main(int argc, char *argv[])
lxcfs_info("Starting LXCFS at %s", argv[0]);

do_reload(false);

if (install_signal_handler(SIGUSR1, sigusr1_reload)) {
lxcfs_error("%s - Failed to install SIGUSR1 signal handler", strerror(errno));
goto out;
Expand All @@ -1480,7 +1496,7 @@ int main(int argc, char *argv[])
#endif

if (!pidfile) {
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s/lxcfs.pid", RUNTIME_PATH);
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s%s", runtime_path, PID_FILE);
pidfile = pidfile_buf;
}

Expand Down
2 changes: 1 addition & 1 deletion tests/main.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if [ -x ${lxcfs} ]; then
LXCFSPID=$!
else
UNSHARE=0
LXCFSPID=$(cat "{{RUNTIME_PATH}}/lxcfs.pid")
LXCFSPID=$(cat "{{DEFAULT_RUNTIME_PATH}}/lxcfs.pid")
echo "=> Re-using host lxcfs"
rmdir $LXCFSDIR
export LXCFSDIR=/var/lib/lxcfs
Expand Down

0 comments on commit 62c7230

Please sign in to comment.