示例#1
0
文件: tirpc_svc_6.c 项目: kraj/ltp
void *server_thread_process(void *arg)
{
	//Server process in a thread
	int err = 0;

	if (run_mode == 1) {
		printf("Server #%d launched\n", atoi(arg));
		printf("Server Nb : %d\n", progNum + atoi(arg));
	}

	svc_unreg(progNum + (long)arg, VERSNUM);

	err = svc_create(exm_proc, progNum + atoi(arg), VERSNUM, "VISIBLE");

	if (err == 0) {
		fprintf(stderr, "Cannot create service.\n");
		exit(1);
	}

	svc_run();

	fprintf(stderr, "svc_run() returned.  ERROR has occurred.\n");
	svc_unreg(progNum, VERSNUM);

	pthread_exit(0);
}
void *my_thread_process(void *arg)
{
	SVCXPRT *transp = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
	int i;

	if (run_mode == 1) {
		fprintf(stderr, "Thread %d\n", atoi(arg));
	}

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *)NULL) {
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		printf("err nconf\n");
		pthread_exit(1);
	}

	transp = svc_tli_create(RPC_ANYFD, nconf, (struct t_bind *)NULL, 0, 0);

	for (i = 0; i < callNb; i++) {
		svc_unreg(progNum + atoi(arg), VERSNUM);
		svc_reg(transp, progNum + atoi(arg), VERSNUM, exm_proc, nconf);

		svc_unreg(progNum + atoi(arg), VERSNUM);

		//If we are here, test was sucessfull
		thread_array_result[atoi(arg)] += 1;
	}

	pthread_exit(0);
}
示例#3
0
文件: tirpc_svc_11.c 项目: 1587/ltp
//****************************************//
//***           Main Function          ***//
//****************************************//
int main(int argn, char *argc[])
{
	//Server parameter is : argc[1] : Server Program Number
	//                                          others arguments depend on server program
	int progNum = atoi(argc[1]);
	SVCXPRT *transp = NULL;
	struct netconfig *nconf;

	//Initialization
	svc_unreg(progNum, VERSNUM);

	if ((nconf = getnetconfigent("udp")) == NULL) {
		fprintf(stderr, "Cannot get netconfig entry for UDP\n");
		exit(1);
	}

	transp = svc_tp_create(exm_proc, progNum, VERSNUM, nconf);

	if (transp == NULL) {
		fprintf(stderr, "Cannot create service.\n");
		exit(1);
	}

	if (!svc_reg(transp, progNum, VERSNUM, exm_proc, nconf)) {
		fprintf(stderr, "svc_reg failed!!\n");
		exit(1);
	}

	svc_run();

	fprintf(stderr, "svc_run() returned.  ERROR has occurred.\n");
	svc_unreg(progNum, VERSNUM);

	return 1;
}
示例#4
0
int main(int argn, char *argc[]) 
{
	//Server parameter is : argc[1] : Server Program Number
	//					    others arguments depend on server program
	int run_mode = 0;
	int progNum = atoi(argc[1]);
	char *simplePing_proc();
	bool_t rslt;
    char nettype[16] = "visible";

	if (run_mode)
	{
		printf("Prog Num : %d\n", progNum);
	}

	svc_unreg(progNum, VERSNUM);

	rslt = rpc_reg(progNum, VERSNUM, PROCSIMPLEPING, (void *)simplePing_proc,
					(xdrproc_t)xdr_int, (xdrproc_t)xdr_int, nettype);

	svc_run();

	fprintf(stderr, "svc_run() returned.  ERROR has occurred.\n");
	svc_unreg(progNum, VERSNUM);

	return 1;
}
示例#5
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   argc[3] : Number of testes function calls
	//					   other arguments depend on test case
	
	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1; //Default test result set to FAILED
	int progNum = atoi(argc[2]);
	SVCXPRT *transp = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
    int nbCall = atoi(argc[3]);
	int nbOk = 0;
	int i;
	
	//Initialization
    if (run_mode)
    {
    	printf("Before creation\n");
		printf("nconf : %d\n", nconf);
	}

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL)
	{
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		printf("err nconf\n");
		exit(1);
	}

	transp = svc_tli_create(RPC_ANYFD, nconf, 
                            (struct t_bind *)NULL,
                            0, 0);
    
    svc_unreg(progNum, VERSNUM);
    
    for (i = 0; i < nbCall; i++)
	{
		svc_reg(transp, progNum, VERSNUM,
            exm_proc, nconf);
    
    	svc_unreg(progNum, VERSNUM);
    }
    
    //If we are here, test has passed
    test_status = 0;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);	
	
	return test_status;
}
示例#6
0
文件: fmd_rpc.c 项目: andreiw/polaris
void
fmd_rpc_fini(void)
{
	rpcprog_t prog;

	svc_exit(); /* force svc_run() threads to exit */

	(void) fmd_conf_getprop(fmd.d_conf, "rpc.adm.prog", &prog);
	svc_unreg(prog, FMD_ADM_VERSION_1);

	(void) fmd_conf_getprop(fmd.d_conf, "rpc.api.prog", &prog);
	svc_unreg(prog, FMD_API_VERSION_1);
}
示例#7
0
文件: 1-basic.c 项目: ystk/debian-ltp
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case
	
	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1; //Default test result set to FAILED
	int progNum = atoi(argc[2]);
	char nettype[16] = "visible";
	SVCXPRT *svcr;
        struct netconfig *nconf;

        //Test initialization
        if ((nconf = getnetconfigent("tcp")) == (struct netconfig *)NULL){
        	fprintf(stderr, "Cannot get netconfig entry for TCP\n");
		exit(1);
        }

	
	if (run_mode == 1)
	{
		printf("Server : %s\n", argc[1]);
		printf("Server # %d\n", progNum);
	}	
	
	//First create server
	svcr = svc_tp_create(exm_proc, progNum, VERSNUM, nconf);
	
	//Prepare destruction
	svc_unreg(progNum, VERSNUM);
	
	//then destroy it
	svc_destroy(svcr);
	
	svc_unreg(progNum, VERSNUM);
	
	//If we are here, test has passed
	test_status = 0;
	
	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);
	
	return test_status;
}
示例#8
0
//****************************************//
//***           Main Function          ***//
//****************************************//
int main(int argn, char *argc[])
{
	//Server parameter is : argc[1] : Server Program Number
	//					    others arguments depend on server program
	int run_mode = 0;
	int progNum = atoi(argc[1]);
	//char *simplePing_proc();
	bool_t rslt;
    //char nettype[16] = "visible";

	SVCXPRT *transp;
	struct netconfig *nconf;

	if ((nconf = getnetconfigent("udp")) == NULL)
    {
    	fprintf(stderr, "Cannot get netconfig entry for UDP\n");
    	exit(1);
	}

	transp = svc_tp_create(exm_proc, progNum, VERSNUM,
                           nconf);

	if (transp == NULL) {
    	fprintf(stderr, "Cannot create service.\n");
    	exit(1);
	}

	svc_run();

	fprintf(stderr, "svc_run() returned.  ERROR has occurred.\n");
	svc_unreg(progNum, VERSNUM);

	return 1;
}
示例#9
0
文件: tirpc_rpc_reg.c 项目: 1587/ltp
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1;	//Default test result set to FAILED
	int progNum = atoi(argc[2]);

	char *registeredProc();
	bool_t rslt;

	if (run_mode == 1) {
		printf("Server #%d\n", progNum);
	}

	svc_unreg(progNum, VERSNUM);
	rslt = rpc_reg(progNum, VERSNUM, PROCNUM, (void *)registeredProc,
		       (xdrproc_t) xdr_int, (xdrproc_t) xdr_int, "visible");
	test_status = (rslt == 0) ? 0 : 1;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
