xref: /illumos-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_door.c (revision 674cb4b09c0706bc1cb658e79f39997d43bad8a0)
12654012fSReza Sabdar /*
2*674cb4b0SReza Sabdar  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
32654012fSReza Sabdar  * Use is subject to license terms.
42654012fSReza Sabdar  */
52654012fSReza Sabdar 
62654012fSReza Sabdar /*
72654012fSReza Sabdar  * BSD 3 Clause License
82654012fSReza Sabdar  *
92654012fSReza Sabdar  * Copyright (c) 2007, The Storage Networking Industry Association.
102654012fSReza Sabdar  *
112654012fSReza Sabdar  * Redistribution and use in source and binary forms, with or without
122654012fSReza Sabdar  * modification, are permitted provided that the following conditions
132654012fSReza Sabdar  * are met:
142654012fSReza Sabdar  * 	- Redistributions of source code must retain the above copyright
152654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
162654012fSReza Sabdar  *
172654012fSReza Sabdar  * 	- Redistributions in binary form must reproduce the above copyright
182654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer in
192654012fSReza Sabdar  *	  the documentation and/or other materials provided with the
202654012fSReza Sabdar  *	  distribution.
212654012fSReza Sabdar  *
222654012fSReza Sabdar  *	- Neither the name of The Storage Networking Industry Association (SNIA)
232654012fSReza Sabdar  *	  nor the names of its contributors may be used to endorse or promote
242654012fSReza Sabdar  *	  products derived from this software without specific prior written
252654012fSReza Sabdar  *	  permission.
262654012fSReza Sabdar  *
272654012fSReza Sabdar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
282654012fSReza Sabdar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
292654012fSReza Sabdar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
302654012fSReza Sabdar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
312654012fSReza Sabdar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
322654012fSReza Sabdar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
332654012fSReza Sabdar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
342654012fSReza Sabdar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
352654012fSReza Sabdar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
362654012fSReza Sabdar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
372654012fSReza Sabdar  * POSSIBILITY OF SUCH DAMAGE.
382654012fSReza Sabdar  */
392654012fSReza Sabdar 
402654012fSReza Sabdar /* This file contains all the door server code */
412654012fSReza Sabdar 
422654012fSReza Sabdar #include <door.h>
432654012fSReza Sabdar #include <alloca.h>
442654012fSReza Sabdar #include <errno.h>
452654012fSReza Sabdar #include <note.h>
462654012fSReza Sabdar #include <libintl.h>
472654012fSReza Sabdar #include <ndmpd_door.h>
482654012fSReza Sabdar #include "ndmpd.h"
492654012fSReza Sabdar 
502654012fSReza Sabdar /* static variables */
512654012fSReza Sabdar static int 	ndmp_door_fildes = -1;
522654012fSReza Sabdar static mutex_t	ndmp_doorsrv_mutex;
532654012fSReza Sabdar 
542654012fSReza Sabdar /* static routines */
552654012fSReza Sabdar static void ndmp_door_server(void *cookie, char *ptr, size_t size,
562654012fSReza Sabdar     door_desc_t *dp, uint_t n_desc);
572654012fSReza Sabdar 
582654012fSReza Sabdar /*
592654012fSReza Sabdar  * Statistics used in ndmpstat command
602654012fSReza Sabdar  */
612654012fSReza Sabdar ndmp_stat_t ndstat;
622654012fSReza Sabdar 
632654012fSReza Sabdar int
ndmp_door_init(void)642654012fSReza Sabdar ndmp_door_init(void)
652654012fSReza Sabdar {
662654012fSReza Sabdar 	int fd;
672654012fSReza Sabdar 
682654012fSReza Sabdar 	(void) mutex_lock(&ndmp_doorsrv_mutex);
692654012fSReza Sabdar 
702654012fSReza Sabdar 	if (ndmp_door_fildes != -1) {
712654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG,
722654012fSReza Sabdar 		    "ndmp_door_init: ndmpd service is already running.");
732654012fSReza Sabdar 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
742654012fSReza Sabdar 		return (0);
752654012fSReza Sabdar 	}
762654012fSReza Sabdar 
772654012fSReza Sabdar 	if ((ndmp_door_fildes = door_create(ndmp_door_server,
782654012fSReza Sabdar 	    NULL, DOOR_UNREF)) < 0) {
792654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Could not create door.");
802654012fSReza Sabdar 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
812654012fSReza Sabdar 		return (-1);
822654012fSReza Sabdar 	}
832654012fSReza Sabdar 
842654012fSReza Sabdar 	(void) unlink(NDMP_DOOR_SVC);
852654012fSReza Sabdar 
862654012fSReza Sabdar 	if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
872654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Can't create %s: %m.",
882654012fSReza Sabdar 		    NDMP_DOOR_SVC);
892654012fSReza Sabdar 		(void) door_revoke(ndmp_door_fildes);
902654012fSReza Sabdar 		ndmp_door_fildes = -1;
912654012fSReza Sabdar 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
922654012fSReza Sabdar 		return (-1);
932654012fSReza Sabdar 	}
942654012fSReza Sabdar 
952654012fSReza Sabdar 	(void) close(fd);
962654012fSReza Sabdar 	(void) fdetach(NDMP_DOOR_SVC);
972654012fSReza Sabdar 
982654012fSReza Sabdar 	if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) {
992654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "ndmp_door_init: fattach failed %m");
1002654012fSReza Sabdar 		(void) door_revoke(ndmp_door_fildes);
1012654012fSReza Sabdar 		ndmp_door_fildes = -1;
1022654012fSReza Sabdar 		(void) mutex_unlock(&ndmp_doorsrv_mutex);
1032654012fSReza Sabdar 		return (-1);
1042654012fSReza Sabdar 	}
1052654012fSReza Sabdar 
1062654012fSReza Sabdar 	NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
1072654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_doorsrv_mutex);
1082654012fSReza Sabdar 	return (0);
1092654012fSReza Sabdar }
1102654012fSReza Sabdar 
1112654012fSReza Sabdar void
ndmp_door_fini(void)1122654012fSReza Sabdar ndmp_door_fini(void)
1132654012fSReza Sabdar {
1142654012fSReza Sabdar 	(void) mutex_lock(&ndmp_doorsrv_mutex);
1152654012fSReza Sabdar 
1162654012fSReza Sabdar 	if (ndmp_door_fildes != -1) {
1172654012fSReza Sabdar 		(void) fdetach(NDMP_DOOR_SVC);
1182654012fSReza Sabdar 		(void) door_revoke(ndmp_door_fildes);
1192654012fSReza Sabdar 		ndmp_door_fildes = -1;
1202654012fSReza Sabdar 	}
1212654012fSReza Sabdar 
1222654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_doorsrv_mutex);
1232654012fSReza Sabdar }
1242654012fSReza Sabdar 
1252654012fSReza Sabdar boolean_t
ndmp_door_check(void)1262654012fSReza Sabdar ndmp_door_check(void)
1272654012fSReza Sabdar {
1282654012fSReza Sabdar 	door_info_t info;
1292654012fSReza Sabdar 	int door;
1302654012fSReza Sabdar 
1312654012fSReza Sabdar 	if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0)
1322654012fSReza Sabdar 		return (0);
1332654012fSReza Sabdar 
1342654012fSReza Sabdar 	if (door_info(door, &info) < 0) {
1352654012fSReza Sabdar 		(void) close(door);
1362654012fSReza Sabdar 		return (0);
1372654012fSReza Sabdar 	}
1382654012fSReza Sabdar 
1392654012fSReza Sabdar 	if (info.di_target > 0) {
1402654012fSReza Sabdar 		NDMP_LOG(LOG_ERR,
1412654012fSReza Sabdar 		    "Service already running: pid %ld", info.di_target);
1422654012fSReza Sabdar 		(void) close(door);
1432654012fSReza Sabdar 		return (1);
1442654012fSReza Sabdar 	}
1452654012fSReza Sabdar 
1462654012fSReza Sabdar 	(void) close(door);
1472654012fSReza Sabdar 	return (0);
1482654012fSReza Sabdar }
1492654012fSReza Sabdar 
1502654012fSReza Sabdar /* door server */
1512654012fSReza Sabdar /*ARGSUSED*/
1522654012fSReza Sabdar void
ndmp_door_server(void * cookie,char * ptr,size_t size,door_desc_t * dp,uint_t n_desc)1532654012fSReza Sabdar ndmp_door_server(void *cookie, char *ptr, size_t size,
1542654012fSReza Sabdar     door_desc_t *dp, uint_t n_desc)
1552654012fSReza Sabdar {
1562654012fSReza Sabdar 	NOTE(ARGUNUSED(cookie,dp,n_desc))
1572654012fSReza Sabdar 	int req_type;
1582654012fSReza Sabdar 	char *buf;
1592654012fSReza Sabdar 	int buflen;
1602654012fSReza Sabdar 	unsigned int used;
1612654012fSReza Sabdar 	ndmp_door_ctx_t *dec_ctx;
1622654012fSReza Sabdar 	ndmp_door_ctx_t *enc_ctx;
1632654012fSReza Sabdar 	unsigned int dec_status;
1642654012fSReza Sabdar 	unsigned int enc_status;
1652654012fSReza Sabdar 
1662654012fSReza Sabdar 	dec_ctx = ndmp_door_decode_start(ptr, size);
1672654012fSReza Sabdar 	if (dec_ctx == 0)
1682654012fSReza Sabdar 		return;
1692654012fSReza Sabdar 
1702654012fSReza Sabdar 	req_type = ndmp_door_get_uint32(dec_ctx);
1712654012fSReza Sabdar 	buflen = NDMP_DOOR_SIZE;
1722654012fSReza Sabdar 
1732654012fSReza Sabdar 	if ((buf = alloca(buflen)) == NULL) {
1742654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Out of memory.");
1752654012fSReza Sabdar 		(void) ndmp_door_decode_finish(dec_ctx);
1762654012fSReza Sabdar 		return;
1772654012fSReza Sabdar 	}
1782654012fSReza Sabdar 
1792654012fSReza Sabdar 	enc_ctx = ndmp_door_encode_start(buf, buflen);
1802654012fSReza Sabdar 	if (enc_ctx == 0) {
1812654012fSReza Sabdar 		(void) ndmp_door_decode_finish(dec_ctx);
1822654012fSReza Sabdar 		return;
1832654012fSReza Sabdar 	}
1842654012fSReza Sabdar 
185*674cb4b0SReza Sabdar 	if (req_type != NDMP_GET_STAT)
1862654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type);
1872654012fSReza Sabdar 
1882654012fSReza Sabdar 	switch (req_type) {
1892654012fSReza Sabdar 	case NDMP_GET_DOOR_STATUS: {
1902654012fSReza Sabdar 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
1912654012fSReza Sabdar 		break;
1922654012fSReza Sabdar 		}
1932654012fSReza Sabdar 	case NDMP_DEVICES_GET_INFO: {
1942654012fSReza Sabdar 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
1952654012fSReza Sabdar 		ndmpd_get_devs(enc_ctx);
1962654012fSReza Sabdar 		break;
1972654012fSReza Sabdar 		}
1982654012fSReza Sabdar 	case NDMP_SHOW: {
1992654012fSReza Sabdar 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
2002654012fSReza Sabdar 		ndmp_connect_list_get(enc_ctx);
2012654012fSReza Sabdar 		break;
2022654012fSReza Sabdar 		}
2032654012fSReza Sabdar 	case NDMP_TERMINATE_SESSION_ID: {
2042654012fSReza Sabdar 		int status, id;
2052654012fSReza Sabdar 		id = ndmp_door_get_int32(dec_ctx);
2062654012fSReza Sabdar 		status = ndmpd_connect_kill_id(id);
2072654012fSReza Sabdar 		if (status == -1) /* session not found */
2082654012fSReza Sabdar 			ndmp_door_put_int32(enc_ctx,
2092654012fSReza Sabdar 			    NDMP_DOOR_SRV_SUCCESS);
2102654012fSReza Sabdar 		else
2112654012fSReza Sabdar 			ndmp_door_put_int32(enc_ctx,
2122654012fSReza Sabdar 			    NDMP_DOOR_SRV_SUCCESS);
2132654012fSReza Sabdar 		ndmp_door_put_int32(enc_ctx, status);
2142654012fSReza Sabdar 		break;
2152654012fSReza Sabdar 		}
2162654012fSReza Sabdar 
2172654012fSReza Sabdar 	case NDMP_GET_STAT:
2182654012fSReza Sabdar 		ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
2192654012fSReza Sabdar 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_trun);
2202654012fSReza Sabdar 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_twait);
2212654012fSReza Sabdar 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_nbk);
2222654012fSReza Sabdar 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_nrs);
2232654012fSReza Sabdar 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_rfile);
2242654012fSReza Sabdar 		ndmp_door_put_uint32(enc_ctx, ndstat.ns_wfile);
2252654012fSReza Sabdar 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_rdisk);
2262654012fSReza Sabdar 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_wdisk);
2272654012fSReza Sabdar 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_rtape);
2282654012fSReza Sabdar 		ndmp_door_put_uint64(enc_ctx, ndstat.ns_wtape);
2292654012fSReza Sabdar 		break;
2302654012fSReza Sabdar 
2312654012fSReza Sabdar 	default:
2322654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG,
2332654012fSReza Sabdar 		    "ndmp_door_server: Invalid request type 0x%x", req_type);
2342654012fSReza Sabdar 		goto decode_error;
2352654012fSReza Sabdar 	}
2362654012fSReza Sabdar 
2372654012fSReza Sabdar 	if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0)
2382654012fSReza Sabdar 		goto decode_error;
2392654012fSReza Sabdar 
2402654012fSReza Sabdar 	if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0)
2412654012fSReza Sabdar 		goto encode_error;
2422654012fSReza Sabdar 
2432654012fSReza Sabdar 	(void) door_return(buf, used, NULL, 0);
2442654012fSReza Sabdar 
2452654012fSReza Sabdar 	return;
2462654012fSReza Sabdar 
2472654012fSReza Sabdar decode_error:
2482654012fSReza Sabdar 	ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
2492654012fSReza Sabdar 	ndmp_door_put_uint32(enc_ctx, dec_status);
2502654012fSReza Sabdar 	(void) ndmp_door_encode_finish(enc_ctx, &used);
2512654012fSReza Sabdar 	(void) door_return(buf, used, NULL, 0);
2522654012fSReza Sabdar 	return;
2532654012fSReza Sabdar 
2542654012fSReza Sabdar encode_error:
2552654012fSReza Sabdar 	enc_ctx = ndmp_door_encode_start(buf, buflen);
2562654012fSReza Sabdar 	ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
2572654012fSReza Sabdar 	ndmp_door_put_uint32(enc_ctx, enc_status);
2582654012fSReza Sabdar 	(void) ndmp_door_encode_finish(enc_ctx, &used);
2592654012fSReza Sabdar 	(void) door_return(buf, used, NULL, 0);
2602654012fSReza Sabdar }
261