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 attribute and made it an explicit call in order to override the runtime dir in between loading the library and initializing lxcfslib.

Signed-off-by: Sebastien Dabdoub <[email protected]>
  • Loading branch information
sdab committed Dec 1, 2023
1 parent b5db694 commit 757df89
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 9 deletions.
22 changes: 19 additions & 3 deletions src/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,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 @@ -892,7 +892,7 @@ static void sigusr2_toggle_virtualization(int signo, siginfo_t *info, void *extr
return;
}

static void __attribute__((constructor)) lxcfs_init(void)
void lxcfslib_init(void)
{
__do_close int init_ns = -EBADF, root_fd = -EBADF,
pidfd = -EBADF;
Expand Down Expand Up @@ -1003,5 +1003,21 @@ 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;
return fc ? fc->private_data : NULL;
}

bool set_runtime_path(const char* new_path)
{
int pathlen;

if (new_path && strlen(new_path) < PATH_MAX) {
pathlen = strlen(new_path);
memcpy(runtime_path, new_path, pathlen);
runtime_path[pathlen] = '\0';
lxcfs_info("Using runtime path %s", runtime_path);
return true;
} else {
lxcfs_error("%s\n", "Failed to overwrite the runtime path");
return false;
}
}
5 changes: 5 additions & 0 deletions src/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,9 @@ static inline pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags)

__visible extern void *lxcfs_fuse_init(struct fuse_conn_info *conn, void *data);

// Overrides the runtime path from DEFAULT_RUNTIME_PATH - /var/run
__visible extern bool set_runtime_path(const char* runtime_path);
// Needs to be called on library load/reload.
__visible extern void lxcfslib_init(void);

#endif /* __LXCFS_BINDINGS_H */
70 changes: 64 additions & 6 deletions src/lxcfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "memory_utils.h"

void *dlopen_handle;
static char runtime_path[PATH_MAX];

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

Expand Down Expand Up @@ -146,7 +147,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 All @@ -162,6 +163,39 @@ static int lxcfs_init_library(void)
return 0;
}

static int do_lxcfslib_init(void)
{
char *error;
void (*__lxcfslib_init)(void);

dlerror();
__lxcfslib_init = (void (*)(void))dlsym(dlopen_handle, "lxcfslib_init");
error = dlerror();
if (error)
return log_error(-1, "%s - Failed to find lxcfslib_init()", error);

__lxcfslib_init();

return 0;
}

static bool do_set_runtime_path(const char *path)
{
char *error;
bool (*__set_runtime_path)(const char *path);

dlerror();
__set_runtime_path = (bool (*)(const char *path))dlsym(dlopen_handle, "set_runtime_path");
error = dlerror();
if (error) {
log_error(-1, "%s - Failed to find set_runtime_path()", error);
return false;
}

lxcfs_info("set runtime path %s", path);
return __set_runtime_path(path);
}

/* do_reload - reload the dynamic library. Done under
* lock and when we know the user_count was 0 */
static void do_reload(bool reinit)
Expand Down Expand Up @@ -199,13 +233,19 @@ 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:
if (strlen(runtime_path) > 0 && !do_set_runtime_path(runtime_path)) {
dlclose(dlopen_handle);
log_exit("failed to override runtime dir with %s", runtime_path);
}

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

Expand Down Expand Up @@ -1117,7 +1157,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 @@ -1190,6 +1230,8 @@ static void usage(void)
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(" --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 @@ -1240,6 +1282,7 @@ static const struct option long_options[] = {
{"enable-pidfd", no_argument, 0, 0 },

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

Expand Down Expand Up @@ -1282,7 +1325,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] = {};
bool debug = false, foreground = false;
#if !HAVE_FUSE3
bool nonempty = false;
Expand All @@ -1299,6 +1342,8 @@ int main(int argc, char *argv[])
char *new_fuse_opts = NULL;
char *const *new_argv;
struct lxcfs_opts *opts;
char *runtime_path_arg = NULL;
int runtime_path_len;

opts = malloc(sizeof(struct lxcfs_opts));
if (opts == NULL) {
Expand All @@ -1318,6 +1363,8 @@ int main(int argc, char *argv[])
opts->use_pidfd = true;
else if (strcmp(long_options[idx].name, "enable-cfs") == 0)
opts->use_cfs = true;
else if (strcmp(long_options[idx].name, "runtime-dir") == 0)
runtime_path_arg = optarg;
else
usage();
break;
Expand Down Expand Up @@ -1370,6 +1417,13 @@ int main(int argc, char *argv[])
goto out;
}

if (runtime_path_arg) {
runtime_path_len = strlen(runtime_path_arg);
memcpy(runtime_path, runtime_path_arg, runtime_path_len);
runtime_path[runtime_path_len] = '\0';
lxcfs_info("runtime path set to %s", runtime_path);
}

fuse_argv[fuse_argc++] = argv[0];
if (debug)
fuse_argv[fuse_argc++] = "-d";
Expand Down Expand Up @@ -1461,6 +1515,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 @@ -1474,7 +1529,10 @@ int main(int argc, char *argv[])
#endif

if (!pidfile) {
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s/lxcfs.pid", DEFAULT_RUNTIME_PATH);
if (runtime_path_arg)
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s/lxcfs.pid", runtime_path_arg);
else
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s/lxcfs.pid", DEFAULT_RUNTIME_PATH);
pidfile = pidfile_buf;
}

Expand Down

0 comments on commit 757df89

Please sign in to comment.