Skip to content

Commit

Permalink
Add a flag for overriding the runtime dir.
Browse files Browse the repository at this point in the history
Adds a --runtime-dir cli flag which overrides the /run dir in the lxcfslib. This ended up being kind of tricky because of how lxcfslib can be reloaded and its use of a library constructor. In order read the cli flag and then set a variable in the library, I removed the contstructor and made init happen as part of the fuse load/reload.

I also added the runtime field to the lxcfs_opts struct and upped its version for backwards compatibility.

Signed-off-by: Sebastien Dabdoub <[email protected]>
  • Loading branch information
sdab committed Jun 3, 2024
1 parent fd3045a commit c6fad6a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 13 deletions.
29 changes: 25 additions & 4 deletions src/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ static int permute_prepare(void)
}

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

Expand Down Expand Up @@ -894,7 +894,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 @@ -903,7 +915,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 @@ -1007,5 +1019,14 @@ void *lxcfs_fuse_init(struct fuse_conn_info *conn, void *data)
can_use_sys_cpu = true;
#endif
has_versioned_opts = true;
return fc ? fc->private_data : NULL;

const struct lxcfs_opts *opts = fc->private_data;
// We can read runtime_path as of opts version 2.
if (opts->version >= 2) {
set_runtime_path(opts->runtime_path);
}

/* initialize the library */
lxcfslib_init();
return fc ? fc->private_data : NULL;
}
2 changes: 2 additions & 0 deletions src/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ struct lxcfs_opts {
bool swap_off;
bool use_pidfd;
bool use_cfs;
// As of opts version 2.
char runtime_path[PATH_MAX];
/*
* Ideally we'd version by size but because of backwards compatability
* and the use of bool instead of explicited __u32 and __u64 we can'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) {
good:
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 @@ -1193,6 +1196,8 @@ static void usage(void)
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(DEFAULT_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", DEFAULT_RUNTIME_PATH);
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s%s", runtime_path, PID_FILE);
pidfile = pidfile_buf;
}

Expand Down

0 comments on commit c6fad6a

Please sign in to comment.