示例#10
0
文件: tirpc_svc_3.c 项目: 1587/ltp
//****************************************//
//***           Main Function          ***//
//****************************************//
int main(int argn, char *argc[])
{
	int progNum = atoi(argc[1]);

	SVCXPRT *transp;
	struct netconfig *nconf;

	if ((nconf = getnetconfigent("udp")) == NULL) {
		fprintf(stderr, "Cannot get netconfig entry for UDP\n");
		exit(1);
	}

	transp = svc_tp_create(exm_proc, progNum, VERSNUM, nconf);

	if (transp == NULL) {
		fprintf(stderr, "Cannot create service.\n");
		exit(1);
	}

	svc_run();

	fprintf(stderr, "svc_run() returned.  ERROR has occurred.\n");
	svc_unreg(progNum, VERSNUM);

	return 1;
}
示例#11
0
文件: tirpc_cleaner.c 项目: 1587/ltp
int main(int argn, char *argc[])
{
	//Server parameter is : argc[1] : Server Program Number
	int progNum = atoi((char *)argc[1]);

	svc_unreg(progNum, VERSNUM);

	return 0;
}
示例#12
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1; //Default test result set to FAILED
	int progNum = atoi(argc[2]);
	char nettype[16] = "visible";
	int transpnum;

	if (run_mode == 1)
	{
		printf("Server : %s\n", argc[1]);
		printf("Server # %d\n", progNum);
		printf("Net : %s\n", nettype);
		printf("Server transport : %d\n", transpnum);
	}

	transpnum = svc_create(exm_proc, progNum, VERSNUM, nettype);

	if (run_mode == 1)
	{
		printf("Server transport after creation : %d\n", transpnum);
	}

	svc_unreg(progNum, VERSNUM);

	test_status = (transpnum != 0) ? 0 : 1;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
