10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
58452SJohn.Wren.Kennedy@Sun.COM * Common Development and Distribution License (the "License").
68452SJohn.Wren.Kennedy@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
218452SJohn.Wren.Kennedy@Sun.COM
220Sstevel@tonic-gate /*
23*11053SSurya.Prakki@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include <sys/lvm/mdmn_commd.h>
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <stdlib.h> /* getenv, exit */
300Sstevel@tonic-gate #include <signal.h>
310Sstevel@tonic-gate #include <unistd.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <memory.h>
340Sstevel@tonic-gate #include <stropts.h>
350Sstevel@tonic-gate #include <netconfig.h>
360Sstevel@tonic-gate #include <sys/resource.h> /* rlimit */
370Sstevel@tonic-gate #include <syslog.h>
380Sstevel@tonic-gate #include <meta.h>
390Sstevel@tonic-gate
400Sstevel@tonic-gate #ifdef DEBUG
410Sstevel@tonic-gate #define RPC_SVC_FG
420Sstevel@tonic-gate #endif
430Sstevel@tonic-gate
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate * This means we shutdown rpc.mdcommd at some time in the window
460Sstevel@tonic-gate * after 1201 seconds and before 2400 seconds of inactivity.
470Sstevel@tonic-gate */
480Sstevel@tonic-gate #define _RPCSVC_CLOSEDOWN 2400
490Sstevel@tonic-gate
500Sstevel@tonic-gate #ifdef RPC_SVC_FG
510Sstevel@tonic-gate static int _rpcpmstart; /* Started by a port monitor ? */
520Sstevel@tonic-gate #endif /* RPC_SVC_FG */
530Sstevel@tonic-gate /* States a server can be in wrt request */
540Sstevel@tonic-gate
550Sstevel@tonic-gate #define _IDLE 0
560Sstevel@tonic-gate #define _SERVED 1
570Sstevel@tonic-gate
580Sstevel@tonic-gate static int _rpcsvcstate = _IDLE; /* Set when a request is serviced */
590Sstevel@tonic-gate static int _rpcsvccount = 0; /* Number of requests being serviced */
600Sstevel@tonic-gate
618452SJohn.Wren.Kennedy@Sun.COM extern int mdmn_send_svc_2();
628452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_work_svc_2();
638452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_wakeup_initiator_svc_2();
648452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_wakeup_master_svc_2();
658452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_comm_lock_svc_2();
668452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_comm_unlock_svc_2();
678452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_comm_suspend_svc_2();
688452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_comm_resume_svc_2();
698452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_comm_reinit_set_svc_2();
708452SJohn.Wren.Kennedy@Sun.COM extern int *mdmn_comm_msglock_svc_2();
710Sstevel@tonic-gate
720Sstevel@tonic-gate
730Sstevel@tonic-gate static void
_msgout(msg)740Sstevel@tonic-gate _msgout(msg)
750Sstevel@tonic-gate char *msg;
760Sstevel@tonic-gate {
770Sstevel@tonic-gate #ifdef RPC_SVC_FG
780Sstevel@tonic-gate if (_rpcpmstart)
790Sstevel@tonic-gate syslog(LOG_ERR, "%s", msg);
800Sstevel@tonic-gate else
810Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", msg);
820Sstevel@tonic-gate #else
830Sstevel@tonic-gate syslog(LOG_ERR, "%s", msg);
840Sstevel@tonic-gate #endif
850Sstevel@tonic-gate }
860Sstevel@tonic-gate
870Sstevel@tonic-gate static void
closedown(void)880Sstevel@tonic-gate closedown(void)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate if (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {
910Sstevel@tonic-gate int size;
920Sstevel@tonic-gate int i, openfd = 0;
930Sstevel@tonic-gate
940Sstevel@tonic-gate size = svc_max_pollfd;
950Sstevel@tonic-gate for (i = 0; i < size && openfd < 2; i++)
960Sstevel@tonic-gate if (svc_pollfd[i].fd >= 0)
970Sstevel@tonic-gate openfd++;
980Sstevel@tonic-gate if (openfd <= 1)
990Sstevel@tonic-gate exit(0);
1000Sstevel@tonic-gate } else
1010Sstevel@tonic-gate _rpcsvcstate = _IDLE;
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate (void) signal(SIGALRM, (void(*)()) closedown);
1040Sstevel@tonic-gate (void) alarm(_RPCSVC_CLOSEDOWN/2);
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate static void
mdmn_commd_2(rqstp,transp)1088452SJohn.Wren.Kennedy@Sun.COM mdmn_commd_2(rqstp, transp)
1090Sstevel@tonic-gate struct svc_req *rqstp;
1100Sstevel@tonic-gate register SVCXPRT *transp;
1110Sstevel@tonic-gate {
1120Sstevel@tonic-gate union {
1130Sstevel@tonic-gate md_mn_msg_t mdmn_send_1_arg;
1140Sstevel@tonic-gate md_mn_msg_t mdmn_work_1_arg;
1150Sstevel@tonic-gate md_mn_result_t mdmn_wakeup_1_arg;
1160Sstevel@tonic-gate md_mn_msgclass_t mdmn_comm_lock_1_arg;
1170Sstevel@tonic-gate md_mn_msgclass_t mdmn_comm_unlock_1_arg;
1180Sstevel@tonic-gate uint_t mdmn_comm_reinit_1_arg;
1190Sstevel@tonic-gate } argument;
1200Sstevel@tonic-gate char *result;
1210Sstevel@tonic-gate bool_t (*_xdr_argument)(), (*_xdr_result)();
1220Sstevel@tonic-gate char *(*local)();
1230Sstevel@tonic-gate int free_result = 0;
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate _rpcsvccount++;
1260Sstevel@tonic-gate switch (rqstp->rq_proc) {
1270Sstevel@tonic-gate case NULLPROC:
1280Sstevel@tonic-gate (void) svc_sendreply(transp, xdr_void,
1290Sstevel@tonic-gate (char *)NULL);
1300Sstevel@tonic-gate _rpcsvccount--;
1310Sstevel@tonic-gate _rpcsvcstate = _SERVED;
1328452SJohn.Wren.Kennedy@Sun.COM svc_done(transp);
1330Sstevel@tonic-gate return;
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate case mdmn_send:
1360Sstevel@tonic-gate _xdr_argument = xdr_md_mn_msg_t;
1370Sstevel@tonic-gate _xdr_result = xdr_md_mn_result_t;
1380Sstevel@tonic-gate (void) memset((char *)&argument, 0, sizeof (argument));
1390Sstevel@tonic-gate if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) {
1400Sstevel@tonic-gate svcerr_decode(transp);
1418452SJohn.Wren.Kennedy@Sun.COM svc_done(transp);
1420Sstevel@tonic-gate _rpcsvccount--;
1430Sstevel@tonic-gate _rpcsvcstate = _SERVED;
1440Sstevel@tonic-gate return;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate /*
1478452SJohn.Wren.Kennedy@Sun.COM * mdmn_send_2 will not always do a sendreply.
1480Sstevel@tonic-gate * it will register in a table and let the mdmn_wakeup1
1490Sstevel@tonic-gate * do the sendreply for that call.
1500Sstevel@tonic-gate * in order to register properly we need the transp handle
1518452SJohn.Wren.Kennedy@Sun.COM * If we get a 0 back from mdmn_send_svc_2() we have no pending
1528452SJohn.Wren.Kennedy@Sun.COM * RPC in-flight, so we drop the service count.
1530Sstevel@tonic-gate */
1548452SJohn.Wren.Kennedy@Sun.COM if (mdmn_send_svc_2((md_mn_msg_t *)&argument, rqstp) == 0) {
1558452SJohn.Wren.Kennedy@Sun.COM _rpcsvccount--;
1568452SJohn.Wren.Kennedy@Sun.COM _rpcsvcstate = _SERVED;
1578452SJohn.Wren.Kennedy@Sun.COM svc_done(rqstp->rq_xprt);
1588452SJohn.Wren.Kennedy@Sun.COM }
1590Sstevel@tonic-gate
1608452SJohn.Wren.Kennedy@Sun.COM return; /* xdr_free is called by mdmn_wakeup_initiator_svc_2 */
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate case mdmn_work:
1630Sstevel@tonic-gate _xdr_argument = xdr_md_mn_msg_t;
1640Sstevel@tonic-gate _xdr_result = xdr_int;
1658452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_work_svc_2;
1660Sstevel@tonic-gate free_result = 1;
1670Sstevel@tonic-gate break;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate case mdmn_wakeup_master:
1700Sstevel@tonic-gate _xdr_argument = xdr_md_mn_result_t;
1710Sstevel@tonic-gate _xdr_result = xdr_int;
1728452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_wakeup_master_svc_2;
1730Sstevel@tonic-gate free_result = 1;
1740Sstevel@tonic-gate break;
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate case mdmn_wakeup_initiator:
1778452SJohn.Wren.Kennedy@Sun.COM /*
1788452SJohn.Wren.Kennedy@Sun.COM * We must have had an in-flight RPC request to get here,
1798452SJohn.Wren.Kennedy@Sun.COM * so drop the in-flight count.
1808452SJohn.Wren.Kennedy@Sun.COM */
1810Sstevel@tonic-gate _xdr_argument = xdr_md_mn_result_t;
1820Sstevel@tonic-gate _xdr_result = xdr_int;
1838452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_wakeup_initiator_svc_2;
1840Sstevel@tonic-gate free_result = 1;
1858452SJohn.Wren.Kennedy@Sun.COM _rpcsvccount--;
1860Sstevel@tonic-gate break;
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate case mdmn_comm_lock:
1890Sstevel@tonic-gate _xdr_argument = xdr_md_mn_set_and_class_t;
1900Sstevel@tonic-gate _xdr_result = xdr_int;
1918452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_comm_lock_svc_2;
1920Sstevel@tonic-gate break;
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate case mdmn_comm_unlock:
1950Sstevel@tonic-gate _xdr_argument = xdr_md_mn_set_and_class_t;
1960Sstevel@tonic-gate _xdr_result = xdr_int;
1978452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_comm_unlock_svc_2;
1980Sstevel@tonic-gate break;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate case mdmn_comm_suspend:
2010Sstevel@tonic-gate _xdr_argument = xdr_md_mn_set_and_class_t;
2020Sstevel@tonic-gate _xdr_result = xdr_int;
2038452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_comm_suspend_svc_2;
2040Sstevel@tonic-gate break;
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate case mdmn_comm_resume:
2070Sstevel@tonic-gate _xdr_argument = xdr_md_mn_set_and_class_t;
2080Sstevel@tonic-gate _xdr_result = xdr_int;
2098452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_comm_resume_svc_2;
2100Sstevel@tonic-gate break;
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate case mdmn_comm_reinit_set:
2130Sstevel@tonic-gate _xdr_argument = xdr_u_int;
2140Sstevel@tonic-gate _xdr_result = xdr_int;
2158452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_comm_reinit_set_svc_2;
2160Sstevel@tonic-gate break;
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate case mdmn_comm_msglock:
2190Sstevel@tonic-gate _xdr_argument = xdr_md_mn_type_and_lock_t;
2200Sstevel@tonic-gate _xdr_result = xdr_int;
2218452SJohn.Wren.Kennedy@Sun.COM local = (char *(*)()) mdmn_comm_msglock_svc_2;
2220Sstevel@tonic-gate break;
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate default:
2250Sstevel@tonic-gate svcerr_noproc(transp);
2260Sstevel@tonic-gate _rpcsvccount--;
2270Sstevel@tonic-gate _rpcsvcstate = _SERVED;
2288452SJohn.Wren.Kennedy@Sun.COM svc_done(transp);
2290Sstevel@tonic-gate return;
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate (void) memset((char *)&argument, 0, sizeof (argument));
2320Sstevel@tonic-gate if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) {
2330Sstevel@tonic-gate svcerr_decode(transp);
2340Sstevel@tonic-gate _rpcsvccount--;
2350Sstevel@tonic-gate _rpcsvcstate = _SERVED;
2368452SJohn.Wren.Kennedy@Sun.COM svc_done(transp);
2370Sstevel@tonic-gate return;
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate result = (*local)(&argument, rqstp);
2400Sstevel@tonic-gate if (_xdr_result && result != NULL &&
2410Sstevel@tonic-gate !svc_sendreply(transp, _xdr_result, result)) {
2420Sstevel@tonic-gate svcerr_systemerr(transp);
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) {
2450Sstevel@tonic-gate _msgout(gettext("unable to free arguments"));
2468452SJohn.Wren.Kennedy@Sun.COM svc_done(transp);
2470Sstevel@tonic-gate exit(1);
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate if (free_result == 1) {
2510Sstevel@tonic-gate free(result);
2520Sstevel@tonic-gate }
2538452SJohn.Wren.Kennedy@Sun.COM
2548452SJohn.Wren.Kennedy@Sun.COM svc_done(transp);
2550Sstevel@tonic-gate _rpcsvccount--;
2560Sstevel@tonic-gate _rpcsvcstate = _SERVED;
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate /*
2600Sstevel@tonic-gate * atexit handler to flag the lack of commd to the kernel so that we don't
2610Sstevel@tonic-gate * panic due to RPC failures when the commd has been killed.
2620Sstevel@tonic-gate */
2630Sstevel@tonic-gate static void
exit_commd()2640Sstevel@tonic-gate exit_commd()
2650Sstevel@tonic-gate {
2660Sstevel@tonic-gate md_error_t ep = mdnullerror;
2678452SJohn.Wren.Kennedy@Sun.COM syslog(LOG_DAEMON | LOG_DEBUG, gettext("mdcommd exiting"));
2680Sstevel@tonic-gate (void) metaioctl(MD_MN_SET_COMMD_RUNNING, 0, &ep, "rpc.mdcommd");
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate
27162Sjeanm /* ARGSUSED */
27262Sjeanm int
main()2730Sstevel@tonic-gate main()
2740Sstevel@tonic-gate {
2750Sstevel@tonic-gate pid_t pid;
2760Sstevel@tonic-gate int i;
2770Sstevel@tonic-gate md_error_t ep = mdnullerror;
2788452SJohn.Wren.Kennedy@Sun.COM int mode = RPC_SVC_MT_USER;
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate (void) sigset(SIGPIPE, SIG_IGN);
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /*
2838452SJohn.Wren.Kennedy@Sun.COM * Attempt to set MT_USER behaviour for mdcommd service routines.
2848452SJohn.Wren.Kennedy@Sun.COM * If this isn't done, there is a possibility that the transport
2858452SJohn.Wren.Kennedy@Sun.COM * handle might be freed before the thread created by mdmn_send_svc_2
2868452SJohn.Wren.Kennedy@Sun.COM * can use it. A consequence of this is that svc_done() must be
2878452SJohn.Wren.Kennedy@Sun.COM * called on the handle when it's no longer needed.
2888452SJohn.Wren.Kennedy@Sun.COM */
2898452SJohn.Wren.Kennedy@Sun.COM if (rpc_control(RPC_SVC_MTMODE_SET, &mode) == FALSE) {
2908452SJohn.Wren.Kennedy@Sun.COM _msgout(gettext("cannot set MT_USER mode for RPC service"));
2918452SJohn.Wren.Kennedy@Sun.COM exit(1);
2928452SJohn.Wren.Kennedy@Sun.COM }
2938452SJohn.Wren.Kennedy@Sun.COM
2948452SJohn.Wren.Kennedy@Sun.COM /*
2950Sstevel@tonic-gate * If stdin looks like a TLI endpoint, we assume
2960Sstevel@tonic-gate * that we were started by a port monitor. If
2970Sstevel@tonic-gate * t_getstate fails with TBADF, this is not a
2980Sstevel@tonic-gate * TLI endpoint.
2990Sstevel@tonic-gate */
3000Sstevel@tonic-gate if (t_getstate(0) != -1 || t_errno != TBADF) {
3010Sstevel@tonic-gate char *netid;
3020Sstevel@tonic-gate struct netconfig *nconf = NULL;
3030Sstevel@tonic-gate SVCXPRT *transp;
3040Sstevel@tonic-gate int pmclose;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate #ifdef RPC_SVC_FG
3070Sstevel@tonic-gate _rpcpmstart = 1;
3080Sstevel@tonic-gate #endif /* RPC_SVC_FG */
3090Sstevel@tonic-gate openlog("mdmn_commd", LOG_PID, LOG_DAEMON);
3100Sstevel@tonic-gate
3110Sstevel@tonic-gate if ((netid = getenv("NLSPROVIDER")) == NULL) {
3120Sstevel@tonic-gate /* started from inetd */
3130Sstevel@tonic-gate pmclose = 1;
3140Sstevel@tonic-gate } else {
3150Sstevel@tonic-gate if ((nconf = getnetconfigent(netid)) == NULL)
3160Sstevel@tonic-gate _msgout(gettext("cannot get transport info"));
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate pmclose = (t_getstate(0) != T_DATAXFER);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
3210Sstevel@tonic-gate _msgout(gettext("cannot create server handle"));
3220Sstevel@tonic-gate exit(1);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate if (nconf)
3250Sstevel@tonic-gate freenetconfigent(nconf);
3268452SJohn.Wren.Kennedy@Sun.COM if (!svc_reg(transp, MDMN_COMMD, TWO, mdmn_commd_2, 0)) {
3270Sstevel@tonic-gate _msgout(gettext(
3288452SJohn.Wren.Kennedy@Sun.COM "unable to register (MDMN_COMMD, TWO)."));
3290Sstevel@tonic-gate exit(1);
3300Sstevel@tonic-gate }
3310Sstevel@tonic-gate
332*11053SSurya.Prakki@Sun.COM (void) atexit(exit_commd);
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate if (pmclose) {
3350Sstevel@tonic-gate (void) signal(SIGALRM, (void(*)()) closedown);
3360Sstevel@tonic-gate (void) alarm(_RPCSVC_CLOSEDOWN/2);
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate
3398452SJohn.Wren.Kennedy@Sun.COM pid = getpid();
3408452SJohn.Wren.Kennedy@Sun.COM (void) metaioctl(MD_MN_SET_COMMD_RUNNING, (void *)pid, &ep,
3410Sstevel@tonic-gate "rpc.mdcommd");
3420Sstevel@tonic-gate svc_run();
3430Sstevel@tonic-gate exit(1);
3440Sstevel@tonic-gate /* NOTREACHED */
3450Sstevel@tonic-gate } else {
3460Sstevel@tonic-gate #ifndef RPC_SVC_FG
3470Sstevel@tonic-gate #pragma weak closefrom
3480Sstevel@tonic-gate /* LINTED */
3490Sstevel@tonic-gate extern void closefrom();
3500Sstevel@tonic-gate int size;
3510Sstevel@tonic-gate struct rlimit rl;
3520Sstevel@tonic-gate pid = fork();
3530Sstevel@tonic-gate if (pid < 0) {
3540Sstevel@tonic-gate perror(gettext("cannot fork"));
3550Sstevel@tonic-gate exit(1);
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate if (pid)
3580Sstevel@tonic-gate exit(0);
3590Sstevel@tonic-gate if (closefrom != NULL)
3600Sstevel@tonic-gate closefrom(0);
3610Sstevel@tonic-gate else {
3620Sstevel@tonic-gate rl.rlim_max = 0;
363*11053SSurya.Prakki@Sun.COM (void) getrlimit(RLIMIT_NOFILE, &rl);
3640Sstevel@tonic-gate if ((size = rl.rlim_max) == 0)
3650Sstevel@tonic-gate exit(1);
3660Sstevel@tonic-gate for (i = 0; i < size; i++)
3670Sstevel@tonic-gate (void) close(i);
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate i = open("/dev/null", 2);
3700Sstevel@tonic-gate (void) dup2(i, 1);
3710Sstevel@tonic-gate (void) dup2(i, 2);
372*11053SSurya.Prakki@Sun.COM (void) setsid();
3730Sstevel@tonic-gate openlog("mdmn_commd", LOG_PID, LOG_DAEMON);
3740Sstevel@tonic-gate #endif
3750Sstevel@tonic-gate }
3768452SJohn.Wren.Kennedy@Sun.COM if (!svc_create(mdmn_commd_2, MDMN_COMMD, TWO, "tcp")) {
3778452SJohn.Wren.Kennedy@Sun.COM _msgout(gettext("unable to create (MDMN_COMMD, TWO) for tcp."));
3780Sstevel@tonic-gate exit(1);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate
381*11053SSurya.Prakki@Sun.COM (void) atexit(exit_commd);
3820Sstevel@tonic-gate (void) metaioctl(MD_MN_SET_COMMD_RUNNING, (void *)1, &ep,
3830Sstevel@tonic-gate "rpc.mdcommd");
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate svc_run();
3860Sstevel@tonic-gate _msgout(gettext("svc_run returned"));
38762Sjeanm return (1);
3880Sstevel@tonic-gate }
389