xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_door.c (revision 10608:3ce7fe6573e8)
17917SReza.Sabdar@Sun.COM /*
2*10608SReza.Sabdar@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37917SReza.Sabdar@Sun.COM  * Use is subject to license terms.
47917SReza.Sabdar@Sun.COM  */
57917SReza.Sabdar@Sun.COM 
67917SReza.Sabdar@Sun.COM /*
77917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
87917SReza.Sabdar@Sun.COM  *
97917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
107917SReza.Sabdar@Sun.COM  *
117917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
127917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
137917SReza.Sabdar@Sun.COM  * are met:
147917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
157917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
167917SReza.Sabdar@Sun.COM  *
177917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
187917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
197917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
207917SReza.Sabdar@Sun.COM  *	  distribution.
217917SReza.Sabdar@Sun.COM  *
227917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
237917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
247917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
257917SReza.Sabdar@Sun.COM  *	  permission.
267917SReza.Sabdar@Sun.COM  *
277917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
287917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
297917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
307917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
317917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
327917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
337917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
347917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
357917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
367917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
377917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
387917SReza.Sabdar@Sun.COM  */
397917SReza.Sabdar@Sun.COM 
407917SReza.Sabdar@Sun.COM /* This file contains all the door server code */
417917SReza.Sabdar@Sun.COM 
427917SReza.Sabdar@Sun.COM #include <door.h>
437917SReza.Sabdar@Sun.COM #include <alloca.h>
447917SReza.Sabdar@Sun.COM #include <errno.h>
457917SReza.Sabdar@Sun.COM #include <note.h>
467917SReza.Sabdar@Sun.COM #include <libintl.h>
477917SReza.Sabdar@Sun.COM #include <ndmpd_door.h>
487917SReza.Sabdar@Sun.COM #include "ndmpd.h"
497917SReza.Sabdar@Sun.COM 
507917SReza.Sabdar@Sun.COM /* static variables */
517917SReza.Sabdar@Sun.COM static int 	ndmp_door_fildes = -1;
527917SReza.Sabdar@Sun.COM static mutex_t	ndmp_doorsrv_mutex;
537917SReza.Sabdar@Sun.COM 
547917SReza.Sabdar@Sun.COM /* static routines */
557917SReza.Sabdar@Sun.COM static void ndmp_door_server(void *cookie, char *ptr, size_t size,
567917SReza.Sabdar@Sun.COM     door_desc_t *dp, uint_t n_desc);
577917SReza.Sabdar@Sun.COM 
587917SReza.Sabdar@Sun.COM /*
597917SReza.Sabdar@Sun.COM  * Statistics used in ndmpstat command
607917SReza.Sabdar@Sun.COM  */
617917SReza.Sabdar@Sun.COM ndmp_stat_t ndstat;
627917SReza.Sabdar@Sun.COM 
637917SReza.Sabdar@Sun.COM int
ndmp_door_init(void)647917SReza.Sabdar@Sun.COM ndmp_door_init(void)
657917SReza.Sabdar@Sun.COM {
667917SReza.Sabdar@Sun.COM 	int fd;
677917SReza.Sabdar@Sun.COM 
687917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_doorsrv_mutex);
697917SReza.Sabdar@Sun.COM 
707917SReza.Sabdar@Sun.COM 	if (ndmp_door_fildes != -1) {
717917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
727917SReza.Sabdar@Sun.COM 		    "ndmp_door_init: ndmpd service is already running.");
737917SReza.Sabdar@Sun.COM 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
747917SReza.Sabdar@Sun.COM 		return (0);
757917SReza.Sabdar@Sun.COM 	}
767917SReza.Sabdar@Sun.COM 
777917SReza.Sabdar@Sun.COM 	if ((ndmp_door_fildes = door_create(ndmp_door_server,
787917SReza.Sabdar@Sun.COM 	    NULL, DOOR_UNREF)) < 0) {
797917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Could not create door.");
807917SReza.Sabdar@Sun.COM 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
817917SReza.Sabdar@Sun.COM 		return (-1);
827917SReza.Sabdar@Sun.COM 	}
837917SReza.Sabdar@Sun.COM 
847917SReza.Sabdar@Sun.COM 	(void) unlink(NDMP_DOOR_SVC);
857917SReza.Sabdar@Sun.COM 
867917SReza.Sabdar@Sun.COM 	if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
877917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Can't create %s: %m.",
887917SReza.Sabdar@Sun.COM 		    NDMP_DOOR_SVC);
897917SReza.Sabdar@Sun.COM 		(void) door_revoke(ndmp_door_fildes);
907917SReza.Sabdar@Sun.COM 		ndmp_door_fildes = -1;
917917SReza.Sabdar@Sun.COM 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
927917SReza.Sabdar@Sun.COM 		return (-1);
937917SReza.Sabdar@Sun.COM 	}
947917SReza.Sabdar@Sun.COM 
957917SReza.Sabdar@Sun.COM 	(void) close(fd);
967917SReza.Sabdar@Sun.COM 	(void) fdetach(NDMP_DOOR_SVC);
977917SReza.Sabdar@Sun.COM 
987917SReza.Sabdar@Sun.COM 	if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) {
997917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "ndmp_door_init: fattach failed %m");
1007917SReza.Sabdar@Sun.COM 		(void) door_revoke(ndmp_door_fildes);
1017917SReza.Sabdar@Sun.COM 		ndmp_door_fildes = -1;
1027917SReza.Sabdar@Sun.COM 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
1037917SReza.Sabdar@Sun.COM 		return (-1);
1047917SReza.Sabdar@Sun.COM 	}
1057917SReza.Sabdar@Sun.COM 
1067917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
1077917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_doorsrv_mutex);
1087917SReza.Sabdar@Sun.COM 	return (0);
1097917SReza.Sabdar@Sun.COM }
1107917SReza.Sabdar@Sun.COM 
1117917SReza.Sabdar@Sun.COM void
ndmp_door_fini(void)1127917SReza.Sabdar@Sun.COM ndmp_door_fini(void)
1137917SReza.Sabdar@Sun.COM {
1147917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_doorsrv_mutex);
1157917SReza.Sabdar@Sun.COM 
1167917SReza.Sabdar@Sun.COM 	if (ndmp_door_fildes != -1) {
1177917SReza.Sabdar@Sun.COM 		(void) fdetach(NDMP_DOOR_SVC);
1187917SReza.Sabdar@Sun.COM 		(void) door_revoke(ndmp_door_fildes);
1197917SReza.Sabdar@Sun.COM 		ndmp_door_fildes = -1;
1207917SReza.Sabdar@Sun.COM 	}
1217917SReza.Sabdar@Sun.COM 
1227917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_doorsrv_mutex);
1237917SReza.Sabdar@Sun.COM }
1247917SReza.Sabdar@Sun.COM 
1257917SReza.Sabdar@Sun.COM boolean_t
ndmp_door_check(void)1267917SReza.Sabdar@Sun.COM ndmp_door_check(void)
1277917SReza.Sabdar@Sun.COM {
1287917SReza.Sabdar@Sun.COM 	door_info_t info;
1297917SReza.Sabdar@Sun.COM 	int door;
1307917SReza.Sabdar@Sun.COM 
1317917SReza.Sabdar@Sun.COM 	if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0)
1327917SReza.Sabdar@Sun.COM 		return (0);
1337917SReza.Sabdar@Sun.COM 
1347917SReza.Sabdar@Sun.COM 	if (door_info(door, &info) < 0) {
1357917SReza.Sabdar@Sun.COM 		(void) close(door);
1367917SReza.Sabdar@Sun.COM 		return (0);
1377917SReza.Sabdar@Sun.COM 	}
1387917SReza.Sabdar@Sun.COM 
1397917SReza.Sabdar@Sun.COM 	if (info.di_target > 0) {
1407917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
1417917SReza.Sabdar@Sun.COM 		    "Service already running: pid %ld", info.di_target);
1427917SReza.Sabdar@Sun.COM 		(void) close(door);
1437917SReza.Sabdar@Sun.COM 		return (1);
1447917SReza.Sabdar@Sun.COM 	}
1457917SReza.Sabdar@Sun.COM 
1467917SReza.Sabdar@Sun.COM 	(void) close(door);
1477917SReza.Sabdar@Sun.COM 	return (0);
1487917SReza.Sabdar@Sun.COM }
1497917SReza.Sabdar@Sun.COM 
1507917SReza.Sabdar@Sun.COM /* door server */
1517917SReza.Sabdar@Sun.COM /*ARGSUSED*/
1527917SReza.Sabdar@Sun.COM void
ndmp_door_server(void * cookie,char * ptr,size_t size,door_desc_t * dp,uint_t n_desc)1537917SReza.Sabdar@Sun.COM ndmp_door_server(void *cookie, char *ptr, size_t size,
1547917SReza.Sabdar@Sun.COM     door_desc_t *dp, uint_t n_desc)
1557917SReza.Sabdar@Sun.COM {
1567917SReza.Sabdar@Sun.COM 	NOTE(ARGUNUSED(cookie,dp,n_desc))
1577917SReza.Sabdar@Sun.COM 	int req_type;
1587917SReza.Sabdar@Sun.COM 	char *buf;
1597917SReza.Sabdar@Sun.COM 	int buflen;
1607917SReza.Sabdar@Sun.COM 	unsigned int used;
1617917SReza.Sabdar@Sun.COM 	ndmp_door_ctx_t *dec_ctx;
1627917SReza.Sabdar@Sun.COM 	ndmp_door_ctx_t *enc_ctx;
1637917SReza.Sabdar@Sun.COM 	unsigned int dec_status;
1647917SReza.Sabdar@Sun.COM 	unsigned int enc_status;
1657917SReza.Sabdar@Sun.COM 
1667917SReza.Sabdar@Sun.COM 	dec_ctx = ndmp_door_decode_start(ptr, size);
1677917SReza.Sabdar@Sun.COM 	if (dec_ctx == 0)
1687917SReza.Sabdar@Sun.COM 		return;
1697917SReza.Sabdar@Sun.COM 
1707917SReza.Sabdar@Sun.COM 	req_type = ndmp_door_get_uint32(dec_ctx);
1717917SReza.Sabdar@Sun.COM 	buflen = NDMP_DOOR_SIZE;
1727917SReza.Sabdar@Sun.COM 
1737917SReza.Sabdar@Sun.COM 	if ((buf = alloca(buflen)) == NULL) {
1747917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Out of memory.");
1757917SReza.Sabdar@Sun.COM 		(void) ndmp_door_decode_finish(dec_ctx);
1767917SReza.Sabdar@Sun.COM 		return;
1777917SReza.Sabdar@Sun.COM 	}
1787917SReza.Sabdar@Sun.COM 
1797917SReza.Sabdar@Sun.COM 	enc_ctx = ndmp_door_encode_start(buf, buflen);
1807917SReza.Sabdar@Sun.COM 	if (enc_ctx == 0) {
1817917SReza.Sabdar@Sun.COM 		(void) ndmp_door_decode_finish(dec_ctx);
1827917SReza.Sabdar@Sun.COM 		return;
1837917SReza.Sabdar@Sun.COM 	}
1847917SReza.Sabdar@Sun.COM 
185*10608SReza.Sabdar@Sun.COM 	if (req_type != NDMP_GET_STAT)
186*10608SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type);
1877917SReza.Sabdar@Sun.COM 
1887917SReza.Sabdar@Sun.COM 	switch (req_type) {
1897917SReza.Sabdar@Sun.COM 	case NDMP_GET_DOOR_STATUS: {
1907917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
1917917SReza.Sabdar@Sun.COM 		break;
1927917SReza.Sabdar@Sun.COM 		}
1937917SReza.Sabdar@Sun.COM 	case NDMP_DEVICES_GET_INFO: {
1947917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
1957917SReza.Sabdar@Sun.COM 		ndmpd_get_devs(enc_ctx);
1967917SReza.Sabdar@Sun.COM 		break;
1977917SReza.Sabdar@Sun.COM 		}
1987917SReza.Sabdar@Sun.COM 	case NDMP_SHOW: {
1997917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
2007917SReza.Sabdar@Sun.COM 		ndmp_connect_list_get(enc_ctx);
2017917SReza.Sabdar@Sun.COM 		break;
2027917SReza.Sabdar@Sun.COM 		}
2037917SReza.Sabdar@Sun.COM 	case NDMP_TERMINATE_SESSION_ID: {
2047917SReza.Sabdar@Sun.COM 		int status, id;
2057917SReza.Sabdar@Sun.COM 		id = ndmp_door_get_int32(dec_ctx);
2067917SReza.Sabdar@Sun.COM 		status = ndmpd_connect_kill_id(id);
2077917SReza.Sabdar@Sun.COM 		if (status == -1) /* session not found */
2087917SReza.Sabdar@Sun.COM 			ndmp_door_put_int32(enc_ctx,
2097917SReza.Sabdar@Sun.COM 			    NDMP_DOOR_SRV_SUCCESS);
2107917SReza.Sabdar@Sun.COM 		else
2117917SReza.Sabdar@Sun.COM 			ndmp_door_put_int32(enc_ctx,
2127917SReza.Sabdar@Sun.COM 			    NDMP_DOOR_SRV_SUCCESS);
2137917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, status);
2147917SReza.Sabdar@Sun.COM 		break;
2157917SReza.Sabdar@Sun.COM 		}
2167917SReza.Sabdar@Sun.COM 
2177917SReza.Sabdar@Sun.COM 	case NDMP_GET_STAT:
2187917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
2197917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_trun);
2207917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_twait);
2217917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_nbk);
2227917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_nrs);
2237917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_rfile);
2247917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_wfile);
2257917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_rdisk);
2267917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_wdisk);
2277917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_rtape);
2287917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_wtape);
2297917SReza.Sabdar@Sun.COM 		break;
2307917SReza.Sabdar@Sun.COM 
2317917SReza.Sabdar@Sun.COM 	default:
2327917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
2337917SReza.Sabdar@Sun.COM 		    "ndmp_door_server: Invalid request type 0x%x", req_type);
2347917SReza.Sabdar@Sun.COM 		goto decode_error;
2357917SReza.Sabdar@Sun.COM 	}
2367917SReza.Sabdar@Sun.COM 
2377917SReza.Sabdar@Sun.COM 	if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0)
2387917SReza.Sabdar@Sun.COM 		goto decode_error;
2397917SReza.Sabdar@Sun.COM 
2407917SReza.Sabdar@Sun.COM 	if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0)
2417917SReza.Sabdar@Sun.COM 		goto encode_error;
2427917SReza.Sabdar@Sun.COM 
2437917SReza.Sabdar@Sun.COM 	(void) door_return(buf, used, NULL, 0);
2447917SReza.Sabdar@Sun.COM 
2457917SReza.Sabdar@Sun.COM 	return;
2467917SReza.Sabdar@Sun.COM 
2477917SReza.Sabdar@Sun.COM decode_error:
2487917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
2497917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint32(enc_ctx, dec_status);
2507917SReza.Sabdar@Sun.COM 	(void) ndmp_door_encode_finish(enc_ctx, &used);
2517917SReza.Sabdar@Sun.COM 	(void) door_return(buf, used, NULL, 0);
2527917SReza.Sabdar@Sun.COM 	return;
2537917SReza.Sabdar@Sun.COM 
2547917SReza.Sabdar@Sun.COM encode_error:
2557917SReza.Sabdar@Sun.COM 	enc_ctx = ndmp_door_encode_start(buf, buflen);
2567917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
2577917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint32(enc_ctx, enc_status);
2587917SReza.Sabdar@Sun.COM 	(void) ndmp_door_encode_finish(enc_ctx, &used);
2597917SReza.Sabdar@Sun.COM 	(void) door_return(buf, used, NULL, 0);
2607917SReza.Sabdar@Sun.COM }
261