/* * Create a configuration for one of the special services */ struct service_config *sc_make_special( const char *service_name, const builtin_s *bp, int instances ) { struct service_config *scp ; const char *func = "sc_make" ; if ( ( scp = sc_alloc( service_name ) ) == NULL ) return( NULL ) ; SC_ID(scp) = new_string( SC_NAME(scp) ) ; if ( SC_ID(scp) == NULL ) { out_of_memory( func ) ; /* * Since we're returning instead of exiting, it's probably a good idea to * free scp */ sc_free( scp ); return( NULL ) ; } SC_SPECIFY( scp, A_ID ) ; /* * All special services are internal */ M_SET( SC_TYPE(scp), ST_SPECIAL ) ; M_SET( SC_TYPE(scp), ST_INTERNAL ) ; SC_BUILTIN(scp) = bp ; SC_SPECIFY( scp, A_TYPE ) ; M_SET( SC_XFLAGS(scp), SF_NORETRY ) ; SC_SPECIFY( scp, A_FLAGS ) ; SC_INSTANCES(scp) = instances ; SC_SPECIFY( scp, A_INSTANCES ) ; SC_WAIT(scp) = NO ; SC_SPECIFY( scp, A_WAIT ) ; return( scp ) ; }
/* * Get a service entry. Steps: * * 1. Parse entry attributes * 2. Determine service id * 3. Insert entry in table */ static void get_service_entry( int fd, pset_h sconfs, const char *name, struct service_config *defaults ) { struct service_config *scp ; const char *func = "get_service_entry" ; scp = sc_alloc( name ) ; if ( scp == NULL ) { skip_entry( fd ) ; return ; } /* Now fill in default attributes if given. */ if ( SC_SPECIFIED( defaults, A_LOG_ON_SUCCESS ) && ! SC_IS_PRESENT( scp, A_LOG_ON_SUCCESS) ) fill_attribute( A_LOG_ON_SUCCESS, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_LOG_ON_FAILURE ) && ! SC_IS_PRESENT( scp, A_LOG_ON_FAILURE ) ) fill_attribute( A_LOG_ON_FAILURE, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_ONLY_FROM ) && ! SC_IS_PRESENT( scp, A_ONLY_FROM ) ) fill_attribute( A_ONLY_FROM, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_NO_ACCESS ) && ! SC_IS_PRESENT( scp, A_NO_ACCESS ) ) fill_attribute( A_NO_ACCESS, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_PASSENV ) && ! SC_IS_PRESENT( scp, A_PASSENV ) ) fill_attribute( A_PASSENV, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_ACCESS_TIMES ) && ! SC_IS_PRESENT( scp, A_ACCESS_TIMES ) ) fill_attribute( A_ACCESS_TIMES, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_BANNER ) && ! SC_IS_PRESENT( scp, A_BANNER ) ) fill_attribute( A_BANNER, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_BANNER_SUCCESS ) && ! SC_IS_PRESENT( scp, A_BANNER_SUCCESS ) ) fill_attribute( A_BANNER_SUCCESS, scp, defaults ) ; if ( SC_SPECIFIED( defaults, A_BANNER_FAIL ) && ! SC_IS_PRESENT( scp, A_BANNER_FAIL ) ) fill_attribute( A_BANNER_FAIL, scp, defaults ) ; if ( parse_entry( SERVICE_ENTRY, fd, scp ) == FAILED ) { sc_free( scp ) ; skip_entry( fd ) ; return ; } /* * If no service id was specified, set it equal to the service name */ if ( ! SC_SPECIFIED( scp, A_ID ) ) { if ( (SC_ID(scp) = new_string( SC_NAME(scp) )) ) SC_PRESENT( scp, A_ID ) ; else { out_of_memory( func ) ; sc_free( scp ) ; return ; } } if ( ! (pset_add( sconfs, scp )) ) { out_of_memory( func ) ; sc_free( scp ) ; return ; } }
static int get_next_inet_entry( int fd, pset_h sconfs, struct service_config *defaults) { char *p; str_h strp; char *line = next_line(fd); struct service_config *scp; unsigned u, i; const char *func = "get_next_inet_entry"; char *name = NULL, *rpcvers = NULL, *rpcproto = NULL; char *group, *proto, *stype; const struct name_value *nvp; struct protoent *pep ; struct passwd *pw ; struct group *grp ; const char *dot = "."; const char *slash = "/"; pset_h args; if( line == CHAR_NULL ) return -2; strp = str_parse( line, " \t", STR_RETURN_ERROR, INT_NULL ) ; if( strp == NULL ) { parsemsg( LOG_CRIT, func, "inetd.conf - str_parse failed" ) ; return( -1 ) ; } if( (args = pset_create(10,10)) == NULL ) { out_of_memory(func); return -1; } /* Break the line into components, based on spaces */ while( (p = str_component( strp )) ) { if( pset_add(args, p) == NULL ) { parsemsg( LOG_CRIT, func, ES_NOMEM ); pset_destroy(args); return -1; } } str_endparse( strp ); /* get the service name */ name = new_string((char *)pset_pointer( args, 0 )); if( name == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - Invalid service name" ); pset_destroy(args); return -1; } /* Check to find the '/' for specifying RPC version numbers */ if( (rpcvers = strstr(name, slash)) != NULL ) { *rpcvers = '\0'; rpcvers++; } scp = sc_alloc( name ); if( scp == NULL ) { pset_destroy(args); free( name ); return -1; } /* * sc_alloc makes its own copy of name. At this point, sc_alloc worked * so we will free our copy to avoid leaks. */ free( name ); /* Replicate inetd behavior in this regard. Also makes sure the * service actually works on system where setgroups(0,NULL) doesn't * work. */ SC_GROUPS(scp) = YES; SC_SPECIFY( scp, A_GROUPS ); /* Get the socket type (stream dgram) */ stype = (char *)pset_pointer(args, 1); if( stype == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - Invalid socket type" ); pset_destroy(args); sc_free(scp); return -1; } nvp = nv_find_value( socket_types, stype ); if( nvp == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - Bad socket type: %s", p); pset_destroy(args); sc_free(scp); return -1; } SC_SOCKET_TYPE(scp) = nvp->value; /* Get the protocol type */ proto = (char *)pset_pointer(args,2); if( strstr(proto, "rpc") != NULL ) { int rpcmin, rpcmax; struct rpc_data *rdp = SC_RPCDATA( scp ) ; if( rpcvers == NULL ) { pset_destroy(args); sc_free(scp); return -1; /* uh oh */ } p = strchr(rpcvers, '-'); if( p && parse_int(rpcvers, 10, '-', &rpcmin) == 0 ) { if( parse_base10(p + 1, &rpcmax) || rpcmin > rpcmax ) { pset_destroy(args); sc_free(scp); return -1; } } else { if( parse_base10(rpcvers, &rpcmin) ) { pset_destroy(args); sc_free(scp); return -1; } rpcmax = rpcmin; } /* now have min and max rpc versions */ rdp->rd_min_version = rpcmin; rdp->rd_max_version = rpcmax; rpcproto = strstr(proto, slash); if( rpcproto == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - bad rpc version numbers" ); pset_destroy(args); sc_free(scp); return -1; } *rpcproto = '\0'; rpcproto++; proto = rpcproto; /* Set the RPC type field */ nvp = nv_find_value( service_types, "RPC" ); if ( nvp == NULL ) { parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ; pset_destroy(args); sc_free(scp); return -1; } M_SET(SC_TYPE(scp), nvp->value); } if ( ( pep = getprotobyname( proto ) ) == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - Protocol %s not in /etc/protocols", proto ) ; pset_destroy(args); sc_free(scp); return -1; } SC_PROTONAME(scp) = new_string( proto ) ; if ( SC_PROTONAME(scp) == NULL ) { out_of_memory( func ) ; pset_destroy(args); sc_free(scp); return -1; } SC_PROTOVAL(scp) = pep->p_proto; SC_SPECIFY(scp, A_PROTOCOL); /* Get the wait attribute */ p = (char *)pset_pointer(args, 3); if ( p == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - No value specified for wait" ); sc_free(scp); return -1; } if ( EQ( p, "wait" ) ) SC_WAIT(scp) = YES ; else if ( EQ( p, "nowait" ) ) SC_WAIT(scp) = NO ; else parsemsg( LOG_ERR, func, "inetd.conf - Bad value for wait: %s", p ) ; /* Get the user to run as */ p = (char *)pset_pointer(args, 4); if ( p == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - No value specified for user" ); sc_free(scp); return -1; } if( (group = strstr(p, dot)) ) { *group = '\0'; group++; grp = (struct group *)getgrnam( (char *)group ) ; if ( grp == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - Unknown group: %s", group ) ; pset_destroy(args); sc_free(scp); return -1; } SC_GID(scp) = ((struct group *)grp)->gr_gid; SC_SPECIFY( scp, A_GROUP ); } pw = getpwnam( p ); if ( pw == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - Unknown user: %s", p ) ; pset_destroy(args); sc_free(scp); return -1; } str_fill( pw->pw_passwd, ' ' ); SC_UID(scp) = pw->pw_uid; SC_USER_GID(scp) = pw->pw_gid; /* Get server name, or flag as internal */ p = (char *)pset_pointer(args, 5); if ( p == NULL ) { parsemsg( LOG_ERR, func, "inetd.conf - No value specified for user" ); sc_free(scp); return -1; } if( EQ( p, "internal" ) ) { nvp = nv_find_value( service_types, "INTERNAL" ); if ( nvp == NULL ) { parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ; pset_destroy(args); sc_free(scp); return -1; } M_SET(SC_TYPE(scp), nvp->value); if( EQ( SC_NAME(scp), "time" ) ) { if( EQ( proto, "stream" ) ) SC_ID(scp) = new_string("time-stream"); else SC_ID(scp) = new_string("time-dgram"); } if( EQ( SC_NAME(scp), "daytime" ) ) { if( EQ( proto, "stream" ) ) SC_ID(scp) = new_string("daytime-stream"); else SC_ID(scp) = new_string("daytime-dgram"); } if( EQ( SC_NAME(scp), "chargen" ) ) { if( EQ( proto, "stream" ) ) SC_ID(scp) = new_string("chargen-stream"); else SC_ID(scp) = new_string("chargen-dgram"); } if( EQ( SC_NAME(scp), "echo" ) ) { if( EQ( proto, "stream" ) ) SC_ID(scp) = new_string("echo-stream"); else SC_ID(scp) = new_string("echo-dgram"); } if( EQ( SC_NAME(scp), "discard" ) ) { parsemsg(LOG_WARNING, func, "inetd.conf - service discard not supported"); pset_destroy(args); sc_free(scp); return -1; } } else { SC_SERVER(scp) = new_string( p ); if ( SC_SERVER(scp) == NULL ) { out_of_memory( func ) ; pset_destroy(args); sc_free(scp); return -1; } SC_SPECIFY( scp, A_SERVER); /* Get argv */ SC_SERVER_ARGV(scp) = (char **)argv_alloc(pset_count(args)+1); for( u = 0; u < pset_count(args)-6 ; u++ ) { p = new_string((char *)pset_pointer(args, u+6)); if( p == NULL ) { for ( i = 1 ; i < u ; i++ ) free( SC_SERVER_ARGV(scp)[i] ); free( SC_SERVER_ARGV(scp) ); pset_destroy(args); sc_free(scp); return -1; } SC_SERVER_ARGV(scp)[u] = p; } /* Set the reuse flag, as this is the default for inetd */ nvp = nv_find_value( service_flags, "REUSE" ); if ( nvp == NULL ) { parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ; pset_destroy(args); sc_free(scp); return -1; } M_SET(SC_XFLAGS(scp), nvp->value); /* Set the NOLIBWRAP flag, since inetd doesn't have libwrap built in */ nvp = nv_find_value( service_flags, "NOLIBWRAP" ); if ( nvp == NULL ) { parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ; pset_destroy(args); sc_free(scp); return -1; } M_SET(SC_XFLAGS(scp), nvp->value); /* Set the NAMEINARGS flag, as that's the default for inetd */ nvp = nv_find_value( service_flags, "NAMEINARGS" ); if ( nvp == NULL ) { parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ; pset_destroy(args); sc_free(scp); return (-1); } M_SET(SC_XFLAGS(scp), nvp->value); SC_SPECIFY( scp, A_SERVER_ARGS ); if ( (SC_ID(scp) = new_string( SC_NAME(scp) )) ) SC_PRESENT( scp, A_ID ) ; else { out_of_memory( func ) ; pset_destroy(args); sc_free(scp); return -1; } } SC_SPECIFY( scp, A_PROTOCOL ); SC_SPECIFY( scp, A_USER ); SC_SPECIFY( scp, A_SOCKET_TYPE ); SC_SPECIFY( scp, A_WAIT ); if( ! pset_add(sconfs, scp) ) { out_of_memory( func ); pset_destroy(args); sc_free(scp); return -1; } pset_destroy(args); parsemsg( LOG_DEBUG, func, "added service %s", SC_NAME(scp)); return 0; }
static int allocate_vnic_ctxt(struct hfi1_devdata *dd, struct hfi1_ctxtdata **vnic_ctxt) { struct hfi1_ctxtdata *uctxt; unsigned int ctxt; int ret; if (dd->flags & HFI1_FROZEN) return -EIO; for (ctxt = dd->first_dyn_alloc_ctxt; ctxt < dd->num_rcv_contexts; ctxt++) if (!dd->rcd[ctxt]) break; if (ctxt == dd->num_rcv_contexts) return -EBUSY; uctxt = hfi1_create_ctxtdata(dd->pport, ctxt, dd->node); if (!uctxt) { dd_dev_err(dd, "Unable to create ctxtdata, failing open\n"); return -ENOMEM; } uctxt->flags = HFI1_CAP_KGET(MULTI_PKT_EGR) | HFI1_CAP_KGET(NODROP_RHQ_FULL) | HFI1_CAP_KGET(NODROP_EGR_FULL) | HFI1_CAP_KGET(DMA_RTAIL); uctxt->seq_cnt = 1; /* Allocate and enable a PIO send context */ uctxt->sc = sc_alloc(dd, SC_VNIC, uctxt->rcvhdrqentsize, uctxt->numa_id); ret = uctxt->sc ? 0 : -ENOMEM; if (ret) goto bail; dd_dev_dbg(dd, "allocated vnic send context %u(%u)\n", uctxt->sc->sw_index, uctxt->sc->hw_context); ret = sc_enable(uctxt->sc); if (ret) goto bail; if (dd->num_msix_entries) hfi1_set_vnic_msix_info(uctxt); hfi1_stats.sps_ctxts++; dd_dev_dbg(dd, "created vnic context %d\n", uctxt->ctxt); *vnic_ctxt = uctxt; return ret; bail: /* * hfi1_free_ctxtdata() also releases send_context * structure if uctxt->sc is not null */ dd->rcd[uctxt->ctxt] = NULL; hfi1_free_ctxtdata(dd, uctxt); dd_dev_dbg(dd, "vnic allocation failed. rc %d\n", ret); return ret; }