示例#13
0
int
main(int ac, char *av[])
{
	char *dir = "/";
	int allflag = 0;
	int df_allflag = 0;
	int opt_cnt = 0;
	int maxservers = 1;	/* zero allows inifinte number of threads */
	int maxservers_set = 0;
	int logmaxservers = 0;
	int pid;
	int i;
	char *provider = (char *)NULL;
	char *df_provider = (char *)NULL;
	struct protob *protobp0, *protobp;
	NETSELDECL(proto) = NULL;
	NETSELDECL(df_proto) = NULL;
	NETSELPDECL(providerp);
	char *defval;
	boolean_t can_do_mlp;
	uint_t dss_npaths = 0;
	char **dss_pathnames = NULL;
	sigset_t sgset;
	char name[PATH_MAX], value[PATH_MAX];
	int ret, bufsz;

	int pipe_fd = -1;

	MyName = *av;

	/*
	 * Initializations that require more privileges than we need to run.
	 */
	(void) _create_daemon_lock(NFSD, DAEMON_UID, DAEMON_GID);
	svcsetprio();

	can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP);
	if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
	    DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS,
	    can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) {
		(void) fprintf(stderr, "%s should be run with"
		    " sufficient privileges\n", av[0]);
		exit(1);
	}

	(void) enable_extended_FILE_stdio(-1, -1);

	/*
	 * Read in the values from SMF first before we check
	 * command line options so the options override SMF values.
	 */
	bufsz = PATH_MAX;
	ret = nfs_smf_get_prop("max_connections", value, DEFAULT_INSTANCE,
	    SCF_TYPE_INTEGER, NFSD, &bufsz);
	if (ret == SA_OK) {
		errno = 0;
		max_conns_allowed = strtol(value, (char **)NULL, 10);
		if (errno != 0)
			max_conns_allowed = -1;
	}

	bufsz = PATH_MAX;
	ret = nfs_smf_get_prop("listen_backlog", value, DEFAULT_INSTANCE,
	    SCF_TYPE_INTEGER, NFSD, &bufsz);
	if (ret == SA_OK) {
		errno = 0;
		listen_backlog = strtol(value, (char **)NULL, 10);
		if (errno != 0) {
			listen_backlog = 32;
		}
	}

	bufsz = PATH_MAX;
	ret = nfs_smf_get_prop("protocol", value, DEFAULT_INSTANCE,
	    SCF_TYPE_ASTRING, NFSD, &bufsz);
	if ((ret == SA_OK) && strlen(value) > 0) {
		df_proto = strdup(value);
		opt_cnt++;
		if (strncasecmp("ALL", value, 3) == 0) {
			free(df_proto);
			df_proto = NULL;
			df_allflag = 1;
		}
	}

	bufsz = PATH_MAX;
	ret = nfs_smf_get_prop("device", value, DEFAULT_INSTANCE,
	    SCF_TYPE_ASTRING, NFSD, &bufsz);
	if ((ret == SA_OK) && strlen(value) > 0) {
		df_provider = strdup(value);
		opt_cnt++;
	}

	bufsz = PATH_MAX;
	ret = nfs_smf_get_prop("servers", value, DEFAULT_INSTANCE,
	    SCF_TYPE_INTEGER, NFSD, &bufsz);
	if (ret == SA_OK) {
		errno = 0;
		maxservers = strtol(value, (char **)NULL, 10);
		if (errno != 0)
			maxservers = 1;
		else
			maxservers_set = 1;
	}

	bufsz = 4;
	ret = nfs_smf_get_prop("server_versmin", value, DEFAULT_INSTANCE,
	    SCF_TYPE_INTEGER, NFSD, &bufsz);
	if (ret == SA_OK)
		nfs_server_vers_min = strtol(value, (char **)NULL, 10);

	bufsz = 4;
	ret = nfs_smf_get_prop("server_versmax", value, DEFAULT_INSTANCE,
	    SCF_TYPE_INTEGER, NFSD, &bufsz);
	if (ret == SA_OK)
		nfs_server_vers_max = strtol(value, (char **)NULL, 10);

	bufsz = PATH_MAX;
	ret = nfs_smf_get_prop("server_delegation", value, DEFAULT_INSTANCE,
	    SCF_TYPE_ASTRING, NFSD, &bufsz);
	if (ret == SA_OK)
		if (strncasecmp(value, "off", 3) == 0)
			nfs_server_delegation = FALSE;

	/*
	 * Conflict options error messages.
	 */
	if (opt_cnt > 1) {
		(void) fprintf(stderr, "\nConflicting options, only one of "
		    "the following options can be specified\n"
		    "in SMF:\n"
		    "\tprotocol=ALL\n"
		    "\tprotocol=protocol\n"
		    "\tdevice=devicename\n\n");
		usage();
	}
	opt_cnt = 0;

	while ((i = getopt(ac, av, "ac:p:s:t:l:")) != EOF) {
		switch (i) {
		case 'a':
			free(df_proto);
			df_proto = NULL;
			free(df_provider);
			df_provider = NULL;

			allflag = 1;
			opt_cnt++;
			break;

		case 'c':
			max_conns_allowed = atoi(optarg);
			break;

		case 'p':
			proto = optarg;
			df_allflag = 0;
			opt_cnt++;
			break;

		/*
		 * DSS: NFSv4 distributed stable storage.
		 *
		 * This is a Contracted Project Private interface, for
		 * the sole use of Sun Cluster HA-NFS. See PSARC/2006/313.
		 */
		case 's':
			if (strlen(optarg) < MAXPATHLEN) {
				/* first "-s" option encountered? */
				if (dss_pathnames == NULL) {
					/*
					 * Allocate maximum possible space
					 * required given cmdline arg count;
					 * "-s <path>" consumes two args.
					 */
					size_t sz = (ac / 2) * sizeof (char *);
					dss_pathnames = (char **)malloc(sz);
					if (dss_pathnames == NULL) {
						(void) fprintf(stderr, "%s: "
						    "dss paths malloc failed\n",
						    av[0]);
						exit(1);
					}
					(void) memset(dss_pathnames, 0, sz);
				}
				dss_pathnames[dss_npaths] = optarg;
				dss_npaths++;
			} else {
				(void) fprintf(stderr,
				    "%s: -s pathname too long.\n", av[0]);
			}
			break;

		case 't':
			provider = optarg;
			df_allflag = 0;
			opt_cnt++;
			break;

		case 'l':
			listen_backlog = atoi(optarg);
			break;

		case '?':
			usage();
			/* NOTREACHED */
		}
	}

	allflag = df_allflag;
	if (proto == NULL)
		proto = df_proto;
	if (provider == NULL)
		provider = df_provider;

	/*
	 * Conflict options error messages.
	 */
	if (opt_cnt > 1) {
		(void) fprintf(stderr, "\nConflicting options, only one of "
		    "the following options can be specified\n"
		    "on the command line:\n"
		    "\t-a\n"
		    "\t-p protocol\n"
		    "\t-t transport\n\n");
		usage();
	}

	if (proto != NULL &&
	    strncasecmp(proto, NC_UDP, strlen(NC_UDP)) == 0) {
		if (nfs_server_vers_max == NFS_V4) {
			if (nfs_server_vers_min == NFS_V4) {
				fprintf(stderr,
				    "NFS version 4 is not supported "
				    "with the UDP protocol.  Exiting\n");
				exit(3);
			} else {
				fprintf(stderr,
				    "NFS version 4 is not supported "
				    "with the UDP protocol.\n");
			}
		}
	}

	/*
	 * If there is exactly one more argument, it is the number of
	 * servers.
	 */
	if (optind == ac - 1) {
		maxservers = atoi(av[optind]);
		maxservers_set = 1;
	}
	/*
	 * If there are two or more arguments, then this is a usage error.
	 */
	else if (optind < ac - 1)
		usage();
	/*
	 * Check the ranges for min/max version specified
	 */
	else if ((nfs_server_vers_min > nfs_server_vers_max) ||
	    (nfs_server_vers_min < NFS_VERSMIN) ||
	    (nfs_server_vers_max > NFS_VERSMAX))
		usage();
	/*
	 * There are no additional arguments, and we haven't set maxservers
	 * explicitly via the config file, we use a default number of
	 * servers.  We will log this.
	 */
	else if (maxservers_set == 0)
		logmaxservers = 1;

	/*
	 * Basic Sanity checks on options
	 *
	 * max_conns_allowed must be positive, except for the special
	 * value of -1 which is used internally to mean unlimited, -1 isn't
	 * documented but we allow it anyway.
	 *
	 * maxservers must be positive
	 * listen_backlog must be positive or zero
	 */
	if (((max_conns_allowed != -1) && (max_conns_allowed <= 0)) ||
	    (listen_backlog < 0) || (maxservers <= 0)) {
		usage();
	}

	/*
	 * Set current dir to server root
	 */
	if (chdir(dir) < 0) {
		(void) fprintf(stderr, "%s:  ", MyName);
		perror(dir);
		exit(1);
	}

