Home | History | Annotate | Download | only in common
      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