int32_t rte_service_run_iter_on_app_lcore(uint32_t id, uint32_t serialize_mt_unsafe) { /* run service on calling core, using all-ones as the service mask */ if (!service_valid(id)) return -EINVAL; struct core_state *cs = &lcore_states[rte_lcore_id()]; struct rte_service_spec_impl *s = &rte_services[id]; /* Atomically add this core to the mapped cores first, then examine if * we can run the service. This avoids a race condition between * checking the value, and atomically adding to the mapped count. */ if (serialize_mt_unsafe) rte_atomic32_inc(&s->num_mapped_cores); if (service_mt_safe(s) == 0 && rte_atomic32_read(&s->num_mapped_cores) > 1) { if (serialize_mt_unsafe) rte_atomic32_dec(&s->num_mapped_cores); return -EBUSY; } int ret = service_run(id, cs, UINT64_MAX); if (serialize_mt_unsafe) rte_atomic32_dec(&s->num_mapped_cores); return ret; }
static inline int32_t service_run(uint32_t i, struct core_state *cs, uint64_t service_mask) { if (!service_valid(i)) return -EINVAL; struct rte_service_spec_impl *s = &rte_services[i]; if (s->comp_runstate != RUNSTATE_RUNNING || s->app_runstate != RUNSTATE_RUNNING || !(service_mask & (UINT64_C(1) << i))) return -ENOEXEC; /* check do we need cmpset, if MT safe or <= 1 core * mapped, atomic ops are not required. */ const int use_atomics = (service_mt_safe(s) == 0) && (rte_atomic32_read(&s->num_mapped_cores) > 1); if (use_atomics) { if (!rte_atomic32_cmpset((uint32_t *)&s->execute_lock, 0, 1)) return -EBUSY; rte_service_runner_do_callback(s, cs, i); rte_atomic32_clear(&s->execute_lock); } else rte_service_runner_do_callback(s, cs, i); return 0; }
int32_t rte_service_component_register(const struct rte_service_spec *spec, uint32_t *id_ptr) { uint32_t i; int32_t free_slot = -1; if (spec->callback == NULL || strlen(spec->name) == 0) return -EINVAL; for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { if (!service_valid(i)) { free_slot = i; break; } } if ((free_slot < 0) || (i == RTE_SERVICE_NUM_MAX)) return -ENOSPC; struct rte_service_spec_impl *s = &rte_services[free_slot]; s->spec = *spec; s->internal_flags |= SERVICE_F_REGISTERED | SERVICE_F_START_CHECK; rte_smp_wmb(); rte_service_count++; if (id_ptr) *id_ptr = free_slot; return 0; }
int32_t rte_service_dump(FILE *f, uint32_t id) { uint32_t i; int print_one = (id != UINT32_MAX); uint64_t total_cycles = 0; for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { if (!service_valid(i)) continue; total_cycles += rte_services[i].cycles_spent; } /* print only the specified service */ if (print_one) { struct rte_service_spec_impl *s; SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL); fprintf(f, "Service %s Summary\n", s->spec.name); uint32_t reset = 0; rte_service_dump_one(f, s, total_cycles, reset); return 0; } /* print all services, as UINT32_MAX was passed as id */ fprintf(f, "Services Summary\n"); for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { if (!service_valid(i)) continue; uint32_t reset = 1; rte_service_dump_one(f, &rte_services[i], total_cycles, reset); } fprintf(f, "Service Cores Summary\n"); for (i = 0; i < RTE_MAX_LCORE; i++) { if (lcore_config[i].core_role != ROLE_SERVICE) continue; uint32_t reset = 1; service_dump_calls_per_lcore(f, i, reset); } return 0; }
static void service_dump_calls_per_lcore(FILE *f, uint32_t lcore, uint32_t reset) { uint32_t i; struct core_state *cs = &lcore_states[lcore]; fprintf(f, "%02d\t", lcore); for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { if (!service_valid(i)) continue; fprintf(f, "%"PRIu64"\t", cs->calls_per_service[i]); if (reset) cs->calls_per_service[i] = 0; } fprintf(f, "\n"); }
int32_t rte_service_get_by_name(const char *name, uint32_t *service_id) { if (!service_id) return -EINVAL; int i; for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { if (service_valid(i) && strcmp(name, rte_services[i].spec.name) == 0) { *service_id = i; return 0; } } return -ENODEV; }
static int32_t service_update(struct rte_service_spec *service, uint32_t lcore, uint32_t *set, uint32_t *enabled) { uint32_t i; int32_t sid = -1; for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { if ((struct rte_service_spec *)&rte_services[i] == service && service_valid(i)) { sid = i; break; } } if (sid == -1 || lcore >= RTE_MAX_LCORE) return -EINVAL; if (!lcore_states[lcore].is_service_core) return -EINVAL; uint64_t sid_mask = UINT64_C(1) << sid; if (set) { if (*set) { lcore_states[lcore].service_mask |= sid_mask; rte_atomic32_inc(&rte_services[sid].num_mapped_cores); } else { lcore_states[lcore].service_mask &= ~(sid_mask); rte_atomic32_dec(&rte_services[sid].num_mapped_cores); } } if (enabled) *enabled = !!(lcore_states[lcore].service_mask & (sid_mask)); rte_smp_wmb(); return 0; }
int f_check( SNET *sn, int ac, char *av[], SNET *pushersn ) { struct cinfo ci; struct timeval tv; char login[ MAXCOOKIELEN ], path[ MAXPATHLEN ]; char rekeybuf[ 128 ], rcookie[ 256 ], scpath[ MAXPATHLEN ]; char *p; int status; double rate; /* * C: CHECK servicecookie * S: 231 ip principal realm */ /* * C: CHECK logincookie * S: 232 ip principal realm */ /* * C: REKEY servicecookie * S: 233 ip principal realm rekeyed-cookie */ if (( al->al_key != CGI ) && ( al->al_key != SERVICE )) { syslog( LOG_ERR, "f_check: %s not allowed", al->al_hostname ); snet_writef( sn, "%d %s: %s not allowed to check.\r\n", 430, av[ 0 ], al->al_hostname ); return( 1 ); } if ( ac < 2 || ac > 3 ) { syslog( LOG_ERR, "f_check: %s: wrong number of args. " "Expected 2 or 3, got %d", al->al_hostname, ac ); snet_writef( sn, "%d %s: Wrong number of args.\r\n", 530, av[ 0 ] ); return( 1 ); } if ( mkcookiepath( NULL, hashlen, av[ 1 ], path, sizeof( path )) < 0 ) { syslog( LOG_ERR, "f_check: mkcookiepath error" ); snet_writef( sn, "%d %s: Invalid cookie name.\r\n", 531, av[ 0 ] ); return( 1 ); } if ( strncmp( av[ 1 ], "cosign-", 7 ) == 0 ) { if ( strict_checks && service_valid( av[ 1 ] ) == NULL ) { snet_writef( sn, "%d %s: Invalid cookie\r\n", 534, av[ 0 ] ); return( 1 ); } status = 231; if ( service_to_login( path, login ) != 0 ) { if (( rate = rate_tick( &checkunknown )) != 0.0 ) { syslog( LOG_NOTICE, "STATS CHECK %s: UNKNOWN %.5f / sec", inet_ntoa( cosign_sin.sin_addr), rate ); } snet_writef( sn, "%d %s: cookie not in db!\r\n", 533, av[ 0 ] ); return( 1 ); } if ( COSIGN_PROTO_SUPPORTS_REKEY( protocol )) { if ( strcasecmp( av[ 0 ], "REKEY" ) == 0 ) { /* save service cookie path for rekeying below. */ if ( strlen( path ) >= sizeof( scpath )) { syslog( LOG_ERR, "f_check: %s exceeds bounds.", path ); snet_writef( sn, "%d %s: Invalid cookie name.\r\n", 531, av[ 0 ]); return( 1 ); } strcpy( scpath, path ); status = 233; } } if ( mkcookiepath( NULL, hashlen, login, path, sizeof( path )) < 0 ) { syslog( LOG_ERR, "f_check: mkcookiepath error.." ); snet_writef( sn, "%d %s: Invalid cookie name.\r\n", 532, av[ 0 ] ); return( 1 ); } } else if ( strncmp( av[ 1 ], "cosign=", 7 ) == 0 ) { status = 232; } else { syslog( LOG_ERR, "f_check: unknown cookie prefix." ); snet_writef( sn, "%d %s: unknown cookie prefix!\r\n", 432, av[ 0 ] ); return( 1 ); } if ( read_cookie( path, &ci ) != 0 ) { if (( rate = rate_tick( &checkunknown )) != 0.0 ) { syslog( LOG_NOTICE, "STATS CHECK %s: UNKNOWN %.5f / sec", inet_ntoa( cosign_sin.sin_addr), rate); } snet_writef( sn, "%d %s: Who me? Dunno.\r\n", 534, av[ 0 ] ); return( 1 ); } if ( ci.ci_state == 0 ) { if (( rate = rate_tick( &checkfail )) != 0.0 ) { syslog( LOG_NOTICE, "STATS CHECK %s: FAIL %.5f / sec", inet_ntoa( cosign_sin.sin_addr), rate); } snet_writef( sn, "%d %s: Already logged out\r\n", 430, av[ 0 ] ); return( 1 ); } /* check for idle timeout, and if so, log'em out */ if ( gettimeofday( &tv, NULL ) != 0 ){ syslog( LOG_ERR, "f_check: gettimeofday: %m" ); return( -1 ); } if ( tv.tv_sec - ci.ci_itime >= idle_out_time ) { if ( tv.tv_sec - ci.ci_itime < ( idle_out_time + grey_time )) { if (( rate = rate_tick( &checkunknown )) != 0.0 ) { syslog( LOG_NOTICE, "STATS CHECK %s: UNKNOWN %.5f / sec", inet_ntoa( cosign_sin.sin_addr ), rate ); } syslog( LOG_NOTICE, "f_check: idle grey window" ); snet_writef( sn, "%d %s: Idle Grey Window\r\n", 531, av[ 0 ] ); return( 1 ); } if (( rate = rate_tick( &checkfail )) != 0.0 ) { syslog( LOG_NOTICE, "STATS CHECK %s: FAIL %.5f / sec", inet_ntoa( cosign_sin.sin_addr), rate); } snet_writef( sn, "%d %s: Idle logged out\r\n", 431, av[ 0 ] ); if ( do_logout( path ) < 0 ) { syslog( LOG_ERR, "f_check: %s: %m", login ); return( -1 ); } return( 1 ); } /* prevent idle out if we are actually using it */ utime( path, NULL ); if (( rate = rate_tick( &checkpass )) != 0.0 ) { syslog( LOG_NOTICE, "STATS CHECK %s: PASS %.5f / sec", inet_ntoa( cosign_sin.sin_addr), rate); } if ( status == 233 ) { /* rekey service cookie. */ if ( mkcookie( sizeof( rekeybuf ), rekeybuf ) != 0 ) { syslog( LOG_ERR, "f_check: rekey: mkcookie failed" ); snet_writef( sn, "%d %s: rekey failed.\r\n", 536, av[ 0 ] ); return( 1 ); } if (( p = strchr( av[ 1 ], '=' )) == NULL ) { syslog( LOG_ERR, "f_check: rekey: bad service name \"%s\".", av[1]); snet_writef( sn, "%d %s rekey failed.\r\n", 536, av[ 0 ] ); return( 1 ); } *p = '\0'; if ( snprintf( rcookie, sizeof( rcookie ), "%s=%s", av[ 1 ], rekeybuf ) >= sizeof( rcookie )) { syslog( LOG_ERR, "f_check: rekey: new cookie too long." ); snet_writef( sn, "%d %s rekey failed.\r\n", 536, av[ 0 ] ); return( 1 ); } *p = '='; if ( mkcookiepath( NULL, hashlen, rcookie, path, sizeof( path )) < 0 ) { syslog( LOG_ERR, "f_check: rekey: mkcookiepath error." ); snet_writef( sn, "%d %s: rekey failed.\r\n", 536, av[ 0 ] ); return( 1 ); } if ( rename( scpath, path ) != 0 ) { syslog( LOG_ERR, "f_check: rekey: rename %s to %s failed: %s.", scpath, path, strerror( errno )); snet_writef( sn, "%d %s: rekey failed.\r\n", 536, av[ 0 ] ); return( 1 ); } } if ( COSIGN_PROTO_SUPPORTS_FACTORS( protocol )) { snet_writef( sn, "%d %s %s %s %s\r\n", status, ci.ci_ipaddr_cur, ci.ci_user, ci.ci_realm, ( status == 233 ? rcookie : "" )); } else { /* if there is more than one realm, we just give the first */ if (( p = strtok( ci.ci_realm, " " )) != NULL ) { snet_writef( sn, "%d %s %s %s\r\n", status, ci.ci_ipaddr, ci.ci_user, p ); } else { snet_writef( sn, "%d %s %s %s\r\n", status, ci.ci_ipaddr, ci.ci_user, ci.ci_realm ); } } return( 0 ); }
int f_retr( SNET *sn, int ac, char *av[], SNET *pushersn ) { struct servicelist *sl; struct cinfo ci; struct timeval tv; char lpath[ MAXPATHLEN ], spath[ MAXPATHLEN ]; char login[ MAXCOOKIELEN ]; if (( al->al_key != CGI ) && ( al->al_key != SERVICE )) { syslog( LOG_ERR, "f_retr: %s not allowed", al->al_hostname ); snet_writef( sn, "%d RETR: %s not allowed to retrieve.\r\n", 442, al->al_hostname ); return( 1 ); } if ( ac != 3 ) { syslog( LOG_ERR, "f_retr: %s Wrong number of args.", al->al_hostname ); snet_writef( sn, "%d RETR: Wrong number of args.\r\n", 540 ); return( 1 ); } if (( sl = service_valid( av[ 1 ] )) == NULL ) { snet_writef( sn, "%d RETR: Invalid cookie\r\n", 545 ); return( 1 ); } if ( mkcookiepath( NULL, hashlen, av[ 1 ], spath, sizeof( spath )) < 0 ) { syslog( LOG_ERR, "f_retr: mkcookiepath error" ); snet_writef( sn, "%d RETR: Invalid cookie name.\r\n", 541 ); return( 1 ); } if ( service_to_login( spath, login ) != 0 ) { snet_writef( sn, "%d RETR: cookie not in db!\r\n", 543 ); return( 1 ); } if ( mkcookiepath( NULL, hashlen, login, lpath, sizeof( lpath )) < 0 ) { syslog( LOG_ERR, "f_retr: mkcookiepath error" ); snet_writef( sn, "%d RETR: Invalid cookie name.\r\n", 541 ); return( 1 ); } if ( read_cookie( lpath, &ci ) != 0 ) { snet_writef( sn, "%d RETR: Who me? Dunno.\r\n", 544 ); return( 1 ); } if ( ci.ci_state == 0 ) { snet_writef( sn, "%d RETR: Already logged out\r\n", 440 ); return( 1 ); } /* check for idle timeout, and if so, log'em out */ if ( gettimeofday( &tv, NULL ) != 0 ){ syslog( LOG_ERR, "f_retr: gettimeofday: %m" ); return( -1 ); } if ( tv.tv_sec - ci.ci_itime >= idle_out_time ) { if ( tv.tv_sec - ci.ci_itime < ( idle_out_time + grey_time )) { syslog( LOG_ERR, "f_retr: idle grey window" ); snet_writef( sn, "%d RETR: Idle Grey Window\r\n", 541 ); return( 1 ); } snet_writef( sn, "%d RETR: Idle logged out\r\n", 441 ); if ( do_logout( lpath ) < 0 ) { syslog( LOG_ERR, "f_retr: %s: %m", login ); return( -1 ); } return( 1 ); } if ( strcmp( av[ 2 ], "tgt") == 0 ) { return( retr_ticket( sn, sl, ci.ci_krbtkt )); } else if ( strcmp( av[ 2 ], "cookies") == 0 ) { return( retr_proxy( sn, login, pushersn )); } syslog( LOG_ERR, "f_retr: no such retrieve type: %s", av[ 1 ] ); snet_writef( sn, "%d RETR: No such retrieve type.\r\n", 441 ); return( 1 ); }