#ifndef DEBUG
	pipe_fd = daemonize_init();
#endif

	openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON);

	/*
	 * establish our lock on the lock file and write our pid to it.
	 * exit if some other process holds the lock, or if there's any
	 * error in writing/locking the file.
	 */
	pid = _enter_daemon_lock(NFSD);
	switch (pid) {
	case 0:
		break;
	case -1:
		fprintf(stderr, "error locking for %s: %s\n", NFSD,
		    strerror(errno));
		exit(2);
	default:
		/* daemon was already running */
		exit(0);
	}

	/*
	 * If we've been given a list of paths to be used for distributed
	 * stable storage, and provided we're going to run a version
	 * that supports it, setup the DSS paths.
	 */
	if (dss_pathnames != NULL && nfs_server_vers_max >= DSS_VERSMIN) {
		if (dss_init(dss_npaths, dss_pathnames) != 0) {
			fprintf(stderr, "%s", "dss_init failed. Exiting.\n");
			exit(1);
		}
	}

	/*
	 * Block all signals till we spawn other
	 * threads.
	 */
	(void) sigfillset(&sgset);
	(void) thr_sigsetmask(SIG_BLOCK, &sgset, NULL);

	if (logmaxservers) {
		fprintf(stderr,
		    "Number of servers not specified. Using default of %d.\n",
		    maxservers);
	}

	/*
	 * Make sure to unregister any previous versions in case the
	 * user is reconfiguring the server in interesting ways.
	 */
	svc_unreg(NFS_PROGRAM, NFS_VERSION);
	svc_unreg(NFS_PROGRAM, NFS_V3);
	svc_unreg(NFS_PROGRAM, NFS_V4);
	svc_unreg(NFS_ACL_PROGRAM, NFS_ACL_V2);
	svc_unreg(NFS_ACL_PROGRAM, NFS_ACL_V3);

	/*
	 * Set up kernel RPC thread pool for the NFS server.
	 */
	if (nfssvcpool(maxservers)) {
		fprintf(stderr, "Can't set up kernel NFS service: %s. "
		    "Exiting.\n", strerror(errno));
		exit(1);
	}

	/*
	 * Set up blocked thread to do LWP creation on behalf of the kernel.
	 */
	if (svcwait(NFS_SVCPOOL_ID)) {
		fprintf(stderr, "Can't set up NFS pool creator: %s. Exiting.\n",
		    strerror(errno));
		exit(1);
	}

	/*
	 * RDMA start and stop thread.
	 * Per pool RDMA listener creation and
	 * destructor thread.
	 *
	 * start rdma services and block in the kernel.
	 * (only if proto or provider is not set to TCP or UDP)
	 */
	if ((proto == NULL) && (provider == NULL)) {
		if (svcrdma(NFS_SVCPOOL_ID, nfs_server_vers_min,
		    nfs_server_vers_max, nfs_server_delegation)) {
			fprintf(stderr,
			    "Can't set up RDMA creator thread : %s\n",
			    strerror(errno));
		}
	}

	/*
	 * Now open up for signal delivery
	 */

	(void) thr_sigsetmask(SIG_UNBLOCK, &sgset, NULL);
	sigset(SIGTERM, sigflush);
	sigset(SIGUSR1, quiesce);

	/*
	 * Build a protocol block list for registration.
	 */
	protobp0 = protobp = (struct protob *)malloc(sizeof (struct protob));
	protobp->serv = "NFS";
	protobp->versmin = nfs_server_vers_min;
	protobp->versmax = nfs_server_vers_max;
	protobp->program = NFS_PROGRAM;

	protobp->next = (struct protob *)malloc(sizeof (struct protob));
	protobp = protobp->next;
	protobp->serv = "NFS_ACL";		/* not used */
	protobp->versmin = nfs_server_vers_min;
	/* XXX - this needs work to get the version just right */
	protobp->versmax = (nfs_server_vers_max > NFS_ACL_V3) ?
	    NFS_ACL_V3 : nfs_server_vers_max;
	protobp->program = NFS_ACL_PROGRAM;
	protobp->next = (struct protob *)NULL;

	if (allflag) {
		if (do_all(protobp0, nfssvc) == -1) {
			fprintf(stderr, "setnetconfig failed : %s\n",
			    strerror(errno));
			exit(1);
		}
	} else if (proto) {
		/* there's more than one match for the same protocol */
		struct netconfig *nconf;
		NCONF_HANDLE *nc;
		bool_t	protoFound = FALSE;
		if ((nc = setnetconfig()) == (NCONF_HANDLE *) NULL) {
			fprintf(stderr, "setnetconfig failed : %s\n",
			    strerror(errno));
			goto done;
		}
		while (nconf = getnetconfig(nc)) {
			if (strcmp(nconf->nc_proto, proto) == 0) {
				protoFound = TRUE;
				do_one(nconf->nc_device, NULL,
				    protobp0, nfssvc);
			}
		}
		(void) endnetconfig(nc);
		if (protoFound == FALSE) {
			fprintf(stderr,
			    "couldn't find netconfig entry for protocol %s\n",
			    proto);
		}
	} else if (provider)
		do_one(provider, proto, protobp0, nfssvc);
	else {
		for (providerp = defaultproviders;
		    *providerp != NULL; providerp++) {
			provider = *providerp;
			do_one(provider, NULL, protobp0, nfssvc);
		}
	}
