Skip to content

Commit 62c7230

Browse files
authored
Merge pull request #645 from mihalicyn/runtime_dir_override
Allow overriding RUNTIME_DIR with a cli flag #2
2 parents 9b873a1 + 5c42da9 commit 62c7230

File tree

5 files changed

+109
-35
lines changed

5 files changed

+109
-35
lines changed

meson.build

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ lxcmandir = join_paths(datadir, 'man')
5757
conf.set_quoted('BINDIR', bindir)
5858
conf.set_quoted('LIBDIR', libdir)
5959
conf.set_quoted('LOCALSTATEDIR', localstatedir)
60-
conf.set_quoted('RUNTIME_PATH', runtimepath)
60+
conf.set_quoted('DEFAULT_RUNTIME_PATH', runtimepath)
6161
conf.set_quoted('SYSCONFDIR', sysconfdir)
6262

6363
conf.set_quoted('LXCCONFDIR', lxcconfdir)

src/bindings.c

+80-20
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <fcntl.h>
88
#include <inttypes.h>
99
#include <libgen.h>
10+
#include <linux/limits.h>
1011
#include <linux/magic.h>
1112
#include <linux/sched.h>
1213
#include <pthread.h>
@@ -40,15 +41,32 @@
4041
#include "syscall_numbers.h"
4142
#include "utils.h"
4243

44+
/* directory under which we mount the controllers - /run/lxcfs/controllers */
45+
#define BASEDIR "/lxcfs/controllers"
46+
#define ROOTDIR "/lxcfs/root"
47+
4348
static bool can_use_pidfd;
4449
static bool can_use_swap;
4550
static bool can_use_sys_cpu;
4651
static bool has_versioned_opts;
4752
static bool memory_is_cgroupv2;
4853
static __u32 host_personality;
54+
static char runtime_path[PATH_MAX] = DEFAULT_RUNTIME_PATH;
55+
4956

5057
static volatile sig_atomic_t reload_successful;
5158

