xref: /illumos-gate/usr/src/lib/libidmap/common/utils.c (revision 2b24ab6b3865caeede9eeb9db6b83e1d89dcd1ea)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Utility routines
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <libintl.h>
36 #include "idmap_impl.h"
37 
38 #define	_UDT_SIZE_INCR	1
39 
40 #define	_GET_IDS_SIZE_INCR	1
41 
42 static struct timeval TIMEOUT = { 25, 0 };
43 
44 idmap_retcode
45 _udt_extend_batch(idmap_udt_handle_t *udthandle)
46 {
47 	idmap_update_op	*tmplist;
48 	size_t		nsize;
49 
50 	if (udthandle->next >= udthandle->batch.idmap_update_batch_len) {
51 		nsize = (udthandle->batch.idmap_update_batch_len +
52 		    _UDT_SIZE_INCR) * sizeof (*tmplist);
53 		tmplist = realloc(
54 		    udthandle->batch.idmap_update_batch_val, nsize);
55 		if (tmplist == NULL)
56 			return (IDMAP_ERR_MEMORY);
57 		(void) memset((uchar_t *)tmplist +
58 		    (udthandle->batch.idmap_update_batch_len *
59 		    sizeof (*tmplist)), 0,
60 		    _UDT_SIZE_INCR * sizeof (*tmplist));
61 		udthandle->batch.idmap_update_batch_val = tmplist;
62 		udthandle->batch.idmap_update_batch_len += _UDT_SIZE_INCR;
63 	}
64 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
65 	    OP_NONE;
66 	return (IDMAP_SUCCESS);
67 }
68 
69 idmap_retcode
70 _get_ids_extend_batch(idmap_get_handle_t *gh)
71 {
72 	idmap_mapping	*t1;
73 	idmap_get_res_t	*t2;
74 	size_t		nsize, len;
75 
76 	len = gh->batch.idmap_mapping_batch_len;
77 	if (gh->next >= len) {
78 		/* extend the request array */
79 		nsize = (len + _GET_IDS_SIZE_INCR) * sizeof (*t1);
80 		t1 = realloc(gh->batch.idmap_mapping_batch_val, nsize);
81 		if (t1 == NULL)
82 			return (IDMAP_ERR_MEMORY);
83 		(void) memset((uchar_t *)t1 + (len * sizeof (*t1)), 0,
84 		    _GET_IDS_SIZE_INCR * sizeof (*t1));
85 		gh->batch.idmap_mapping_batch_val = t1;
86 
87 		/* extend the return list */
88 		nsize = (len + _GET_IDS_SIZE_INCR) * sizeof (*t2);
89 		t2 = realloc(gh->retlist, nsize);
90 		if (t2 == NULL)
91 			return (IDMAP_ERR_MEMORY);
92 		(void) memset((uchar_t *)t2 + (len * sizeof (*t2)), 0,
93 		    _GET_IDS_SIZE_INCR * sizeof (*t2));
94 		gh->retlist = t2;
95 
96 		gh->batch.idmap_mapping_batch_len += _GET_IDS_SIZE_INCR;
97 	}
98 	return (IDMAP_SUCCESS);
99 }
100 
101 idmap_stat
102 _iter_get_next_list(int type, idmap_iter_t *iter,
103 		void *arg, uchar_t **list, size_t valsize,
104 		xdrproc_t xdr_arg_proc, xdrproc_t xdr_res_proc)
105 {
106 
107 	CLIENT		*clnt;
108 	enum clnt_stat	clntstat;
109 
110 	iter->next = 0;
111 	iter->retlist = NULL;
112 	_IDMAP_GET_CLIENT_HANDLE(iter->ih, clnt);
113 
114 	/* init the result */
115 	if (*list) {
116 		xdr_free(xdr_res_proc, (caddr_t)*list);
117 	} else {
118 		if ((*list = malloc(valsize)) == NULL) {
119 			errno = ENOMEM;
120 			return (IDMAP_ERR_MEMORY);
121 		}
122 	}
123 	(void) memset(*list, 0, valsize);
124 
125 	clntstat = clnt_call(clnt, type,
126 	    xdr_arg_proc, (caddr_t)arg,
127 	    xdr_res_proc, (caddr_t)*list,
128 	    TIMEOUT);
129 	if (clntstat != RPC_SUCCESS) {
130 		free(*list);
131 		return (_idmap_rpc2stat(clnt));
132 	}
133 	iter->retlist = *list;
134 	return (IDMAP_SUCCESS);
135 }
136 
137 idmap_stat
138 _idmap_rpc2stat(CLIENT *clnt)
139 {
140 	/*
141 	 * We only deal with door_call(3C) errors here. We look at
142 	 * r_err.re_errno instead of r_err.re_status because we need
143 	 * to differentiate between RPC failures caused by bad door fd
144 	 * and others.
145 	 */
146 	struct rpc_err r_err;
147 	if (clnt) {
148 		clnt_geterr(clnt, &r_err);
149 		errno = r_err.re_errno;
150 		switch (r_err.re_errno) {
151 		case ENOMEM:
152 			return (IDMAP_ERR_MEMORY);
153 		case EBADF:
154 			return (IDMAP_ERR_RPC_HANDLE);
155 		default:
156 			return (IDMAP_ERR_RPC);
157 		}
158 	}
159 
160 	/* null handle */
161 	return (IDMAP_ERR_RPC_HANDLE);
162 }
163