done:

	free(protobp);
	free(protobp0);

	if (num_fds == 0) {
		fprintf(stderr, "Could not start NFS service for any protocol."
		    " Exiting.\n");
		exit(1);
	}

	end_listen_fds = num_fds;

	/*
	 * nfsd is up and running as far as we are concerned.
	 */
	daemonize_fini(pipe_fd);

	/*
	 * Get rid of unneeded privileges.
	 */
	__fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION,
	    PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL);

	/*
	 * Poll for non-data control events on the transport descriptors.
	 */
	poll_for_action();

	/*
	 * If we get here, something failed in poll_for_action().
	 */
	return (1);
}
示例#14
0
文件: mountd.c 项目: andreiw/polaris
int
main(int argc, char *argv[])
{
	int	pid;
	int	c;
	int	rpc_svc_mode = RPC_SVC_MT_AUTO;
	int	maxthreads;
	int	maxrecsz = RPC_MAXDATASIZE;
	bool_t	exclbind = TRUE;
	bool_t	can_do_mlp;
	long	thr_flags = (THR_NEW_LWP|THR_DAEMON);

	/*
	 * Mountd requires uid 0 for:
	 *	/etc/rmtab updates (we could chown it to daemon)
	 *	/etc/dfs/dfstab reading (it wants to lock out share which
	 *		doesn't do any locking before first truncate;
	 *		NFS share does; should use fcntl locking instead)
	 *	Needed privileges:
	 *		auditing
	 *		nfs syscall
	 *		file dac search (so it can stat all files)
	 *	Optional privileges:
	 *		MLP
	 */
	can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP);
	if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, -1, -1,
	    PRIV_SYS_NFS, PRIV_PROC_AUDIT, PRIV_FILE_DAC_SEARCH,
	    can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) {
		(void) fprintf(stderr,
			"%s must be run as with sufficient privileges\n",
			argv[0]);
		exit(1);
	}

	maxthreads = 0;

	while ((c = getopt(argc, argv, "vrm:")) != EOF) {
		switch (c) {
		case 'v':
			verbose++;
			break;
		case 'r':
			rejecting = 1;
			break;
		case 'm':
			maxthreads = atoi(optarg);
			if (maxthreads < 1) {
				(void) fprintf(stderr,
	"%s: must specify positive maximum threads count, using default\n",
						argv[0]);
				maxthreads = 0;
			}
			break;
		}
	}

	/*
	 * Read in the NFS version values from config file.
	 */
	if ((defopen(NFSADMIN)) == 0) {
		char *defval;
		int defvers;

		if ((defval = defread("NFS_SERVER_VERSMIN=")) != NULL) {
			errno = 0;
			defvers = strtol(defval, (char **)NULL, 10);
			if (errno == 0) {
				mount_vers_min = defvers;
				/*
				 * special because NFSv2 is
				 * supported by mount v1 & v2
				 */
				if (defvers == NFS_VERSION)
					mount_vers_min = MOUNTVERS;
			}
		}
		if ((defval = defread("NFS_SERVER_VERSMAX=")) != NULL) {
			errno = 0;
			defvers = strtol(defval, (char **)NULL, 10);
			if (errno == 0) {
				mount_vers_max = defvers;
			}
		}

		/* close defaults file */
		defopen(NULL);
	}

	/*
	 * Sanity check versions,
	 * even though we may get versions > MOUNTVERS3, we still need
	 * to start nfsauth service, so continue on regardless of values.
	 */
	if (mount_vers_min > mount_vers_max) {
		syslog(LOG_NOTICE, "NFS_SERVER_VERSMIN > NFS_SERVER_VERSMAX");
		mount_vers_max = mount_vers_min;
	}
	(void) setlocale(LC_ALL, "");
	(void) rwlock_init(&sharetab_lock, USYNC_THREAD, NULL);
	(void) mutex_init(&mnttab_lock, USYNC_THREAD, NULL);
	netgroup_init();