59+
60+
static char *get_base_dir(void)
61+
{
62+
return must_make_path(runtime_path, BASEDIR, NULL);
63+
}
64+
65+
static char *get_root_dir(void)
66+
{
67+
return must_make_path(runtime_path, ROOTDIR, NULL);
68+
}
69+
5270
bool liblxcfs_functional(void)
5371
{
5472
return reload_successful != 0;
@@ -580,8 +598,9 @@ pid_t lookup_initpid_in_store(pid_t pid)
580598

581599
static bool umount_if_mounted(void)
582600
{
583-
if (umount2(BASEDIR, MNT_DETACH) < 0 && errno != EINVAL) {
584-
lxcfs_error("Failed to unmount %s: %s.\n", BASEDIR, strerror(errno));
601+
__do_free char *base_dir = get_base_dir();
602+
if (umount2(base_dir, MNT_DETACH) < 0 && errno != EINVAL) {
603+
lxcfs_error("Failed to unmount %s: %s.\n", base_dir, strerror(errno));
585604
return false;
586605
}
587606
return true;
@@ -639,13 +658,14 @@ static bool is_on_ramfs(void)
639658
static int pivot_enter(void)
640659
{
641660
__do_close int oldroot = -EBADF, newroot = -EBADF;
661+
__do_free char *root_dir = get_root_dir();
642662

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

648-
newroot = open(ROOTDIR, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
668+
newroot = open(root_dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
649669
if (newroot < 0)
650670
return log_error_errno(-1, errno,
651671
"Failed to open new root for fchdir");
@@ -654,7 +674,7 @@ static int pivot_enter(void)
654674
if (fchdir(newroot) < 0)
655675
return log_error_errno(-1,
656676
errno, "Failed to change directory to new rootfs: %s",
657-
ROOTDIR);
677+
root_dir);
658678

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

682702
static int chroot_enter(void)
683703
{
684-
if (mount(ROOTDIR, "/", NULL, MS_REC | MS_BIND, NULL)) {
685-
lxcfs_error("Failed to recursively bind-mount %s into /.", ROOTDIR);
704+
__do_free char *root_dir = get_root_dir();
705+
706+
if (mount(root_dir, "/", NULL, MS_REC | MS_BIND, NULL)) {
707+
lxcfs_error("Failed to recursively bind-mount %s into /.", root_dir);
686708
return -1;
687709
}
688710

@@ -725,23 +747,33 @@ static int permute_and_enter(void)
725747
/* Prepare our new clean root. */
726748
static int permute_prepare(void)
727749
{
728-
if (mkdir(ROOTDIR, 0700) < 0 && errno != EEXIST) {
750+
__do_free char *base_dir = get_base_dir();
751+
__do_free char *root_dir = get_root_dir();
752+
__do_free char *new_runtime = must_make_path(root_dir, runtime_path, NULL);
753+
__do_free char *new_base_dir = must_make_path(root_dir, base_dir, NULL);
754+
755+
if (mkdir(root_dir, 0700) < 0 && errno != EEXIST) {
729756
lxcfs_error("%s\n", "Failed to create directory for new root.");
730757
return -1;
731758
}
732759

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

738-
if (mount(RUNTIME_PATH, ROOTDIR RUNTIME_PATH, NULL, MS_BIND, 0) < 0) {
739-
lxcfs_error("Failed to bind-mount /run into new root: %s.\n", strerror(errno));
765+
if (!mkdir_p(new_runtime, 0700)) {
766+
lxcfs_error("Failed to create dir %s\n", new_runtime);
767+
return -1;
768+
}
769+
770+
if (mount(runtime_path, new_runtime, NULL, MS_BIND, 0) < 0) {
771+
lxcfs_error("Failed to bind-mount %s into new root: %s.\n", runtime_path, strerror(errno));
740772
return -1;
741773
}
742774

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

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

765797
static bool cgfs_prepare_mounts(void)
766798
{
767-
if (!mkdir_p(BASEDIR, 0700)) {
799+
__do_free char *base_dir = get_base_dir();
800+
801+
if (!mkdir_p(base_dir, 0700)) {
768802
lxcfs_error("%s\n", "Failed to create lxcfs cgroup mountpoint.");
769803
return false;
770804
}
@@ -790,7 +824,7 @@ static bool cgfs_prepare_mounts(void)
790824
return false;
791825
}
792826

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

801835
static bool cgfs_mount_hierarchies(void)
802836
{
803-
if (!mkdir_p(BASEDIR DEFAULT_CGROUP_MOUNTPOINT, 0755))
837+
__do_free char *base_dir = get_base_dir();
838+
__do_free char *base_dir_cgroup_mount = must_make_path(base_dir, DEFAULT_CGROUP_MOUNTPOINT, NULL);
839+
840+
if (!mkdir_p(base_dir_cgroup_mount, 0700))
804841
return false;
805842

806-
if (!cgroup_ops->mount(cgroup_ops, BASEDIR))
843+
if (!cgroup_ops->mount(cgroup_ops, base_dir))
807844
return false;
808845

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

865-
static void __attribute__((constructor)) lxcfs_init(void)
902+
bool set_runtime_path(const char* new_path)
903+
{
904+
if (new_path && strlen(new_path) < PATH_MAX) {
905+
strcpy(runtime_path, new_path);
906+
lxcfs_info("Using runtime path %s", runtime_path);
907+
return true;
908+
} else {
909+
lxcfs_error("%s\n", "Failed to overwrite the runtime path");
910+
return false;
911+
}
912+
}
913+
914+
void lxcfslib_init(void)
866915
{
867916
__do_close int init_ns = -EBADF, root_fd = -EBADF,
868917
pidfd = -EBADF;
@@ -871,7 +920,7 @@ static void __attribute__((constructor)) lxcfs_init(void)
871920
pid_t pid;
872921
struct hierarchy *hierarchy;
873922

874-
lxcfs_info("Running constructor %s to reload liblxcfs", __func__);
923+
lxcfs_info("Running %s to reload liblxcfs", __func__);
875924

876925
cgroup_ops = cgroup_init();
877926
if (!cgroup_ops) {
@@ -971,9 +1020,20 @@ static void __attribute__((destructor)) lxcfs_exit(void)
9711020
void *lxcfs_fuse_init(struct fuse_conn_info *conn, void *data)
9721021
{
9731022
struct fuse_context *fc = fuse_get_context();
1023+
struct lxcfs_opts *opts = fc ? fc->private_data : NULL;
1024+
9741025
#if HAVE_FUSE_RETURNS_DT_TYPE
9751026
can_use_sys_cpu = true;
9761027
#endif
9771028
has_versioned_opts = true;
978-
return fc ? fc->private_data : NULL;
1029+
1030+
// We can read runtime_path as of opts version 2.
1031+
if (opts && opts->version >= 2) {
1032+
set_runtime_path(opts->runtime_path);
1033+
}
1034+
1035+
/* initialize the library */
1036+
lxcfslib_init();
1037+
1038+
return opts;
9791039
}

src/bindings.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
#include "proc_loadavg.h"
2424
#include "sysfs_fuse.h"
2525

26-
/* directory under which we mount the controllers - /run/lxcfs/controllers */
27-
#define BASEDIR RUNTIME_PATH "/lxcfs/controllers"
28-
#define ROOTDIR RUNTIME_PATH "/lxcfs/root"
29-
3026
/* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */
3127
#define LXCFS_NUMSTRLEN64 21
3228

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

121119
typedef enum lxcfs_opt_t {

src/lxcfs.c

+25-9
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@
3232
#include "macro.h"
3333
#include "memory_utils.h"
3434

35+
#define PID_FILE "/lxcfs.pid"
36+
3537
void *dlopen_handle;
38+
static char runtime_path[PATH_MAX] = DEFAULT_RUNTIME_PATH;
39+
3640

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

@@ -146,7 +150,7 @@ static int stop_loadavg(void)
146150

147151
static volatile sig_atomic_t need_reload;
148152

149-
static int lxcfs_init_library(void)
153+
static int do_lxcfs_fuse_init(void)
150154
{
151155
char *error;
152156
void *(*__lxcfs_fuse_init)(struct fuse_conn_info * conn, void * cfg);
@@ -199,13 +203,12 @@ static void do_reload(bool reinit)
199203

200204
dlopen_handle = dlopen(lxcfs_lib_path, RTLD_LAZY);
201205
if (!dlopen_handle)
202-
log_exit("%s - Failed to open liblxcfs.so", dlerror());
206+
log_exit("%s - Failed to open liblxcfs.so at %s", dlerror(), lxcfs_lib_path);
203207
else
204208
lxcfs_debug("Opened %s", lxcfs_lib_path);
205209

206210
good:
207-
/* initialize the library */
208-
if (reinit && lxcfs_init_library() < 0) {
211+
if (reinit && do_lxcfs_fuse_init() < 0) {
209212
log_exit("Failed to initialize liblxcfs.so");
210213
}
211214

@@ -1119,7 +1122,7 @@ static void *lxcfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
11191122
static void *lxcfs_init(struct fuse_conn_info *conn)
11201123
#endif
11211124
{
1122-
if (lxcfs_init_library() < 0)
1125+
if (do_lxcfs_fuse_init() < 0)
11231126
return NULL;
11241127

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

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

12461251
{"pidfile", required_argument, 0, 'p' },
1252+
{"runtime-dir", required_argument, 0, 0 },
12471253
{ },
12481254
};
12491255

@@ -1286,7 +1292,7 @@ int main(int argc, char *argv[])
12861292
int pidfile_fd = -EBADF;
12871293
int ret = EXIT_FAILURE;
12881294
char *pidfile = NULL, *token = NULL;
1289-
char pidfile_buf[STRLITERALLEN(RUNTIME_PATH) + STRLITERALLEN("/lxcfs.pid") + 1] = {};
1295+
char pidfile_buf[PATH_MAX + sizeof(PID_FILE)] = {};
12901296
bool debug = false, foreground = false;
12911297
#if !HAVE_FUSE3
12921298
bool nonempty = false;
@@ -1303,6 +1309,7 @@ int main(int argc, char *argv[])
13031309
char *new_fuse_opts = NULL;
13041310
char *const *new_argv;
13051311
struct lxcfs_opts *opts;
1312+
char *runtime_path_arg = NULL;
13061313

13071314
opts = malloc(sizeof(struct lxcfs_opts));
13081315
if (opts == NULL) {
@@ -1313,7 +1320,7 @@ int main(int argc, char *argv[])
13131320
opts->swap_off = false;
13141321
opts->use_pidfd = false;
13151322
opts->use_cfs = false;
1316-
opts->version = 1;
1323+
opts->version = 2;
13171324

13181325
while ((c = getopt_long(argc, argv, "dulfhvso:p:", long_options, &idx)) != -1) {
13191326
switch (c) {
@@ -1324,6 +1331,8 @@ int main(int argc, char *argv[])
13241331
opts->use_cfs = true;
13251332
else if (strcmp(long_options[idx].name, "enable-cgroup") == 0)
13261333
cgroup_is_enabled = true;
1334+
else if (strcmp(long_options[idx].name, "runtime-dir") == 0)
1335+
runtime_path_arg = optarg;
13271336
else
13281337
usage();
13291338
break;
@@ -1376,6 +1385,12 @@ int main(int argc, char *argv[])
13761385
goto out;
13771386
}
13781387

1388+
if (runtime_path_arg) {
1389+
strcpy(runtime_path, runtime_path_arg);
1390+
lxcfs_info("runtime path set to %s", runtime_path);
1391+
}
1392+
strcpy(opts->runtime_path, runtime_path);
1393+
13791394
fuse_argv[fuse_argc++] = argv[0];
13801395
if (debug)
13811396
fuse_argv[fuse_argc++] = "-d";
@@ -1467,6 +1482,7 @@ int main(int argc, char *argv[])
14671482
lxcfs_info("Starting LXCFS at %s", argv[0]);
14681483

14691484
do_reload(false);
1485+
14701486
if (install_signal_handler(SIGUSR1, sigusr1_reload)) {
14711487
lxcfs_error("%s - Failed to install SIGUSR1 signal handler", strerror(errno));
14721488
goto out;
@@ -1480,7 +1496,7 @@ int main(int argc, char *argv[])
14801496
#endif
14811497

14821498
if (!pidfile) {
1483-
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s/lxcfs.pid", RUNTIME_PATH);
1499+
snprintf(pidfile_buf, sizeof(pidfile_buf), "%s%s", runtime_path, PID_FILE);
14841500
pidfile = pidfile_buf;
14851501
}
14861502

tests/main.sh.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ if [ -x ${lxcfs} ]; then
4949
LXCFSPID=$!
5050
else
5151
UNSHARE=0
52-
LXCFSPID=$(cat "{{RUNTIME_PATH}}/lxcfs.pid")
52+
LXCFSPID=$(cat "{{DEFAULT_RUNTIME_PATH}}/lxcfs.pid")
5353
echo "=> Re-using host lxcfs"
5454
rmdir $LXCFSDIR
5555
export LXCFSDIR=/var/lib/lxcfs

0 commit comments

Comments
 (0)