Line data Source code
1 : #define _GNU_SOURCE
2 : #include "run.h"
3 :
4 : #include "../../../../util/tile/fd_tile_private.h"
5 :
6 : #include <sched.h>
7 : #include <stdlib.h> /* strtoul */
8 : #include <errno.h>
9 : #include <unistd.h>
10 : #include <sys/wait.h>
11 :
12 : #define NAME "run1"
13 :
14 : fd_topo_run_tile_t
15 : fdctl_tile_run( fd_topo_tile_t const * tile );
16 :
17 : void
18 : run1_cmd_args( int * pargc,
19 : char *** pargv,
20 0 : args_t * args) {
21 0 : char * usage = "usage: run1 <tile-name> <kind-id>";
22 0 : if( FD_UNLIKELY( *pargc < 2 ) ) FD_LOG_ERR(( "%s", usage ));
23 :
24 0 : args->run1.pipe_fd = fd_env_strip_cmdline_int( pargc, pargv, "--pipe-fd", NULL, -1 );
25 0 : strncpy( args->run1.tile_name, **pargv, sizeof( args->run1.tile_name ) - 1 );
26 :
27 0 : (*pargc)--;
28 0 : (*pargv)++;
29 :
30 0 : char * endptr;
31 0 : ulong kind_id = strtoul( **pargv, &endptr, 10 );
32 0 : if( FD_UNLIKELY( *endptr!='\0' || kind_id==ULONG_MAX ) ) FD_LOG_ERR(( "invalid tile-id provided `%s`", **pargv ));
33 0 : args->run1.kind_id = kind_id;
34 :
35 0 : (*pargc)--;
36 0 : (*pargv)++;
37 0 : }
38 :
39 : typedef struct {
40 : config_t * config;
41 : fd_topo_tile_t * tile;
42 : int pipefd;
43 : } tile_main_args_t;
44 :
45 : static int
46 0 : tile_main( void * _args ) {
47 0 : tile_main_args_t * args = (tile_main_args_t *)_args;
48 :
49 0 : fd_topo_run_tile_t run_tile = fdctl_tile_run( args->tile );
50 0 : fd_topo_run_tile( &args->config->topo, args->tile, args->config->development.sandbox, 0, args->config->development.core_dump_level, args->config->uid, args->config->gid, args->pipefd, &run_tile );
51 :
52 : /* If we get here, the tile run loop has requested to exit the tile,
53 : so it is cleanly shutting down. */
54 0 : FD_TEST( args->tile->allow_shutdown );
55 0 : return 0;
56 0 : }
57 :
58 : void
59 : run1_cmd_fn( args_t * args,
60 0 : config_t * config ) {
61 0 : ulong pid = fd_sandbox_getpid(); /* Need to read /proc again.. we got a new PID from clone */
62 0 : fd_log_private_tid_set( pid );
63 :
64 0 : ulong tile_id = fd_topo_find_tile( &config->topo, args->run1.tile_name, args->run1.kind_id );
65 0 : if( FD_UNLIKELY( tile_id==ULONG_MAX ) ) FD_LOG_ERR(( "tile %s:%lu not found", args->run1.tile_name, args->run1.kind_id ));
66 0 : fd_topo_tile_t * tile = &config->topo.tiles[ tile_id ];
67 :
68 0 : char thread_name[ FD_LOG_NAME_MAX ] = {0};
69 0 : FD_TEST( fd_cstr_printf_check( thread_name, FD_LOG_NAME_MAX-1UL, NULL, "%s:%lu", tile->name, tile->kind_id ) );
70 0 : fd_log_thread_set( thread_name );
71 :
72 0 : FD_CPUSET_DECL( affinity );
73 0 : if( FD_UNLIKELY( -1==fd_cpuset_getaffinity( 0, affinity ) ) )
74 0 : FD_LOG_ERR(( "fd_cpuset_getaffinity() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
75 0 : ulong cpu_idx = fd_cpuset_first( affinity );
76 0 : cpu_idx = fd_ulong_if( cpu_idx<FD_TILE_MAX, cpu_idx, ULONG_MAX );
77 :
78 0 : if( FD_UNLIKELY( cpu_idx==ULONG_MAX ) ) {
79 0 : FD_LOG_WARNING(( "unable to find a CPU to run on, using CPU 0" ));
80 0 : cpu_idx = 0UL;
81 0 : }
82 :
83 0 : void * stack = fd_topo_tile_stack_join( config->name, tile->name, tile->kind_id );
84 :
85 0 : tile_main_args_t clone_args = {
86 0 : .config = config,
87 0 : .tile = tile,
88 0 : .pipefd = args->run1.pipe_fd,
89 0 : };
90 :
91 : /* Also clone tiles into PID namespaces so they cannot signal each
92 : other or the parent. */
93 0 : int flags = config->development.sandbox ? CLONE_NEWPID : 0;
94 0 : pid_t clone_pid = clone( tile_main, (uchar *)stack + FD_TILE_PRIVATE_STACK_SZ, flags, &clone_args );
95 0 : if( FD_UNLIKELY( clone_pid<0 ) ) FD_LOG_ERR(( "clone() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
96 :
97 0 : if( FD_LIKELY( args->run1.pipe_fd!=-1 ) ) {
98 0 : ulong pid = (ulong)clone_pid;
99 0 : if( FD_UNLIKELY( 8UL!=write( args->run1.pipe_fd, &pid, 8UL ) ) ) FD_LOG_ERR(( "write() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
100 0 : }
101 0 : }
|