xref: /illumos-gate/usr/src/lib/libidmap/common/utils.c (revision 4fe85d41bb4eb0db41934722f4b06c8acec2d25a)
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