#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	/* Don't drop core if the NFS module isn't loaded. */
	(void) signal(SIGSYS, SIG_IGN);

	(void) signal(SIGHUP, sigexit);
	(void) signal(SIGCLD, sigexit);

	switch (fork()) {
	case 0:		/* child */
		break;
	case -1:
		perror("mountd: can't fork");
		exit(1);
	default:	/* parent */
		for (;;)
			(void) pause();
		/* NOTREACHED */
	}

	(void) signal(SIGHUP, SIG_DFL);
	(void) signal(SIGCLD, SIG_DFL);

	/*
	 * If we coredump it'll be in /core
	 */
	if (chdir("/") < 0)
		syslog(LOG_ERR, "chdir /: %m");

	/*
	 * Close existing file descriptors, open "/dev/null" as
	 * standard input, output, and error, and detach from
	 * controlling terminal.
	 */
	closefrom(0);
	(void) open("/dev/null", O_RDONLY);
	(void) open("/dev/null", O_WRONLY);
	(void) dup(1);
	(void) setsid();

	openlog("mountd", LOG_PID, LOG_DAEMON);

	/*
	 * establish our lock on the lock file and write our pid to it.
	 * exit if some other process holds the lock, or if there's any
	 * error in writing/locking the file.
	 */
	pid = _enter_daemon_lock(MOUNTD);
	switch (pid) {
	case 0:
		break;
	case -1:
		syslog(LOG_ERR, "error locking for %s: %s", MOUNTD,
		    strerror(errno));
		exit(2);
	default:
		/* daemon was already running */
		exit(0);
	}

	audit_mountd_setup();	/* BSM */

	/*
	 * Tell RPC that we want automatic thread mode.
	 * A new thread will be spawned for each request.
	 */
	if (!rpc_control(RPC_SVC_MTMODE_SET, &rpc_svc_mode)) {
		syslog(LOG_ERR, "unable to set automatic MT mode");
		exit(1);
	}

	/*
	 * Enable non-blocking mode and maximum record size checks for
	 * connection oriented transports.
	 */
	if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) {
		syslog(LOG_INFO, "unable to set RPC max record size");
	}

	/*
	 * Prevent our non-priv udp and tcp ports bound w/wildcard addr
	 * from being hijacked by a bind to a more specific addr.
	 */
	if (!rpc_control(__RPC_SVC_EXCLBIND_SET, &exclbind)) {
		syslog(LOG_INFO,  "warning: unable to set udp/tcp EXCLBIND");
	}

	/*
	 * If the -m argument was specified, then set the
	 * maximum number of threads to the value specified.
	 */
	if (maxthreads > 0 && !rpc_control(RPC_SVC_THRMAX_SET, &maxthreads)) {
		syslog(LOG_ERR, "unable to set maxthreads");
		exit(1);
	}

	/*
	 * Make sure to unregister any previous versions in case the
	 * user is reconfiguring the server in interesting ways.
	 */
	svc_unreg(MOUNTPROG, MOUNTVERS);
	svc_unreg(MOUNTPROG, MOUNTVERS_POSIX);
	svc_unreg(MOUNTPROG, MOUNTVERS3);

	/*
	 * Create the nfsauth thread with same signal disposition
	 * as the main thread. We need to create a separate thread
	 * since mountd() will be both an RPC server (for remote
	 * traffic) _and_ a doors server (for kernel upcalls).
	 */
	if (thr_create(NULL, 0, nfsauth_svc, 0, thr_flags, &nfsauth_thread)) {
		syslog(LOG_ERR, gettext("Failed to create NFSAUTH svc thread"));
		exit(2);
	}

	/*
	 * Create datagram and connection oriented services
	 */
	if (mount_vers_max >= MOUNTVERS) {
		if (svc_create(mnt, MOUNTPROG, MOUNTVERS, "datagram_v") == 0) {
			syslog(LOG_ERR,
				"couldn't register datagram_v MOUNTVERS");
			exit(1);
		}
		if (svc_create(mnt, MOUNTPROG, MOUNTVERS, "circuit_v") == 0) {
			syslog(LOG_ERR,
				"couldn't register circuit_v MOUNTVERS");
			exit(1);
		}
	}
	if (mount_vers_max >= MOUNTVERS_POSIX) {
		if (svc_create(mnt, MOUNTPROG, MOUNTVERS_POSIX,
							"datagram_v") == 0) {
			syslog(LOG_ERR,
				"couldn't register datagram_v MOUNTVERS_POSIX");
			exit(1);
		}
		if (svc_create(mnt, MOUNTPROG, MOUNTVERS_POSIX,
							"circuit_v") == 0) {
			syslog(LOG_ERR,
				"couldn't register circuit_v MOUNTVERS_POSIX");
			exit(1);
		}
	}

	if (mount_vers_max >= MOUNTVERS3) {
		if (svc_create(mnt, MOUNTPROG, MOUNTVERS3, "datagram_v") == 0) {
			syslog(LOG_ERR,
				"couldn't register datagram_v MOUNTVERS3");
			exit(1);
		}
		if (svc_create(mnt, MOUNTPROG, MOUNTVERS3, "circuit_v") == 0) {
			syslog(LOG_ERR,
				"couldn't register circuit_v MOUNTVERS3");
			exit(1);
		}
	}

	/*
	 * Start serving
	 */
	rmtab_load();
	(void) kill(getppid(), SIGHUP);

	/* Get rid of the most dangerous basic privileges. */
	__fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_INFO, PRIV_PROC_SESSION,
	    (char *)NULL);

	svc_run();
	syslog(LOG_ERR, "Error: svc_run shouldn't have returned");
	abort();
	/* NOTREACHED */
	return (0);
}
示例#15
0
文件: fmd_rpc.c 项目: andreiw/polaris
/*
 * We use our own private version of svc_create() which registers our services
 * only on loopback transports and enables an option whereby Solaris ucreds
 * are associated with each connection, permitting us to check privilege bits.
 */
