Line data Source code
1 : #ifndef HEADER_fd_src_discof_admin_fd_adminctl_h 2 : #define HEADER_fd_src_discof_admin_fd_adminctl_h 3 : 4 : #include "../../util/fd_util_base.h" 5 : 6 : /* fd_adminctl_t provides APIs for out-of-band command-and-control 7 : signals to the firedancer process via the admin tile. It provides a 8 : ring of shared-memory command slots between command processes and the 9 : admin tile. 10 : 11 : Each slot is owned by one CAS word that packs state, process pid, 12 : request sequence number, and reservation timestamp. Command 13 : processes send commands to the main app process via a reserve and 14 : publish scheme. A call to fd_adminctl_reserve claims a command slot; 15 : the command process then has exclusive write access to writing the 16 : command payload. The fd_adminctl_publish publishes the command to 17 : the app process and effectively transfers ownership of the slot to 18 : the app process. The app process will poll for a command via 19 : fd_adminctl_poll, process the command, and send back a result via 20 : fd_adminctl_complete. The command process receives the result via 21 : fd_adminctl_wait which blocks on the result. At this point, the slot 22 : is free again and is free to be claimed by another command process. 23 : 24 : If a command process dies while it has ownership of a slot (after 25 : a reservation has been made, but before a publish OR while a command 26 : result is available but not consumed), then other command processes 27 : are free to claim the slot. If for some reason the command process 28 : is hung, the caller will be responsible for cleaning up and killing 29 : the process. 30 : 31 : All input into fd_adminctl_t must be trusted. If the adminctl memory 32 : layout changes, adminctl magic must be updated. */ 33 : 34 0 : #define FD_ADMINCTL_CMD_IDLE (0UL) 35 0 : #define FD_ADMINCTL_CMD_ADD_AUTH_VOTER (1UL) 36 0 : #define FD_ADMINCTL_CMD_SET_IDENTITY (2UL) 37 0 : #define FD_ADMINCTL_CMD_GET_IDENTITY (3UL) 38 0 : #define FD_ADMINCTL_CMD_REMOVE_ALL_AUTH_VOTERS (4UL) 39 0 : #define FD_ADMINCTL_CMD_SNAP_CREATE (5UL) 40 : 41 0 : #define FD_ADMINCTL_ALIGN (8UL) 42 0 : #define FD_ADMINCTL_PAYLOAD_MAX (256UL) 43 0 : #define FD_ADMINCTL_SLOT_CNT (4UL) 44 : 45 : /* Shared command result codes. */ 46 0 : #define FD_ADMINCTL_RESULT_SUCCESS (0UL) 47 0 : #define FD_ADMINCTL_RESULT_UNKNOWN_COMMAND (1UL) 48 0 : #define FD_ADMINCTL_RESULT_ABI_VERSION_MISMATCH (2UL) 49 0 : #define FD_ADMINCTL_RESULT_ABI_SIZE_MISMATCH (3UL) 50 : 51 : /* App-specific command result codes. 52 : NOTE: It is important these codes start at 2UL. */ 53 : 54 : struct fd_adminctl_add_auth_voter_v1 { 55 : ulong version; /* ==FD_ADMINCTL_ADD_AUTH_VOTER_PAYLOAD_VERSION */ 56 : uchar keypair[ 64UL ]; 57 : }; 58 : typedef struct fd_adminctl_add_auth_voter_v1 fd_adminctl_add_auth_voter_t; 59 0 : #define FD_ADMINCTL_ADD_AUTH_VOTER_PAYLOAD_VERSION (1UL) 60 : 61 0 : #define FD_ADD_AUTHORIZED_VOTER_RESULT_KEYPAIR_MISMATCH (0x1001UL) 62 0 : #define FD_ADD_AUTHORIZED_VOTER_RESULT_MAX_AUTH_VOTERS (0x1002UL) 63 0 : #define FD_ADD_AUTHORIZED_VOTER_RESULT_DUPLICATE_AUTH_VOTER (0x1003UL) 64 : 65 0 : #define FD_SNAPSHOT_CREATE_RESULT_BUSY (0x2001UL) 66 0 : #define FD_SNAPSHOT_CREATE_RESULT_UNSUPPORTED (0x2002UL) 67 0 : #define FD_SNAPSHOT_CREATE_RESULT_NOT_READY (0x2003UL) 68 0 : #define FD_SNAPSHOT_CREATE_RESULT_UNEXPECTED_RESPONSE (0x2004UL) 69 0 : #define FD_SNAPSHOT_CREATE_RESULT_SLOT_IN_PAST (0x2005UL) 70 : 71 : struct fd_adminctl_snap_create_v1 { 72 : ulong version; /* ==FD_ADMINCTL_SNAP_CREATE_PAYLOAD_VERSION */ 73 : ulong slot; /* 0 to create a snapshot of the published root 74 : immediately, else stop rooting at the first rooted 75 : slot >= this slot and snapshot it */ 76 : }; 77 : typedef struct fd_adminctl_snap_create_v1 fd_adminctl_snap_create_t; 78 0 : #define FD_ADMINCTL_SNAP_CREATE_PAYLOAD_VERSION (1UL) 79 : 80 : struct fd_adminctl_set_identity_v1 { 81 : ulong version; /* ==FD_ADMINCTL_SET_IDENTITY_PAYLOAD_VERSION */ 82 : uchar keypair[ 64UL ]; 83 : }; 84 : typedef struct fd_adminctl_set_identity_v1 fd_adminctl_set_identity_t; 85 0 : #define FD_ADMINCTL_SET_IDENTITY_PAYLOAD_VERSION (1UL) 86 : 87 0 : #define FD_SET_IDENTITY_RESULT_PAYLOAD_TOO_SMALL (2UL) 88 0 : #define FD_SET_IDENTITY_RESULT_UNSUPPORTED_PAYLOAD_VERSION (3UL) 89 0 : #define FD_SET_IDENTITY_RESULT_UNEXPECTED_PAYLOAD_SIZE (4UL) 90 0 : #define FD_SET_IDENTITY_RESULT_KEYPAIR_MISMATCH (5UL) 91 : 92 : struct fd_adminctl_get_identity_req_v1 { 93 : ulong version; /* ==FD_ADMINCTL_GET_IDENTITY_PAYLOAD_VERSION */ 94 : }; 95 : typedef struct fd_adminctl_get_identity_req_v1 fd_adminctl_get_identity_req_t; 96 : 97 : struct fd_adminctl_get_identity_resp_v1 { 98 : ulong version; /* ==FD_ADMINCTL_GET_IDENTITY_PAYLOAD_VERSION */ 99 : uchar identity_pubkey[ 32UL ]; 100 : }; 101 : typedef struct fd_adminctl_get_identity_resp_v1 fd_adminctl_get_identity_resp_t; 102 0 : #define FD_ADMINCTL_GET_IDENTITY_PAYLOAD_VERSION (1UL) 103 : 104 0 : #define FD_GET_IDENTITY_RESULT_PAYLOAD_TOO_SMALL (2UL) 105 0 : #define FD_GET_IDENTITY_RESULT_UNSUPPORTED_PAYLOAD_VERSION (3UL) 106 0 : #define FD_GET_IDENTITY_RESULT_UNEXPECTED_PAYLOAD_SIZE (4UL) 107 : 108 : struct fd_adminctl_remove_all_auth_voters_v1 { 109 : ulong version; /* ==FD_ADMINCTL_REMOVE_ALL_AUTH_VOTERS_PAYLOAD_VERSION */ 110 : }; 111 : typedef struct fd_adminctl_remove_all_auth_voters_v1 fd_adminctl_remove_all_auth_voters_t; 112 0 : #define FD_ADMINCTL_REMOVE_ALL_AUTH_VOTERS_PAYLOAD_VERSION (1UL) 113 : 114 0 : #define FD_REMOVE_ALL_AUTH_VOTERS_RESULT_PAYLOAD_TOO_SMALL (2UL) 115 0 : #define FD_REMOVE_ALL_AUTH_VOTERS_RESULT_UNSUPPORTED_PAYLOAD_VERSION (3UL) 116 0 : #define FD_REMOVE_ALL_AUTH_VOTERS_RESULT_UNEXPECTED_PAYLOAD_SIZE (4UL) 117 : 118 : typedef struct fd_adminctl_private fd_adminctl_t; 119 : 120 : FD_PROTOTYPES_BEGIN 121 : 122 : FD_FN_CONST ulong 123 : fd_adminctl_align( void ); 124 : 125 : FD_FN_CONST ulong 126 : fd_adminctl_footprint( void ); 127 : 128 : void * 129 : fd_adminctl_new( void * shmem ); 130 : 131 : fd_adminctl_t * 132 : fd_adminctl_join( void * shadminctl ); 133 : 134 : /* fd_adminctl_reserve claims a command slot and returns an identifier 135 : for the command reservation (index into the command buffer). Returns 136 : ULONG_MAX if every slot is busy or reserved. If a reservation is 137 : successful, payload_out receives a pointer into shared memory valid 138 : until publish completes or the reservation is abandoned by process 139 : death. */ 140 : 141 : ulong 142 : fd_adminctl_reserve( fd_adminctl_t * adminctl, 143 : void ** payload_out, 144 : ulong * payload_max_out ); 145 : 146 : /* fd_adminctl_publish validates the reservation and publishes the 147 : command to the admin tile. This should only be called by a command 148 : process after a successful reservation. After this function is 149 : called, the ownership of the slot is transferred to the app process. 150 : If a publish is made after a reservation, it will always succeed. */ 151 : 152 : void 153 : fd_adminctl_publish( fd_adminctl_t * adminctl, 154 : ulong slot_id, 155 : ulong cmd_id, 156 : ulong payload_sz ); 157 : 158 : /* fd_adminctl_wait waits for the command identified by slot_id to 159 : complete and returns the command result. This command should only be 160 : called by a command process after a successful publish. After the 161 : function returns, the command slot will be reclaimed. The command 162 : process result is returned. */ 163 : 164 : ulong 165 : fd_adminctl_wait( fd_adminctl_t * adminctl, 166 : ulong slot_id ); 167 : 168 : /* fd_adminctl_wait_response is fd_adminctl_wait for commands that also 169 : return a response payload. Before the slot is reclaimed, up to 170 : resp_max bytes of the response payload are copied into resp and the 171 : response payload size is stored in resp_sz_out. */ 172 : 173 : ulong 174 : fd_adminctl_wait_response( fd_adminctl_t * adminctl, 175 : ulong slot_id, 176 : void * resp, 177 : ulong resp_max, 178 : ulong * resp_sz_out ); 179 : 180 : /* fd_adminctl_poll checks a command slot at a time and returns the 181 : command id and payload if a command is available. The command is now 182 : ready to be processed by the app process. If no command is 183 : available, the function returns FD_ADMINCTL_CMD_IDLE. Under the 184 : hood, it checks one slot at a time and advances the poll cursor. 185 : This function should be called repeatedly by only the main app 186 : process. */ 187 : 188 : ulong 189 : fd_adminctl_poll( fd_adminctl_t * adminctl, 190 : ulong * slot_id_out, 191 : void ** payload_out, 192 : ulong * payload_sz_out ); 193 : 194 : /* fd_adminctl_complete publishes the result for the command that has 195 : finished being processed. It should only be called by the app 196 : process after the command has been processed. */ 197 : 198 : void 199 : fd_adminctl_complete( fd_adminctl_t * adminctl, 200 : ulong slot_id, 201 : ulong result ); 202 : 203 : /* fd_adminctl_complete_response is fd_adminctl_complete for commands 204 : that also return a response payload. The request payload is zeroed 205 : and replaced with the resp_sz bytes at resp before the result is 206 : published. */ 207 : 208 : void 209 : fd_adminctl_complete_response( fd_adminctl_t * adminctl, 210 : ulong slot_id, 211 : ulong result, 212 : void const * resp, 213 : ulong resp_sz ); 214 : 215 : FD_PROTOTYPES_END 216 : 217 : #endif /* HEADER_fd_src_discof_admin_fd_adminctl_h */