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