static int
fmd_rpc_svc_create_local(void (*disp)(struct svc_req *, SVCXPRT *),
    rpcprog_t prog, rpcvers_t vers, uint_t ssz, uint_t rsz, int force)
{
	struct netconfig *ncp;
	struct netbuf buf;
	SVCXPRT *xprt;
	void *hdl;
	int fd, n = 0;

	char door[PATH_MAX];
	time_t tm;

	if ((hdl = setnetconfig()) == NULL) {
		fmd_error(EFMD_RPC_REG, "failed to iterate over "
		    "netconfig database: %s\n", nc_sperror());
		return (fmd_set_errno(EFMD_RPC_REG));
	}

	if (force)
		svc_unreg(prog, vers); /* clear stale rpcbind registrations */

	buf.buf = alloca(_SS_MAXSIZE);
	buf.maxlen = _SS_MAXSIZE;
	buf.len = 0;

	while ((ncp = getnetconfig(hdl)) != NULL) {
		if (strcmp(ncp->nc_protofmly, NC_LOOPBACK) != 0)
			continue;

		if (!force && rpcb_getaddr(prog, vers, ncp, &buf, HOST_SELF)) {
			(void) endnetconfig(hdl);
			return (fmd_set_errno(EFMD_RPC_BOUND));
		}

		if ((fd = t_open(ncp->nc_device, O_RDWR, NULL)) == -1) {
			fmd_error(EFMD_RPC_REG, "failed to open %s: %s\n",
			    ncp->nc_device, t_strerror(t_errno));
			continue;
		}

		svc_fd_negotiate_ucred(fd); /* enable ucred option on xprt */

		if ((xprt = svc_tli_create(fd, ncp, NULL, ssz, rsz)) == NULL) {
			(void) t_close(fd);
			continue;
		}

		if (svc_reg(xprt, prog, vers, disp, ncp) == FALSE) {
			fmd_error(EFMD_RPC_REG, "failed to register "
			    "rpc service on %s\n", ncp->nc_netid);
			svc_destroy(xprt);
			continue;
		}

		n++;
	}

	(void) endnetconfig(hdl);

	/*
	 * If we failed to register services (n == 0) because rpcbind is down,
	 * then check to see if the RPC door file exists before attempting an
	 * svc_door_create(), which cleverly destroys any existing door file.
	 * The RPC APIs have no stable errnos, so we use rpcb_gettime() as a
	 * hack to determine if rpcbind itself is down.
	 */
	if (!force && n == 0 && rpcb_gettime(HOST_SELF, &tm) == FALSE &&
	    snprintf(door, sizeof (door), RPC_DOOR_RENDEZVOUS,
	    prog, vers) > 0 && access(door, F_OK) == 0)
		return (fmd_set_errno(EFMD_RPC_BOUND));

	/*
	 * Attempt to create a door server for the RPC program as well.  Limit
	 * the maximum request size for the door transport to the receive size.
	 */
	if ((xprt = svc_door_create(disp, prog, vers, ssz)) == NULL) {
		fmd_error(EFMD_RPC_REG, "failed to create door for "
		    "rpc service 0x%lx/0x%lx\n", prog, vers);
	} else {
		(void) svc_control(xprt, SVCSET_CONNMAXREC, &rsz);
		n++;
	}

	return (n);
}