14520Snw141292 /*
24520Snw141292  * CDDL HEADER START
34520Snw141292  *
44520Snw141292  * The contents of this file are subject to the terms of the
54520Snw141292  * Common Development and Distribution License (the "License").
64520Snw141292  * You may not use this file except in compliance with the License.
74520Snw141292  *
84520Snw141292  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94520Snw141292  * or http://www.opensolaris.org/os/licensing.
104520Snw141292  * See the License for the specific language governing permissions
114520Snw141292  * and limitations under the License.
124520Snw141292  *
134520Snw141292  * When distributing Covered Code, include this CDDL HEADER in each
144520Snw141292  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154520Snw141292  * If applicable, add the following below this CDDL HEADER, with the
164520Snw141292  * fields enclosed by brackets "[]" replaced with your own identifying
174520Snw141292  * information: Portions Copyright [yyyy] [name of copyright owner]
184520Snw141292  *
194520Snw141292  * CDDL HEADER END
204520Snw141292  */
214520Snw141292 /*
22*5908Sjp151216  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
234520Snw141292  * Use is subject to license terms.
244520Snw141292  */
254520Snw141292 
264520Snw141292 #pragma ident	"%Z%%M%	%I%	%E% SMI"
274520Snw141292 
284520Snw141292 /*
294520Snw141292  * Utility routines
304520Snw141292  */
314520Snw141292 
324520Snw141292 #include <stdio.h>
334520Snw141292 #include <stdlib.h>
344520Snw141292 #include <errno.h>
354520Snw141292 #include <libintl.h>
364520Snw141292 #include "idmap_impl.h"
374520Snw141292 
384520Snw141292 #define	_UDT_SIZE_INCR	1
394520Snw141292 
404520Snw141292 #define	_GET_IDS_SIZE_INCR	1
414520Snw141292 
424520Snw141292 static struct timeval TIMEOUT = { 25, 0 };
434520Snw141292 
444520Snw141292 idmap_retcode
45*5908Sjp151216 _udt_extend_batch(idmap_udt_handle_t *udthandle)
46*5908Sjp151216 {
474520Snw141292 	idmap_update_op	*tmplist;
484520Snw141292 	size_t		nsize;
494520Snw141292 
504520Snw141292 	if (udthandle->next >= udthandle->batch.idmap_update_batch_len) {
514520Snw141292 		nsize = (udthandle->batch.idmap_update_batch_len +
52*5908Sjp151216 		    _UDT_SIZE_INCR) * sizeof (*tmplist);
534520Snw141292 		tmplist = realloc(
54*5908Sjp151216 		    udthandle->batch.idmap_update_batch_val, nsize);
554520Snw141292 		if (tmplist == NULL)
564520Snw141292 			return (IDMAP_ERR_MEMORY);
574520Snw141292 		(void) memset((uchar_t *)tmplist +
58*5908Sjp151216 		    (udthandle->batch.idmap_update_batch_len *
59*5908Sjp151216 		    sizeof (*tmplist)), 0,
60*5908Sjp151216 		    _UDT_SIZE_INCR * sizeof (*tmplist));
614520Snw141292 		udthandle->batch.idmap_update_batch_val = tmplist;
624520Snw141292 		udthandle->batch.idmap_update_batch_len += _UDT_SIZE_INCR;
634520Snw141292 	}
644520Snw141292 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
65*5908Sjp151216 	    OP_NONE;
664520Snw141292 	return (IDMAP_SUCCESS);
674520Snw141292 }
684520Snw141292 
694520Snw141292 idmap_retcode
70*5908Sjp151216 _get_ids_extend_batch(idmap_get_handle_t *gh)
71*5908Sjp151216 {
724520Snw141292 	idmap_mapping	*t1;
734520Snw141292 	idmap_get_res_t	*t2;
744520Snw141292 	size_t		nsize, len;
754520Snw141292 
764520Snw141292 	len = gh->batch.idmap_mapping_batch_len;
774520Snw141292 	if (gh->next >= len) {
784520Snw141292 		/* extend the request array */
794520Snw141292 		nsize = (len + _GET_IDS_SIZE_INCR) * sizeof (*t1);
804520Snw141292 		t1 = realloc(gh->batch.idmap_mapping_batch_val, nsize);
814520Snw141292 		if (t1 == NULL)
824520Snw141292 			return (IDMAP_ERR_MEMORY);
834520Snw141292 		(void) memset((uchar_t *)t1 + (len * sizeof (*t1)), 0,
84*5908Sjp151216 		    _GET_IDS_SIZE_INCR * sizeof (*t1));
854520Snw141292 		gh->batch.idmap_mapping_batch_val = t1;
864520Snw141292 
874520Snw141292 		/* extend the return list */
884520Snw141292 		nsize = (len + _GET_IDS_SIZE_INCR) * sizeof (*t2);
894520Snw141292 		t2 = realloc(gh->retlist, nsize);
904520Snw141292 		if (t2 == NULL)
914520Snw141292 			return (IDMAP_ERR_MEMORY);
924520Snw141292 		(void) memset((uchar_t *)t2 + (len * sizeof (*t2)), 0,
93*5908Sjp151216 		    _GET_IDS_SIZE_INCR * sizeof (*t2));
944520Snw141292 		gh->retlist = t2;
954520Snw141292 
964520Snw141292 		gh->batch.idmap_mapping_batch_len += _GET_IDS_SIZE_INCR;
974520Snw141292 	}
984520Snw141292 	return (IDMAP_SUCCESS);
994520Snw141292 }
1004520Snw141292 
1014520Snw141292 idmap_stat
1024520Snw141292 _iter_get_next_list(int type, idmap_iter_t *iter,
1034520Snw141292 		void *arg, uchar_t **list, size_t valsize,
104*5908Sjp151216 		xdrproc_t xdr_arg_proc, xdrproc_t xdr_res_proc)
105*5908Sjp151216 {
1064520Snw141292 
1074520Snw141292 	CLIENT		*clnt;
1084520Snw141292 	enum clnt_stat	clntstat;
1094520Snw141292 
1104520Snw141292 	iter->next = 0;
1114520Snw141292 	iter->retlist = NULL;
1124520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(iter->ih, clnt);
1134520Snw141292 
1144520Snw141292 	/* init the result */
1154520Snw141292 	if (*list) {
1164520Snw141292 		xdr_free(xdr_res_proc, (caddr_t)*list);
1174520Snw141292 	} else {
1184520Snw141292 		if ((*list = malloc(valsize)) == NULL) {
1194520Snw141292 			errno = ENOMEM;
1204520Snw141292 			return (IDMAP_ERR_MEMORY);
1214520Snw141292 		}
1224520Snw141292 	}
1234520Snw141292 	(void) memset(*list, 0, valsize);
1244520Snw141292 
1254520Snw141292 	clntstat = clnt_call(clnt, type,
126*5908Sjp151216 	    xdr_arg_proc, (caddr_t)arg,
127*5908Sjp151216 	    xdr_res_proc, (caddr_t)*list,
128*5908Sjp151216 	    TIMEOUT);
1294520Snw141292 	if (clntstat != RPC_SUCCESS) {
1304520Snw141292 		free(*list);
1314644Sbaban 		return (_idmap_rpc2stat(clnt));
1324520Snw141292 	}
1334520Snw141292 	iter->retlist = *list;
1344520Snw141292 	return (IDMAP_SUCCESS);
1354520Snw141292 }
1364644Sbaban 
1374644Sbaban idmap_stat
138*5908Sjp151216 _idmap_rpc2stat(CLIENT *clnt)
139*5908Sjp151216 {
1404644Sbaban 	/*
1414644Sbaban 	 * We only deal with door_call(3C) errors here. We look at
1424644Sbaban 	 * r_err.re_errno instead of r_err.re_status because we need
1434644Sbaban 	 * to differentiate between RPC failures caused by bad door fd
1444644Sbaban 	 * and others.
1454644Sbaban 	 */
1464644Sbaban 	struct rpc_err r_err;
1474644Sbaban 	if (clnt) {
1484644Sbaban 		clnt_geterr(clnt, &r_err);
1494644Sbaban 		errno = r_err.re_errno;
1504644Sbaban 		switch (r_err.re_errno) {
1514644Sbaban 		case ENOMEM:
1524644Sbaban 			return (IDMAP_ERR_MEMORY);
1534644Sbaban 		case EBADF:
1544644Sbaban 			return (IDMAP_ERR_RPC_HANDLE);
1554644Sbaban 		default:
1564644Sbaban 			return (IDMAP_ERR_RPC);
1574644Sbaban 		}
1584644Sbaban 	}
1594644Sbaban 
1604644Sbaban 	/* null handle */
1614644Sbaban 	return (IDMAP_ERR_RPC_HANDLE);
1624644Sbaban }
163