7
7
#include <fcntl.h>
8
8
#include <inttypes.h>
9
9
#include <libgen.h>
10
+ #include <linux/limits.h>
10
11
#include <linux/magic.h>
11
12
#include <linux/sched.h>
12
13
#include <pthread.h>
40
41
#include "syscall_numbers.h"
41
42
#include "utils.h"
42
43
44
+ /* directory under which we mount the controllers - /run/lxcfs/controllers */
45
+ #define BASEDIR "/lxcfs/controllers"
46
+ #define ROOTDIR "/lxcfs/root"
47
+
43
48
static bool can_use_pidfd ;
44
49
static bool can_use_swap ;
45
50
static bool can_use_sys_cpu ;
46
51
static bool has_versioned_opts ;
47
52
static bool memory_is_cgroupv2 ;
48
53
static __u32 host_personality ;
54
+ static char runtime_path [PATH_MAX ] = DEFAULT_RUNTIME_PATH ;
55
+
49
56
50
57
static volatile sig_atomic_t reload_successful ;
51
58
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
+
52
70
bool liblxcfs_functional (void )
53
71
{
54
72
return reload_successful != 0 ;
@@ -580,8 +598,9 @@ pid_t lookup_initpid_in_store(pid_t pid)
580
598
581
599
static bool umount_if_mounted (void )
582
600
{
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 ));
585
604
return false;
586
605
}
587
606
return true;
@@ -639,13 +658,14 @@ static bool is_on_ramfs(void)
639
658
static int pivot_enter (void )
640
659
{
641
660
__do_close int oldroot = - EBADF , newroot = - EBADF ;
661
+ __do_free char * root_dir = get_root_dir ();
642
662
643
663
oldroot = open ("/" , O_DIRECTORY | O_RDONLY | O_CLOEXEC );
644
664
if (oldroot < 0 )
645
665
return log_error_errno (-1 , errno ,
646
666
"Failed to open old root for fchdir" );
647
667
648
- newroot = open (ROOTDIR , O_DIRECTORY | O_RDONLY | O_CLOEXEC );
668
+ newroot = open (root_dir , O_DIRECTORY | O_RDONLY | O_CLOEXEC );
649
669
if (newroot < 0 )
650
670
return log_error_errno (-1 , errno ,
651
671
"Failed to open new root for fchdir" );
@@ -654,7 +674,7 @@ static int pivot_enter(void)
654
674
if (fchdir (newroot ) < 0 )
655
675
return log_error_errno (-1 ,
656
676
errno , "Failed to change directory to new rootfs: %s" ,
657
- ROOTDIR );
677
+ root_dir );
658
678
659
679
/* pivot_root into our new root fs */
660
680
if (pivot_root ("." , "." ) < 0 )
@@ -681,8 +701,10 @@ static int pivot_enter(void)
681
701
682
702
static int chroot_enter (void )
683
703
{
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 );
686
708
return -1 ;
687
709
}
688
710
@@ -725,23 +747,33 @@ static int permute_and_enter(void)
725
747
/* Prepare our new clean root. */
726
748
static int permute_prepare (void )
727
749
{
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 ) {
729
756
lxcfs_error ("%s\n" , "Failed to create directory for new root." );
730
757
return -1 ;
731
758
}
732
759
733
- if (mount ("/" , ROOTDIR , NULL , MS_BIND , 0 ) < 0 ) {
760
+ if (mount ("/" , root_dir , NULL , MS_BIND , 0 ) < 0 ) {
734
761
lxcfs_error ("Failed to bind-mount / for new root: %s.\n" , strerror (errno ));
735
762
return -1 ;
736
763
}
737
764
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 ));
740
772
return -1 ;
741
773
}
742
774
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 ));
745
777
return -1 ;
746
778
}
747
779
@@ -764,7 +796,9 @@ static bool permute_root(void)
764
796
765
797
static bool cgfs_prepare_mounts (void )
766
798
{
767
- if (!mkdir_p (BASEDIR , 0700 )) {
799
+ __do_free char * base_dir = get_base_dir ();
800
+
801
+ if (!mkdir_p (base_dir , 0700 )) {
768
802
lxcfs_error ("%s\n" , "Failed to create lxcfs cgroup mountpoint." );
769
803
return false;
770
804
}
@@ -790,7 +824,7 @@ static bool cgfs_prepare_mounts(void)
790
824
return false;
791
825
}
792
826
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 ) {
794
828
lxcfs_error ("%s\n" , "Failed to mount tmpfs over lxcfs cgroup mountpoint." );
795
829
return false;
796
830
}
@@ -800,14 +834,17 @@ static bool cgfs_prepare_mounts(void)
800
834
801
835
static bool cgfs_mount_hierarchies (void )
802
836
{
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 ))
804
841
return false;
805
842
806
- if (!cgroup_ops -> mount (cgroup_ops , BASEDIR ))
843
+ if (!cgroup_ops -> mount (cgroup_ops , base_dir ))
807
844
return false;
808
845
809
846
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 );
811
848
(* h )-> fd = open (path , O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW );
812
849
if ((* h )-> fd < 0 )
813
850
return false;
@@ -862,7 +899,19 @@ static void sigusr2_toggle_virtualization(int signo, siginfo_t *info, void *extr
862
899
return ;
863
900
}
864
901
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 )
866
915
{
867
916
__do_close int init_ns = - EBADF , root_fd = - EBADF ,
868
917
pidfd = - EBADF ;
@@ -871,7 +920,7 @@ static void __attribute__((constructor)) lxcfs_init(void)
871
920
pid_t pid ;
872
921
struct hierarchy * hierarchy ;
873
922
874
- lxcfs_info ("Running constructor %s to reload liblxcfs" , __func__ );
923
+ lxcfs_info ("Running %s to reload liblxcfs" , __func__ );
875
924
876
925
cgroup_ops = cgroup_init ();
877
926
if (!cgroup_ops ) {
@@ -971,9 +1020,20 @@ static void __attribute__((destructor)) lxcfs_exit(void)
971
1020
void * lxcfs_fuse_init (struct fuse_conn_info * conn , void * data )
972
1021
{
973
1022
struct fuse_context * fc = fuse_get_context ();
1023
+ struct lxcfs_opts * opts = fc ? fc -> private_data : NULL ;
1024
+
974
1025
#if HAVE_FUSE_RETURNS_DT_TYPE
975
1026
can_use_sys_cpu = true;
976
1027
#endif
977
1028
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 ;
979
1039
}
0 commit comments