Line data Source code
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 0 : enabled( config_t const * config ) {
11 0 : return !!config->firedancer.vinyl.enabled;
12 0 : }
13 :
14 : static void
15 0 : init( config_t const * config ) {
16 0 : FD_LOG_NOTICE(( "RUN: `mkdir -p %s`", config->paths.accounts ));
17 0 : if( FD_UNLIKELY( -1==fd_file_util_mkdir_all( config->paths.accounts, config->uid, config->gid, 0 ) ) ) {
18 0 : FD_LOG_ERR(( "fd_file_util_mkdir_all(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) ));
19 0 : }
20 :
21 0 : FD_LOG_NOTICE(( "RUN: `touch %s", config->paths.accounts ));
22 0 : int vinyl_fd = open( config->paths.accounts, O_RDWR|O_CREAT|O_CLOEXEC, S_IRUSR|S_IWUSR );
23 0 : if( FD_UNLIKELY( vinyl_fd<0 ) ) {
24 0 : 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 ) ));
25 0 : }
26 :
27 : // FD_LOG_NOTICE(( "RUN: `chown %u:%u %s`", config->uid, config->gid, config->paths.accounts ));
28 0 : if( FD_UNLIKELY( fchown( vinyl_fd, config->uid, config->gid )<0 ) ) {
29 0 : FD_LOG_ERR(( "chown(`%s`,%u:%u) failed (%i-%s)", config->paths.accounts, config->uid, config->gid, errno, fd_io_strerror( errno ) ));
30 0 : }
31 :
32 : // FD_LOG_NOTICE(( "RUN: `chmod 0600 %s`", config->paths.accounts ));
33 0 : if( FD_UNLIKELY( fchmod( vinyl_fd, S_IRUSR|S_IWUSR )<0 ) ) {
34 0 : FD_LOG_ERR(( "chmod(`%s`,S_IRUSR|S_IWUSR) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) ));
35 0 : }
36 0 : struct stat st;
37 0 : if( FD_UNLIKELY( 0!=fstat( vinyl_fd, &st ) ) ) {
38 0 : FD_LOG_ERR(( "fstat(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) ));
39 0 : }
40 :
41 0 : ulong bstream_sz = config->firedancer.vinyl.file_size_gib<<30;
42 0 : if( (ulong)st.st_size < bstream_sz ) {
43 0 : FD_LOG_NOTICE(( "RUN: `fallocate -l %lu %s`", bstream_sz, config->paths.accounts ));
44 0 : int err = posix_fallocate( vinyl_fd, 0L, (long)bstream_sz );
45 0 : if( FD_UNLIKELY( err ) ) {
46 0 : FD_LOG_ERR(( "posix_fallocate(`%s`,%lu MiB) failed (%i-%s)", config->paths.accounts, bstream_sz>>20, err, fd_io_strerror( err ) ));
47 0 : }
48 0 : }
49 :
50 0 : if( FD_UNLIKELY( close( vinyl_fd )<0 ) ) {
51 0 : FD_LOG_ERR(( "close(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) ));
52 0 : }
53 0 : }
54 :
55 : static int
56 : fini( config_t const * config,
57 0 : int pre_init ) {
58 0 : (void)pre_init;
59 :
60 0 : FD_LOG_NOTICE(( "RUN: `rm %s`", config->paths.accounts ));
61 0 : if( FD_UNLIKELY( unlink( config->paths.accounts )<0 ) ) {
62 0 : FD_LOG_ERR(( "unlink(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) ));
63 0 : }
64 0 : return 1;
65 0 : }
66 :
67 : static configure_result_t
68 : check( config_t const * config,
69 0 : int check_type FD_PARAM_UNUSED ) {
70 0 : struct stat st;
71 0 : if( FD_UNLIKELY( 0!=stat( config->paths.accounts, &st ) ) ) {
72 0 : if( errno==ENOENT ) NOT_CONFIGURED( "`%s` does not exist", config->paths.accounts );
73 0 : else PARTIALLY_CONFIGURED( "stat(`%s`) failed (%i-%s)", config->paths.accounts, errno, fd_io_strerror( errno ) );
74 0 : }
75 :
76 0 : ulong bstream_sz = config->firedancer.vinyl.file_size_gib<<30;
77 0 : if( FD_UNLIKELY( (ulong)st.st_size < bstream_sz ) )
78 0 : PARTIALLY_CONFIGURED( "accounts database `%s` needs to be resized (have %lu GiB, want %lu GiB)", config->paths.accounts, (ulong)(st.st_size>>30), config->firedancer.vinyl.file_size_gib );
79 :
80 0 : CHECK( check_file( config->paths.accounts, config->uid, config->gid, S_IFREG | S_IRUSR | S_IWUSR ) );
81 0 : CONFIGURE_OK();
82 0 : }
83 :
84 : configure_stage_t fd_cfg_stage_accdb = {
85 : .name = "accdb",
86 : .enabled = enabled,
87 : .init = init,
88 : .fini = fini,
89 : .check = check,
90 : };
|