xref: /onnv-gate/usr/src/lib/libndmp/common/libndmp.c (revision 8193:9b3c96bc17e3)
17917SReza.Sabdar@Sun.COM /*
27917SReza.Sabdar@Sun.COM  * Copyright 2008 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 #include <locale.h>
407917SReza.Sabdar@Sun.COM #include <stdlib.h>
417917SReza.Sabdar@Sun.COM #include <strings.h>
427917SReza.Sabdar@Sun.COM #include <unistd.h>
437917SReza.Sabdar@Sun.COM #include <fcntl.h>
447917SReza.Sabdar@Sun.COM #include <door.h>
457917SReza.Sabdar@Sun.COM #include <thread.h>
467917SReza.Sabdar@Sun.COM #include <ndmpd_door.h>
477917SReza.Sabdar@Sun.COM #include <libndmp.h>
487917SReza.Sabdar@Sun.COM 
497917SReza.Sabdar@Sun.COM static int ndmp_door_fildes = -1;
507917SReza.Sabdar@Sun.COM static char *buf;
517917SReza.Sabdar@Sun.COM static ndmp_door_ctx_t *dec_ctx;
527917SReza.Sabdar@Sun.COM static ndmp_door_ctx_t *enc_ctx;
537917SReza.Sabdar@Sun.COM static door_arg_t arg;
547917SReza.Sabdar@Sun.COM static mutex_t ndmp_lock = DEFAULTMUTEX;
557917SReza.Sabdar@Sun.COM 
567917SReza.Sabdar@Sun.COM static int ndmp_door_setup(int opcode);
577917SReza.Sabdar@Sun.COM static int ndmp_door_call(void);
587917SReza.Sabdar@Sun.COM static int ndmp_door_fini(void);
597917SReza.Sabdar@Sun.COM 
607917SReza.Sabdar@Sun.COM /* ndmp library APIs */
617917SReza.Sabdar@Sun.COM int
ndmp_get_devinfo(ndmp_devinfo_t ** dip,size_t * size)627917SReza.Sabdar@Sun.COM ndmp_get_devinfo(ndmp_devinfo_t **dip, size_t *size)
637917SReza.Sabdar@Sun.COM {
647917SReza.Sabdar@Sun.COM 	ndmp_devinfo_t *dipptr;
657917SReza.Sabdar@Sun.COM 	int i;
667917SReza.Sabdar@Sun.COM 	int opcode = NDMP_DEVICES_GET_INFO;
677917SReza.Sabdar@Sun.COM 
687917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_lock);
697917SReza.Sabdar@Sun.COM 	if (ndmp_door_setup(opcode))
707917SReza.Sabdar@Sun.COM 		goto err;
717917SReza.Sabdar@Sun.COM 
727917SReza.Sabdar@Sun.COM 	if (ndmp_door_call())
737917SReza.Sabdar@Sun.COM 		goto err;
747917SReza.Sabdar@Sun.COM 
757917SReza.Sabdar@Sun.COM 	/* get the number of devices available */
767917SReza.Sabdar@Sun.COM 	*size = ndmp_door_get_uint32(dec_ctx);
777917SReza.Sabdar@Sun.COM 
787917SReza.Sabdar@Sun.COM 	*dip = malloc(sizeof (ndmp_devinfo_t) * *size);
797917SReza.Sabdar@Sun.COM 	if (!*dip) {
807917SReza.Sabdar@Sun.COM 		free(buf);
817917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_MEM_ALLOC;
827917SReza.Sabdar@Sun.COM 		goto err;
837917SReza.Sabdar@Sun.COM 	}
847917SReza.Sabdar@Sun.COM 	dipptr = *dip;
857917SReza.Sabdar@Sun.COM 	for (i = 0; i < *size; i++, dipptr++) {
867917SReza.Sabdar@Sun.COM 		dipptr->nd_dev_type = ndmp_door_get_int32(dec_ctx);
877917SReza.Sabdar@Sun.COM 		dipptr->nd_name = ndmp_door_get_string(dec_ctx);
887917SReza.Sabdar@Sun.COM 		dipptr->nd_lun = ndmp_door_get_int32(dec_ctx);
897917SReza.Sabdar@Sun.COM 		dipptr->nd_sid = ndmp_door_get_int32(dec_ctx);
907917SReza.Sabdar@Sun.COM 		dipptr->nd_vendor = ndmp_door_get_string(dec_ctx);
917917SReza.Sabdar@Sun.COM 		dipptr->nd_product = ndmp_door_get_string(dec_ctx);
927917SReza.Sabdar@Sun.COM 		dipptr->nd_revision = ndmp_door_get_string(dec_ctx);
93*8193SReza.Sabdar@Sun.COM 		dipptr->nd_serial = ndmp_door_get_string(dec_ctx);
94*8193SReza.Sabdar@Sun.COM 		dipptr->nd_wwn = ndmp_door_get_string(dec_ctx);
957917SReza.Sabdar@Sun.COM 	}
967917SReza.Sabdar@Sun.COM 	if (ndmp_door_fini()) {
977917SReza.Sabdar@Sun.COM 		free(*dip);
987917SReza.Sabdar@Sun.COM 		goto err;
997917SReza.Sabdar@Sun.COM 	}
1007917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
1017917SReza.Sabdar@Sun.COM 	return (0);
1027917SReza.Sabdar@Sun.COM err:
1037917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
1047917SReza.Sabdar@Sun.COM 	return (-1);
1057917SReza.Sabdar@Sun.COM }
1067917SReza.Sabdar@Sun.COM 
1077917SReza.Sabdar@Sun.COM void
ndmp_get_devinfo_free(ndmp_devinfo_t * dip,size_t size)1087917SReza.Sabdar@Sun.COM ndmp_get_devinfo_free(ndmp_devinfo_t *dip, size_t size)
1097917SReza.Sabdar@Sun.COM {
1107917SReza.Sabdar@Sun.COM 	ndmp_devinfo_t *dipptr;
1117917SReza.Sabdar@Sun.COM 	int i;
1127917SReza.Sabdar@Sun.COM 
1137917SReza.Sabdar@Sun.COM 	dipptr = dip;
1147917SReza.Sabdar@Sun.COM 	for (i = 0; i < size; i++, dipptr++) {
1157917SReza.Sabdar@Sun.COM 		free(dipptr->nd_name);
1167917SReza.Sabdar@Sun.COM 		free(dipptr->nd_vendor);
1177917SReza.Sabdar@Sun.COM 		free(dipptr->nd_product);
1187917SReza.Sabdar@Sun.COM 		free(dipptr->nd_revision);
1197917SReza.Sabdar@Sun.COM 	}
1207917SReza.Sabdar@Sun.COM 	free(dip);
1217917SReza.Sabdar@Sun.COM }
1227917SReza.Sabdar@Sun.COM 
1237917SReza.Sabdar@Sun.COM int
ndmp_terminate_session(int session)1247917SReza.Sabdar@Sun.COM ndmp_terminate_session(int session)
1257917SReza.Sabdar@Sun.COM {
1267917SReza.Sabdar@Sun.COM 	int ret;
1277917SReza.Sabdar@Sun.COM 	int opcode = NDMP_TERMINATE_SESSION_ID;
1287917SReza.Sabdar@Sun.COM 
1297917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_lock);
1307917SReza.Sabdar@Sun.COM 	if (ndmp_door_setup(opcode))
1317917SReza.Sabdar@Sun.COM 		goto err;
1327917SReza.Sabdar@Sun.COM 
1337917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint32(enc_ctx, session);
1347917SReza.Sabdar@Sun.COM 	if (ndmp_door_call())
1357917SReza.Sabdar@Sun.COM 		goto err;
1367917SReza.Sabdar@Sun.COM 
1377917SReza.Sabdar@Sun.COM 	ret = ndmp_door_get_uint32(dec_ctx);
1387917SReza.Sabdar@Sun.COM 	if (ndmp_door_fini())
1397917SReza.Sabdar@Sun.COM 		goto err;
1407917SReza.Sabdar@Sun.COM 
1417917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
1427917SReza.Sabdar@Sun.COM 	return (ret);
1437917SReza.Sabdar@Sun.COM err:
1447917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
1457917SReza.Sabdar@Sun.COM 	return (-1);
1467917SReza.Sabdar@Sun.COM }
1477917SReza.Sabdar@Sun.COM 
1487917SReza.Sabdar@Sun.COM int
ndmp_get_session_info(ndmp_session_info_t ** sinfo,size_t * size)1497917SReza.Sabdar@Sun.COM ndmp_get_session_info(ndmp_session_info_t **sinfo, size_t *size)
1507917SReza.Sabdar@Sun.COM {
1517917SReza.Sabdar@Sun.COM 	int status;
1527917SReza.Sabdar@Sun.COM 	int i, j;
1537917SReza.Sabdar@Sun.COM 	ndmp_session_info_t *sp;
1547917SReza.Sabdar@Sun.COM 	ndmp_dt_pval_t *ep;
1557917SReza.Sabdar@Sun.COM 	ndmp_dt_name_t *np;
1567917SReza.Sabdar@Sun.COM 	ndmp_dt_name_v3_t *npv3;
1577917SReza.Sabdar@Sun.COM 	int opcode = NDMP_SHOW;
1587917SReza.Sabdar@Sun.COM 
1597917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_lock);
1607917SReza.Sabdar@Sun.COM 	if (ndmp_door_setup(opcode))
1617917SReza.Sabdar@Sun.COM 		goto err;
1627917SReza.Sabdar@Sun.COM 
1637917SReza.Sabdar@Sun.COM 	if (ndmp_door_call())
1647917SReza.Sabdar@Sun.COM 		goto err;
1657917SReza.Sabdar@Sun.COM 
1667917SReza.Sabdar@Sun.COM 	/* number of sessions */
1677917SReza.Sabdar@Sun.COM 	*size = ndmp_door_get_int32(dec_ctx);
1687917SReza.Sabdar@Sun.COM 
1697917SReza.Sabdar@Sun.COM 	*sinfo = malloc((sizeof (ndmp_session_info_t)) * *size);
1707917SReza.Sabdar@Sun.COM 	if (!*sinfo) {
1717917SReza.Sabdar@Sun.COM 		free(buf);
1727917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_MEM_ALLOC;
1737917SReza.Sabdar@Sun.COM 		goto err;
1747917SReza.Sabdar@Sun.COM 	}
1757917SReza.Sabdar@Sun.COM 	sp = *sinfo;
1767917SReza.Sabdar@Sun.COM 	for (i = 0; i < *size; i++, sp++) {
1777917SReza.Sabdar@Sun.COM 		status = ndmp_door_get_int32(dec_ctx);
1787917SReza.Sabdar@Sun.COM 		if (status == NDMP_SESSION_NODATA)
1797917SReza.Sabdar@Sun.COM 			continue;
1807917SReza.Sabdar@Sun.COM 
1817917SReza.Sabdar@Sun.COM 		/* connection common info */
1827917SReza.Sabdar@Sun.COM 		sp->nsi_sid = ndmp_door_get_int32(dec_ctx);
1837917SReza.Sabdar@Sun.COM 		sp->nsi_pver = ndmp_door_get_int32(dec_ctx);
1847917SReza.Sabdar@Sun.COM 		sp->nsi_auth = ndmp_door_get_int32(dec_ctx);
1857917SReza.Sabdar@Sun.COM 		sp->nsi_eof = ndmp_door_get_int32(dec_ctx);
1867917SReza.Sabdar@Sun.COM 		sp->nsi_cl_addr = ndmp_door_get_string(dec_ctx);
1877917SReza.Sabdar@Sun.COM 		/*
1887917SReza.Sabdar@Sun.COM 		 * scsi and tape data are same for all version,
1897917SReza.Sabdar@Sun.COM 		 * so keep reading
1907917SReza.Sabdar@Sun.COM 		 */
1917917SReza.Sabdar@Sun.COM 		/* connection common scsi info.   */
1927917SReza.Sabdar@Sun.COM 		sp->nsi_scsi.ns_scsi_open = ndmp_door_get_int32(dec_ctx);
1937917SReza.Sabdar@Sun.COM 		sp->nsi_scsi.ns_adapter_name = ndmp_door_get_string(dec_ctx);
1947917SReza.Sabdar@Sun.COM 		sp->nsi_scsi.ns_valid_target_set = ndmp_door_get_int32(dec_ctx);
1957917SReza.Sabdar@Sun.COM 		if (sp->nsi_scsi.ns_valid_target_set) {
1967917SReza.Sabdar@Sun.COM 			sp->nsi_scsi.ns_scsi_id = ndmp_door_get_int32(dec_ctx);
1977917SReza.Sabdar@Sun.COM 			sp->nsi_scsi.ns_lun = ndmp_door_get_int32(dec_ctx);
1987917SReza.Sabdar@Sun.COM 		}
1997917SReza.Sabdar@Sun.COM 
2007917SReza.Sabdar@Sun.COM 		/* connection common tape info.   */
2017917SReza.Sabdar@Sun.COM 		sp->nsi_tape.nt_fd = ndmp_door_get_int32(dec_ctx);
2027917SReza.Sabdar@Sun.COM 		if (sp->nsi_tape.nt_fd != -1) {
2037917SReza.Sabdar@Sun.COM 			sp->nsi_tape.nt_rec_count =
2047917SReza.Sabdar@Sun.COM 			    ndmp_door_get_uint64(dec_ctx);
2057917SReza.Sabdar@Sun.COM 			sp->nsi_tape.nt_mode = ndmp_door_get_int32(dec_ctx);
2067917SReza.Sabdar@Sun.COM 			sp->nsi_tape.nt_dev_name =
2077917SReza.Sabdar@Sun.COM 			    ndmp_door_get_string(dec_ctx);
2087917SReza.Sabdar@Sun.COM 			sp->nsi_tape.nt_adapter_name =
2097917SReza.Sabdar@Sun.COM 			    ndmp_door_get_string(dec_ctx);
2107917SReza.Sabdar@Sun.COM 			sp->nsi_tape.nt_sid = ndmp_door_get_int32(dec_ctx);
2117917SReza.Sabdar@Sun.COM 			sp->nsi_tape.nt_lun = ndmp_door_get_int32(dec_ctx);
2127917SReza.Sabdar@Sun.COM 		}
2137917SReza.Sabdar@Sun.COM 		/* all the V2 mover data are same as V3/V4 */
2147917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_state = ndmp_door_get_int32(dec_ctx);
2157917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_mode = ndmp_door_get_int32(dec_ctx);
2167917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_pause_reason = ndmp_door_get_int32(dec_ctx);
2177917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_halt_reason = ndmp_door_get_int32(dec_ctx);
2187917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_rec_size = ndmp_door_get_uint64(dec_ctx);
2197917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_rec_num = ndmp_door_get_uint64(dec_ctx);
2207917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_mov_pos = ndmp_door_get_uint64(dec_ctx);
2217917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_window_offset = ndmp_door_get_uint64(dec_ctx);
2227917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_window_length = ndmp_door_get_uint64(dec_ctx);
2237917SReza.Sabdar@Sun.COM 		sp->nsi_mover.nm_sock = ndmp_door_get_int32(dec_ctx);
2247917SReza.Sabdar@Sun.COM 
2257917SReza.Sabdar@Sun.COM 		/* Read V3/V4 mover info */
2267917SReza.Sabdar@Sun.COM 		if ((sp->nsi_pver == NDMP_V3) || (sp->nsi_pver == NDMP_V4)) {
2277917SReza.Sabdar@Sun.COM 			sp->nsi_mover.nm_listen_sock =
2287917SReza.Sabdar@Sun.COM 			    ndmp_door_get_int32(dec_ctx);
2297917SReza.Sabdar@Sun.COM 			sp->nsi_mover.nm_addr_type =
2307917SReza.Sabdar@Sun.COM 			    ndmp_door_get_int32(dec_ctx);
2317917SReza.Sabdar@Sun.COM 			sp->nsi_mover.nm_tcp_addr =
2327917SReza.Sabdar@Sun.COM 			    ndmp_door_get_string(dec_ctx);
2337917SReza.Sabdar@Sun.COM 		}
2347917SReza.Sabdar@Sun.COM 
2357917SReza.Sabdar@Sun.COM 		/* connection common data info */
2367917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_oper = ndmp_door_get_int32(dec_ctx);
2377917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_state = ndmp_door_get_int32(dec_ctx);
2387917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_halt_reason = ndmp_door_get_int32(dec_ctx);
2397917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_sock = ndmp_door_get_int32(dec_ctx);
2407917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_addr_type = ndmp_door_get_int32(dec_ctx);
2417917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_abort = ndmp_door_get_int32(dec_ctx);
2427917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_read_offset = ndmp_door_get_uint64(dec_ctx);
2437917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_read_length = ndmp_door_get_uint64(dec_ctx);
2447917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_total_size = ndmp_door_get_uint64(dec_ctx);
2457917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_env_len = ndmp_door_get_uint64(dec_ctx);
2467917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_env =
2477917SReza.Sabdar@Sun.COM 		    malloc(sizeof (ndmp_dt_pval_t) * sp->nsi_data.nd_env_len);
2487917SReza.Sabdar@Sun.COM 		if (!sp->nsi_data.nd_env) {
2497917SReza.Sabdar@Sun.COM 			free(buf);
2507917SReza.Sabdar@Sun.COM 			ndmp_errno = ENDMP_MEM_ALLOC;
2517917SReza.Sabdar@Sun.COM 			goto err;
2527917SReza.Sabdar@Sun.COM 		}
2537917SReza.Sabdar@Sun.COM 		ep = sp->nsi_data.nd_env;
2547917SReza.Sabdar@Sun.COM 		for (j = 0; j < sp->nsi_data.nd_env_len; j++, ep++) {
2557917SReza.Sabdar@Sun.COM 			ep->np_name = ndmp_door_get_string(dec_ctx);
2567917SReza.Sabdar@Sun.COM 			ep->np_value = ndmp_door_get_string(dec_ctx);
2577917SReza.Sabdar@Sun.COM 		}
2587917SReza.Sabdar@Sun.COM 		sp->nsi_data.nd_tcp_addr = ndmp_door_get_string(dec_ctx);
2597917SReza.Sabdar@Sun.COM 
2607917SReza.Sabdar@Sun.COM 		/* Read V2 data info */
2617917SReza.Sabdar@Sun.COM 		if (sp->nsi_pver == NDMP_V2) {
2627917SReza.Sabdar@Sun.COM 			sp->nsi_data.nld_nlist_len =
2637917SReza.Sabdar@Sun.COM 			    ndmp_door_get_int64(dec_ctx);
2647917SReza.Sabdar@Sun.COM 			sp->nsi_data.nd_nlist.nld_nlist =
2657917SReza.Sabdar@Sun.COM 			    malloc(sizeof (ndmp_dt_name_t) *
2667917SReza.Sabdar@Sun.COM 			    sp->nsi_data.nld_nlist_len);
2677917SReza.Sabdar@Sun.COM 			if (!sp->nsi_data.nd_nlist.nld_nlist) {
2687917SReza.Sabdar@Sun.COM 				free(buf);
2697917SReza.Sabdar@Sun.COM 				ndmp_errno = ENDMP_MEM_ALLOC;
2707917SReza.Sabdar@Sun.COM 				goto err;
2717917SReza.Sabdar@Sun.COM 			}
2727917SReza.Sabdar@Sun.COM 			np = sp->nsi_data.nd_nlist.nld_nlist;
2737917SReza.Sabdar@Sun.COM 
2747917SReza.Sabdar@Sun.COM 			for (j = 0; j < sp->nsi_data.nld_nlist_len; j++, np++) {
2757917SReza.Sabdar@Sun.COM 				np->nn_name = ndmp_door_get_string(dec_ctx);
2767917SReza.Sabdar@Sun.COM 				np->nn_dest = ndmp_door_get_string(dec_ctx);
2777917SReza.Sabdar@Sun.COM 			}
2787917SReza.Sabdar@Sun.COM 		} else if ((sp->nsi_pver == NDMP_V3) ||
2797917SReza.Sabdar@Sun.COM 		    (sp->nsi_pver == NDMP_V4)) {
2807917SReza.Sabdar@Sun.COM 			/* Read V3/V4 data info */
2817917SReza.Sabdar@Sun.COM 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock =
2827917SReza.Sabdar@Sun.COM 			    ndmp_door_get_int32(dec_ctx);
2837917SReza.Sabdar@Sun.COM 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_bytes_processed =
2847917SReza.Sabdar@Sun.COM 			    ndmp_door_get_uint64(dec_ctx);
2857917SReza.Sabdar@Sun.COM 			sp->nsi_data.nld_nlist_len =
2867917SReza.Sabdar@Sun.COM 			    ndmp_door_get_uint64(dec_ctx);
2877917SReza.Sabdar@Sun.COM 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist =
2887917SReza.Sabdar@Sun.COM 			    malloc(sizeof (ndmp_dt_name_v3_t) *
2897917SReza.Sabdar@Sun.COM 			    sp->nsi_data.nld_nlist_len);
2907917SReza.Sabdar@Sun.COM 			if (!sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist) {
2917917SReza.Sabdar@Sun.COM 				free(buf);
2927917SReza.Sabdar@Sun.COM 				ndmp_errno = ENDMP_MEM_ALLOC;
2937917SReza.Sabdar@Sun.COM 				goto err;
2947917SReza.Sabdar@Sun.COM 			}
2957917SReza.Sabdar@Sun.COM 			npv3 = sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
2967917SReza.Sabdar@Sun.COM 			for (j = 0; j < sp->nsi_data.nld_nlist_len;
2977917SReza.Sabdar@Sun.COM 			    j++, npv3++) {
2987917SReza.Sabdar@Sun.COM 				npv3->nn3_opath = ndmp_door_get_string(dec_ctx);
2997917SReza.Sabdar@Sun.COM 				npv3->nn3_dpath = ndmp_door_get_string(dec_ctx);
3007917SReza.Sabdar@Sun.COM 				npv3->nn3_node = ndmp_door_get_uint64(dec_ctx);
3017917SReza.Sabdar@Sun.COM 				npv3->nn3_fh_info =
3027917SReza.Sabdar@Sun.COM 				    ndmp_door_get_uint64(dec_ctx);
3037917SReza.Sabdar@Sun.COM 			}
3047917SReza.Sabdar@Sun.COM 		}
3057917SReza.Sabdar@Sun.COM 	}
3067917SReza.Sabdar@Sun.COM 
3077917SReza.Sabdar@Sun.COM 	if (ndmp_door_fini())
3087917SReza.Sabdar@Sun.COM 		goto err;
3097917SReza.Sabdar@Sun.COM 
3107917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
3117917SReza.Sabdar@Sun.COM 	return (0);
3127917SReza.Sabdar@Sun.COM err:
3137917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
3147917SReza.Sabdar@Sun.COM 	return (-1);
3157917SReza.Sabdar@Sun.COM }
3167917SReza.Sabdar@Sun.COM 
3177917SReza.Sabdar@Sun.COM void
ndmp_get_session_info_free(ndmp_session_info_t * sinfo,size_t size)3187917SReza.Sabdar@Sun.COM ndmp_get_session_info_free(ndmp_session_info_t *sinfo, size_t size)
3197917SReza.Sabdar@Sun.COM {
3207917SReza.Sabdar@Sun.COM 	ndmp_session_info_t *sp;
3217917SReza.Sabdar@Sun.COM 	ndmp_dt_pval_t *ep;
3227917SReza.Sabdar@Sun.COM 	ndmp_dt_name_t *np;
3237917SReza.Sabdar@Sun.COM 	ndmp_dt_name_v3_t *npv3;
3247917SReza.Sabdar@Sun.COM 	int i, j;
3257917SReza.Sabdar@Sun.COM 
3267917SReza.Sabdar@Sun.COM 	sp = sinfo;
3277917SReza.Sabdar@Sun.COM 	for (i = 0; i < size; i++, sp++) {
3287917SReza.Sabdar@Sun.COM 		free(sp->nsi_cl_addr);
3297917SReza.Sabdar@Sun.COM 		free(sp->nsi_scsi.ns_adapter_name);
3307917SReza.Sabdar@Sun.COM 		if (sp->nsi_tape.nt_fd != -1) {
3317917SReza.Sabdar@Sun.COM 			free(sp->nsi_tape.nt_dev_name);
3327917SReza.Sabdar@Sun.COM 			free(sp->nsi_tape.nt_adapter_name);
3337917SReza.Sabdar@Sun.COM 		}
3347917SReza.Sabdar@Sun.COM 		if ((sp->nsi_pver == NDMP_V3) || (sp->nsi_pver == NDMP_V4))
3357917SReza.Sabdar@Sun.COM 			free(sp->nsi_mover.nm_tcp_addr);
3367917SReza.Sabdar@Sun.COM 
3377917SReza.Sabdar@Sun.COM 		ep = sp->nsi_data.nd_env;
3387917SReza.Sabdar@Sun.COM 		for (j = 0; j < sp->nsi_data.nd_env_len; j++, ep++) {
3397917SReza.Sabdar@Sun.COM 			free(ep->np_name);
3407917SReza.Sabdar@Sun.COM 			free(ep->np_value);
3417917SReza.Sabdar@Sun.COM 		}
3427917SReza.Sabdar@Sun.COM 		free(sp->nsi_data.nd_env);
3437917SReza.Sabdar@Sun.COM 		free(sp->nsi_data.nd_tcp_addr);
3447917SReza.Sabdar@Sun.COM 
3457917SReza.Sabdar@Sun.COM 		if (sp->nsi_pver == NDMP_V2) {
3467917SReza.Sabdar@Sun.COM 			np = sp->nsi_data.nd_nlist.nld_nlist;
3477917SReza.Sabdar@Sun.COM 			for (j = 0; j < sp->nsi_data.nld_nlist_len; j++, np++) {
3487917SReza.Sabdar@Sun.COM 				free(np->nn_name);
3497917SReza.Sabdar@Sun.COM 				free(np->nn_dest);
3507917SReza.Sabdar@Sun.COM 			}
3517917SReza.Sabdar@Sun.COM 			free(sp->nsi_data.nd_nlist.nld_nlist);
3527917SReza.Sabdar@Sun.COM 		} else if ((sp->nsi_pver == NDMP_V3) ||
3537917SReza.Sabdar@Sun.COM 		    (sp->nsi_pver == NDMP_V4)) {
3547917SReza.Sabdar@Sun.COM 			npv3 = sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
3557917SReza.Sabdar@Sun.COM 			for (j = 0; j < sp->nsi_data.nld_nlist_len;
3567917SReza.Sabdar@Sun.COM 			    j++, npv3++) {
3577917SReza.Sabdar@Sun.COM 				free(npv3->nn3_opath);
3587917SReza.Sabdar@Sun.COM 				free(npv3->nn3_dpath);
3597917SReza.Sabdar@Sun.COM 			}
3607917SReza.Sabdar@Sun.COM 			free(sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist);
3617917SReza.Sabdar@Sun.COM 		}
3627917SReza.Sabdar@Sun.COM 	}
3637917SReza.Sabdar@Sun.COM 	free(sinfo);
3647917SReza.Sabdar@Sun.COM }
3657917SReza.Sabdar@Sun.COM 
3667917SReza.Sabdar@Sun.COM /* ARGSUSED */
3677917SReza.Sabdar@Sun.COM int
ndmp_get_stats(ndmp_stat_t * statp)3687917SReza.Sabdar@Sun.COM ndmp_get_stats(ndmp_stat_t *statp)
3697917SReza.Sabdar@Sun.COM {
3707917SReza.Sabdar@Sun.COM 	int opcode = NDMP_GET_STAT;
3717917SReza.Sabdar@Sun.COM 
3727917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_lock);
3737917SReza.Sabdar@Sun.COM 	if (!statp) {
3747917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_INVALID_ARG;
3757917SReza.Sabdar@Sun.COM 		goto err;
3767917SReza.Sabdar@Sun.COM 	}
3777917SReza.Sabdar@Sun.COM 
3787917SReza.Sabdar@Sun.COM 	if (ndmp_door_setup(opcode))
3797917SReza.Sabdar@Sun.COM 		goto err;
3807917SReza.Sabdar@Sun.COM 
3817917SReza.Sabdar@Sun.COM 	if (ndmp_door_call())
3827917SReza.Sabdar@Sun.COM 		goto err;
3837917SReza.Sabdar@Sun.COM 
3847917SReza.Sabdar@Sun.COM 	statp->ns_trun = ndmp_door_get_uint32(dec_ctx);
3857917SReza.Sabdar@Sun.COM 	statp->ns_twait = ndmp_door_get_uint32(dec_ctx);
3867917SReza.Sabdar@Sun.COM 	statp->ns_nbk = ndmp_door_get_uint32(dec_ctx);
3877917SReza.Sabdar@Sun.COM 	statp->ns_nrs = ndmp_door_get_uint32(dec_ctx);
3887917SReza.Sabdar@Sun.COM 	statp->ns_rfile = ndmp_door_get_uint32(dec_ctx);
3897917SReza.Sabdar@Sun.COM 	statp->ns_wfile = ndmp_door_get_uint32(dec_ctx);
3907917SReza.Sabdar@Sun.COM 	statp->ns_rdisk = ndmp_door_get_uint64(dec_ctx);
3917917SReza.Sabdar@Sun.COM 	statp->ns_wdisk = ndmp_door_get_uint64(dec_ctx);
3927917SReza.Sabdar@Sun.COM 	statp->ns_rtape = ndmp_door_get_uint64(dec_ctx);
3937917SReza.Sabdar@Sun.COM 	statp->ns_wtape = ndmp_door_get_uint64(dec_ctx);
3947917SReza.Sabdar@Sun.COM 
3957917SReza.Sabdar@Sun.COM 	if (ndmp_door_fini())
3967917SReza.Sabdar@Sun.COM 		goto err;
3977917SReza.Sabdar@Sun.COM 
3987917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
3997917SReza.Sabdar@Sun.COM 	return (0);
4007917SReza.Sabdar@Sun.COM err:
4017917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
4027917SReza.Sabdar@Sun.COM 	return (-1);
4037917SReza.Sabdar@Sun.COM }
4047917SReza.Sabdar@Sun.COM 
4057917SReza.Sabdar@Sun.COM int
ndmp_door_status(void)4067917SReza.Sabdar@Sun.COM ndmp_door_status(void)
4077917SReza.Sabdar@Sun.COM {
4087917SReza.Sabdar@Sun.COM 	int opcode = NDMP_GET_DOOR_STATUS;
4097917SReza.Sabdar@Sun.COM 
4107917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&ndmp_lock);
4117917SReza.Sabdar@Sun.COM 	if (ndmp_door_setup(opcode))
4127917SReza.Sabdar@Sun.COM 		goto err;
4137917SReza.Sabdar@Sun.COM 
4147917SReza.Sabdar@Sun.COM 	if (ndmp_door_call())
4157917SReza.Sabdar@Sun.COM 		goto err;
4167917SReza.Sabdar@Sun.COM 
4177917SReza.Sabdar@Sun.COM 	if (ndmp_door_fini())
4187917SReza.Sabdar@Sun.COM 		goto err;
4197917SReza.Sabdar@Sun.COM 
4207917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
4217917SReza.Sabdar@Sun.COM 	return (0);
4227917SReza.Sabdar@Sun.COM err:
4237917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&ndmp_lock);
4247917SReza.Sabdar@Sun.COM 	return (-1);
4257917SReza.Sabdar@Sun.COM }
4267917SReza.Sabdar@Sun.COM 
4277917SReza.Sabdar@Sun.COM static int
ndmp_door_setup(int opcode)4287917SReza.Sabdar@Sun.COM ndmp_door_setup(int opcode)
4297917SReza.Sabdar@Sun.COM {
4307917SReza.Sabdar@Sun.COM 	/* Open channel to NDMP service */
4317917SReza.Sabdar@Sun.COM 	if ((ndmp_door_fildes == -1) &&
4327917SReza.Sabdar@Sun.COM 	    (ndmp_door_fildes = open(NDMP_DOOR_SVC, O_RDONLY)) < 0) {
4337917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_DOOR_OPEN;
4347917SReza.Sabdar@Sun.COM 		return (-1);
4357917SReza.Sabdar@Sun.COM 	}
4367917SReza.Sabdar@Sun.COM 
4377917SReza.Sabdar@Sun.COM 	buf = malloc(NDMP_DOOR_SIZE);
4387917SReza.Sabdar@Sun.COM 	if (!buf) {
4397917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_MEM_ALLOC;
4407917SReza.Sabdar@Sun.COM 		return (-1);
4417917SReza.Sabdar@Sun.COM 	}
4427917SReza.Sabdar@Sun.COM 
4437917SReza.Sabdar@Sun.COM 	enc_ctx = ndmp_door_encode_start(buf, NDMP_DOOR_SIZE);
4447917SReza.Sabdar@Sun.COM 	if (enc_ctx == 0) {
4457917SReza.Sabdar@Sun.COM 		free(buf);
4467917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_DOOR_ENCODE_START;
4477917SReza.Sabdar@Sun.COM 		return (-1);
4487917SReza.Sabdar@Sun.COM 	}
4497917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint32(enc_ctx, opcode);
4507917SReza.Sabdar@Sun.COM 	return (0);
4517917SReza.Sabdar@Sun.COM }
4527917SReza.Sabdar@Sun.COM 
4537917SReza.Sabdar@Sun.COM static int
ndmp_door_call(void)4547917SReza.Sabdar@Sun.COM ndmp_door_call(void)
4557917SReza.Sabdar@Sun.COM {
4567917SReza.Sabdar@Sun.COM 	uint32_t used;
4577917SReza.Sabdar@Sun.COM 	int rc;
4587917SReza.Sabdar@Sun.COM 
4597917SReza.Sabdar@Sun.COM 	if ((ndmp_door_encode_finish(enc_ctx, &used)) != 0) {
4607917SReza.Sabdar@Sun.COM 		free(buf);
4617917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_DOOR_ENCODE_FINISH;
4627917SReza.Sabdar@Sun.COM 		return (-1);
4637917SReza.Sabdar@Sun.COM 	}
4647917SReza.Sabdar@Sun.COM 
4657917SReza.Sabdar@Sun.COM 	arg.data_ptr = buf;
4667917SReza.Sabdar@Sun.COM 	arg.data_size = used;
4677917SReza.Sabdar@Sun.COM 	arg.desc_ptr = NULL;
4687917SReza.Sabdar@Sun.COM 	arg.desc_num = 0;
4697917SReza.Sabdar@Sun.COM 	arg.rbuf = buf;
4707917SReza.Sabdar@Sun.COM 	arg.rsize = NDMP_DOOR_SIZE;
4717917SReza.Sabdar@Sun.COM 
4727917SReza.Sabdar@Sun.COM 	if (door_call(ndmp_door_fildes, &arg) < 0) {
4737917SReza.Sabdar@Sun.COM 		free(buf);
4747917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_DOOR_SRV_TIMEOUT;
4757917SReza.Sabdar@Sun.COM 		(void) close(ndmp_door_fildes);
4767917SReza.Sabdar@Sun.COM 		ndmp_door_fildes = -1;
4777917SReza.Sabdar@Sun.COM 		return (-1);
4787917SReza.Sabdar@Sun.COM 	}
4797917SReza.Sabdar@Sun.COM 
4807917SReza.Sabdar@Sun.COM 	dec_ctx = ndmp_door_decode_start(arg.data_ptr, arg.data_size);
4817917SReza.Sabdar@Sun.COM 	rc = ndmp_door_get_uint32(dec_ctx);
4827917SReza.Sabdar@Sun.COM 	if (rc != NDMP_DOOR_SRV_SUCCESS) {
4837917SReza.Sabdar@Sun.COM 		free(buf);
4847917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_DOOR_SRV_OPERATION;
4857917SReza.Sabdar@Sun.COM 		return (-1);
4867917SReza.Sabdar@Sun.COM 	}
4877917SReza.Sabdar@Sun.COM 	return (0);
4887917SReza.Sabdar@Sun.COM }
4897917SReza.Sabdar@Sun.COM 
4907917SReza.Sabdar@Sun.COM static int
ndmp_door_fini(void)4917917SReza.Sabdar@Sun.COM ndmp_door_fini(void)
4927917SReza.Sabdar@Sun.COM {
4937917SReza.Sabdar@Sun.COM 	if ((ndmp_door_decode_finish(dec_ctx)) != 0) {
4947917SReza.Sabdar@Sun.COM 		free(buf);
4957917SReza.Sabdar@Sun.COM 		ndmp_errno = ENDMP_DOOR_DECODE_FINISH;
4967917SReza.Sabdar@Sun.COM 		return (-1);
4977917SReza.Sabdar@Sun.COM 	}
4987917SReza.Sabdar@Sun.COM 	free(buf);
4997917SReza.Sabdar@Sun.COM 	return (0);
5007917SReza.Sabdar@Sun.COM }
501