Line data Source code
1 : /* This stage configures the normal pages directory, which is where the
2 : files backing memory-mapped unlocked workspaces should be stored.
3 :
4 : The files backing these workspaces are stored in the normal pages
5 : directory configured by this command, and follow the normal workspace
6 : shmem file naming convention. */
7 :
8 : #include "../../../shared/commands/configure/configure.h"
9 :
10 : #include "../../../platform/fd_file_util.h"
11 :
12 : #include <unistd.h>
13 : #include <errno.h>
14 : #include <stdio.h>
15 : #include <stdlib.h> /* strtoul */
16 : #include <dirent.h>
17 : #include <sys/stat.h>
18 : #include <sys/mount.h>
19 : #include <linux/capability.h>
20 :
21 : static void
22 0 : init( config_t const * config ) {
23 0 : char const * path = config->hugetlbfs.normal_page_mount_path;
24 :
25 0 : FD_LOG_NOTICE(( "RUN: `mkdir -p %s`", path ));
26 0 : if( FD_UNLIKELY( -1==fd_file_util_mkdir_all( path, config->uid, config->gid ) ) ) {
27 0 : FD_LOG_ERR(( "could not create normal page directory `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) ));
28 0 : }
29 0 : if( FD_UNLIKELY( chown( path, config->uid, config->gid ) ) )
30 0 : FD_LOG_ERR(( "chown of normal page directory `%s` failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
31 0 : if( FD_UNLIKELY( chmod( config->hugetlbfs.normal_page_mount_path, S_IRUSR | S_IWUSR | S_IXUSR ) ) )
32 0 : FD_LOG_ERR(( "chmod of normal page directory `%s` failed (%i-%s)", config->hugetlbfs.normal_page_mount_path, errno, fd_io_strerror( errno ) ));
33 0 : }
34 :
35 : static int
36 0 : is_mountpoint( char const * directory ) {
37 0 : struct stat st;
38 0 : int result = stat( directory, &st );
39 0 : if( FD_UNLIKELY( -1==result && errno==ENOENT ) ) return 0;
40 0 : if( FD_UNLIKELY( -1==result ) ) FD_LOG_ERR(( "failed to stat `%s` (%i-%s)", directory, errno, fd_io_strerror( errno ) ));
41 :
42 0 : char parent_path[ PATH_MAX+4UL ];
43 0 : FD_TEST( fd_cstr_printf_check( parent_path, sizeof(parent_path), NULL, "%s/..", directory ) );
44 :
45 0 : struct stat st_parent;
46 0 : result = stat( parent_path, &st_parent );
47 0 : if( FD_UNLIKELY( -1==result && errno==ENOENT ) ) return 0;
48 0 : if( FD_UNLIKELY( -1==result ) ) FD_LOG_ERR(( "failed to stat `%s` (%i-%s)", parent_path, errno, fd_io_strerror( errno ) ));
49 :
50 0 : return st_parent.st_dev!=st.st_dev;
51 0 : }
52 :
53 : static void
54 : fini( config_t const * config,
55 0 : int pre_init ) {
56 0 : (void)pre_init;
57 0 : char const * path = config->hugetlbfs.normal_page_mount_path;
58 :
59 : /* fd_shmem_cfg mounts a tmpfs filesystem onto the .normal directory
60 : sometimes, which is the expected way to manage normal pages, but
61 : not what is done by firedancer-dev to support a special temporary
62 : funk use case where normal pages are backed by disk. To prevent
63 : fighting with the other script, we unmount the normal pages if they
64 : have been mounted. */
65 :
66 0 : if( FD_UNLIKELY( is_mountpoint( path ) ) ) {
67 0 : FD_LOG_NOTICE(( "RUN: `umount %s`", path ));
68 0 : if( FD_UNLIKELY( -1==umount( path ) && errno!=EINVAL && errno!=ENOENT ) )
69 0 : FD_LOG_ERR(( "error unmounting normal pages directory at `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) ));
70 0 : }
71 :
72 0 : FD_LOG_NOTICE(( "RUN: `rm -rf %s`", path ));
73 0 : if( FD_UNLIKELY( -1==fd_file_util_rmtree( path, 1 ) ) ) FD_LOG_ERR(( "error removing normal pages directory at `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) ));
74 0 : }
75 :
76 :
77 : static configure_result_t
78 0 : check( config_t const * config ) {
79 0 : char const * path = config->hugetlbfs.normal_page_mount_path;
80 :
81 0 : struct stat st;
82 0 : int result = stat( path, &st );
83 0 : if( FD_UNLIKELY( result && errno!=ENOENT ) )
84 0 : PARTIALLY_CONFIGURED( "failed to stat `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) );
85 :
86 0 : if( FD_UNLIKELY( is_mountpoint( path ) ) )
87 0 : PARTIALLY_CONFIGURED( "normal pages directory `%s` is a mountpoint", path );
88 :
89 0 : if( FD_UNLIKELY( result ) )
90 0 : NOT_CONFIGURED( "normal pages directory `%s` does not exist", path );
91 :
92 0 : CHECK( check_dir( path, config->uid, config->gid, S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR ) );
93 :
94 0 : CONFIGURE_OK();
95 0 : }
96 :
97 : configure_stage_t fd_cfg_stage_normalpage = {
98 : .name = "normalpage",
99 : .always_recreate = 0,
100 : .init = init,
101 : .fini = fini,
102 : .check = check,
103 : };
|