Line data Source code
1 : #include "../fd_util.h"
2 : #include "fd_wksp_private.h"
3 :
4 : #if FD_HAS_HOSTED
5 :
6 : /* TODO: add owner query */
7 :
8 : #include <stdio.h>
9 : #include <errno.h>
10 : #include <unistd.h>
11 : #include <fcntl.h>
12 : #include <sys/stat.h>
13 :
14 : FD_IMPORT_CSTR( fd_wksp_ctl_help, "src/util/wksp/fd_wksp_ctl_help" );
15 :
16 : /* fd_printf_wksp pretty prints the detailed workspace state to file.
17 : Includes detailed metadata integrity checking. Return value
18 : semantics are the same as for fprintf. */
19 :
20 : static int
21 : fprintf_wksp( FILE * file,
22 0 : fd_wksp_t * wksp ) {
23 :
24 0 : if( FD_UNLIKELY( !file ) ) {
25 0 : FD_LOG_WARNING(( "NULL file" ));
26 0 : return -1;
27 0 : }
28 :
29 0 : if( FD_UNLIKELY( !wksp ) ) {
30 0 : FD_LOG_WARNING(( "NULL wksp" ));
31 0 : return -1;
32 0 : }
33 :
34 0 : int ret = 0;
35 0 : # define TRAP(x) do { int _err = (x); if( _err<0 ) { fd_wksp_private_unlock( wksp ); return _err; } ret += _err; } while(0)
36 :
37 0 : ulong part_max = wksp->part_max;
38 0 : ulong gaddr_lo = wksp->gaddr_lo;
39 0 : ulong gaddr_hi = wksp->gaddr_hi;
40 :
41 0 : fd_wksp_private_pinfo_t * pinfo = fd_wksp_private_pinfo( wksp );
42 :
43 0 : TRAP( fprintf( file,
44 0 : "wksp %s\n"
45 0 : "\tmagic 0x%016lx\n"
46 0 : "\tseed %u\n"
47 0 : "\tpart_max %lu\n"
48 0 : "\tdata_max %lu\n"
49 0 : "\tgaddr [0x%016lx,0x%016lx)\n",
50 0 : wksp->name, wksp->magic, wksp->seed, part_max, wksp->data_max, gaddr_lo, gaddr_hi ) );
51 :
52 : /* TODO: considering running verify and/or doing extra metadata
53 : integrity checks */
54 :
55 0 : ulong cnt = 0UL;
56 :
57 0 : if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) ) { cnt++; TRAP( fprintf( file, "\tlock err\n" ) ); }
58 0 : else {
59 0 : ulong used_cnt = 0UL; ulong free_cnt = 0UL;
60 0 : ulong used_sz = 0UL; ulong free_sz = 0UL;
61 0 : ulong used_max = 0UL; ulong free_max = 0UL;
62 :
63 0 : ulong cycle_tag = wksp->cycle_tag++;
64 :
65 0 : ulong last_i = FD_WKSP_PRIVATE_PINFO_IDX_NULL;
66 0 : ulong last_hi = gaddr_lo;
67 0 : ulong i = fd_wksp_private_pinfo_idx( wksp->part_head_cidx );
68 0 : while( !fd_wksp_private_pinfo_idx_is_null( i ) ) {
69 0 : if( FD_UNLIKELY( i>=part_max ) ) { cnt++; TRAP( fprintf( file, "\tindex err\n" ) ); break; }
70 0 : if( FD_UNLIKELY( pinfo[ i ].cycle_tag==cycle_tag ) ) { cnt++; TRAP( fprintf( file, "\tcycle err\n" ) ); break; }
71 0 : pinfo[ i ].cycle_tag = cycle_tag;
72 :
73 0 : ulong lo = pinfo[ i ].gaddr_lo;
74 0 : ulong hi = pinfo[ i ].gaddr_hi;
75 0 : ulong tag = pinfo[ i ].tag;
76 0 : ulong sz = hi - lo;
77 0 : ulong h = fd_wksp_private_pinfo_idx( pinfo[ i ].prev_cidx );
78 :
79 0 : int used = !!tag;
80 0 : if( used ) {
81 0 : used_cnt++;
82 0 : used_sz += sz;
83 0 : if( sz>used_max ) used_max = sz;
84 0 : } else {
85 0 : free_cnt++;
86 0 : free_sz += sz;
87 0 : if( sz>free_max ) free_max = sz;
88 0 : }
89 :
90 0 : TRAP( fprintf( file, "\tpartition [0x%016lx,0x%016lx) sz %20lu tag %20lu idx %lu", lo, hi, sz, tag, i ) );
91 0 : if( FD_UNLIKELY( h !=last_i ) ) { cnt++; TRAP( fprintf( file, ", link_err" ) ); }
92 0 : if( FD_UNLIKELY( lo!=last_hi ) ) { cnt++; TRAP( fprintf( file, ", adjacent_err" ) ); }
93 0 : if( FD_UNLIKELY( lo>=hi ) ) { cnt++; TRAP( fprintf( file, ", size_err" ) ); }
94 0 : TRAP( fprintf( file, "\n" ) );
95 :
96 0 : last_i = i;
97 0 : last_hi = hi;
98 0 : i = fd_wksp_private_pinfo_idx( pinfo[ i ].next_cidx );
99 0 : }
100 :
101 0 : ulong j = fd_wksp_private_pinfo_idx( wksp->part_tail_cidx );
102 0 : if( FD_UNLIKELY( j!=last_i ) ) { cnt++; TRAP( fprintf( file, "\ttail err\n" ) ); }
103 0 : if( FD_UNLIKELY( gaddr_hi!=last_hi ) ) { cnt++; TRAP( fprintf( file, "\tincomplete err\n" ) ); }
104 :
105 0 : TRAP( fprintf( file, "\t%20lu bytes used (%20lu blocks, largest %20lu bytes)\n", used_sz, used_cnt, used_max ) );
106 0 : TRAP( fprintf( file, "\t%20lu bytes free (%20lu blocks, largest %20lu bytes)\n", free_sz, free_cnt, free_max ) );
107 :
108 0 : fd_wksp_private_unlock( wksp );
109 0 : }
110 :
111 0 : TRAP( fprintf( file, "\t%20lu errors detected\n", cnt ) );
112 0 : # undef TRAP
113 :
114 0 : return ret;
115 0 : }
116 :
117 : int
118 : main( int argc,
119 0 : char ** argv ) {
120 0 : fd_boot( &argc, &argv );
121 0 : # define SHIFT(n) argv+=(n),argc-=(n)
122 :
123 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "no arguments" ));
124 0 : char const * bin = argv[0];
125 0 : SHIFT(1);
126 :
127 0 : umask( (mode_t)0 ); /* So mode setting gets respected */
128 :
129 0 : ulong tag = 1UL;
130 :
131 0 : int cnt = 0;
132 0 : while( argc ) {
133 0 : char const * cmd = argv[0];
134 0 : SHIFT(1);
135 :
136 0 : if( !strcmp( cmd, "help" ) ) {
137 :
138 0 : fflush( stdout ); fflush( stderr );
139 0 : fputs( fd_wksp_ctl_help, stdout );
140 0 : fflush( stdout ); fflush( stderr );
141 :
142 0 : FD_LOG_NOTICE(( "%i: %s: success", cnt, cmd ));
143 :
144 0 : } else if( !strcmp( cmd, "tag" ) ) {
145 :
146 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
147 :
148 0 : tag = fd_cstr_to_ulong( argv[0] );
149 :
150 0 : FD_LOG_NOTICE(( "%i: %s %lu: success", cnt, cmd, tag ));
151 0 : SHIFT(1);
152 :
153 0 : } else if( !strcmp( cmd, "supported-styles" ) ) {
154 :
155 0 : printf( "%s\n", FD_HAS_LZ4 ? "0 1 2 3" : "0 1 2" );
156 :
157 0 : FD_LOG_NOTICE(( "%i: %s: success", cnt, cmd ));
158 :
159 0 : } else if( !strcmp( cmd, "new" ) ) {
160 :
161 0 : if( FD_UNLIKELY( argc<5 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
162 :
163 0 : char const * name = argv[0];
164 0 : ulong page_cnt = fd_cstr_to_ulong ( argv[1] );
165 0 : ulong page_sz = fd_cstr_to_shmem_page_sz( argv[2] );
166 0 : char const * seq = argv[3];
167 0 : ulong mode = fd_cstr_to_ulong_octal ( argv[4] );
168 :
169 : /* Partition the pages over the seq */
170 :
171 0 : ulong sub_page_cnt[ 512 ];
172 0 : ulong sub_cpu_idx [ 512 ];
173 0 : ulong sub_cnt = fd_cstr_to_ulong_seq( seq, sub_cpu_idx, 512UL );
174 :
175 0 : if( FD_UNLIKELY( !sub_cnt ) )
176 0 : FD_LOG_ERR(( "%i: %s %s %lu %s %s 0%03lo: empty or invalid cpu sequence\n\t"
177 0 : "Do %s help for help", cnt, cmd, name, page_cnt, argv[2], seq, mode, bin ));
178 :
179 0 : if( FD_UNLIKELY( sub_cnt>512UL ) )
180 0 : FD_LOG_ERR(( "%i: %s %s %lu %s %s 0%03lo: sequence too long, increase limit in fd_wksp_ctl.c\n\t"
181 0 : "Do %s help for help", cnt, cmd, name, page_cnt, argv[2], seq, mode, bin ));
182 :
183 0 : ulong sub_page_min = page_cnt / sub_cnt;
184 0 : ulong sub_page_rem = page_cnt % sub_cnt;
185 0 : for( ulong sub_idx=0UL; sub_idx<sub_cnt; sub_idx++ ) sub_page_cnt[ sub_idx ] = sub_page_min + (ulong)(sub_idx<sub_page_rem);
186 :
187 : /* Create the workspace */
188 :
189 : /* TODO: allow user to specify seed and/or part_max */
190 0 : int err = fd_wksp_new_named( name, page_sz, sub_cnt, sub_page_cnt, sub_cpu_idx, mode, 0U, 0UL ); /* logs details */
191 0 : if( FD_UNLIKELY( err ) )
192 0 : FD_LOG_ERR(( "%i: %s %s %lu %s %s 0%03lo: fd_wksp_new_named failed (%i-%s)\n\t"
193 0 : "Do %s help for help", cnt, cmd, name, page_cnt, argv[2], seq, mode, err, fd_wksp_strerror( err ), bin ));
194 :
195 0 : FD_LOG_NOTICE(( "%i: %s %s %lu %s %s 0%03lo: success", cnt, cmd, name, page_cnt, argv[2], seq, mode ));
196 0 : SHIFT(5);
197 :
198 0 : } else if( !strcmp( cmd, "delete" ) ) {
199 :
200 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
201 :
202 0 : char const * name = argv[0];
203 :
204 0 : int err = fd_wksp_delete_named( name );
205 0 : if( FD_UNLIKELY( err ) )
206 0 : FD_LOG_ERR(( "%i: %s %s: fd_wksp_delete_named failed (%i-%s)\n\t"
207 0 : "Do %s help for help", cnt, cmd, name, err, fd_wksp_strerror( err ), bin ));
208 :
209 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
210 0 : SHIFT(1);
211 :
212 0 : } else if( !strcmp( cmd, "alloc" ) ) {
213 :
214 0 : if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
215 :
216 0 : char const * name = argv[0];
217 0 : ulong align = fd_cstr_to_ulong( argv[1] );
218 0 : ulong sz = fd_cstr_to_ulong( argv[2] );
219 :
220 0 : char name_gaddr[ FD_WKSP_CSTR_MAX ];
221 0 : if( !fd_wksp_cstr_alloc( name, align, sz, tag, name_gaddr ) ) /* logs details */
222 0 : FD_LOG_ERR(( "%i: %s %s %lu %lu %lu: fd_wksp_cstr_alloc failed", cnt, cmd, name, align, sz, tag ));
223 0 : printf( "%s\n", name_gaddr );
224 :
225 0 : FD_LOG_NOTICE(( "%i: %s %s %lu %lu: success", cnt, cmd, name, align, sz ));
226 0 : SHIFT(3);
227 :
228 0 : } else if( !strcmp( cmd, "info" ) ) {
229 :
230 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
231 :
232 0 : char const * name = argv[0];
233 0 : ulong tag = fd_cstr_to_ulong( argv[1] );
234 :
235 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
236 0 : if( FD_LIKELY( wksp ) ) {
237 0 : fd_wksp_tag_query_info_t info[1];
238 0 : ulong tag_cnt = tag ? fd_wksp_tag_query( wksp, &tag, 1UL, info, 1UL ) : 0UL; /* logs details */
239 0 : if( tag_cnt ) printf( "%s:%lu %lu\n", name, info->gaddr_lo, info->gaddr_hi - info->gaddr_lo );
240 0 : else printf( "- 0\n" );
241 0 : fd_wksp_detach( wksp ); /* logs details */
242 0 : }
243 :
244 0 : FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, tag ));
245 0 : SHIFT(2);
246 :
247 0 : } else if( !strcmp( cmd, "free" ) ) {
248 :
249 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
250 :
251 0 : char const * name_gaddr = argv[0];
252 :
253 0 : fd_wksp_cstr_free( name_gaddr ); /* logs details */
254 :
255 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name_gaddr )); /* FIXME: HMMM (print success on bad free?) */
256 0 : SHIFT(1);
257 :
258 0 : } else if( !strcmp( cmd, "tag-query" ) ) {
259 :
260 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
261 :
262 0 : char const * name_gaddr = argv[0];
263 :
264 0 : printf( "%lu\n", fd_wksp_cstr_tag( name_gaddr ) ); /* logs details */
265 :
266 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name_gaddr ));
267 0 : SHIFT(1);
268 :
269 0 : } else if( !strcmp( cmd, "tag-free" ) ) {
270 :
271 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
272 :
273 0 : char const * name = argv[0];
274 0 : ulong tag = fd_cstr_to_ulong( argv[1] );
275 :
276 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
277 0 : if( FD_LIKELY( wksp ) ) {
278 0 : fd_wksp_tag_free( wksp, &tag, 1UL ); /* logs details */
279 0 : fd_wksp_detach( wksp ); /* logs details */
280 0 : }
281 :
282 0 : FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, tag ));
283 0 : SHIFT(2);
284 :
285 0 : } else if( !strcmp( cmd, "memset" ) ) {
286 :
287 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
288 :
289 0 : char const * name_gaddr = argv[0];
290 0 : int c = fd_cstr_to_int( argv[1] );
291 :
292 0 : fd_wksp_cstr_memset( name_gaddr, c ); /* logs details */
293 :
294 0 : FD_LOG_NOTICE(( "%i: %s %s %i: success", cnt, cmd, name_gaddr, c ));
295 0 : SHIFT(2);
296 :
297 0 : } else if( !strcmp( cmd, "check" ) ) {
298 :
299 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
300 :
301 0 : char const * name = argv[0];
302 :
303 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
304 0 : if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
305 :
306 0 : if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) ) FD_LOG_ERR(( "%i: %s %s: failed", cnt, cmd, name )); /* logs details */
307 0 : fd_wksp_private_unlock( wksp );
308 :
309 0 : fd_wksp_detach( wksp ); /* logs details */
310 :
311 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
312 0 : SHIFT(1);
313 :
314 0 : } else if( !strcmp( cmd, "verify" ) ) {
315 :
316 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
317 :
318 0 : char const * name = argv[0];
319 :
320 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
321 0 : if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
322 :
323 0 : if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) || /* logs details */
324 0 : FD_UNLIKELY( fd_wksp_verify( wksp ) ) ) /* logs details */
325 0 : FD_LOG_ERR(( "%i: %s %s: failed", cnt, cmd, name ));
326 0 : fd_wksp_private_unlock( wksp );
327 :
328 0 : fd_wksp_detach( wksp ); /* logs details */
329 :
330 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
331 0 : SHIFT(1);
332 :
333 0 : } else if( !strcmp( cmd, "rebuild" ) ) {
334 :
335 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
336 :
337 0 : char const * name = argv[0];
338 0 : char const * _seed = argv[1];
339 :
340 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
341 0 : if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s %s: wksp_attach failed", cnt, cmd, name, _seed ));
342 :
343 0 : uint seed = strcmp( _seed, "-" ) ? fd_cstr_to_uint( _seed ) : fd_wksp_seed( wksp );
344 :
345 0 : if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) || /* logs details */
346 0 : FD_UNLIKELY( fd_wksp_rebuild( wksp, seed ) ) ) /* logs details */
347 0 : FD_LOG_ERR(( "%i: %s %s %u: failed", cnt, cmd, name, seed ));
348 0 : fd_wksp_private_unlock( wksp );
349 :
350 0 : fd_wksp_detach( wksp ); /* logs details */
351 :
352 0 : FD_LOG_NOTICE(( "%i: %s %s %u: success", cnt, cmd, name, seed ));
353 0 : SHIFT(2);
354 :
355 0 : } else if( !strcmp( cmd, "reset" ) ) {
356 :
357 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
358 :
359 0 : char const * name = argv[0];
360 :
361 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
362 0 : if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
363 0 : fd_wksp_reset( wksp, fd_wksp_seed( wksp ) ); /* logs details */
364 0 : fd_wksp_detach( wksp ); /* logs details */
365 :
366 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
367 0 : SHIFT(1);
368 :
369 0 : } else if( !strcmp( cmd, "usage" ) ) {
370 :
371 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
372 :
373 0 : char const * name = argv[0];
374 0 : ulong tag = fd_cstr_to_ulong( argv[1] );
375 :
376 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
377 0 : if( FD_UNLIKELY( !wksp ) ) fprintf( stdout, "-\n" );
378 0 : else {
379 0 : fd_wksp_usage_t usage[1];
380 0 : fd_wksp_usage( wksp, &tag, 1UL, usage );
381 0 : fprintf( stdout,
382 0 : "wksp %s\n"
383 0 : "\t%20lu bytes max (%lu blocks, %lu blocks max)\n"
384 0 : "\t%20lu bytes used (%lu blocks)\n"
385 0 : "\t%20lu bytes avail (%lu blocks)\n"
386 0 : "\t%20lu bytes w/tag %4lu (%lu blocks)\n",
387 0 : wksp->name,
388 0 : usage->total_sz, usage->total_cnt, usage->total_max,
389 0 : usage->total_sz - usage->free_sz, usage->total_cnt - usage->free_cnt,
390 0 : usage->free_sz, usage->free_cnt,
391 0 : usage->used_sz, tag, usage->used_cnt );
392 0 : fd_wksp_detach( wksp ); /* logs details */
393 0 : }
394 :
395 0 : FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, tag ));
396 0 : SHIFT(2);
397 :
398 0 : } else if( !strcmp( cmd, "query" ) ) {
399 :
400 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
401 :
402 0 : char const * name = argv[0];
403 :
404 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
405 0 : if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
406 0 : fprintf_wksp( stdout, wksp ); /* logs details */
407 0 : fd_wksp_detach( wksp ); /* logs details */
408 :
409 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
410 0 : SHIFT(1);
411 :
412 0 : } else if( !strcmp( cmd, "checkpt" ) ) {
413 :
414 0 : if( FD_UNLIKELY( argc<5 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
415 :
416 0 : char const * name = argv[0];
417 0 : char const * path = argv[1];
418 0 : ulong mode = fd_cstr_to_ulong_octal( argv[2] );
419 0 : int style = fd_cstr_to_int ( argv[3] );
420 0 : char const * info = argv[4];
421 :
422 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
423 0 : if( FD_UNLIKELY( !wksp ) )
424 0 : FD_LOG_ERR(( "%i: %s %s %s 0%03lo %i ...: wksp_attach failed", cnt, cmd, name, path, mode, style ));
425 :
426 0 : int err = fd_wksp_checkpt( wksp, path, mode, style, info ); /* logs details */
427 0 : if( FD_UNLIKELY( err ) )
428 0 : FD_LOG_ERR(( "%i: %s %s %s 0%03lo %i ...: fd_wksp_checkpt failed", cnt, cmd, name, path, mode, style ));
429 :
430 0 : fd_wksp_detach( wksp ); /* logs details */
431 :
432 0 : FD_LOG_NOTICE(( "%i: %s %s %s 0%03lo %i ...: success", cnt, cmd, name, path, mode, style ));
433 0 : SHIFT(5);
434 :
435 0 : } else if( !strcmp( cmd, "checkpt-query" ) ) {
436 :
437 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
438 :
439 0 : char const * path = argv[0];
440 0 : int verbose = fd_cstr_to_int( argv[1] );
441 :
442 0 : fd_wksp_printf( fileno( stdout ), path, verbose );
443 :
444 0 : FD_LOG_NOTICE(( "%i: %s %s %i: success", cnt, cmd, path, verbose ));
445 0 : SHIFT(2);
446 :
447 0 : } else if( !strcmp( cmd, "restore" ) ) {
448 :
449 0 : if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
450 :
451 0 : char const * name = argv[0];
452 0 : char const * path = argv[1];
453 0 : char const * _seed = argv[2];
454 :
455 0 : fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
456 0 : if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s %s %s: wksp_attach failed", cnt, cmd, name, path, _seed ));
457 :
458 0 : uint seed = strcmp( _seed, "-" ) ? fd_cstr_to_uint( _seed ) : fd_wksp_seed( wksp );
459 :
460 0 : int err = fd_wksp_restore( wksp, path, seed ); /* logs details */
461 0 : if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "%i: %s %s %s %u: fd_wksp_restore failed", cnt, cmd, name, path, seed ));
462 :
463 0 : fd_wksp_detach( wksp ); /* logs details */
464 :
465 0 : FD_LOG_NOTICE(( "%i: %s %s %s %u: success", cnt, cmd, name, path, seed ));
466 0 : SHIFT(3);
467 :
468 0 : } else {
469 :
470 0 : FD_LOG_ERR(( "%i: %s: unknown command\n\t"
471 0 : "Do %s help for help", cnt, cmd, bin ));
472 :
473 0 : }
474 0 : cnt++;
475 0 : }
476 :
477 0 : if( FD_UNLIKELY( cnt<1 ) ) FD_LOG_NOTICE(( "processed %i commands\n\tDo %s help for help", cnt, bin ));
478 0 : else FD_LOG_NOTICE(( "processed %i commands", cnt ));
479 :
480 0 : # undef SHIFT
481 0 : fd_halt();
482 0 : return 0;
483 0 : }
484 :
485 : #else
486 :
487 : int
488 : main( int argc,
489 : char ** argv ) {
490 : fd_boot( &argc, &argv );
491 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "No arguments" ));
492 : if( FD_UNLIKELY( argc>1 ) ) FD_LOG_ERR(( "fd_wksp_ctl not supported on this platform" ));
493 : FD_LOG_NOTICE(( "processed 0 commands" ));
494 : fd_halt();
495 : return 0;
496 : }
497 :
498 : #endif
|