|
| 1 | +#include "../../../shared/commands/configure/configure.h" |
| 2 | +#include "../../../platform/fd_file_util.h" |
| 3 | + |
| 4 | +#include <errno.h> |
| 5 | +#include <fcntl.h> /* open */ |
| 6 | +#include <unistd.h> /* fchown, close */ |
| 7 | +#include <sys/stat.h> /* fchmod */ |
| 8 | + |
| 9 | +static int |
| 10 | +enabled( config_t const * config ) { |
| 11 | + return !!config->firedancer.vinyl.enabled; |
| 12 | +} |
| 13 | + |
| 14 | +static void |
| 15 | +init( config_t const * config ) { |
| 16 | + if( FD_UNLIKELY( -1==fd_file_util_mkdir_all( config->paths.accounts, config->uid, config->gid, 0 ) ) ) { |
| 17 | + FD_LOG_ERR(( "fd_file_util_mkdir_all(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) )); |
| 18 | + } |
| 19 | + |
| 20 | + int vinyl_fd = open( config->paths.accounts, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, S_IRUSR|S_IWUSR ); |
| 21 | + if( FD_UNLIKELY( vinyl_fd<0 ) ) { |
| 22 | + FD_LOG_ERR(( "open(`%s`,O_RDWR|O_CREAT|O_CLOEXEC,S_IRUSR|S_IWUSR) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) )); |
| 23 | + } |
| 24 | + |
| 25 | + if( FD_UNLIKELY( fchown( vinyl_fd, config->uid, config->gid )<0 ) ) { |
| 26 | + FD_LOG_ERR(( "chown(`%s`,%u:%u) failed (%i-%s)", config->paths.accounts, config->uid, config->gid, errno, fd_io_strerror( errno ) )); |
| 27 | + } |
| 28 | + |
| 29 | + if( FD_UNLIKELY( fchmod( vinyl_fd, S_IRUSR|S_IWUSR )<0 ) ) { |
| 30 | + FD_LOG_ERR(( "chmod(`%s`,S_IRUSR|S_IWUSR) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) )); |
| 31 | + } |
| 32 | + |
| 33 | + ulong bstream_sz = config->firedancer.vinyl.file_size_gib<<30; |
| 34 | + if( FD_UNLIKELY( 0!=ftruncate( vinyl_fd, (long)bstream_sz ) ) ) { |
| 35 | + FD_LOG_ERR(( "ftruncate(`%s`,%lu bytes) failed (%i-%s)", config->paths.accounts, bstream_sz, errno, fd_io_strerror( errno ) )); |
| 36 | + } |
| 37 | + |
| 38 | + if( FD_UNLIKELY( close( vinyl_fd )<0 ) ) { |
| 39 | + FD_LOG_ERR(( "close(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) )); |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +static int |
| 44 | +fini( config_t const * config, |
| 45 | + int pre_init ) { |
| 46 | + (void)pre_init; |
| 47 | + if( FD_UNLIKELY( unlink( config->paths.accounts )<0 ) ) { |
| 48 | + FD_LOG_ERR(( "unlink(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) )); |
| 49 | + } |
| 50 | + return 1; |
| 51 | +} |
| 52 | + |
| 53 | +static configure_result_t |
| 54 | +check( config_t const * config ) { |
| 55 | + struct stat st; |
| 56 | + if( FD_UNLIKELY( 0!=stat( config->paths.accounts, &st ) ) ) { |
| 57 | + if( errno==ENOENT ) NOT_CONFIGURED( "`%s` does not exist", config->paths.accounts ); |
| 58 | + else NOT_CONFIGURED( "stat(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) ); |
| 59 | + } |
| 60 | + |
| 61 | + ulong bstream_sz = config->firedancer.vinyl.file_size_gib<<30; |
| 62 | + if( FD_UNLIKELY( (ulong)st.st_size!=bstream_sz ) ) |
| 63 | + NOT_CONFIGURED( "`%s` needs to be resized (have %lu bytes, want %lu bytes)", config->paths.accounts, (ulong)st.st_size, bstream_sz ); |
| 64 | + |
| 65 | + CHECK( check_file( config->paths.accounts, config->uid, config->gid, S_IFREG | S_IRUSR | S_IWUSR ) ); |
| 66 | + CONFIGURE_OK(); |
| 67 | +} |
| 68 | + |
| 69 | +configure_stage_t fd_cfg_stage_vinyl = { |
| 70 | + .name = "vinyl", |
| 71 | + .enabled = enabled, |
| 72 | + .init = init, |
| 73 | + .fini = fini, |
| 74 | + .check = check, |
| 75 | +}; |
0 commit comments