xref: /titanic_44/usr/src/lib/libndmp/common/libndmp.c (revision 2654012f83cec5dc15b61dfe3e4a4915f186e7a6)
1*2654012fSReza Sabdar /*
2*2654012fSReza Sabdar  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3*2654012fSReza Sabdar  * Use is subject to license terms.
4*2654012fSReza Sabdar  */
5*2654012fSReza Sabdar 
6*2654012fSReza Sabdar /*
7*2654012fSReza Sabdar  * BSD 3 Clause License
8*2654012fSReza Sabdar  *
9*2654012fSReza Sabdar  * Copyright (c) 2007, The Storage Networking Industry Association.
10*2654012fSReza Sabdar  *
11*2654012fSReza Sabdar  * Redistribution and use in source and binary forms, with or without
12*2654012fSReza Sabdar  * modification, are permitted provided that the following conditions
13*2654012fSReza Sabdar  * are met:
14*2654012fSReza Sabdar  * 	- Redistributions of source code must retain the above copyright
15*2654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
16*2654012fSReza Sabdar  *
17*2654012fSReza Sabdar  * 	- Redistributions in binary form must reproduce the above copyright
18*2654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer in
19*2654012fSReza Sabdar  *	  the documentation and/or other materials provided with the
20*2654012fSReza Sabdar  *	  distribution.
21*2654012fSReza Sabdar  *
22*2654012fSReza Sabdar  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23*2654012fSReza Sabdar  *	  nor the names of its contributors may be used to endorse or promote
24*2654012fSReza Sabdar  *	  products derived from this software without specific prior written
25*2654012fSReza Sabdar  *	  permission.
26*2654012fSReza Sabdar  *
27*2654012fSReza Sabdar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*2654012fSReza Sabdar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*2654012fSReza Sabdar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*2654012fSReza Sabdar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*2654012fSReza Sabdar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*2654012fSReza Sabdar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*2654012fSReza Sabdar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*2654012fSReza Sabdar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*2654012fSReza Sabdar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*2654012fSReza Sabdar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*2654012fSReza Sabdar  * POSSIBILITY OF SUCH DAMAGE.
38*2654012fSReza Sabdar  */
39*2654012fSReza Sabdar #include <locale.h>
40*2654012fSReza Sabdar #include <stdlib.h>
41*2654012fSReza Sabdar #include <strings.h>
42*2654012fSReza Sabdar #include <unistd.h>
43*2654012fSReza Sabdar #include <fcntl.h>
44*2654012fSReza Sabdar #include <door.h>
45*2654012fSReza Sabdar #include <thread.h>
46*2654012fSReza Sabdar #include <ndmpd_door.h>
47*2654012fSReza Sabdar #include <libndmp.h>
48*2654012fSReza Sabdar 
49*2654012fSReza Sabdar static int ndmp_door_fildes = -1;
50*2654012fSReza Sabdar static char *buf;
51*2654012fSReza Sabdar static ndmp_door_ctx_t *dec_ctx;
52*2654012fSReza Sabdar static ndmp_door_ctx_t *enc_ctx;
53*2654012fSReza Sabdar static door_arg_t arg;
54*2654012fSReza Sabdar static mutex_t ndmp_lock = DEFAULTMUTEX;
55*2654012fSReza Sabdar 
56*2654012fSReza Sabdar static int ndmp_door_setup(int opcode);
57*2654012fSReza Sabdar static int ndmp_door_call(void);
58*2654012fSReza Sabdar static int ndmp_door_fini(void);
59*2654012fSReza Sabdar 
60*2654012fSReza Sabdar /* ndmp library APIs */
61*2654012fSReza Sabdar int
62*2654012fSReza Sabdar ndmp_get_devinfo(ndmp_devinfo_t **dip, size_t *size)
63*2654012fSReza Sabdar {
64*2654012fSReza Sabdar 	ndmp_devinfo_t *dipptr;
65*2654012fSReza Sabdar 	int i;
66*2654012fSReza Sabdar 	int opcode = NDMP_DEVICES_GET_INFO;
67*2654012fSReza Sabdar 
68*2654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
69*2654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
70*2654012fSReza Sabdar 		goto err;
71*2654012fSReza Sabdar 
72*2654012fSReza Sabdar 	if (ndmp_door_call())
73*2654012fSReza Sabdar 		goto err;
74*2654012fSReza Sabdar 
75*2654012fSReza Sabdar 	/* get the number of devices available */
76*2654012fSReza Sabdar 	*size = ndmp_door_get_uint32(dec_ctx);
77*2654012fSReza Sabdar 
78*2654012fSReza Sabdar 	*dip = malloc(sizeof (ndmp_devinfo_t) * *size);
79*2654012fSReza Sabdar 	if (!*dip) {
80*2654012fSReza Sabdar 		free(buf);
81*2654012fSReza Sabdar 		ndmp_errno = ENDMP_MEM_ALLOC;
82*2654012fSReza Sabdar 		goto err;
83*2654012fSReza Sabdar 	}
84*2654012fSReza Sabdar 	dipptr = *dip;
85*2654012fSReza Sabdar 	for (i = 0; i < *size; i++, dipptr++) {
86*2654012fSReza Sabdar 		dipptr->nd_dev_type = ndmp_door_get_int32(dec_ctx);
87*2654012fSReza Sabdar 		dipptr->nd_name = ndmp_door_get_string(dec_ctx);
88*2654012fSReza Sabdar 		dipptr->nd_lun = ndmp_door_get_int32(dec_ctx);
89*2654012fSReza Sabdar 		dipptr->nd_sid = ndmp_door_get_int32(dec_ctx);
90*2654012fSReza Sabdar 		dipptr->nd_vendor = ndmp_door_get_string(dec_ctx);
91*2654012fSReza Sabdar 		dipptr->nd_product = ndmp_door_get_string(dec_ctx);
92*2654012fSReza Sabdar 		dipptr->nd_revision = ndmp_door_get_string(dec_ctx);
93*2654012fSReza Sabdar 	}
94*2654012fSReza Sabdar 	if (ndmp_door_fini()) {
95*2654012fSReza Sabdar 		free(*dip);
96*2654012fSReza Sabdar 		goto err;
97*2654012fSReza Sabdar 	}
98*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
99*2654012fSReza Sabdar 	return (0);
100*2654012fSReza Sabdar err:
101*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
102*2654012fSReza Sabdar 	return (-1);
103*2654012fSReza Sabdar }
104*2654012fSReza Sabdar 
105*2654012fSReza Sabdar void
106*2654012fSReza Sabdar ndmp_get_devinfo_free(ndmp_devinfo_t *dip, size_t size)
107*2654012fSReza Sabdar {
108*2654012fSReza Sabdar 	ndmp_devinfo_t *dipptr;
109*2654012fSReza Sabdar 	int i;
110*2654012fSReza Sabdar 
111*2654012fSReza Sabdar 	dipptr = dip;
112*2654012fSReza Sabdar 	for (i = 0; i < size; i++, dipptr++) {
113*2654012fSReza Sabdar 		free(dipptr->nd_name);
114*2654012fSReza Sabdar 		free(dipptr->nd_vendor);
115*2654012fSReza Sabdar 		free(dipptr->nd_product);
116*2654012fSReza Sabdar 		free(dipptr->nd_revision);
117*2654012fSReza Sabdar 	}
118*2654012fSReza Sabdar 	free(dip);
119*2654012fSReza Sabdar }
120*2654012fSReza Sabdar 
121*2654012fSReza Sabdar int
122*2654012fSReza Sabdar ndmp_terminate_session(int session)
123*2654012fSReza Sabdar {
124*2654012fSReza Sabdar 	int ret;
125*2654012fSReza Sabdar 	int opcode = NDMP_TERMINATE_SESSION_ID;
126*2654012fSReza Sabdar 
127*2654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
128*2654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
129*2654012fSReza Sabdar 		goto err;
130*2654012fSReza Sabdar 
131*2654012fSReza Sabdar 	ndmp_door_put_uint32(enc_ctx, session);
132*2654012fSReza Sabdar 	if (ndmp_door_call())
133*2654012fSReza Sabdar 		goto err;
134*2654012fSReza Sabdar 
135*2654012fSReza Sabdar 	ret = ndmp_door_get_uint32(dec_ctx);
136*2654012fSReza Sabdar 	if (ndmp_door_fini())
137*2654012fSReza Sabdar 		goto err;
138*2654012fSReza Sabdar 
139*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
140*2654012fSReza Sabdar 	return (ret);
141*2654012fSReza Sabdar err:
142*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
143*2654012fSReza Sabdar 	return (-1);
144*2654012fSReza Sabdar }
145*2654012fSReza Sabdar 
146*2654012fSReza Sabdar int
147*2654012fSReza Sabdar ndmp_get_session_info(ndmp_session_info_t **sinfo, size_t *size)
148*2654012fSReza Sabdar {
149*2654012fSReza Sabdar 	int status;
150*2654012fSReza Sabdar 	int i, j;
151*2654012fSReza Sabdar 	ndmp_session_info_t *sp;
152*2654012fSReza Sabdar 	ndmp_dt_pval_t *ep;
153*2654012fSReza Sabdar 	ndmp_dt_name_t *np;
154*2654012fSReza Sabdar 	ndmp_dt_name_v3_t *npv3;
155*2654012fSReza Sabdar 	int opcode = NDMP_SHOW;
156*2654012fSReza Sabdar 
157*2654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
158*2654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
159*2654012fSReza Sabdar 		goto err;
160*2654012fSReza Sabdar 
161*2654012fSReza Sabdar 	if (ndmp_door_call())
162*2654012fSReza Sabdar 		goto err;
163*2654012fSReza Sabdar 
164*2654012fSReza Sabdar 	/* number of sessions */
165*2654012fSReza Sabdar 	*size = ndmp_door_get_int32(dec_ctx);
166*2654012fSReza Sabdar 
167*2654012fSReza Sabdar 	*sinfo = malloc((sizeof (ndmp_session_info_t)) * *size);
168*2654012fSReza Sabdar 	if (!*sinfo) {
169*2654012fSReza Sabdar 		free(buf);
170*2654012fSReza Sabdar 		ndmp_errno = ENDMP_MEM_ALLOC;
171*2654012fSReza Sabdar 		goto err;
172*2654012fSReza Sabdar 	}
173*2654012fSReza Sabdar 	sp = *sinfo;
174*2654012fSReza Sabdar 	for (i = 0; i < *size; i++, sp++) {
175*2654012fSReza Sabdar 		status = ndmp_door_get_int32(dec_ctx);
176*2654012fSReza Sabdar 		if (status == NDMP_SESSION_NODATA)
177*2654012fSReza Sabdar 			continue;
178*2654012fSReza Sabdar 
179*2654012fSReza Sabdar 		/* connection common info */
180*2654012fSReza Sabdar 		sp->nsi_sid = ndmp_door_get_int32(dec_ctx);
181*2654012fSReza Sabdar 		sp->nsi_pver = ndmp_door_get_int32(dec_ctx);
182*2654012fSReza Sabdar 		sp->nsi_auth = ndmp_door_get_int32(dec_ctx);
183*2654012fSReza Sabdar 		sp->nsi_eof = ndmp_door_get_int32(dec_ctx);
184*2654012fSReza Sabdar 		sp->nsi_cl_addr = ndmp_door_get_string(dec_ctx);
185*2654012fSReza Sabdar 		/*
186*2654012fSReza Sabdar 		 * scsi and tape data are same for all version,
187*2654012fSReza Sabdar 		 * so keep reading
188*2654012fSReza Sabdar 		 */
189*2654012fSReza Sabdar 		/* connection common scsi info.   */
190*2654012fSReza Sabdar 		sp->nsi_scsi.ns_scsi_open = ndmp_door_get_int32(dec_ctx);
191*2654012fSReza Sabdar 		sp->nsi_scsi.ns_adapter_name = ndmp_door_get_string(dec_ctx);
192*2654012fSReza Sabdar 		sp->nsi_scsi.ns_valid_target_set = ndmp_door_get_int32(dec_ctx);
193*2654012fSReza Sabdar 		if (sp->nsi_scsi.ns_valid_target_set) {
194*2654012fSReza Sabdar 			sp->nsi_scsi.ns_scsi_id = ndmp_door_get_int32(dec_ctx);
195*2654012fSReza Sabdar 			sp->nsi_scsi.ns_lun = ndmp_door_get_int32(dec_ctx);
196*2654012fSReza Sabdar 		}
197*2654012fSReza Sabdar 
198*2654012fSReza Sabdar 		/* connection common tape info.   */
199*2654012fSReza Sabdar 		sp->nsi_tape.nt_fd = ndmp_door_get_int32(dec_ctx);
200*2654012fSReza Sabdar 		if (sp->nsi_tape.nt_fd != -1) {
201*2654012fSReza Sabdar 			sp->nsi_tape.nt_rec_count =
202*2654012fSReza Sabdar 			    ndmp_door_get_uint64(dec_ctx);
203*2654012fSReza Sabdar 			sp->nsi_tape.nt_mode = ndmp_door_get_int32(dec_ctx);
204*2654012fSReza Sabdar 			sp->nsi_tape.nt_dev_name =
205*2654012fSReza Sabdar 			    ndmp_door_get_string(dec_ctx);
206*2654012fSReza Sabdar 			sp->nsi_tape.nt_adapter_name =
207*2654012fSReza Sabdar 			    ndmp_door_get_string(dec_ctx);
208*2654012fSReza Sabdar 			sp->nsi_tape.nt_sid = ndmp_door_get_int32(dec_ctx);
209*2654012fSReza Sabdar 			sp->nsi_tape.nt_lun = ndmp_door_get_int32(dec_ctx);
210*2654012fSReza Sabdar 		}
211*2654012fSReza Sabdar 		/* all the V2 mover data are same as V3/V4 */
212*2654012fSReza Sabdar 		sp->nsi_mover.nm_state = ndmp_door_get_int32(dec_ctx);
213*2654012fSReza Sabdar 		sp->nsi_mover.nm_mode = ndmp_door_get_int32(dec_ctx);
214*2654012fSReza Sabdar 		sp->nsi_mover.nm_pause_reason = ndmp_door_get_int32(dec_ctx);
215*2654012fSReza Sabdar 		sp->nsi_mover.nm_halt_reason = ndmp_door_get_int32(dec_ctx);
216*2654012fSReza Sabdar 		sp->nsi_mover.nm_rec_size = ndmp_door_get_uint64(dec_ctx);
217*2654012fSReza Sabdar 		sp->nsi_mover.nm_rec_num = ndmp_door_get_uint64(dec_ctx);
218*2654012fSReza Sabdar 		sp->nsi_mover.nm_mov_pos = ndmp_door_get_uint64(dec_ctx);
219*2654012fSReza Sabdar 		sp->nsi_mover.nm_window_offset = ndmp_door_get_uint64(dec_ctx);
220*2654012fSReza Sabdar 		sp->nsi_mover.nm_window_length = ndmp_door_get_uint64(dec_ctx);
221*2654012fSReza Sabdar 		sp->nsi_mover.nm_sock = ndmp_door_get_int32(dec_ctx);
222*2654012fSReza Sabdar 
223*2654012fSReza Sabdar 		/* Read V3/V4 mover info */
224*2654012fSReza Sabdar 		if ((sp->nsi_pver == NDMP_V3) || (sp->nsi_pver == NDMP_V4)) {
225*2654012fSReza Sabdar 			sp->nsi_mover.nm_listen_sock =
226*2654012fSReza Sabdar 			    ndmp_door_get_int32(dec_ctx);
227*2654012fSReza Sabdar 			sp->nsi_mover.nm_addr_type =
228*2654012fSReza Sabdar 			    ndmp_door_get_int32(dec_ctx);
229*2654012fSReza Sabdar 			sp->nsi_mover.nm_tcp_addr =
230*2654012fSReza Sabdar 			    ndmp_door_get_string(dec_ctx);
231*2654012fSReza Sabdar 		}
232*2654012fSReza Sabdar 
233*2654012fSReza Sabdar 		/* connection common data info */
234*2654012fSReza Sabdar 		sp->nsi_data.nd_oper = ndmp_door_get_int32(dec_ctx);
235*2654012fSReza Sabdar 		sp->nsi_data.nd_state = ndmp_door_get_int32(dec_ctx);
236*2654012fSReza Sabdar 		sp->nsi_data.nd_halt_reason = ndmp_door_get_int32(dec_ctx);
237*2654012fSReza Sabdar 		sp->nsi_data.nd_sock = ndmp_door_get_int32(dec_ctx);
238*2654012fSReza Sabdar 		sp->nsi_data.nd_addr_type = ndmp_door_get_int32(dec_ctx);
239*2654012fSReza Sabdar 		sp->nsi_data.nd_abort = ndmp_door_get_int32(dec_ctx);
240*2654012fSReza Sabdar 		sp->nsi_data.nd_read_offset = ndmp_door_get_uint64(dec_ctx);
241*2654012fSReza Sabdar 		sp->nsi_data.nd_read_length = ndmp_door_get_uint64(dec_ctx);
242*2654012fSReza Sabdar 		sp->nsi_data.nd_total_size = ndmp_door_get_uint64(dec_ctx);
243*2654012fSReza Sabdar 		sp->nsi_data.nd_env_len = ndmp_door_get_uint64(dec_ctx);
244*2654012fSReza Sabdar 		sp->nsi_data.nd_env =
245*2654012fSReza Sabdar 		    malloc(sizeof (ndmp_dt_pval_t) * sp->nsi_data.nd_env_len);
246*2654012fSReza Sabdar 		if (!sp->nsi_data.nd_env) {
247*2654012fSReza Sabdar 			free(buf);
248*2654012fSReza Sabdar 			ndmp_errno = ENDMP_MEM_ALLOC;
249*2654012fSReza Sabdar 			goto err;
250*2654012fSReza Sabdar 		}
251*2654012fSReza Sabdar 		ep = sp->nsi_data.nd_env;
252*2654012fSReza Sabdar 		for (j = 0; j < sp->nsi_data.nd_env_len; j++, ep++) {
253*2654012fSReza Sabdar 			ep->np_name = ndmp_door_get_string(dec_ctx);
254*2654012fSReza Sabdar 			ep->np_value = ndmp_door_get_string(dec_ctx);
255*2654012fSReza Sabdar 		}
256*2654012fSReza Sabdar 		sp->nsi_data.nd_tcp_addr = ndmp_door_get_string(dec_ctx);
257*2654012fSReza Sabdar 
258*2654012fSReza Sabdar 		/* Read V2 data info */
259*2654012fSReza Sabdar 		if (sp->nsi_pver == NDMP_V2) {
260*2654012fSReza Sabdar 			sp->nsi_data.nld_nlist_len =
261*2654012fSReza Sabdar 			    ndmp_door_get_int64(dec_ctx);
262*2654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_nlist =
263*2654012fSReza Sabdar 			    malloc(sizeof (ndmp_dt_name_t) *
264*2654012fSReza Sabdar 			    sp->nsi_data.nld_nlist_len);
265*2654012fSReza Sabdar 			if (!sp->nsi_data.nd_nlist.nld_nlist) {
266*2654012fSReza Sabdar 				free(buf);
267*2654012fSReza Sabdar 				ndmp_errno = ENDMP_MEM_ALLOC;
268*2654012fSReza Sabdar 				goto err;
269*2654012fSReza Sabdar 			}
270*2654012fSReza Sabdar 			np = sp->nsi_data.nd_nlist.nld_nlist;
271*2654012fSReza Sabdar 
272*2654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len; j++, np++) {
273*2654012fSReza Sabdar 				np->nn_name = ndmp_door_get_string(dec_ctx);
274*2654012fSReza Sabdar 				np->nn_dest = ndmp_door_get_string(dec_ctx);
275*2654012fSReza Sabdar 			}
276*2654012fSReza Sabdar 		} else if ((sp->nsi_pver == NDMP_V3) ||
277*2654012fSReza Sabdar 		    (sp->nsi_pver == NDMP_V4)) {
278*2654012fSReza Sabdar 			/* Read V3/V4 data info */
279*2654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock =
280*2654012fSReza Sabdar 			    ndmp_door_get_int32(dec_ctx);
281*2654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_bytes_processed =
282*2654012fSReza Sabdar 			    ndmp_door_get_uint64(dec_ctx);
283*2654012fSReza Sabdar 			sp->nsi_data.nld_nlist_len =
284*2654012fSReza Sabdar 			    ndmp_door_get_uint64(dec_ctx);
285*2654012fSReza Sabdar 			sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist =
286*2654012fSReza Sabdar 			    malloc(sizeof (ndmp_dt_name_v3_t) *
287*2654012fSReza Sabdar 			    sp->nsi_data.nld_nlist_len);
288*2654012fSReza Sabdar 			if (!sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist) {
289*2654012fSReza Sabdar 				free(buf);
290*2654012fSReza Sabdar 				ndmp_errno = ENDMP_MEM_ALLOC;
291*2654012fSReza Sabdar 				goto err;
292*2654012fSReza Sabdar 			}
293*2654012fSReza Sabdar 			npv3 = sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
294*2654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len;
295*2654012fSReza Sabdar 			    j++, npv3++) {
296*2654012fSReza Sabdar 				npv3->nn3_opath = ndmp_door_get_string(dec_ctx);
297*2654012fSReza Sabdar 				npv3->nn3_dpath = ndmp_door_get_string(dec_ctx);
298*2654012fSReza Sabdar 				npv3->nn3_node = ndmp_door_get_uint64(dec_ctx);
299*2654012fSReza Sabdar 				npv3->nn3_fh_info =
300*2654012fSReza Sabdar 				    ndmp_door_get_uint64(dec_ctx);
301*2654012fSReza Sabdar 			}
302*2654012fSReza Sabdar 		}
303*2654012fSReza Sabdar 	}
304*2654012fSReza Sabdar 
305*2654012fSReza Sabdar 	if (ndmp_door_fini())
306*2654012fSReza Sabdar 		goto err;
307*2654012fSReza Sabdar 
308*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
309*2654012fSReza Sabdar 	return (0);
310*2654012fSReza Sabdar err:
311*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
312*2654012fSReza Sabdar 	return (-1);
313*2654012fSReza Sabdar }
314*2654012fSReza Sabdar 
315*2654012fSReza Sabdar void
316*2654012fSReza Sabdar ndmp_get_session_info_free(ndmp_session_info_t *sinfo, size_t size)
317*2654012fSReza Sabdar {
318*2654012fSReza Sabdar 	ndmp_session_info_t *sp;
319*2654012fSReza Sabdar 	ndmp_dt_pval_t *ep;
320*2654012fSReza Sabdar 	ndmp_dt_name_t *np;
321*2654012fSReza Sabdar 	ndmp_dt_name_v3_t *npv3;
322*2654012fSReza Sabdar 	int i, j;
323*2654012fSReza Sabdar 
324*2654012fSReza Sabdar 	sp = sinfo;
325*2654012fSReza Sabdar 	for (i = 0; i < size; i++, sp++) {
326*2654012fSReza Sabdar 		free(sp->nsi_cl_addr);
327*2654012fSReza Sabdar 		free(sp->nsi_scsi.ns_adapter_name);
328*2654012fSReza Sabdar 		if (sp->nsi_tape.nt_fd != -1) {
329*2654012fSReza Sabdar 			free(sp->nsi_tape.nt_dev_name);
330*2654012fSReza Sabdar 			free(sp->nsi_tape.nt_adapter_name);
331*2654012fSReza Sabdar 		}
332*2654012fSReza Sabdar 		if ((sp->nsi_pver == NDMP_V3) || (sp->nsi_pver == NDMP_V4))
333*2654012fSReza Sabdar 			free(sp->nsi_mover.nm_tcp_addr);
334*2654012fSReza Sabdar 
335*2654012fSReza Sabdar 		ep = sp->nsi_data.nd_env;
336*2654012fSReza Sabdar 		for (j = 0; j < sp->nsi_data.nd_env_len; j++, ep++) {
337*2654012fSReza Sabdar 			free(ep->np_name);
338*2654012fSReza Sabdar 			free(ep->np_value);
339*2654012fSReza Sabdar 		}
340*2654012fSReza Sabdar 		free(sp->nsi_data.nd_env);
341*2654012fSReza Sabdar 		free(sp->nsi_data.nd_tcp_addr);
342*2654012fSReza Sabdar 
343*2654012fSReza Sabdar 		if (sp->nsi_pver == NDMP_V2) {
344*2654012fSReza Sabdar 			np = sp->nsi_data.nd_nlist.nld_nlist;
345*2654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len; j++, np++) {
346*2654012fSReza Sabdar 				free(np->nn_name);
347*2654012fSReza Sabdar 				free(np->nn_dest);
348*2654012fSReza Sabdar 			}
349*2654012fSReza Sabdar 			free(sp->nsi_data.nd_nlist.nld_nlist);
350*2654012fSReza Sabdar 		} else if ((sp->nsi_pver == NDMP_V3) ||
351*2654012fSReza Sabdar 		    (sp->nsi_pver == NDMP_V4)) {
352*2654012fSReza Sabdar 			npv3 = sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
353*2654012fSReza Sabdar 			for (j = 0; j < sp->nsi_data.nld_nlist_len;
354*2654012fSReza Sabdar 			    j++, npv3++) {
355*2654012fSReza Sabdar 				free(npv3->nn3_opath);
356*2654012fSReza Sabdar 				free(npv3->nn3_dpath);
357*2654012fSReza Sabdar 			}
358*2654012fSReza Sabdar 			free(sp->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist);
359*2654012fSReza Sabdar 		}
360*2654012fSReza Sabdar 	}
361*2654012fSReza Sabdar 	free(sinfo);
362*2654012fSReza Sabdar }
363*2654012fSReza Sabdar 
364*2654012fSReza Sabdar /* ARGSUSED */
365*2654012fSReza Sabdar int
366*2654012fSReza Sabdar ndmp_get_stats(ndmp_stat_t *statp)
367*2654012fSReza Sabdar {
368*2654012fSReza Sabdar 	int opcode = NDMP_GET_STAT;
369*2654012fSReza Sabdar 
370*2654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
371*2654012fSReza Sabdar 	if (!statp) {
372*2654012fSReza Sabdar 		ndmp_errno = ENDMP_INVALID_ARG;
373*2654012fSReza Sabdar 		goto err;
374*2654012fSReza Sabdar 	}
375*2654012fSReza Sabdar 
376*2654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
377*2654012fSReza Sabdar 		goto err;
378*2654012fSReza Sabdar 
379*2654012fSReza Sabdar 	if (ndmp_door_call())
380*2654012fSReza Sabdar 		goto err;
381*2654012fSReza Sabdar 
382*2654012fSReza Sabdar 	statp->ns_trun = ndmp_door_get_uint32(dec_ctx);
383*2654012fSReza Sabdar 	statp->ns_twait = ndmp_door_get_uint32(dec_ctx);
384*2654012fSReza Sabdar 	statp->ns_nbk = ndmp_door_get_uint32(dec_ctx);
385*2654012fSReza Sabdar 	statp->ns_nrs = ndmp_door_get_uint32(dec_ctx);
386*2654012fSReza Sabdar 	statp->ns_rfile = ndmp_door_get_uint32(dec_ctx);
387*2654012fSReza Sabdar 	statp->ns_wfile = ndmp_door_get_uint32(dec_ctx);
388*2654012fSReza Sabdar 	statp->ns_rdisk = ndmp_door_get_uint64(dec_ctx);
389*2654012fSReza Sabdar 	statp->ns_wdisk = ndmp_door_get_uint64(dec_ctx);
390*2654012fSReza Sabdar 	statp->ns_rtape = ndmp_door_get_uint64(dec_ctx);
391*2654012fSReza Sabdar 	statp->ns_wtape = ndmp_door_get_uint64(dec_ctx);
392*2654012fSReza Sabdar 
393*2654012fSReza Sabdar 	if (ndmp_door_fini())
394*2654012fSReza Sabdar 		goto err;
395*2654012fSReza Sabdar 
396*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
397*2654012fSReza Sabdar 	return (0);
398*2654012fSReza Sabdar err:
399*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
400*2654012fSReza Sabdar 	return (-1);
401*2654012fSReza Sabdar }
402*2654012fSReza Sabdar 
403*2654012fSReza Sabdar int
404*2654012fSReza Sabdar ndmp_door_status(void)
405*2654012fSReza Sabdar {
406*2654012fSReza Sabdar 	int opcode = NDMP_GET_DOOR_STATUS;
407*2654012fSReza Sabdar 
408*2654012fSReza Sabdar 	(void) mutex_lock(&ndmp_lock);
409*2654012fSReza Sabdar 	if (ndmp_door_setup(opcode))
410*2654012fSReza Sabdar 		goto err;
411*2654012fSReza Sabdar 
412*2654012fSReza Sabdar 	if (ndmp_door_call())
413*2654012fSReza Sabdar 		goto err;
414*2654012fSReza Sabdar 
415*2654012fSReza Sabdar 	if (ndmp_door_fini())
416*2654012fSReza Sabdar 		goto err;
417*2654012fSReza Sabdar 
418*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
419*2654012fSReza Sabdar 	return (0);
420*2654012fSReza Sabdar err:
421*2654012fSReza Sabdar 	(void) mutex_unlock(&ndmp_lock);
422*2654012fSReza Sabdar 	return (-1);
423*2654012fSReza Sabdar }
424*2654012fSReza Sabdar 
425*2654012fSReza Sabdar static int
426*2654012fSReza Sabdar ndmp_door_setup(int opcode)
427*2654012fSReza Sabdar {
428*2654012fSReza Sabdar 	/* Open channel to NDMP service */
429*2654012fSReza Sabdar 	if ((ndmp_door_fildes == -1) &&
430*2654012fSReza Sabdar 	    (ndmp_door_fildes = open(NDMP_DOOR_SVC, O_RDONLY)) < 0) {
431*2654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_OPEN;
432*2654012fSReza Sabdar 		return (-1);
433*2654012fSReza Sabdar 	}
434*2654012fSReza Sabdar 
435*2654012fSReza Sabdar 	buf = malloc(NDMP_DOOR_SIZE);
436*2654012fSReza Sabdar 	if (!buf) {
437*2654012fSReza Sabdar 		ndmp_errno = ENDMP_MEM_ALLOC;
438*2654012fSReza Sabdar 		return (-1);
439*2654012fSReza Sabdar 	}
440*2654012fSReza Sabdar 
441*2654012fSReza Sabdar 	enc_ctx = ndmp_door_encode_start(buf, NDMP_DOOR_SIZE);
442*2654012fSReza Sabdar 	if (enc_ctx == 0) {
443*2654012fSReza Sabdar 		free(buf);
444*2654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_ENCODE_START;
445*2654012fSReza Sabdar 		return (-1);
446*2654012fSReza Sabdar 	}
447*2654012fSReza Sabdar 	ndmp_door_put_uint32(enc_ctx, opcode);
448*2654012fSReza Sabdar 	return (0);
449*2654012fSReza Sabdar }
450*2654012fSReza Sabdar 
451*2654012fSReza Sabdar static int
452*2654012fSReza Sabdar ndmp_door_call(void)
453*2654012fSReza Sabdar {
454*2654012fSReza Sabdar 	uint32_t used;
455*2654012fSReza Sabdar 	int rc;
456*2654012fSReza Sabdar 
457*2654012fSReza Sabdar 	if ((ndmp_door_encode_finish(enc_ctx, &used)) != 0) {
458*2654012fSReza Sabdar 		free(buf);
459*2654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_ENCODE_FINISH;
460*2654012fSReza Sabdar 		return (-1);
461*2654012fSReza Sabdar 	}
462*2654012fSReza Sabdar 
463*2654012fSReza Sabdar 	arg.data_ptr = buf;
464*2654012fSReza Sabdar 	arg.data_size = used;
465*2654012fSReza Sabdar 	arg.desc_ptr = NULL;
466*2654012fSReza Sabdar 	arg.desc_num = 0;
467*2654012fSReza Sabdar 	arg.rbuf = buf;
468*2654012fSReza Sabdar 	arg.rsize = NDMP_DOOR_SIZE;
469*2654012fSReza Sabdar 
470*2654012fSReza Sabdar 	if (door_call(ndmp_door_fildes, &arg) < 0) {
471*2654012fSReza Sabdar 		free(buf);
472*2654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_SRV_TIMEOUT;
473*2654012fSReza Sabdar 		(void) close(ndmp_door_fildes);
474*2654012fSReza Sabdar 		ndmp_door_fildes = -1;
475*2654012fSReza Sabdar 		return (-1);
476*2654012fSReza Sabdar 	}
477*2654012fSReza Sabdar 
478*2654012fSReza Sabdar 	dec_ctx = ndmp_door_decode_start(arg.data_ptr, arg.data_size);
479*2654012fSReza Sabdar 	rc = ndmp_door_get_uint32(dec_ctx);
480*2654012fSReza Sabdar 	if (rc != NDMP_DOOR_SRV_SUCCESS) {
481*2654012fSReza Sabdar 		free(buf);
482*2654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_SRV_OPERATION;
483*2654012fSReza Sabdar 		return (-1);
484*2654012fSReza Sabdar 	}
485*2654012fSReza Sabdar 	return (0);
486*2654012fSReza Sabdar }
487*2654012fSReza Sabdar 
488*2654012fSReza Sabdar static int
489*2654012fSReza Sabdar ndmp_door_fini(void)
490*2654012fSReza Sabdar {
491*2654012fSReza Sabdar 	if ((ndmp_door_decode_finish(dec_ctx)) != 0) {
492*2654012fSReza Sabdar 		free(buf);
493*2654012fSReza Sabdar 		ndmp_errno = ENDMP_DOOR_DECODE_FINISH;
494*2654012fSReza Sabdar 		return (-1);
495*2654012fSReza Sabdar 	}
496*2654012fSReza Sabdar 	free(buf);
497*2654012fSReza Sabdar 	return (0);
498*2654012fSReza Sabdar }
499