Home | History | Annotate | Download | only in snoop
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <ctype.h>
     27 #include <string.h>
     28 #include <strings.h>
     29 #include <stdlib.h>
     30 #include <sys/types.h>
     31 #include <sys/errno.h>
     32 #include <sys/tiuser.h>
     33 #include <setjmp.h>
     34 #include <netdb.h>
     35 #include <sys/socket.h>
     36 #include <errno.h>
     37 
     38 #include <rpc/types.h>
     39 #include <rpc/xdr.h>
     40 #include <rpc/auth.h>
     41 #include <rpc/clnt.h>
     42 #include <rpc/rpc_msg.h>
     43 #include "snoop.h"
     44 
     45 #include <sys/stat.h>
     46 #include <sys/param.h>
     47 
     48 /*
     49  * We generate ds_nfs_com.h with -DUSE_FOR_SNOOP defined to
     50  * get the parts of the protocol which are already defined in
     51  * either the base NFSv4 or extended NFSv41 protocols.
     52  *
     53  * It will grab the definitions for us and the implementations
     54  * are over in ./nfs4_xdr.c.
     55  */
     56 #include "ds_nfs_com.h"
     57 #include "ds_prot.h"
     58 
     59 /*
     60  * Yuck, but with the way things are implemented, this works!.
     61  * And it needs to be before the "nfs4_cmn.h"
     62  */
     63 typedef ds_secinfo secinfo4;
     64 
     65 #include "nfs4_cmn.h"
     66 
     67 extern XDR xdrm;
     68 
     69 extern char *get_sum_line();
     70 extern jmp_buf xdr_err;
     71 
     72 typedef struct {
     73 	char *short_name;		/* for summary output */
     74 	char *long_name;		/* for detail output */
     75 } type_names_t;
     76 
     77 typedef struct {
     78 	char	*short_name;
     79 	char	*long_name;
     80 	void	(*args)(char *, bool_t);
     81 	void	(*res)(char *, bool_t);
     82 } op_info_t;
     83 
     84 static void ds_checkstate_args(char *, bool_t);
     85 static void ds_checkstate_res(char *, bool_t);
     86 static void ds_exibi_args(char *, bool_t);
     87 static void ds_exibi_res(char *, bool_t);
     88 static void ds_fmatpt_args(char *, bool_t);
     89 static void ds_fmatpt_res(char *, bool_t);
     90 static void ds_map_mds_dataset_id_args(char *, bool_t);
     91 static void ds_map_mds_dataset_id_res(char *, bool_t);
     92 static void ds_map_mdssid_args(char *, bool_t);
     93 static void ds_map_mdssid_res(char *, bool_t);
     94 static void ds_renew_args(char *, bool_t);
     95 static void ds_renew_res(char *, bool_t);
     96 static void ds_reportavail_args(char *, bool_t);
     97 static void ds_reportavail_res(char *, bool_t);
     98 static void ds_secinfo_args(char *, bool_t);
     99 static void ds_secinfo_res(char *, bool_t);
    100 static void ds_shutdown_args(char *, bool_t);
    101 static void ds_shutdown_res(char *, bool_t);
    102 
    103 /*
    104  * PNFSCTLDS -- 104001
    105  */
    106 static op_info_t pnfsctlds_ops[] = {
    107 	{"DS_NULL", "Null procedure", NULL, NULL},
    108 	{"DS_CHECKSTATE", "Verify the presented file state",
    109 	    ds_checkstate_args, ds_checkstate_res},
    110 	{"DS_EXIBI", "Exchange Identity and Boot Instance",
    111 	    ds_exibi_args, ds_exibi_res},
    112 	{"DS_FMATPT", "Placeholder for post pNFS/Basic putback",
    113 	    ds_fmatpt_args, ds_fmatpt_res},
    114 	{"DS_MAP_MDS_DATASET_ID", "Return the root path",
    115 	    ds_map_mds_dataset_id_args, ds_map_mds_dataset_id_res},
    116 	{"DS_MAP_MDSSID", "Map the given MDS Storage ID",
    117 	    ds_map_mdssid_args, ds_map_mdssid_res},
    118 	{"DS_RENEW", "Force an exchange of boot instances",
    119 	    ds_renew_args, ds_renew_res},
    120 	{"DS_REPORTAVAIL", "Provide availability information for"
    121 	    " storage pools and network interfaces",
    122 	    ds_reportavail_args, ds_reportavail_res},
    123 	{"DS_SECINFO", "Inquire about security flavors of an object",
    124 	    ds_secinfo_args, ds_secinfo_res},
    125 	{"DS_SHUTDOWN", "Data Server is in a graceful shutdown",
    126 	    ds_shutdown_args, ds_shutdown_res}
    127 };
    128 static uint_t num_pnfsctlds_ops = sizeof (pnfsctlds_ops) / sizeof (op_info_t);
    129 
    130 /*
    131  * PNFSCTLMDS -- 104000
    132  */
    133 static void mds_commit_args(char *, bool_t);
    134 static void mds_commit_res(char *, bool_t);
    135 static void mds_getattr_args(char *, bool_t);
    136 static void mds_getattr_res(char *, bool_t);
    137 static void mds_invalidate_args(char *, bool_t);
    138 static void mds_invalidate_res(char *, bool_t);
    139 static void mds_list_args(char *, bool_t);
    140 static void mds_list_res(char *, bool_t);
    141 static void mds_obj_move_args(char *, bool_t);
    142 static void mds_obj_move_res(char *, bool_t);
    143 static void mds_obj_move_abort_args(char *, bool_t);
    144 static void mds_obj_move_abort_res(char *, bool_t);
    145 static void mds_obj_move_status_args(char *, bool_t);
    146 static void mds_obj_move_status_res(char *, bool_t);
    147 static void mds_pnfsstat_args(char *, bool_t);
    148 static void mds_pnfsstat_res(char *, bool_t);
    149 static void mds_read_args(char *, bool_t);
    150 static void mds_read_res(char *, bool_t);
    151 static void mds_remove_args(char *, bool_t);
    152 static void mds_remove_res(char *, bool_t);
    153 static void mds_setattr_args(char *, bool_t);
    154 static void mds_setattr_res(char *, bool_t);
    155 static void mds_stat_args(char *, bool_t);
    156 static void mds_stat_res(char *, bool_t);
    157 static void mds_snap_args(char *, bool_t);
    158 static void mds_snap_res(char *, bool_t);
    159 static void mds_write_args(char *, bool_t);
    160 static void mds_write_res(char *, bool_t);
    161 
    162 static op_info_t pnfsctlmds_ops[] = {
    163 	{"MDS_NULL", "Null procedure", NULL, NULL},
    164 	{"MDS_COMMIT", "Commit a range written to a DS",
    165 	    mds_commit_args, mds_commit_res},
    166 	{"MDS_GETATTR", "Query DS for attributes for the specified object",
    167 	    mds_getattr_args, mds_getattr_res},
    168 	{"MDS_INVALIDATE", "Invalidate state at the DS",
    169 	    mds_invalidate_args, mds_invalidate_res},
    170 	{"MDS_LIST", "Get a list of objects from the DS",
    171 	    mds_list_args, mds_list_res},
    172 	{"MDS_OBJ_MOVE", "Data movement initiation",
    173 	    mds_obj_move_args, mds_obj_move_res},
    174 	{"MDS_OBJ_MOVE_ABORT", "Stop data movement",
    175 	    mds_obj_move_abort_args, mds_obj_move_abort_res},
    176 	{"MDS_OBJ_MOVE_STATUS", "Query data movement status",
    177 	    mds_obj_move_status_args, mds_obj_move_status_res},
    178 	{"MDS_PNNFSTAT", "Return the kstat counters",
    179 	    mds_pnfsstat_args, mds_pnfsstat_res},
    180 	{"MDS_READ", "Read a range of bytes from a DS",
    181 	    mds_read_args, mds_read_res},
    182 	{"CTL_MDS_REMOVE", "Remove object(s) or entire fsid at the DS",
    183 	    mds_remove_args, mds_remove_res},
    184 	{"MDS_SETATTR", "Set/Store attributes for the specified"
    185 	    " object at the DS",
    186 	    mds_setattr_args, mds_setattr_res},
    187 	{"MDS_STAT", "Collect statistics for the status of an object",
    188 	    mds_stat_args, mds_stat_res},
    189 	{"MDS_SNAP", "For a given MDS Dataset ID at the MDS, snapshot"
    190 	    " the data-set",
    191 	    mds_snap_args, mds_snap_res},
    192 	{"MDS_WRITE", "Write a range of bytes to a DS",
    193 	    mds_write_args, mds_write_res}
    194 };
    195 static uint_t num_pnfsctlmds_ops = sizeof (pnfsctlmds_ops) / sizeof (op_info_t);
    196 
    197 /*
    198  * PNFSCTLMV -- 104002
    199  */
    200 static void ds_move_args(char *, bool_t);
    201 static void ds_move_res(char *, bool_t);
    202 
    203 static op_info_t pnfsctlmv_ops[] = {
    204 	{"DS_DS_NULL", "Null procedure", NULL, NULL},
    205 	{"MDS_DS_MOVE", "DS to DS data movement",
    206 	    ds_move_args, ds_move_res},
    207 };
    208 static uint_t num_pnfsctlmv_ops = sizeof (pnfsctlmv_ops) / sizeof (op_info_t);
    209 
    210 /*
    211  * Status types.
    212  */
    213 static type_names_t ds_status_types[] = {
    214 	{"DS_OK", "OK "},
    215 	{"DSERR_ACCESS", "Permission denied"},
    216 	{"DSERR_ATTR_NOTSUPP", "Attribute not supported"},
    217 	{"DSERR_BAD_COOKIE", "Bad cookie"},
    218 	{"DSERR_BADHANDLE", "Bad file handle"},
    219 	{"DSERR_BAD_MDSSID", "Bad MDS sid"},
    220 	{"DSERR_BAD_STATEID", "Bad stateid"},
    221 	{"DSERR_EXPIRED", "Expired"},
    222 	{"DSERR_FHEXPIRED", "File handled expired"},
    223 	{"DSERR_GRACE", "Grace"},
    224 	{"DSERR_INVAL", "Invalid"},
    225 	{"DSERR_IO", "IO Error"},
    226 	{"DSERR_NOENT", "No such entry"},
    227 	{"DSERR_NOT_AUTH", "Not authorized"},
    228 	{"DSERR_NOSPC", "No space left on device"},
    229 	{"DSERR_NOTSUPP", "Not supported"},
    230 	{"DSERR_OLD_STATEID", "Old stateid"},
    231 	{"DSERR_PNFS_NO_LAYOUT", "No layout"},
    232 	{"DSERR_RESOURCE", "Resource error"},
    233 	{"DSERR_SERVERFAULT", "General server fault"},
    234 	{"DSERR_STALE", "Stale pNFS file handle"},
    235 	{"DSERR_STALE_CLIENTID", "Stale clientid"},
    236 	{"DSERR_STALE_DSID", "Stale DSid"},
    237 	{"DSERR_STALE_STATEID", "Stale stateid"},
    238 	{"DSERR_TOOSMALL", "Too small"},
    239 	{"DSERR_WRONGSEC", "Wrong security flavor"},
    240 	{"DSERR_XDR", "XDR error"},
    241 	{"DSERR_ILLEGAL", "Illegal"}
    242 };
    243 static uint_t num_status_types =
    244     sizeof (ds_status_types) / sizeof (type_names_t);
    245 
    246 typedef struct {
    247 	op_info_t	*ops;
    248 	char		*name;
    249 	uint_t		count;
    250 } ds_program_t;
    251 
    252 static char *storage_types_map[] = {
    253 	"(unknown)",
    254 	"ZFS"
    255 };
    256 
    257 static void
    258 detail_client_owner(client_owner4 *cow)
    259 {
    260 	sprintf(get_line(0, 0), "Client Owner hash = [%04X] ",
    261 	    cowner_hash(&cow->co_ownerid));
    262 	sprintf(get_line(0, 0), "    len = %u   val = %s ",
    263 	    cow->co_ownerid.co_ownerid_len,
    264 	    tohex(cow->co_ownerid.co_ownerid_val,
    265 	    cow->co_ownerid.co_ownerid_len));
    266 	sprintf(get_line(0, 0), "    verifier = %llu",
    267 	    cow->co_verifier);
    268 }
    269 
    270 
    271 /*
    272  * The state engine will pass in a valid line buffer for all
    273  * summary actions. It will pass in a NULL pointer for all
    274  * detailed actions. Therefore, if line is NULL, we know
    275  * to get a new line for a detailed action.
    276  */
    277 static void
    278 print_status(char *line, ds_status status)
    279 {
    280 	if (line == NULL)
    281 		line = get_line(0, 0);
    282 
    283 	if (status < 0 || status >= num_status_types)
    284 		strcpy(line, "(unknown error)");
    285 	else
    286 		strcpy(line, ds_status_types[status].long_name);
    287 }
    288 
    289 /*ARGSUSED*/
    290 static void
    291 interpret_pnfsctl(ds_program_t *dsp, int flags, int type, int xid,
    292     int vers, int proc, char *data, int len)
    293 {
    294 	char *line = NULL;
    295 	char *line2 = NULL;
    296 
    297 	if (proc < 0 || proc >= dsp->count)
    298 		return;
    299 
    300 	if (flags & F_SUM) {
    301 		line2 = line = get_sum_line();
    302 
    303 		if (type == CALL) {
    304 			(void) sprintf(line, "%s C %s",
    305 			    dsp->name, dsp->ops[proc].short_name);
    306 			line += strlen(line);
    307 			if (dsp->ops[proc].args)
    308 				dsp->ops[proc].args(line, TRUE);
    309 			line += strlen(line);
    310 			check_retransmit(line, xid);
    311 		} else {
    312 			(void) sprintf(line, "%s R %s ",
    313 			    dsp->name, dsp->ops[proc].short_name);
    314 			line += strlen(line);
    315 			if (dsp->ops[proc].res) {
    316 				dsp->ops[proc].res(line, TRUE);
    317 			}
    318 		}
    319 	}
    320 
    321 	if (flags & F_DTAIL) {
    322 		char buf1[20], buf2[20];
    323 		(void) sprintf(buf1, "%s:  ", dsp->name);
    324 		(void) sprintf(buf2, "Sun %s", dsp->name);
    325 		show_header(buf1, buf2, len);
    326 		show_space();
    327 		(void) sprintf(get_line(0, 0), "Proc = %d (%s)",
    328 		    proc, dsp->ops[proc].long_name);
    329 		if (type == CALL) {
    330 			if (dsp->ops[proc].args)
    331 				dsp->ops[proc].args(NULL, FALSE);
    332 		} else {
    333 			if (dsp->ops[proc].res)
    334 				dsp->ops[proc].res(NULL, FALSE);
    335 		}
    336 		show_trailer();
    337 	}
    338 
    339 	utf8free();
    340 }
    341 
    342 /*ARGSUSED*/
    343 void
    344 interpret_pnfsctlmv(int flags, int type, int xid, int vers, int proc,
    345     char *data, int len)
    346 {
    347 	ds_program_t	sp;
    348 
    349 	sp.ops = pnfsctlmv_ops;
    350 	sp.count = num_pnfsctlmv_ops;
    351 	sp.name = "CTL-MV";
    352 
    353 	interpret_pnfsctl(&sp, flags, type, xid, vers, proc, data, len);
    354 }
    355 
    356 /*ARGSUSED*/
    357 void
    358 interpret_pnfsctlds(int flags, int type, int xid, int vers, int proc,
    359     char *data, int len)
    360 {
    361 	ds_program_t	sp;
    362 
    363 	sp.ops = pnfsctlds_ops;
    364 	sp.count = num_pnfsctlds_ops;
    365 	sp.name = "CTL-DS";
    366 
    367 	interpret_pnfsctl(&sp, flags, type, xid, vers, proc, data, len);
    368 }
    369 
    370 /*ARGSUSED*/
    371 void
    372 interpret_pnfsctlmds(int flags, int type, int xid, int vers, int proc,
    373     char *data, int len)
    374 {
    375 	ds_program_t	sp;
    376 
    377 	sp.ops = pnfsctlmds_ops;
    378 	sp.count = num_pnfsctlmds_ops;
    379 	sp.name = "CTL-MDS";
    380 
    381 	interpret_pnfsctl(&sp, flags, type, xid, vers, proc, data, len);
    382 }
    383 
    384 /*
    385  * Helper functions
    386  */
    387 
    388 static void
    389 detail_mds_sid(mds_sid *ms, int index, char *indent)
    390 {
    391 	char	buf[20];
    392 
    393 	if (index != -1) {
    394 		sprintf(buf, "[%d]", index);
    395 	} else {
    396 		buf[0] = '\0';
    397 	}
    398 
    399 	sprintf(get_line(0, 0), "%s    mds_sid%s", indent, buf);
    400 	sprintf(get_line(0, 0), "%s        %s", indent,
    401 	    tohex(ms->val, ms->len));
    402 }
    403 
    404 static bool_t
    405 detail_ds_guid_map(uint_t len, ds_guid_map *dg, char *legend, char *indent)
    406 {
    407 	XDR		zxdr;
    408 	ds_zfsguid	zfsguid;
    409 	char		*p;
    410 	int		i;
    411 	int		j;
    412 
    413 	for (i = 0; i < len; i++) {
    414 		sprintf(get_line(0, 0), "%s%s[%d]", indent, legend, i);
    415 
    416 		/*
    417 		 * Whenever we get more, we'll have to check this better!
    418 		 */
    419 		if (dg[i].ds_guid.stor_type != ZFS)
    420 			p = storage_types_map[0];
    421 		else
    422 			p = storage_types_map[dg[i].ds_guid.stor_type];
    423 
    424 		sprintf(get_line(0, 0), "%s    storage type = %s", indent, p);
    425 		xdrmem_create(&zxdr,
    426 		    dg[i].ds_guid.ds_guid_u.zfsguid.zfsguid_val,
    427 		    dg[i].ds_guid.ds_guid_u.zfsguid.zfsguid_len,
    428 		    XDR_DECODE);
    429 		memset(&zfsguid, '\0', sizeof (zfsguid));
    430 		if (!xdr_ds_zfsguid(&zxdr, &zfsguid))
    431 			return (FALSE);
    432 
    433 		sprintf(get_line(0, 0), "%s    zpool guid = %llu",
    434 		    indent, zfsguid.zpool_guid);
    435 		sprintf(get_line(0, 0), "%s    dataset guid = %llu",
    436 		    indent, zfsguid.dataset_guid);
    437 
    438 		xdr_free(xdr_ds_zfsguid, (char *)&zfsguid);
    439 
    440 		for (j = 0; j < dg[i].mds_sid_array.mds_sid_array_len; j++) {
    441 			detail_mds_sid(&dg[i].mds_sid_array.
    442 			    mds_sid_array_val[j], j, indent);
    443 		}
    444 	}
    445 
    446 	return (TRUE);
    447 }
    448 
    449 static void
    450 detail_netaddr4(netaddr4 *addr)
    451 {
    452 	sprintf(get_line(0, 0), "    netaddr = %s/%s",
    453 	    addr->na_r_addr, addr->na_r_netid);
    454 }
    455 
    456 static void
    457 detail_layout_array(layout4 *alo, int len)
    458 {
    459 	int	i;
    460 
    461 	for (i = 0; i < len; i++) {
    462 		sprintf(get_line(0, 0), "Layout [%u]:", i);
    463 		sprintf(get_line(0, 0), "    Layout offset = %llu",
    464 		    alo[i].lo_offset);
    465 		sprintf(get_line(0, 0), "    Layout length = %llu",
    466 		    alo[i].lo_length);
    467 		sprintf(get_line(0, 0), "    Layout iomode = %s",
    468 		    detail_iomode_name(alo[i].lo_iomode));
    469 		sprintf(get_line(0, 0), "    Layout type = %s",
    470 		    detail_lotype_name(alo[i].lo_content.loc_type));
    471 		if (alo[i].lo_content.loc_type == LAYOUT4_NFSV4_1_FILES) {
    472 			detail_file_layout(&alo[i]);
    473 		} else {
    474 			sprintf(get_line(0, 0), "Non-file layout = %s",
    475 			    tohex(alo[i].lo_content.loc_body.loc_body_val,
    476 			    alo[i].lo_content.loc_body.loc_body_len));
    477 		}
    478 	}
    479 }
    480 
    481 /*
    482  * State functions
    483  */
    484 
    485 static void
    486 ds_checkstate_args(char *line, bool_t summary)
    487 {
    488 	DS_CHECKSTATEargs	args;
    489 	client_owner4		*cow;
    490 
    491 	memset(&args, '\0', sizeof (args));
    492 	if (!xdr_DS_CHECKSTATEargs(&xdrm, &args))
    493 		longjmp(xdr_err, 1);
    494 
    495 	cow = &args.co_owner;
    496 	if (summary) {
    497 		sprintf(line, " %s %s H=[%04X]",
    498 		    sum_stateid(&args.stateid),
    499 		    sum_fh4(&args.fh),
    500 		    cowner_hash(&cow->co_ownerid));
    501 	} else {
    502 		detail_stateid(&args.stateid);
    503 		detail_fh4(&args.fh, "");
    504 		detail_client_owner(cow);
    505 	}
    506 
    507 	xdr_free(xdr_DS_CHECKSTATEargs, (char *)&args);
    508 }
    509 
    510 static void
    511 ds_checkstate_res(char *line, bool_t summary)
    512 {
    513 	DS_CHECKSTATEres	res;
    514 	ds_filestate		*df;
    515 
    516 	int	i;
    517 
    518 	memset(&res, '\0', sizeof (res));
    519 	if (!xdr_DS_CHECKSTATEres(&xdrm, &res))
    520 		longjmp(xdr_err, 1);
    521 
    522 	if (res.status != DS_OK) {
    523 		print_status(line, res.status);
    524 		return;
    525 	}
    526 
    527 	df = &res.DS_CHECKSTATEres_u.file_state;
    528 
    529 	if (summary) {
    530 		sprintf(line, " %s L=%d M=0%03o",
    531 		    sum_clientid(df->mds_clid),
    532 		    df->layout.layout_len,
    533 		    df->open_mode);
    534 	} else {
    535 		detail_clientid(df->mds_clid);
    536 		sprintf(get_line(0, 0), "Mode = 0%03o", df->open_mode);
    537 		detail_layout_array(df->layout.layout_val,
    538 		    df->layout.layout_len);
    539 	}
    540 
    541 	xdr_free(xdr_DS_CHECKSTATEres, (char *)&res);
    542 }
    543 
    544 static void
    545 ds_exibi_args(char *line, bool_t summary)
    546 {
    547 	DS_EXIBIargs	args;
    548 
    549 	memset(&args, '\0', sizeof (args));
    550 	if (!xdr_DS_EXIBIargs(&xdrm, &args))
    551 		longjmp(xdr_err, 1);
    552 
    553 	if (summary) {
    554 	} else {
    555 		sprintf(get_line(0, 0), "Identity verifier = %llu",
    556 		    args.ds_ident.boot_verifier);
    557 		sprintf(get_line(0, 0), "Identity instance = %s",
    558 		    utf8localize((utf8string *)&args.ds_ident.instance));
    559 	}
    560 
    561 	xdr_free(xdr_DS_EXIBIargs, (char *)&args);
    562 }
    563 
    564 static void
    565 ds_exibi_res(char *line, bool_t summary)
    566 {
    567 	DS_EXIBIres	res;
    568 	DS_EXIBIresok	*res_ok;
    569 
    570 	memset(&res, '\0', sizeof (res));
    571 	if (!xdr_DS_EXIBIres(&xdrm, &res))
    572 		longjmp(xdr_err, 1);
    573 
    574 	if (res.status != DS_OK) {
    575 		print_status(line, res.status);
    576 		return;
    577 	}
    578 
    579 	res_ok = &res.DS_EXIBIres_u.res_ok;
    580 
    581 	if (summary) {
    582 		sprintf(line, " DI=%llu LP=%hu",
    583 		    res_ok->ds_id,
    584 		    res_ok->mds_lease_period);
    585 	} else {
    586 		sprintf(get_line(0, 0), "DS id = %llu", res_ok->ds_id);
    587 		sprintf(get_line(0, 0), "MDS id = %llu", res_ok->mds_id);
    588 		sprintf(get_line(0, 0), "MDS boot verifier = %llu",
    589 		    res_ok->mds_boot_verifier);
    590 		sprintf(get_line(0, 0), "MDS boot lease = %hu",
    591 		    res_ok->mds_lease_period);
    592 	}
    593 
    594 	xdr_free(xdr_DS_EXIBIres, (char *)&res);
    595 }
    596 
    597 static void
    598 ds_fmatpt_args(char *line, bool_t summary)
    599 {
    600 	DS_FMATPTargs	args;
    601 
    602 	memset(&args, '\0', sizeof (args));
    603 	if (!xdr_DS_FMATPTargs(&xdrm, &args))
    604 		longjmp(xdr_err, 1);
    605 
    606 	if (summary) {
    607 	} else {
    608 		sprintf(get_line(0, 0), "FMA event = %s",
    609 		    utf8localize((utf8string *)&args.fma_msg));
    610 	}
    611 
    612 	xdr_free(xdr_DS_FMATPTargs, (char *)&args);
    613 }
    614 
    615 static void
    616 ds_fmatpt_res(char *line, bool_t summary)
    617 {
    618 	DS_FMATPTres	res;
    619 
    620 	memset(&res, '\0', sizeof (res));
    621 	if (!xdr_DS_FMATPTres(&xdrm, &res))
    622 		longjmp(xdr_err, 1);
    623 
    624 	if (res.status != DS_OK) {
    625 		print_status(line, res.status);
    626 		xdr_free(xdr_DS_FMATPTres, (char *)&res);
    627 		return;
    628 	}
    629 
    630 	xdr_free(xdr_DS_FMATPTres, (char *)&res);
    631 }
    632 
    633 static void
    634 ds_map_mds_dataset_id_args(char *line, bool_t summary)
    635 {
    636 	DS_MAP_MDS_DATASET_IDargs	args;
    637 
    638 	memset(&args, '\0', sizeof (args));
    639 	if (!xdr_DS_MAP_MDS_DATASET_IDargs(&xdrm, &args))
    640 		longjmp(xdr_err, 1);
    641 
    642 	if (summary) {
    643 		sprintf(line, " MDI=%llu",
    644 		    args.mds_dataset_id);
    645 	} else {
    646 		sprintf(get_line(0, 0), "MDS datset id = %llu",
    647 		    args.mds_dataset_id);
    648 	}
    649 
    650 	xdr_free(xdr_DS_MAP_MDS_DATASET_IDargs, (char *)&args);
    651 }
    652 
    653 static void
    654 ds_map_mds_dataset_id_res(char *line, bool_t summary)
    655 {
    656 	DS_MAP_MDS_DATASET_IDres	res;
    657 	DS_MAP_MDS_DATASET_IDresok	*res_ok;
    658 
    659 	memset(&res, '\0', sizeof (res));
    660 	if (!xdr_DS_MAP_MDS_DATASET_IDres(&xdrm, &res))
    661 		longjmp(xdr_err, 1);
    662 
    663 	if (res.status != DS_OK) {
    664 		print_status(line, res.status);
    665 		xdr_free(xdr_DS_MAP_MDS_DATASET_IDres, (char *)&res);
    666 		return;
    667 	}
    668 
    669 	res_ok = &res.DS_MAP_MDS_DATASET_IDres_u.res_ok;
    670 
    671 	if (summary) {
    672 		sprintf(line, " P=(%.20s)",
    673 		    utf8localize((utf8string *)&res_ok->pathname));
    674 	} else {
    675 		sprintf(get_line(0, 0), "Pathname = %s",
    676 		    utf8localize((utf8string *)&res_ok->pathname));
    677 	}
    678 
    679 	xdr_free(xdr_DS_MAP_MDS_DATASET_IDres, (char *)&res);
    680 }
    681 
    682 static void
    683 ds_map_mdssid_args(char *line, bool_t summary)
    684 {
    685 	DS_MAP_MDSSIDargs	args;
    686 
    687 	memset(&args, '\0', sizeof (args));
    688 	if (!xdr_DS_MAP_MDSSIDargs(&xdrm, &args))
    689 		longjmp(xdr_err, 1);
    690 
    691 	if (summary) {
    692 	} else {
    693 		detail_mds_sid(&args.mma_sid, -1, "");
    694 	}
    695 
    696 	xdr_free(xdr_DS_MAP_MDSSIDargs, (char *)&args);
    697 }
    698 
    699 static void
    700 ds_map_mdssid_res(char *line, bool_t summary)
    701 {
    702 	DS_MAP_MDSSIDres	res;
    703 	DS_MAP_MDSSIDresok	*res_ok;
    704 
    705 	memset(&res, '\0', sizeof (res));
    706 	if (!xdr_DS_MAP_MDSSIDres(&xdrm, &res))
    707 		longjmp(xdr_err, 1);
    708 
    709 	if (res.status != DS_OK) {
    710 		print_status(line, res.status);
    711 		xdr_free(xdr_DS_MAP_MDSSIDres, (char *)&res);
    712 		return;
    713 	}
    714 
    715 	res_ok = &res.DS_MAP_MDSSIDres_u.res_ok;
    716 
    717 	if (summary) {
    718 	} else {
    719 		if (!detail_ds_guid_map(1, &res_ok->guid_map, "Guid", "")) {
    720 			xdr_free(xdr_DS_MAP_MDSSIDres, (char *)&res);
    721 			longjmp(xdr_err, 1);
    722 		}
    723 
    724 	}
    725 
    726 	xdr_free(xdr_DS_MAP_MDSSIDres, (char *)&res);
    727 }
    728 
    729 static void
    730 ds_renew_args(char *line, bool_t summary)
    731 {
    732 	DS_RENEWargs	args;
    733 
    734 	memset(&args, '\0', sizeof (args));
    735 	if (!xdr_DS_RENEWargs(&xdrm, &args))
    736 		longjmp(xdr_err, 1);
    737 
    738 	if (summary) {
    739 		sprintf(line, " DI=%llu",
    740 		    args.ds_id);
    741 	} else {
    742 		sprintf(get_line(0, 0), "DS id = %llu", args.ds_id);
    743 		sprintf(get_line(0, 0),
    744 		    "DS Bootime verifier = %llu", args.ds_boottime);
    745 	}
    746 
    747 	xdr_free(xdr_DS_RENEWargs, (char *)&args);
    748 }
    749 
    750 static void
    751 ds_renew_res(char *line, bool_t summary)
    752 {
    753 	DS_RENEWres	res;
    754 	ds_verifier	*vrfy;
    755 
    756 	memset(&res, '\0', sizeof (res));
    757 	if (!xdr_DS_RENEWres(&xdrm, &res))
    758 		longjmp(xdr_err, 1);
    759 
    760 	if (res.status != DS_OK) {
    761 		print_status(line, res.status);
    762 		xdr_free(xdr_DS_RENEWres, (char *)&res);
    763 		return;
    764 	}
    765 
    766 	vrfy = &res.DS_RENEWres_u.mds_boottime;
    767 
    768 	if (summary) {
    769 	} else {
    770 		sprintf(get_line(0, 0),
    771 		    "MDS Bootime verifier = %llu", vrfy);
    772 	}
    773 
    774 	xdr_free(xdr_DS_RENEWres, (char *)&res);
    775 }
    776 
    777 static void
    778 ds_reportavail_args_dtl(DS_REPORTAVAILargs *args)
    779 {
    780 	int		i;
    781 	char		*p;
    782 
    783 	sprintf(get_line(0, 0), "DS id = %llu", args->ds_id);
    784 	sprintf(get_line(0, 0), "Verifier = %llu", args->ds_verifier);
    785 	sprintf(get_line(0, 0), "Attribute Version = %u", args->ds_attrvers);
    786 
    787 	for (i = 0; i < args->ds_addrs.ds_addrs_len; i++) {
    788 		sprintf(get_line(0, 0), "Addr[%d]", i);
    789 		sprintf(get_line(0, 0), "    validuse = %x",
    790 		    args->ds_addrs.ds_addrs_val[i].validuse);
    791 		detail_netaddr4(&args->ds_addrs.ds_addrs_val[i].addr);
    792 	}
    793 
    794 	for (i = 0; i < args->ds_storinfo.ds_storinfo_len; i++) {
    795 		ds_zfsinfo	*dz;
    796 		int		j;
    797 
    798 		sprintf(get_line(0, 0), "Storage Info[%d]", i);
    799 
    800 		/*
    801 		 * Whenever we get more, we'll have to check this better!
    802 		 */
    803 		if (args->ds_storinfo.ds_storinfo_val[i].type != ZFS)
    804 			p = storage_types_map[0];
    805 		else
    806 			p = storage_types_map[args->ds_storinfo.
    807 			    ds_storinfo_val[i].type];
    808 
    809 		sprintf(get_line(0, 0), "    Storage Type = %s", p);
    810 
    811 		dz = &args->ds_storinfo.ds_storinfo_val[i].ds_storinfo_u.
    812 		    zfs_info;
    813 		if (!detail_ds_guid_map(1, &dz->guid_map, "Guid", "    ")) {
    814 			xdr_free(xdr_DS_REPORTAVAILargs, (char *)args);
    815 			longjmp(xdr_err, 1);
    816 		}
    817 
    818 		/*
    819 		 * Note that this nvpair may change to a bitmap!
    820 		 */
    821 		for (j = 0; j < dz->attrs.attrs_len; j++) {
    822 			sprintf(get_line(0, 0), "    Attribute[%d] = ",
    823 			    j, utf8localize((utf8string *)
    824 			    &dz->attrs.attrs_val[j].attrname));
    825 			sprintf(get_line(0, 0), "        %s",
    826 			    utf8localize((utf8string *)
    827 			    &dz->attrs.attrs_val[j].attrvalue));
    828 		}
    829 	}
    830 }
    831 
    832 static void
    833 ds_reportavail_args(char *line, bool_t summary)
    834 {
    835 	DS_REPORTAVAILargs	args;
    836 
    837 	memset(&args, '\0', sizeof (args));
    838 	if (!xdr_DS_REPORTAVAILargs(&xdrm, &args))
    839 		longjmp(xdr_err, 1);
    840 
    841 	if (summary) {
    842 		sprintf(line, " DI=%llu A=%d LA=%u LS=%u",
    843 		    args.ds_id,
    844 		    args.ds_attrvers,
    845 		    args.ds_addrs.ds_addrs_len,
    846 		    args.ds_storinfo.ds_storinfo_len);
    847 	} else {
    848 		ds_reportavail_args_dtl(&args);
    849 	}
    850 
    851 	xdr_free(xdr_DS_REPORTAVAILargs, (char *)&args);
    852 }
    853 
    854 static void
    855 ds_reportavail_res(char *line, bool_t summary)
    856 {
    857 	DS_REPORTAVAILres	res;
    858 	DS_REPORTAVAILresok	*res_ok;
    859 
    860 	memset(&res, '\0', sizeof (res));
    861 	if (!xdr_DS_REPORTAVAILres(&xdrm, &res))
    862 		longjmp(xdr_err, 1);
    863 
    864 	if (res.status != DS_OK) {
    865 		print_status(line, res.status);
    866 		xdr_free(xdr_DS_REPORTAVAILres, (char *)&res);
    867 		return;
    868 	}
    869 
    870 	res_ok = &res.DS_REPORTAVAILres_u.res_ok;
    871 
    872 	if (summary) {
    873 		sprintf(line, " L=%hu",
    874 		    res_ok->guid_map.guid_map_len);
    875 	} else {
    876 		sprintf(get_line(0, 0), "Attribute Version = %u",
    877 		    res_ok->ds_attrvers);
    878 		if (!detail_ds_guid_map(res_ok->guid_map.guid_map_len,
    879 		    res_ok->guid_map.guid_map_val, "Guid", "")) {
    880 			xdr_free(xdr_DS_REPORTAVAILres, (char *)&res);
    881 			longjmp(xdr_err, 1);
    882 		}
    883 	}
    884 
    885 	xdr_free(xdr_DS_REPORTAVAILres, (char *)&res);
    886 }
    887 
    888 static void
    889 ds_secinfo_args(char *line, bool_t summary)
    890 {
    891 	DS_SECINFOargs	args;
    892 
    893 	memset(&args, '\0', sizeof (args));
    894 	if (!xdr_DS_SECINFOargs(&xdrm, &args))
    895 		longjmp(xdr_err, 1);
    896 
    897 	if (summary) {
    898 		sprintf(line, " %s",
    899 		    sum_fh4(&args.object));
    900 	} else {
    901 		detail_fh4(&args.object, "");
    902 		detail_netaddr4(&args.cl_addr);
    903 	}
    904 
    905 	xdr_free(xdr_DS_SECINFOargs, (char *)&args);
    906 }
    907 
    908 static void
    909 ds_secinfo_res(char *line, bool_t summary)
    910 {
    911 	DS_SECINFOres	res;
    912 	DS_SECINFOresok	*res_ok;
    913 
    914 	memset(&res, '\0', sizeof (res));
    915 	if (!xdr_DS_SECINFOres(&xdrm, &res))
    916 		longjmp(xdr_err, 1);
    917 
    918 	if (res.status != DS_OK) {
    919 		print_status(line, res.status);
    920 		xdr_free(xdr_DS_SECINFOres, (char *)&res);
    921 		return;
    922 	}
    923 
    924 	res_ok = &res.DS_SECINFOres_u.res_ok;
    925 
    926 	if (summary) {
    927 	} else {
    928 		int		i;
    929 		ds_secinfo	*ds;
    930 
    931 		for (i = 0; i < res_ok->DS_SECINFOresok_len; i++) {
    932 			ds = &res_ok->DS_SECINFOresok_val[i];
    933 			detail_secinfo4((secinfo4 *)ds);
    934 		}
    935 	}
    936 
    937 	xdr_free(xdr_DS_SECINFOres, (char *)&res);
    938 }
    939 
    940 static void
    941 ds_shutdown_args(char *line, bool_t summary)
    942 {
    943 	DS_SHUTDOWNargs	args;
    944 
    945 	memset(&args, '\0', sizeof (args));
    946 	if (!xdr_DS_SHUTDOWNargs(&xdrm, &args))
    947 		longjmp(xdr_err, 1);
    948 
    949 	if (summary) {
    950 		sprintf(line, " DI=%llu",
    951 		    args.ds_id);
    952 	} else {
    953 		sprintf(get_line(0, 0), "DS id = %llu", args.ds_id);
    954 	}
    955 
    956 	xdr_free(xdr_DS_SHUTDOWNargs, (char *)&args);
    957 }
    958 
    959 static void
    960 ds_shutdown_res(char *line, bool_t summary)
    961 {
    962 	DS_SHUTDOWNres	res;
    963 
    964 	memset(&res, '\0', sizeof (res));
    965 	if (!xdr_DS_SHUTDOWNres(&xdrm, &res))
    966 		longjmp(xdr_err, 1);
    967 
    968 	if (res.status != DS_OK) {
    969 		print_status(line, res.status);
    970 		xdr_free(xdr_DS_SHUTDOWNres, (char *)&res);
    971 		return;
    972 	}
    973 
    974 	xdr_free(xdr_DS_SHUTDOWNres, (char *)&res);
    975 }
    976 
    977 static void
    978 mds_commit_args(char *line, bool_t summary)
    979 {
    980 	DS_COMMITargs	args;
    981 
    982 	int	i;
    983 
    984 	memset(&args, '\0', sizeof (args));
    985 	if (!xdr_DS_COMMITargs(&xdrm, &args))
    986 		longjmp(xdr_err, 1);
    987 
    988 	if (summary) {
    989 		sprintf(line, " %s C=%u",
    990 		    sum_fh4(&args.fh),
    991 		    args.cmv.cmv_len);
    992 	} else {
    993 		detail_fh4(&args.fh, "");
    994 
    995 		for (i = 0; i < args.cmv.cmv_len; i++) {
    996 			sprintf(get_line(0, 0),
    997 			    "File Segment[%d]", i);
    998 			sprintf(get_line(0, 0),
    999 			    "    offset = %llu",
   1000 			    args.cmv.cmv_val[i].offset);
   1001 			sprintf(get_line(0, 0),
   1002 			    "    count = %u",
   1003 			    args.cmv.cmv_val[i].count);
   1004 		}
   1005 	}
   1006 
   1007 	xdr_free(xdr_DS_COMMITargs, (char *)&args);
   1008 }
   1009 
   1010 static void
   1011 mds_commit_res(char *line, bool_t summary)
   1012 {
   1013 	DS_COMMITres	res;
   1014 	DS_COMMITresok	*res_ok;
   1015 
   1016 	int	i;
   1017 
   1018 	memset(&res, '\0', sizeof (res));
   1019 	if (!xdr_DS_COMMITres(&xdrm, &res))
   1020 		longjmp(xdr_err, 1);
   1021 
   1022 	if (res.status != DS_OK) {
   1023 		print_status(line, res.status);
   1024 		xdr_free(xdr_DS_COMMITres, (char *)&res);
   1025 		return;
   1026 	}
   1027 
   1028 	res_ok = &res.DS_COMMITres_u.res_ok;
   1029 
   1030 	if (summary) {
   1031 		sprintf(line, " C=%u",
   1032 		    res_ok->count.count_len);
   1033 	} else {
   1034 		sprintf(get_line(0, 0),
   1035 		    "Write Verifier = %llu", res_ok->writeverf);
   1036 		for (i = 0; i < res_ok->count.count_len; i++) {
   1037 			sprintf(get_line(0, 0),
   1038 			    "Count[%d] = %u", i,
   1039 			    res_ok->count.count_val[i]);
   1040 		}
   1041 	}
   1042 
   1043 	xdr_free(xdr_DS_COMMITres, (char *)&res);
   1044 }
   1045 
   1046 static void
   1047 mds_getattr_args(char *line, bool_t summary)
   1048 {
   1049 	DS_GETATTRargs	args;
   1050 
   1051 	memset(&args, '\0', sizeof (args));
   1052 	if (!xdr_DS_GETATTRargs(&xdrm, &args))
   1053 		longjmp(xdr_err, 1);
   1054 
   1055 	if (summary) {
   1056 		sprintf(line, " %s",
   1057 		    sum_fh4(&args.fh));
   1058 	} else {
   1059 		detail_fh4(&args.fh, "");
   1060 	}
   1061 
   1062 	xdr_free(xdr_DS_GETATTRargs, (char *)&args);
   1063 }
   1064 
   1065 static void
   1066 mds_getattr_res(char *line, bool_t summary)
   1067 {
   1068 	DS_GETATTRres	res;
   1069 	ds_attr		*da;
   1070 
   1071 	memset(&res, '\0', sizeof (res));
   1072 	if (!xdr_DS_GETATTRres(&xdrm, &res))
   1073 		longjmp(xdr_err, 1);
   1074 
   1075 	if (res.status != DS_OK) {
   1076 		print_status(line, res.status);
   1077 		xdr_free(xdr_DS_GETATTRres, (char *)&res);
   1078 		return;
   1079 	}
   1080 
   1081 	da = &res.DS_GETATTRres_u.dattrs;
   1082 
   1083 	if (summary) {
   1084 	} else {
   1085 	}
   1086 
   1087 	xdr_free(xdr_DS_GETATTRres, (char *)&res);
   1088 }
   1089 
   1090 static void
   1091 mds_invalidate_args(char *line, bool_t summary)
   1092 {
   1093 	DS_INVALIDATEargs	args;
   1094 
   1095 	memset(&args, '\0', sizeof (args));
   1096 	if (!xdr_DS_INVALIDATEargs(&xdrm, &args))
   1097 		longjmp(xdr_err, 1);
   1098 
   1099 	if (summary) {
   1100 	} else {
   1101 	}
   1102 
   1103 	xdr_free(xdr_DS_INVALIDATEargs, (char *)&args);
   1104 }
   1105 
   1106 static void
   1107 mds_invalidate_res(char *line, bool_t summary)
   1108 {
   1109 	DS_INVALIDATEres	res;
   1110 
   1111 	memset(&res, '\0', sizeof (res));
   1112 	if (!xdr_DS_INVALIDATEres(&xdrm, &res))
   1113 		longjmp(xdr_err, 1);
   1114 
   1115 	if (res.status != DS_OK) {
   1116 		print_status(line, res.status);
   1117 		xdr_free(xdr_DS_INVALIDATEres, (char *)&res);
   1118 		return;
   1119 	}
   1120 
   1121 	if (summary) {
   1122 	} else {
   1123 	}
   1124 
   1125 	xdr_free(xdr_DS_INVALIDATEres, (char *)&res);
   1126 }
   1127 
   1128 static void
   1129 mds_list_args(char *line, bool_t summary)
   1130 {
   1131 	DS_LISTargs	args;
   1132 
   1133 	memset(&args, '\0', sizeof (args));
   1134 	if (!xdr_DS_LISTargs(&xdrm, &args))
   1135 		longjmp(xdr_err, 1);
   1136 
   1137 	if (summary) {
   1138 	} else {
   1139 	}
   1140 
   1141 	xdr_free(xdr_DS_LISTargs, (char *)&args);
   1142 }
   1143 
   1144 static void
   1145 mds_list_res(char *line, bool_t summary)
   1146 {
   1147 	DS_LISTres	res;
   1148 	DS_LISTresok	*res_ok;
   1149 
   1150 	memset(&res, '\0', sizeof (res));
   1151 	if (!xdr_DS_LISTres(&xdrm, &res))
   1152 		longjmp(xdr_err, 1);
   1153 
   1154 	if (res.status != DS_OK) {
   1155 		print_status(line, res.status);
   1156 		return;
   1157 	}
   1158 
   1159 	res_ok = &res.DS_LISTres_u.res_ok;
   1160 
   1161 	if (summary) {
   1162 	} else {
   1163 	}
   1164 
   1165 	xdr_free(xdr_DS_LISTres, (char *)&res);
   1166 }
   1167 
   1168 static void
   1169 mds_obj_move_args(char *line, bool_t summary)
   1170 {
   1171 	DS_OBJ_MOVEargs	args;
   1172 
   1173 	memset(&args, '\0', sizeof (args));
   1174 	if (!xdr_DS_OBJ_MOVEargs(&xdrm, &args))
   1175 		longjmp(xdr_err, 1);
   1176 
   1177 	if (summary) {
   1178 		/*
   1179 		 * Not sure if sum_fh4() will be handled
   1180 		 * correctly here...
   1181 		 */
   1182 		sprintf(line, " Tid=%llu S%s",
   1183 		    args.taskid, sum_fh4(&args.source));
   1184 		line += strlen(line);
   1185 
   1186 		/*
   1187 		 * So hack it up!
   1188 		 */
   1189 		sprintf(line, " T%s",
   1190 		    sum_fh4(&args.target));
   1191 	} else {
   1192 		sprintf(get_line(0, 0), "Task ID = %llu",
   1193 		    args.taskid);
   1194 		detail_fh4(&args.source, "Source ");
   1195 		detail_fh4(&args.target, "Target ");
   1196 		detail_netaddr4(&args.targetserver);
   1197 	}
   1198 
   1199 	xdr_free(xdr_DS_OBJ_MOVEargs, (char *)&args);
   1200 }
   1201 
   1202 static void
   1203 mds_obj_move_res(char *line, bool_t summary)
   1204 {
   1205 	DS_OBJ_MOVEres	res;
   1206 
   1207 	memset(&res, '\0', sizeof (res));
   1208 	if (!xdr_DS_OBJ_MOVEres(&xdrm, &res))
   1209 		longjmp(xdr_err, 1);
   1210 
   1211 	if (res.status != DS_OK) {
   1212 		print_status(line, res.status);
   1213 		xdr_free(xdr_DS_OBJ_MOVEres, (char *)&res);
   1214 		return;
   1215 	}
   1216 
   1217 	xdr_free(xdr_DS_OBJ_MOVEres, (char *)&res);
   1218 }
   1219 
   1220 static void
   1221 mds_obj_move_abort_args(char *line, bool_t summary)
   1222 {
   1223 	DS_OBJ_MOVE_ABORTargs	args;
   1224 
   1225 	memset(&args, '\0', sizeof (args));
   1226 	if (!xdr_DS_OBJ_MOVE_ABORTargs(&xdrm, &args))
   1227 		longjmp(xdr_err, 1);
   1228 
   1229 	if (summary) {
   1230 		sprintf(line, " Tid=%llu",
   1231 		    args.taskid);
   1232 	} else {
   1233 		sprintf(get_line(0, 0), "Task ID = %llu",
   1234 		    args.taskid);
   1235 	}
   1236 
   1237 	xdr_free(xdr_DS_OBJ_MOVE_ABORTargs, (char *)&args);
   1238 }
   1239 
   1240 static void
   1241 mds_obj_move_abort_res(char *line, bool_t summary)
   1242 {
   1243 	DS_OBJ_MOVE_ABORTres	res;
   1244 
   1245 	memset(&res, '\0', sizeof (res));
   1246 	if (!xdr_DS_OBJ_MOVE_ABORTres(&xdrm, &res))
   1247 		longjmp(xdr_err, 1);
   1248 
   1249 	if (res.status != DS_OK) {
   1250 		print_status(line, res.status);
   1251 		xdr_free(xdr_DS_OBJ_MOVE_ABORTres, (char *)&res);
   1252 		return;
   1253 	}
   1254 
   1255 	xdr_free(xdr_DS_OBJ_MOVE_ABORTres, (char *)&res);
   1256 }
   1257 
   1258 static void
   1259 mds_obj_move_status_args(char *line, bool_t summary)
   1260 {
   1261 	DS_OBJ_MOVE_STATUSargs	args;
   1262 
   1263 	memset(&args, '\0', sizeof (args));
   1264 	if (!xdr_DS_OBJ_MOVE_STATUSargs(&xdrm, &args))
   1265 		longjmp(xdr_err, 1);
   1266 
   1267 	if (summary) {
   1268 		sprintf(line, " Tid=%llu",
   1269 		    args.taskid);
   1270 	} else {
   1271 		sprintf(get_line(0, 0), "Task ID = %llu",
   1272 		    args.taskid);
   1273 	}
   1274 
   1275 	xdr_free(xdr_DS_OBJ_MOVE_STATUSargs, (char *)&args);
   1276 }
   1277 
   1278 static void
   1279 mds_obj_move_status_res(char *line, bool_t summary)
   1280 {
   1281 	DS_OBJ_MOVE_STATUSres	res;
   1282 	DS_OBJ_MOVE_STATUSresok	*res_ok;
   1283 
   1284 	memset(&res, '\0', sizeof (res));
   1285 	if (!xdr_DS_OBJ_MOVE_STATUSres(&xdrm, &res))
   1286 		longjmp(xdr_err, 1);
   1287 
   1288 	if (res.status != DS_OK) {
   1289 		print_status(line, res.status);
   1290 		xdr_free(xdr_DS_OBJ_MOVE_STATUSres, (char *)&res);
   1291 		return;
   1292 	}
   1293 
   1294 	res_ok = &res.DS_OBJ_MOVE_STATUSres_u.res_ok;
   1295 
   1296 	if (summary) {
   1297 		sprintf(line, " Max=%llu (%s)",
   1298 		    res_ok->maxoffset,
   1299 		    res_ok->complete ? "done" :
   1300 		    "working");
   1301 	} else {
   1302 		sprintf(get_line(0, 0), "Max Offset = %llu",
   1303 		    res_ok->maxoffset);
   1304 		sprintf(get_line(0, 0), "Complete = %s",
   1305 		    res_ok->complete ? "done" :
   1306 		    "working");
   1307 	}
   1308 
   1309 	xdr_free(xdr_DS_OBJ_MOVE_STATUSres, (char *)&res);
   1310 }
   1311 
   1312 static void
   1313 mds_pnfsstat_args(char *line, bool_t summary)
   1314 {
   1315 	DS_PNFSSTATargs	args;
   1316 
   1317 	memset(&args, '\0', sizeof (args));
   1318 	if (!xdr_DS_PNFSSTATargs(&xdrm, &args))
   1319 		longjmp(xdr_err, 1);
   1320 
   1321 	if (summary) {
   1322 	} else {
   1323 	}
   1324 
   1325 	xdr_free(xdr_DS_PNFSSTATargs, (char *)&args);
   1326 }
   1327 
   1328 static void
   1329 mds_pnfsstat_res(char *line, bool_t summary)
   1330 {
   1331 	DS_PNFSSTATres	res;
   1332 	DS_PNFSSTATresok	*res_ok;
   1333 
   1334 	memset(&res, '\0', sizeof (res));
   1335 	if (!xdr_DS_PNFSSTATres(&xdrm, &res))
   1336 		longjmp(xdr_err, 1);
   1337 
   1338 	if (res.status != DS_OK) {
   1339 		print_status(line, res.status);
   1340 		xdr_free(xdr_DS_PNFSSTATres, (char *)&res);
   1341 		return;
   1342 	}
   1343 
   1344 	res_ok = &res.DS_PNFSSTATres_u.res_ok;
   1345 
   1346 	if (summary) {
   1347 	} else {
   1348 	}
   1349 
   1350 	xdr_free(xdr_DS_PNFSSTATres, (char *)&res);
   1351 }
   1352 
   1353 static void
   1354 mds_read_args(char *line, bool_t summary)
   1355 {
   1356 	DS_READargs	args;
   1357 
   1358 	memset(&args, '\0', sizeof (args));
   1359 	if (!xdr_DS_READargs(&xdrm, &args))
   1360 		longjmp(xdr_err, 1);
   1361 
   1362 	if (summary) {
   1363 	} else {
   1364 	}
   1365 
   1366 	xdr_free(xdr_DS_READargs, (char *)&args);
   1367 }
   1368 
   1369 static void
   1370 mds_read_res(char *line, bool_t summary)
   1371 {
   1372 	DS_READres	res;
   1373 	DS_READresok	*res_ok;
   1374 
   1375 	memset(&res, '\0', sizeof (res));
   1376 	if (!xdr_DS_READres(&xdrm, &res))
   1377 		longjmp(xdr_err, 1);
   1378 
   1379 	if (res.status != DS_OK) {
   1380 		print_status(line, res.status);
   1381 		xdr_free(xdr_DS_READres, (char *)&res);
   1382 		return;
   1383 	}
   1384 
   1385 	res_ok = &res.DS_READres_u.res_ok;
   1386 
   1387 	if (summary) {
   1388 	} else {
   1389 	}
   1390 
   1391 	xdr_free(xdr_DS_READres, (char *)&res);
   1392 }
   1393 
   1394 static void
   1395 mds_remove_args(char *line, bool_t summary)
   1396 {
   1397 	CTL_MDS_REMOVEargs	args;
   1398 
   1399 	memset(&args, '\0', sizeof (args));
   1400 	if (!xdr_CTL_MDS_REMOVEargs(&xdrm, &args))
   1401 		longjmp(xdr_err, 1);
   1402 
   1403 	if (summary) {
   1404 	} else {
   1405 	}
   1406 
   1407 	xdr_free(xdr_CTL_MDS_REMOVEargs, (char *)&args);
   1408 }
   1409 
   1410 static void
   1411 mds_remove_res(char *line, bool_t summary)
   1412 {
   1413 	CTL_MDS_REMOVEres	res;
   1414 
   1415 	memset(&res, '\0', sizeof (res));
   1416 	if (!xdr_CTL_MDS_REMOVEres(&xdrm, &res))
   1417 		longjmp(xdr_err, 1);
   1418 
   1419 	if (res.status != DS_OK) {
   1420 		print_status(line, res.status);
   1421 		xdr_free(xdr_CTL_MDS_REMOVEres, (char *)&res);
   1422 		return;
   1423 	}
   1424 
   1425 	if (summary) {
   1426 	} else {
   1427 	}
   1428 
   1429 	xdr_free(xdr_CTL_MDS_REMOVEres, (char *)&res);
   1430 }
   1431 
   1432 static void
   1433 mds_setattr_args(char *line, bool_t summary)
   1434 {
   1435 	DS_SETATTRargs	args;
   1436 
   1437 	memset(&args, '\0', sizeof (args));
   1438 	if (!xdr_DS_SETATTRargs(&xdrm, &args))
   1439 		longjmp(xdr_err, 1);
   1440 
   1441 	if (summary) {
   1442 	} else {
   1443 	}
   1444 
   1445 	xdr_free(xdr_DS_SETATTRargs, (char *)&args);
   1446 }
   1447 
   1448 static void
   1449 mds_setattr_res(char *line, bool_t summary)
   1450 {
   1451 	DS_SETATTRres	res;
   1452 
   1453 	memset(&res, '\0', sizeof (res));
   1454 	if (!xdr_DS_SETATTRres(&xdrm, &res))
   1455 		longjmp(xdr_err, 1);
   1456 
   1457 	if (res.status != DS_OK) {
   1458 		print_status(line, res.status);
   1459 		xdr_free(xdr_DS_SETATTRres, (char *)&res);
   1460 		return;
   1461 	}
   1462 
   1463 	if (summary) {
   1464 	} else {
   1465 	}
   1466 
   1467 	xdr_free(xdr_DS_SETATTRres, (char *)&res);
   1468 }
   1469 
   1470 static void
   1471 mds_stat_args(char *line, bool_t summary)
   1472 {
   1473 	DS_STATargs	args;
   1474 
   1475 	memset(&args, '\0', sizeof (args));
   1476 	if (!xdr_DS_STATargs(&xdrm, &args))
   1477 		longjmp(xdr_err, 1);
   1478 
   1479 	if (summary) {
   1480 	} else {
   1481 	}
   1482 
   1483 	xdr_free(xdr_DS_STATargs, (char *)&args);
   1484 }
   1485 
   1486 static void
   1487 mds_stat_res(char *line, bool_t summary)
   1488 {
   1489 	DS_STATres	res;
   1490 	ds_attr		*da;
   1491 
   1492 	memset(&res, '\0', sizeof (res));
   1493 	if (!xdr_DS_STATres(&xdrm, &res))
   1494 		longjmp(xdr_err, 1);
   1495 
   1496 	if (res.status != DS_OK) {
   1497 		print_status(line, res.status);
   1498 		xdr_free(xdr_DS_STATres, (char *)&res);
   1499 		return;
   1500 	}
   1501 
   1502 	da = &res.DS_STATres_u.dattr;
   1503 
   1504 	if (summary) {
   1505 	} else {
   1506 	}
   1507 
   1508 	xdr_free(xdr_DS_STATres, (char *)&res);
   1509 }
   1510 
   1511 static void
   1512 mds_snap_args(char *line, bool_t summary)
   1513 {
   1514 	DS_SNAPargs	args;
   1515 
   1516 	memset(&args, '\0', sizeof (args));
   1517 	if (!xdr_DS_SNAPargs(&xdrm, &args))
   1518 		longjmp(xdr_err, 1);
   1519 
   1520 	if (summary) {
   1521 	} else {
   1522 	}
   1523 
   1524 	xdr_free(xdr_DS_SNAPargs, (char *)&args);
   1525 }
   1526 
   1527 static void
   1528 mds_snap_res(char *line, bool_t summary)
   1529 {
   1530 	DS_SNAPres	res;
   1531 	DS_SNAPresok	*res_ok;
   1532 
   1533 	memset(&res, '\0', sizeof (res));
   1534 	if (!xdr_DS_SNAPres(&xdrm, &res))
   1535 		longjmp(xdr_err, 1);
   1536 
   1537 	if (res.status != DS_OK) {
   1538 		print_status(line, res.status);
   1539 		xdr_free(xdr_DS_SNAPres, (char *)&res);
   1540 		return;
   1541 	}
   1542 
   1543 	res_ok = &res.DS_SNAPres_u.res_ok;
   1544 
   1545 	if (summary) {
   1546 	} else {
   1547 	}
   1548 
   1549 	xdr_free(xdr_DS_SNAPres, (char *)&res);
   1550 }
   1551 
   1552 static void
   1553 mds_write_args(char *line, bool_t summary)
   1554 {
   1555 	DS_WRITEargs	args;
   1556 
   1557 	memset(&args, '\0', sizeof (args));
   1558 	if (!xdr_DS_WRITEargs(&xdrm, &args))
   1559 		longjmp(xdr_err, 1);
   1560 
   1561 	if (summary) {
   1562 	} else {
   1563 	}
   1564 
   1565 	xdr_free(xdr_DS_WRITEargs, (char *)&args);
   1566 }
   1567 
   1568 static void
   1569 mds_write_res(char *line, bool_t summary)
   1570 {
   1571 	DS_WRITEres	res;
   1572 	DS_WRITEresok	*res_ok;
   1573 
   1574 	memset(&res, '\0', sizeof (res));
   1575 	if (!xdr_DS_WRITEres(&xdrm, &res))
   1576 		longjmp(xdr_err, 1);
   1577 
   1578 	if (res.status != DS_OK) {
   1579 		print_status(line, res.status);
   1580 		xdr_free(xdr_DS_WRITEres, (char *)&res);
   1581 		return;
   1582 	}
   1583 
   1584 	res_ok = &res.DS_WRITEres_u.res_ok;
   1585 
   1586 	if (summary) {
   1587 	} else {
   1588 	}
   1589 
   1590 	xdr_free(xdr_DS_WRITEres, (char *)&res);
   1591 }
   1592 
   1593 static void
   1594 ds_move_args(char *line, bool_t summary)
   1595 {
   1596 	MOVEargs	args;
   1597 
   1598 	memset(&args, '\0', sizeof (args));
   1599 	if (!xdr_MOVEargs(&xdrm, &args))
   1600 		longjmp(xdr_err, 1);
   1601 
   1602 	if (summary) {
   1603 	} else {
   1604 	}
   1605 
   1606 	xdr_free(xdr_MOVEargs, (char *)&args);
   1607 }
   1608 
   1609 static void
   1610 ds_move_res(char *line, bool_t summary)
   1611 {
   1612 	MOVEres	res;
   1613 	MOVEresok	*res_ok;
   1614 
   1615 	memset(&res, '\0', sizeof (res));
   1616 	if (!xdr_MOVEres(&xdrm, &res))
   1617 		longjmp(xdr_err, 1);
   1618 
   1619 	if (res.status != DS_OK) {
   1620 		print_status(line, res.status);
   1621 		xdr_free(xdr_MOVEres, (char *)&res);
   1622 		return;
   1623 	}
   1624 
   1625 	res_ok = &res.MOVEres_u.res_ok;
   1626 
   1627 	if (summary) {
   1628 	} else {
   1629 	}
   1630 
   1631 	xdr_free(xdr_MOVEres, (char *)&res);
   1632 }
   1633