12654012fSReza Sabdar /*
22654012fSReza Sabdar  * Copyright 2008 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 #include <locale.h>
402654012fSReza Sabdar #include <stdlib.h>
412654012fSReza Sabdar #include <strings.h>
422654012fSReza Sabdar #include <unistd.h>
432654012fSReza Sabdar #include <fcntl.h>
442654012fSReza Sabdar #include <door.h>
452654012fSReza Sabdar #include <thread.h>
462654012fSReza Sabdar #include <ndmpd_door.h>
472654012fSReza Sabdar #include <libndmp.h>
482654012fSReza Sabdar 
492654012fSReza Sabdar static int ndmp_door_fildes = -1;
502654012fSReza Sabdar static char *buf;
512654012fSReza Sabdar static ndmp_door_ctx_t *dec_ctx;
522654012fSReza Sabdar static ndmp_door_ctx_t *enc_ctx;
532654012fSReza Sabdar static door_arg_t arg;
542654012fSReza Sabdar static mutex_t ndmp_lock = DEFAULTMUTEX;
552654012fSReza Sabdar 
562654012fSReza Sabdar static int ndmp_door_setup(int opcode);
572654012fSReza Sabdar static int ndmp_door_call(void);
582654012fSReza Sabdar static int ndmp_door_fini(void);
592654012fSReza Sabdar 
602654012fSReza Sabdar /* ndmp library APIs */
612654012fSReza Sabdar int
ndmp_get_devinfo(ndmp_devinfo_t ** dip,size_t * size)622654012fSReza Sabdar ndmp_get_devinfo(ndmp_devinfo_t **dip, size_t *size)
632654012fSReza Sabdar {
642654012fSReza Sabdar 	ndmp_devinfo_t *dipptr;
652654012fSReza Sabdar 	int i;
662654012fSReza Sabdar 	int opcode = NDMP_DEVICES_GET_INFO;
672654012fSReza Sabdar 
682654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
692654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
702654012fSReza Sabdar 		goto err;
712654012fSReza Sabdar 
722654012fSReza Sabdar 	if (ndmp_door_call())
732654012fSReza Sabdar 		goto err;
742654012fSReza Sabdar 
752654012fSReza Sabdar 	/* get the number of devices available */
762654012fSReza Sabdar 	*size = ndmp_door_get_uint32(dec_ctx);
772654012fSReza Sabdar 
782654012fSReza Sabdar 	*dip = malloc(sizeof (ndmp_devinfo_t) * *size);
792654012fSReza Sabdar 	if (!*dip) {
802654012fSReza Sabdar 		free(buf);
812654012fSReza Sabdar 		ndmp_errno = ENDMP_MEM_ALLOC;
822654012fSReza Sabdar 		goto err;
832654012fSReza Sabdar 	}
842654012fSReza Sabdar 	dipptr = *dip;
852654012fSReza Sabdar 	for (i = 0; i < *size; i++, dipptr++) {
862654012fSReza Sabdar 		dipptr->nd_dev_type = ndmp_door_get_int32(dec_ctx);
872654012fSReza Sabdar 		dipptr->nd_name = ndmp_door_get_string(dec_ctx);
882654012fSReza Sabdar 		dipptr->nd_lun = ndmp_door_get_int32(dec_ctx);
892654012fSReza Sabdar 		dipptr->nd_sid = ndmp_door_get_int32(dec_ctx);
902654012fSReza Sabdar 		dipptr->nd_vendor = ndmp_door_get_string(dec_ctx);
912654012fSReza Sabdar 		dipptr->nd_product = ndmp_door_get_string(dec_ctx);
922654012fSReza Sabdar 		dipptr->nd_revision = ndmp_door_get_string(dec_ctx);
93*7bc22e45SReza Sabdar 		dipptr->nd_serial = ndmp_door_get_string(dec_ctx);
94*7bc22e45SReza Sabdar 		dipptr->nd_wwn = ndmp_door_get_string(dec_ctx);
952654012fSReza Sabdar 	}
962654012fSReza Sabdar 	if (ndmp_door_fini()) {
972654012fSReza Sabdar 		free(*dip);
982654012fSReza Sabdar 		goto err;
992654012fSReza Sabdar 	}
1002654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
1012654012fSReza Sabdar 	return (0);
1022654012fSReza Sabdar err:
1032654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
1042654012fSReza Sabdar 	return (-1);
1052654012fSReza Sabdar }
1062654012fSReza Sabdar 
1072654012fSReza Sabdar void
ndmp_get_devinfo_free(ndmp_devinfo_t * dip,size_t size)1082654012fSReza Sabdar ndmp_get_devinfo_free(ndmp_devinfo_t *dip, size_t size)
1092654012fSReza Sabdar {
1102654012fSReza Sabdar 	ndmp_devinfo_t *dipptr;
1112654012fSReza Sabdar 	int i;
1122654012fSReza Sabdar 
1132654012fSReza Sabdar 	dipptr = dip;
1142654012fSReza Sabdar 	for (i = 0; i < size; i++, dipptr++) {
1152654012fSReza Sabdar 		free(dipptr->nd_name);
1162654012fSReza Sabdar 		free(dipptr->nd_vendor);
1172654012fSReza Sabdar 		free(dipptr->nd_product);
1182654012fSReza Sabdar 		free(dipptr->nd_revision);
1192654012fSReza Sabdar 	}
1202654012fSReza Sabdar 	free(dip);
1212654012fSReza Sabdar }
1222654012fSReza Sabdar 
1232654012fSReza Sabdar int
ndmp_terminate_session(int session)1242654012fSReza Sabdar ndmp_terminate_session(int session)
1252654012fSReza Sabdar {
1262654012fSReza Sabdar 	int ret;
1272654012fSReza Sabdar 	int opcode = NDMP_TERMINATE_SESSION_ID;
1282654012fSReza Sabdar 
1292654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
1302654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
1312654012fSReza Sabdar 		goto err;
1322654012fSReza Sabdar 
1332654012fSReza Sabdar 	ndmp_door_put_uint32(enc_ctx, session);
1342654012fSReza Sabdar 	if (ndmp_door_call())
1352654012fSReza Sabdar 		goto err;
1362654012fSReza Sabdar 
1372654012fSReza Sabdar 	ret = ndmp_door_get_uint32(dec_ctx);
1382654012fSReza Sabdar 	if (ndmp_door_fini())
1392654012fSReza Sabdar 		goto err;
1402654012fSReza Sabdar 
1412654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
1422654012fSReza Sabdar 	return (ret);
1432654012fSReza Sabdar err:
1442654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
1452654012fSReza Sabdar 	return (-1);
1462654012fSReza Sabdar }
1472654012fSReza Sabdar 
1482654012fSReza Sabdar int
ndmp_get_session_info(ndmp_session_info_t ** sinfo,size_t * size)1492654012fSReza Sabdar ndmp_get_session_info(ndmp_session_info_t **sinfo, size_t *size)
1502654012fSReza Sabdar {
1512654012fSReza Sabdar 	int status;
1522654012fSReza Sabdar 	int i, j;
1532654012fSReza Sabdar 	ndmp_session_info_t *sp;
1542654012fSReza Sabdar 	ndmp_dt_pval_t *ep;
1552654012fSReza Sabdar 	ndmp_dt_name_t *np;
1562654012fSReza Sabdar 	ndmp_dt_name_v3_t *npv3;
1572654012fSReza Sabdar 	int opcode = NDMP_SHOW;
1582654012fSReza Sabdar 
1592654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
1602654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
1612654012fSReza Sabdar 		goto err;
1622654012fSReza Sabdar 
1632654012fSReza Sabdar 	if (ndmp_door_call())
1642654012fSReza Sabdar 		goto err;
1652654012fSReza Sabdar 
1662654012fSReza Sabdar 	/* number of sessions */
1672654012fSReza Sabdar 	*size = ndmp_door_get_int32(dec_ctx);
1682654012fSReza Sabdar 
1692654012fSReza Sabdar 	*sinfo = malloc((sizeof (ndmp_session_info_t)) * *size);
1702654012fSReza Sabdar 	if (!*sinfo) {
1712654012fSReza Sabdar 		free(buf);
1722654012fSReza Sabdar 		ndmp_errno = ENDMP_MEM_ALLOC;
1732654012fSReza Sabdar 		goto err;
1742654012fSReza Sabdar 	}
1752654012fSReza Sabdar 	sp = *sinfo;
1762654012fSReza Sabdar 	for (i = 0; i < *size; i++, sp++) {
1772654012fSReza Sabdar 		status = ndmp_door_get_int32(dec_ctx);
1782654012fSReza Sabdar 		if (status == NDMP_SESSION_NODATA)
1792654012fSReza Sabdar 			continue;
1802654012fSReza Sabdar 
1812654012fSReza Sabdar 		/* connection common info */
1822654012fSReza Sabdar 		sp->nsi_sid = ndmp_door_get_int32(dec_ctx);
1832654012fSReza Sabdar 		sp->nsi_pver = ndmp_door_get_int32(dec_ctx);
1842654012fSReza Sabdar 		sp->nsi_auth = ndmp_door_get_int32(dec_ctx);
1852654012fSReza Sabdar 		sp->nsi_eof = ndmp_door_get_int32(dec_ctx);
1862654012fSReza Sabdar 		sp->nsi_cl_addr = ndmp_door_get_string(dec_ctx);
1872654012fSReza Sabdar 		/*
1882654012fSReza Sabdar 		 * scsi and tape data are same for all version,
1892654012fSReza Sabdar 		 * so keep reading
1902654012fSReza Sabdar 		 */
1912654012fSReza Sabdar 		/* connection common scsi info.   */
1922654012fSReza Sabdar 		sp->nsi_scsi.ns_scsi_open = ndmp_door_get_int32(dec_ctx);
1932654012fSReza Sabdar 		sp->nsi_scsi.ns_adapter_name = ndmp_door_get_string(dec_ctx);
1942654012fSReza Sabdar 		sp->nsi_scsi.ns_valid_target_set = ndmp_door_get_int32(dec_ctx);
1952654012fSReza Sabdar 		if (sp->nsi_scsi.ns_valid_target_set) {
1962654012fSReza Sabdar 			sp->nsi_scsi.ns_scsi_id = ndmp_door_get_int32(dec_ctx);
1972654012fSReza Sabdar 			sp->nsi_scsi.ns_lun = ndmp_door_get_int32(dec_ctx);
1982654012fSReza Sabdar 		}
1992654012fSReza Sabdar 
2002654012fSReza Sabdar 		/* connection common tape info.   */
2012654012fSReza Sabdar 		sp->nsi_tape.nt_fd = ndmp_door_get_int32(dec_ctx);
2022654012fSReza Sabdar 		if (sp->nsi_tape.nt_fd != -1) {
2032654012fSReza Sabdar 			sp->nsi_tape.nt_rec_count =
2042654012fSReza Sabdar 			    ndmp_door_get_uint64(dec_ctx);
2052654012fSReza Sabdar 			sp->nsi_tape.nt_mode = ndmp_door_get_int32(dec_ctx);
2062654012fSReza Sabdar 			sp->nsi_tape.nt_dev_name =
2072654012fSReza Sabdar 			    ndmp_door_get_string(dec_ctx);
2082654012fSReza Sabdar 			sp->nsi_tape.nt_adapter_name =
2092654012fSReza Sabdar 			    ndmp_door_get_string(dec_ctx);
2102654012fSReza Sabdar 			sp->nsi_tape.nt_sid = ndmp_door_get_int32(dec_ctx);
2112654012fSReza Sabdar 			sp->nsi_tape.nt_lun = ndmp_door_get_int32(dec_ctx);
2122654012fSReza Sabdar 		}
2132654012fSReza Sabdar 		/* all the V2 mover data are same as V3/V4 */
2142654012fSReza Sabdar 		sp->nsi_mover.nm_state = ndmp_door_get_int32(dec_ctx);
2152654012fSReza Sabdar 		sp->nsi_mover.nm_mode = ndmp_door_get_int32(dec_ctx);
2162654012fSReza Sabdar 		sp->nsi_mover.nm_pause_reason = ndmp_door_get_int32(dec_ctx);
2172654012fSReza Sabdar 		sp->nsi_mover.nm_halt_reason = ndmp_door_get_int32(dec_ctx);
2182654012fSReza Sabdar 		sp->nsi_mover.nm_rec_size = ndmp_door_get_uint64(dec_ctx);
2192654012fSReza Sabdar 		sp->nsi_mover.nm_rec_num = ndmp_door_get_uint64(dec_ctx);
2202654012fSReza Sabdar 		sp->nsi_mover.nm_mov_pos = ndmp_door_get_uint64(dec_ctx);
2212654012fSReza Sabdar 		sp->nsi_mover.nm_window_offset = ndmp_door_get_uint64(dec_ctx);
2222654012fSReza Sabdar 		sp->nsi_mover.nm_window_length = ndmp_door_get_uint64(dec_ctx);
2232654012fSReza Sabdar 		sp->nsi_mover.nm_sock = ndmp_door_get_int32(dec_ctx);
2242654012fSReza Sabdar 
2252654012fSReza Sabdar 		/* Read V3/V4 mover info */
2262654012fSReza Sabdar 		if ((sp->nsi_pver == NDMP_V3) || (sp->nsi_pver == NDMP_V4)) {
2272654012fSReza Sabdar 			sp->nsi_mover.nm_listen_sock =
2282654012fSReza Sabdar 			    ndmp_door_get_int32(dec_ctx);
2292654012fSReza Sabdar 			sp->nsi_mover.nm_addr_type =
2302654012fSReza Sabdar 			    ndmp_door_get_int32(dec_ctx);
2312654012fSReza Sabdar 			sp->nsi_mover.nm_tcp_addr =
2322654012fSReza Sabdar 			    ndmp_door_get_string(dec_ctx);
2332654012fSReza Sabdar 		}
2342654012fSReza Sabdar 
2352654012fSReza Sabdar 		/* connection common data info */
2362654012fSReza Sabdar 		sp->nsi_data.nd_oper = ndmp_door_get_int32(dec_ctx);
2372654012fSReza Sabdar 		sp->nsi_data.nd_state = ndmp_door_get_int32(dec_ctx);
2382654012fSReza Sabdar 		sp->nsi_data.nd_halt_reason = ndmp_door_get_int32(dec_ctx);
2392654012fSReza Sabdar 		sp->nsi_data.nd_sock = ndmp_door_get_int32(dec_ctx);
2402654012fSReza Sabdar 		sp->nsi_data.nd_addr_type = ndmp_door_get_int32(dec_ctx);
2412654012fSReza Sabdar 		sp->nsi_data.nd_abort = ndmp_door_get_int32(dec_ctx);
2422654012fSReza Sabdar 		sp->nsi_data.nd_read_offset = ndmp_door_get_uint64(dec_ctx);
2432654012fSReza Sabdar 		sp->nsi_data.nd_read_length = ndmp_door_get_uint64(dec_ctx);
2442654012fSReza Sabdar 		sp->nsi_data.nd_total_size = ndmp_door_get_uint64(dec_ctx);
2452654012fSReza Sabdar 		sp->nsi_data.nd_env_len = ndmp_door_get_uint64(dec_ctx);
2462654012fSReza Sabdar 		sp->nsi_data.nd_env =
2472654012fSReza Sabdar 		    malloc(sizeof (ndmp_dt_pval_t) * sp->nsi_data.nd_env_len);
2482654012fSReza Sabdar 		if (!sp->nsi_data.nd_env) {
2492654012fSReza Sabdar 			free(buf);
2502654012fSReza Sabdar 			ndmp_errno = ENDMP_MEM_ALLOC;
2512654012fSReza Sabdar 			goto err;
2522654012fSReza Sabdar 		}
2532654012fSReza Sabdar 		ep = sp->nsi_data.nd_env;
2542654012fSReza Sabdar 		for (j = 0; j < sp->nsi_data.nd_env_len; j++, ep++) {
2552654012fSReza Sabdar 			ep->np_name = ndmp_door_get_string(dec_ctx);
2562654012fSReza Sabdar 			ep->np_value = ndmp_door_get_string(dec_ctx);
2572654012fSReza Sabdar 		}
2582654012fSReza Sabdar 		sp->nsi_data.nd_tcp_addr = ndmp_door_get_string(dec_ctx);
2592654012fSReza Sabdar 
2602654012fSReza Sabdar 		/* Read V2 data info */
2612654012fSReza Sabdar 		if (sp->nsi_pver == NDMP_V2) {
2622654012fSReza Sabdar 			sp->nsi_data.nld_nlist_len =
2632654012fSReza Sabdar 			    ndmp_door_get_int64(dec_ctx);
2642654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_nlist =
2652654012fSReza Sabdar 			    malloc(sizeof (ndmp_dt_name_t) *
2662654012fSReza Sabdar 			    sp->nsi_data.nld_nlist_len);
2672654012fSReza Sabdar 			if (!sp->nsi_data.nd_nlist.nld_nlist) {
2682654012fSReza Sabdar 				free(buf);
2692654012fSReza Sabdar 				ndmp_errno = ENDMP_MEM_ALLOC;
2702654012fSReza Sabdar 				goto err;
2712654012fSReza Sabdar 			}
2722654012fSReza Sabdar 			np = sp->nsi_data.nd_nlist.nld_nlist;
2732654012fSReza Sabdar 
2742654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len; j++, np++) {
2752654012fSReza Sabdar 				np->nn_name = ndmp_door_get_string(dec_ctx);
2762654012fSReza Sabdar 				np->nn_dest = ndmp_door_get_string(dec_ctx);
2772654012fSReza Sabdar 			}
2782654012fSReza Sabdar 		} else if ((sp->nsi_pver == NDMP_V3) ||
2792654012fSReza Sabdar 		    (sp->nsi_pver == NDMP_V4)) {
2802654012fSReza Sabdar 			/* Read V3/V4 data info */
2812654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock =
2822654012fSReza Sabdar 			    ndmp_door_get_int32(dec_ctx);
2832654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_bytes_processed =
2842654012fSReza Sabdar 			    ndmp_door_get_uint64(dec_ctx);
2852654012fSReza Sabdar 			sp->nsi_data.nld_nlist_len =
2862654012fSReza Sabdar 			    ndmp_door_get_uint64(dec_ctx);
2872654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist =
2882654012fSReza Sabdar 			    malloc(sizeof (ndmp_dt_name_v3_t) *
2892654012fSReza Sabdar 			    sp->nsi_data.nld_nlist_len);
2902654012fSReza Sabdar 			if (!sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist) {
2912654012fSReza Sabdar 				free(buf);
2922654012fSReza Sabdar 				ndmp_errno = ENDMP_MEM_ALLOC;
2932654012fSReza Sabdar 				goto err;
2942654012fSReza Sabdar 			}
2952654012fSReza Sabdar 			npv3 = sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
2962654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len;
2972654012fSReza Sabdar 			    j++, npv3++) {
2982654012fSReza Sabdar 				npv3->nn3_opath = ndmp_door_get_string(dec_ctx);
2992654012fSReza Sabdar 				npv3->nn3_dpath = ndmp_door_get_string(dec_ctx);
3002654012fSReza Sabdar 				npv3->nn3_node = ndmp_door_get_uint64(dec_ctx);
3012654012fSReza Sabdar 				npv3->nn3_fh_info =
3022654012fSReza Sabdar 				    ndmp_door_get_uint64(dec_ctx);
3032654012fSReza Sabdar 			}
3042654012fSReza Sabdar 		}
3052654012fSReza Sabdar 	}
3062654012fSReza Sabdar 
3072654012fSReza Sabdar 	if (ndmp_door_fini())
3082654012fSReza Sabdar 		goto err;
3092654012fSReza Sabdar 
3102654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
3112654012fSReza Sabdar 	return (0);
3122654012fSReza Sabdar err:
3132654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
3142654012fSReza Sabdar 	return (-1);
3152654012fSReza Sabdar }
3162654012fSReza Sabdar 
3172654012fSReza Sabdar void
ndmp_get_session_info_free(ndmp_session_info_t * sinfo,size_t size)3182654012fSReza Sabdar ndmp_get_session_info_free(ndmp_session_info_t *sinfo, size_t size)
3192654012fSReza Sabdar {
3202654012fSReza Sabdar 	ndmp_session_info_t *sp;
3212654012fSReza Sabdar 	ndmp_dt_pval_t *ep;
3222654012fSReza Sabdar 	ndmp_dt_name_t *np;
3232654012fSReza Sabdar 	ndmp_dt_name_v3_t *npv3;
3242654012fSReza Sabdar 	int i, j;
3252654012fSReza Sabdar 
3262654012fSReza Sabdar 	sp = sinfo;
3272654012fSReza Sabdar 	for (i = 0; i < size; i++, sp++) {
3282654012fSReza Sabdar 		free(sp->nsi_cl_addr);
3292654012fSReza Sabdar 		free(sp->nsi_scsi.ns_adapter_name);
3302654012fSReza Sabdar 		if (sp->nsi_tape.nt_fd != -1) {
3312654012fSReza Sabdar 			free(sp->nsi_tape.nt_dev_name);
3322654012fSReza Sabdar 			free(sp->nsi_tape.nt_adapter_name);
3332654012fSReza Sabdar 		}
3342654012fSReza Sabdar 		if ((sp->nsi_pver == NDMP_V3) || (sp->nsi_pver == NDMP_V4))
3352654012fSReza Sabdar 			free(sp->nsi_mover.nm_tcp_addr);
3362654012fSReza Sabdar 
3372654012fSReza Sabdar 		ep = sp->nsi_data.nd_env;
3382654012fSReza Sabdar 		for (j = 0; j < sp->nsi_data.nd_env_len; j++, ep++) {
3392654012fSReza Sabdar 			free(ep->np_name);
3402654012fSReza Sabdar 			free(ep->np_value);
3412654012fSReza Sabdar 		}
3422654012fSReza Sabdar 		free(sp->nsi_data.nd_env);
3432654012fSReza Sabdar 		free(sp->nsi_data.nd_tcp_addr);
3442654012fSReza Sabdar 
3452654012fSReza Sabdar 		if (sp->nsi_pver == NDMP_V2) {
3462654012fSReza Sabdar 			np = sp->nsi_data.nd_nlist.nld_nlist;
3472654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len; j++, np++) {
3482654012fSReza Sabdar 				free(np->nn_name);
3492654012fSReza Sabdar 				free(np->nn_dest);
3502654012fSReza Sabdar 			}
3512654012fSReza Sabdar 			free(sp->nsi_data.nd_nlist.nld_nlist);
3522654012fSReza Sabdar 		} else if ((sp->nsi_pver == NDMP_V3) ||
3532654012fSReza Sabdar 		    (sp->nsi_pver == NDMP_V4)) {
3542654012fSReza Sabdar 			npv3 = sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
3552654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len;
3562654012fSReza Sabdar 			    j++, npv3++) {
3572654012fSReza Sabdar 				free(npv3->nn3_opath);
3582654012fSReza Sabdar 				free(npv3->nn3_dpath);
3592654012fSReza Sabdar 			}
3602654012fSReza Sabdar 			free(sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist);
3612654012fSReza Sabdar 		}
3622654012fSReza Sabdar 	}
3632654012fSReza Sabdar 	free(sinfo);
3642654012fSReza Sabdar }
3652654012fSReza Sabdar 
3662654012fSReza Sabdar /* ARGSUSED */
3672654012fSReza Sabdar int
ndmp_get_stats(ndmp_stat_t * statp)3682654012fSReza Sabdar ndmp_get_stats(ndmp_stat_t *statp)
3692654012fSReza Sabdar {
3702654012fSReza Sabdar 	int opcode = NDMP_GET_STAT;
3712654012fSReza Sabdar 
3722654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
3732654012fSReza Sabdar 	if (!statp) {
3742654012fSReza Sabdar 		ndmp_errno = ENDMP_INVALID_ARG;
3752654012fSReza Sabdar 		goto err;
3762654012fSReza Sabdar 	}
3772654012fSReza Sabdar 
3782654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
3792654012fSReza Sabdar 		goto err;
3802654012fSReza Sabdar 
3812654012fSReza Sabdar 	if (ndmp_door_call())
3822654012fSReza Sabdar 		goto err;
3832654012fSReza Sabdar 
3842654012fSReza Sabdar 	statp->ns_trun = ndmp_door_get_uint32(dec_ctx);
3852654012fSReza Sabdar 	statp->ns_twait = ndmp_door_get_uint32(dec_ctx);
3862654012fSReza Sabdar 	statp->ns_nbk = ndmp_door_get_uint32(dec_ctx);
3872654012fSReza Sabdar 	statp->ns_nrs = ndmp_door_get_uint32(dec_ctx);
3882654012fSReza Sabdar 	statp->ns_rfile = ndmp_door_get_uint32(dec_ctx);
3892654012fSReza Sabdar 	statp->ns_wfile = ndmp_door_get_uint32(dec_ctx);
3902654012fSReza Sabdar 	statp->ns_rdisk = ndmp_door_get_uint64(dec_ctx);
3912654012fSReza Sabdar 	statp->ns_wdisk = ndmp_door_get_uint64(dec_ctx);
3922654012fSReza Sabdar 	statp->ns_rtape = ndmp_door_get_uint64(dec_ctx);
3932654012fSReza Sabdar 	statp->ns_wtape = ndmp_door_get_uint64(dec_ctx);
3942654012fSReza Sabdar 
3952654012fSReza Sabdar 	if (ndmp_door_fini())
3962654012fSReza Sabdar 		goto err;
3972654012fSReza Sabdar 
3982654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
3992654012fSReza Sabdar 	return (0);
4002654012fSReza Sabdar err:
4012654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
4022654012fSReza Sabdar 	return (-1);
4032654012fSReza Sabdar }
4042654012fSReza Sabdar 
4052654012fSReza Sabdar int
ndmp_door_status(void)4062654012fSReza Sabdar ndmp_door_status(void)
4072654012fSReza Sabdar {
4082654012fSReza Sabdar 	int opcode = NDMP_GET_DOOR_STATUS;
4092654012fSReza Sabdar 
4102654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
4112654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
4122654012fSReza Sabdar 		goto err;
4132654012fSReza Sabdar 
4142654012fSReza Sabdar 	if (ndmp_door_call())
4152654012fSReza Sabdar 		goto err;
4162654012fSReza Sabdar 
4172654012fSReza Sabdar 	if (ndmp_door_fini())
4182654012fSReza Sabdar 		goto err;
4192654012fSReza Sabdar 
4202654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
4212654012fSReza Sabdar 	return (0);
4222654012fSReza Sabdar err:
4232654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
4242654012fSReza Sabdar 	return (-1);
4252654012fSReza Sabdar }
4262654012fSReza Sabdar 
4272654012fSReza Sabdar static int
ndmp_door_setup(int opcode)4282654012fSReza Sabdar ndmp_door_setup(int opcode)
4292654012fSReza Sabdar {
4302654012fSReza Sabdar 	/* Open channel to NDMP service */
4312654012fSReza Sabdar 	if ((ndmp_door_fildes == -1) &&
4322654012fSReza Sabdar 	    (ndmp_door_fildes = open(NDMP_DOOR_SVC, O_RDONLY)) < 0) {
4332654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_OPEN;
4342654012fSReza Sabdar 		return (-1);
4352654012fSReza Sabdar 	}
4362654012fSReza Sabdar 
4372654012fSReza Sabdar 	buf = malloc(NDMP_DOOR_SIZE);
4382654012fSReza Sabdar 	if (!buf) {
4392654012fSReza Sabdar 		ndmp_errno = ENDMP_MEM_ALLOC;
4402654012fSReza Sabdar 		return (-1);
4412654012fSReza Sabdar 	}
4422654012fSReza Sabdar 
4432654012fSReza Sabdar 	enc_ctx = ndmp_door_encode_start(buf, NDMP_DOOR_SIZE);
4442654012fSReza Sabdar 	if (enc_ctx == 0) {
4452654012fSReza Sabdar 		free(buf);
4462654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_ENCODE_START;
4472654012fSReza Sabdar 		return (-1);
4482654012fSReza Sabdar 	}
4492654012fSReza Sabdar 	ndmp_door_put_uint32(enc_ctx, opcode);
4502654012fSReza Sabdar 	return (0);
4512654012fSReza Sabdar }
4522654012fSReza Sabdar 
4532654012fSReza Sabdar static int
ndmp_door_call(void)4542654012fSReza Sabdar ndmp_door_call(void)
4552654012fSReza Sabdar {
4562654012fSReza Sabdar 	uint32_t used;
4572654012fSReza Sabdar 	int rc;
4582654012fSReza Sabdar 
4592654012fSReza Sabdar 	if ((ndmp_door_encode_finish(enc_ctx, &used)) != 0) {
4602654012fSReza Sabdar 		free(buf);
4612654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_ENCODE_FINISH;
4622654012fSReza Sabdar 		return (-1);
4632654012fSReza Sabdar 	}
4642654012fSReza Sabdar 
4652654012fSReza Sabdar 	arg.data_ptr = buf;
4662654012fSReza Sabdar 	arg.data_size = used;
4672654012fSReza Sabdar 	arg.desc_ptr = NULL;
4682654012fSReza Sabdar 	arg.desc_num = 0;
4692654012fSReza Sabdar 	arg.rbuf = buf;
4702654012fSReza Sabdar 	arg.rsize = NDMP_DOOR_SIZE;
4712654012fSReza Sabdar 
4722654012fSReza Sabdar 	if (door_call(ndmp_door_fildes, &arg) < 0) {
4732654012fSReza Sabdar 		free(buf);
4742654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_SRV_TIMEOUT;
4752654012fSReza Sabdar 		(void) close(ndmp_door_fildes);
4762654012fSReza Sabdar 		ndmp_door_fildes = -1;
4772654012fSReza Sabdar 		return (-1);
4782654012fSReza Sabdar 	}
4792654012fSReza Sabdar 
4802654012fSReza Sabdar 	dec_ctx = ndmp_door_decode_start(arg.data_ptr, arg.data_size);
4812654012fSReza Sabdar 	rc = ndmp_door_get_uint32(dec_ctx);
4822654012fSReza Sabdar 	if (rc != NDMP_DOOR_SRV_SUCCESS) {
4832654012fSReza Sabdar 		free(buf);
4842654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_SRV_OPERATION;
4852654012fSReza Sabdar 		return (-1);
4862654012fSReza Sabdar 	}
4872654012fSReza Sabdar 	return (0);
4882654012fSReza Sabdar }
4892654012fSReza Sabdar 
4902654012fSReza Sabdar static int
ndmp_door_fini(void)4912654012fSReza Sabdar ndmp_door_fini(void)
4922654012fSReza Sabdar {
4932654012fSReza Sabdar 	if ((ndmp_door_decode_finish(dec_ctx)) != 0) {
4942654012fSReza Sabdar 		free(buf);
4952654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_DECODE_FINISH;
4962654012fSReza Sabdar 		return (-1);
4972654012fSReza Sabdar 	}
4982654012fSReza Sabdar 	free(buf);
4992654012fSReza Sabdar 	return (0);
5002654012fSReza Sabdar }
501