xref: /titanic_52/usr/src/cmd/ndmpd/ndmp/ndmpd_config.c (revision 5bc1e22263da29a716575a856dd867c1f58f4a8b)
12654012fSReza Sabdar /*
28c4f9701SJanice Chang  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
32654012fSReza Sabdar  */
42654012fSReza Sabdar 
52654012fSReza Sabdar /*
62654012fSReza Sabdar  * BSD 3 Clause License
72654012fSReza Sabdar  *
82654012fSReza Sabdar  * Copyright (c) 2007, The Storage Networking Industry Association.
92654012fSReza Sabdar  *
102654012fSReza Sabdar  * Redistribution and use in source and binary forms, with or without
112654012fSReza Sabdar  * modification, are permitted provided that the following conditions
122654012fSReza Sabdar  * are met:
132654012fSReza Sabdar  * 	- Redistributions of source code must retain the above copyright
142654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
152654012fSReza Sabdar  *
162654012fSReza Sabdar  * 	- Redistributions in binary form must reproduce the above copyright
172654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer in
182654012fSReza Sabdar  *	  the documentation and/or other materials provided with the
192654012fSReza Sabdar  *	  distribution.
202654012fSReza Sabdar  *
212654012fSReza Sabdar  *	- Neither the name of The Storage Networking Industry Association (SNIA)
222654012fSReza Sabdar  *	  nor the names of its contributors may be used to endorse or promote
232654012fSReza Sabdar  *	  products derived from this software without specific prior written
242654012fSReza Sabdar  *	  permission.
252654012fSReza Sabdar  *
262654012fSReza Sabdar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
272654012fSReza Sabdar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
282654012fSReza Sabdar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
292654012fSReza Sabdar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
302654012fSReza Sabdar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
312654012fSReza Sabdar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
322654012fSReza Sabdar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
332654012fSReza Sabdar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
342654012fSReza Sabdar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
352654012fSReza Sabdar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
362654012fSReza Sabdar  * POSSIBILITY OF SUCH DAMAGE.
372654012fSReza Sabdar  */
382654012fSReza Sabdar /* Copyright (c) 2007, The Storage Networking Industry Association. */
392654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
403ed73a35SAlbert Lee /* Copyright 2014 Nexenta Systems, Inc.  All rights reserved. */
412654012fSReza Sabdar 
422654012fSReza Sabdar #include <dirent.h>
432654012fSReza Sabdar #include <errno.h>
442654012fSReza Sabdar #include <stdio.h>
452654012fSReza Sabdar #include <stdlib.h>
462654012fSReza Sabdar #include <string.h>
472654012fSReza Sabdar #include <sys/stat.h>
482654012fSReza Sabdar #include <sys/mnttab.h>
492654012fSReza Sabdar #include <sys/mntent.h>
502654012fSReza Sabdar #include <sys/mntio.h>
512654012fSReza Sabdar #include <sys/statvfs.h>
522654012fSReza Sabdar #include <sys/utsname.h>
532654012fSReza Sabdar #include <sys/scsi/scsi.h>
542654012fSReza Sabdar #include <unistd.h>
552654012fSReza Sabdar #include <sys/systeminfo.h>
562654012fSReza Sabdar #include "ndmpd_common.h"
572654012fSReza Sabdar #include "ndmpd.h"
582654012fSReza Sabdar 
592654012fSReza Sabdar static void simple_get_attrs(ulong_t *attributes);
602654012fSReza Sabdar 
612654012fSReza Sabdar /*
622654012fSReza Sabdar  * Number of environment variable for the file system
632654012fSReza Sabdar  * info in V3 net_fs_info.
642654012fSReza Sabdar  */
652654012fSReza Sabdar #define	V3_N_FS_ENVS	4
662654012fSReza Sabdar 
672654012fSReza Sabdar /*
682654012fSReza Sabdar  * Is the file system a valid one to be reported to the
692654012fSReza Sabdar  * clients?
702654012fSReza Sabdar  */
712654012fSReza Sabdar #define	IS_VALID_FS(fs) (fs && ( \
722654012fSReza Sabdar 	strcasecmp(fs->mnt_fstype, MNTTYPE_UFS) == 0 || \
732654012fSReza Sabdar 	strcasecmp(fs->mnt_fstype, MNTTYPE_ZFS) == 0 || \
742654012fSReza Sabdar 	strcasecmp(fs->mnt_fstype, MNTTYPE_NFS) == 0 || \
752654012fSReza Sabdar 	strcasecmp(fs->mnt_fstype, MNTTYPE_NFS3) == 0 || \
762654012fSReza Sabdar 	strcasecmp(fs->mnt_fstype, MNTTYPE_NFS4) == 0))
772654012fSReza Sabdar 
782654012fSReza Sabdar #define	MNTTYPE_LEN	10
792654012fSReza Sabdar 
802654012fSReza Sabdar extern struct fs_ops sfs2_ops;
812654012fSReza Sabdar extern struct fs_ops sfs2cpv_ops;
822654012fSReza Sabdar 
832654012fSReza Sabdar 
842654012fSReza Sabdar /*
852654012fSReza Sabdar  * ************************************************************************
862654012fSReza Sabdar  * NDMP V2 HANDLERS
872654012fSReza Sabdar  * ************************************************************************
882654012fSReza Sabdar  */
892654012fSReza Sabdar 
902654012fSReza Sabdar /*
912654012fSReza Sabdar  * ndmpd_config_get_host_info_v2
922654012fSReza Sabdar  *
932654012fSReza Sabdar  * This handler handles the ndmp_config_get_host_info request.
942654012fSReza Sabdar  * Host specific information is returned.
952654012fSReza Sabdar  *
962654012fSReza Sabdar  * Parameters:
972654012fSReza Sabdar  *   connection (input) - connection handle.
982654012fSReza Sabdar  *   body       (input) - request message body.
992654012fSReza Sabdar  *
1002654012fSReza Sabdar  * Returns:
1012654012fSReza Sabdar  *   void
1022654012fSReza Sabdar  */
1032654012fSReza Sabdar /*ARGSUSED*/
1042654012fSReza Sabdar void
1052654012fSReza Sabdar ndmpd_config_get_host_info_v2(ndmp_connection_t *connection, void *body)
1062654012fSReza Sabdar {
1072654012fSReza Sabdar 	ndmp_config_get_host_info_reply_v2 reply;
1082654012fSReza Sabdar 	ndmp_auth_type auth_types[2];
1092654012fSReza Sabdar 	char buf[HOSTNAMELEN + 1];
1102654012fSReza Sabdar 	struct utsname uts;
1112654012fSReza Sabdar 	char hostidstr[16];
1122654012fSReza Sabdar 	ulong_t hostid;
1132654012fSReza Sabdar 
1142654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
1152654012fSReza Sabdar 	(void) memset(buf, 0, sizeof (buf));
1162654012fSReza Sabdar 	(void) gethostname(buf, sizeof (buf));
1172654012fSReza Sabdar 
1182654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
1192654012fSReza Sabdar 	reply.hostname = buf;
1202654012fSReza Sabdar 	(void) uname(&uts);
1212654012fSReza Sabdar 	reply.os_type = uts.sysname;
1222654012fSReza Sabdar 	reply.os_vers = uts.release;
1232654012fSReza Sabdar 
1242654012fSReza Sabdar 	if (sysinfo(SI_HW_SERIAL, hostidstr, sizeof (hostidstr)) < 0) {
1252654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "sysinfo error: %m.");
1262654012fSReza Sabdar 		reply.error = NDMP_UNDEFINED_ERR;
1272654012fSReza Sabdar 	}
1282654012fSReza Sabdar 
1292654012fSReza Sabdar 	/*
1302654012fSReza Sabdar 	 * Convert the hostid to hex. The returned string must match
1312654012fSReza Sabdar 	 * the string returned by hostid(1).
1322654012fSReza Sabdar 	 */
1332654012fSReza Sabdar 	hostid = strtoul(hostidstr, 0, 0);
1342654012fSReza Sabdar 	(void) snprintf(hostidstr, sizeof (hostidstr), "%lx", hostid);
1352654012fSReza Sabdar 	reply.hostid = hostidstr;
1362654012fSReza Sabdar 
1372654012fSReza Sabdar 	auth_types[0] = NDMP_AUTH_TEXT;
1382654012fSReza Sabdar 	reply.auth_type.auth_type_len = 1;
1392654012fSReza Sabdar 	reply.auth_type.auth_type_val = auth_types;
1402654012fSReza Sabdar 
1412654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
1422654012fSReza Sabdar 	    "sending ndmp_config_get_host_info reply");
1432654012fSReza Sabdar }
1442654012fSReza Sabdar 
1452654012fSReza Sabdar 
1462654012fSReza Sabdar /*
1472654012fSReza Sabdar  * ndmpd_config_get_butype_attr_v2
1482654012fSReza Sabdar  *
1492654012fSReza Sabdar  * This handler handles the ndmp_config_get_butype_attr request.
1502654012fSReza Sabdar  * Information about the specified backup type is returned.
1512654012fSReza Sabdar  *
1522654012fSReza Sabdar  * Parameters:
1532654012fSReza Sabdar  *   connection (input) - connection handle.
1542654012fSReza Sabdar  *   body       (input) - request message body.
1552654012fSReza Sabdar  *
1562654012fSReza Sabdar  * Returns:
1572654012fSReza Sabdar  *   void
1582654012fSReza Sabdar  */
1592654012fSReza Sabdar void
1602654012fSReza Sabdar ndmpd_config_get_butype_attr_v2(ndmp_connection_t *connection, void *body)
1612654012fSReza Sabdar {
1622654012fSReza Sabdar 	ndmp_config_get_butype_attr_request *request;
1632654012fSReza Sabdar 	ndmp_config_get_butype_attr_reply reply;
1642654012fSReza Sabdar 
1652654012fSReza Sabdar 	request = (ndmp_config_get_butype_attr_request *)body;
1662654012fSReza Sabdar 
1672654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
1682654012fSReza Sabdar 
1692654012fSReza Sabdar 	if (strcmp(request->name, "dump") == 0) {
1702654012fSReza Sabdar 		(void) simple_get_attrs(&reply.attrs);
1712654012fSReza Sabdar 	} else if (strcmp(request->name, "tar") == 0) {
1722654012fSReza Sabdar 		reply.attrs = NDMP_NO_BACKUP_FILELIST;
1732654012fSReza Sabdar 	} else {
1742654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", request->name);
1752654012fSReza Sabdar 		NDMP_LOG(LOG_ERR,
1762654012fSReza Sabdar 		    "Supported backup types are 'dump' and 'tar' only.");
1772654012fSReza Sabdar 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
1782654012fSReza Sabdar 	}
1792654012fSReza Sabdar 
1802654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
1812654012fSReza Sabdar 	    "sending ndmp_config_get_butype_attr reply");
1822654012fSReza Sabdar }
1832654012fSReza Sabdar 
1842654012fSReza Sabdar 
1852654012fSReza Sabdar /*
1862654012fSReza Sabdar  * ndmpd_config_get_mover_type_v2
1872654012fSReza Sabdar  *
1882654012fSReza Sabdar  * This handler handles the ndmp_config_get_mover_type request.
1892654012fSReza Sabdar  * Information about the supported mover types is returned.
1902654012fSReza Sabdar  *
1912654012fSReza Sabdar  * Parameters:
1922654012fSReza Sabdar  *   connection (input) - connection handle.
1932654012fSReza Sabdar  *   body       (input) - request message body.
1942654012fSReza Sabdar  *
1952654012fSReza Sabdar  * Returns:
1962654012fSReza Sabdar  *   void
1972654012fSReza Sabdar  */
1982654012fSReza Sabdar /*ARGSUSED*/
1992654012fSReza Sabdar void
2002654012fSReza Sabdar ndmpd_config_get_mover_type_v2(ndmp_connection_t *connection, void *body)
2012654012fSReza Sabdar {
2022654012fSReza Sabdar 	ndmp_config_get_mover_type_reply reply;
2032654012fSReza Sabdar 	ndmp_addr_type types[2];
2042654012fSReza Sabdar 
2052654012fSReza Sabdar 	types[0] = NDMP_ADDR_LOCAL;
2062654012fSReza Sabdar 	types[1] = NDMP_ADDR_TCP;
2072654012fSReza Sabdar 
2082654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
2092654012fSReza Sabdar 	reply.methods.methods_len = 2;
2102654012fSReza Sabdar 	reply.methods.methods_val = types;
2112654012fSReza Sabdar 
2122654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
2132654012fSReza Sabdar 	    "sending ndmp_config_get_mover_type reply");
2142654012fSReza Sabdar }
2152654012fSReza Sabdar 
2162654012fSReza Sabdar 
2172654012fSReza Sabdar 
2182654012fSReza Sabdar /*
2192654012fSReza Sabdar  * ndmpd_config_get_auth_attr_v2
2202654012fSReza Sabdar  *
2212654012fSReza Sabdar  * This handler handles the ndmp_config_get_auth_attr request.
2222654012fSReza Sabdar  * Authorization type specific information is returned.
2232654012fSReza Sabdar  *
2242654012fSReza Sabdar  * Parameters:
2252654012fSReza Sabdar  *   connection (input) - connection handle.
2262654012fSReza Sabdar  *   body       (input) - request message body.
2272654012fSReza Sabdar  *
2282654012fSReza Sabdar  * Returns:
2292654012fSReza Sabdar  *   void
2302654012fSReza Sabdar  */
2312654012fSReza Sabdar void
2322654012fSReza Sabdar ndmpd_config_get_auth_attr_v2(ndmp_connection_t *connection, void *body)
2332654012fSReza Sabdar {
2342654012fSReza Sabdar 	ndmp_config_get_auth_attr_request *request;
2352654012fSReza Sabdar 	ndmp_config_get_auth_attr_reply reply;
2362654012fSReza Sabdar 	ndmpd_session_t *session = ndmp_get_client_data(connection);
2372654012fSReza Sabdar 
2382654012fSReza Sabdar 	request = (ndmp_config_get_auth_attr_request *)body;
2392654012fSReza Sabdar 
2402654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
2412654012fSReza Sabdar 	reply.server_attr.auth_type = request->auth_type;
2422654012fSReza Sabdar 
2432654012fSReza Sabdar 	switch (request->auth_type) {
2442654012fSReza Sabdar 	case NDMP_AUTH_TEXT:
2452654012fSReza Sabdar 		break;
2462654012fSReza Sabdar 	case NDMP_AUTH_MD5:
2472654012fSReza Sabdar 		/* Create a 64 byte random session challenge */
2482654012fSReza Sabdar 		randomize(session->ns_challenge, MD5_CHALLENGE_SIZE);
2492654012fSReza Sabdar 		(void) memcpy(reply.server_attr.ndmp_auth_attr_u.challenge,
2502654012fSReza Sabdar 		    session->ns_challenge, MD5_CHALLENGE_SIZE);
2512654012fSReza Sabdar 		break;
2522654012fSReza Sabdar 	case NDMP_AUTH_NONE:
2532654012fSReza Sabdar 		/* FALL THROUGH */
2542654012fSReza Sabdar 	default:
2552654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "Invalid authentication type: %d.",
2562654012fSReza Sabdar 		    request->auth_type);
2572654012fSReza Sabdar 		NDMP_LOG(LOG_ERR,
2582654012fSReza Sabdar 		    "Supported authentication types are md5 and cleartext.");
2592654012fSReza Sabdar 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
2602654012fSReza Sabdar 		break;
2612654012fSReza Sabdar 	}
2622654012fSReza Sabdar 
2632654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
2642654012fSReza Sabdar 	    "sending ndmp_config_get_auth_attr reply");
2652654012fSReza Sabdar }
2662654012fSReza Sabdar 
2672654012fSReza Sabdar 
2682654012fSReza Sabdar /*
2692654012fSReza Sabdar  * ************************************************************************
2702654012fSReza Sabdar  * NDMP V3 HANDLERS
2712654012fSReza Sabdar  * ************************************************************************
2722654012fSReza Sabdar  */
2732654012fSReza Sabdar 
2742654012fSReza Sabdar /*
2752654012fSReza Sabdar  * ndmpd_config_get_host_info_v3
2762654012fSReza Sabdar  *
2772654012fSReza Sabdar  * This handler handles the ndmp_config_get_host_info request.
2782654012fSReza Sabdar  * Host specific information is returned.
2792654012fSReza Sabdar  *
2802654012fSReza Sabdar  * Parameters:
2812654012fSReza Sabdar  *   connection (input) - connection handle.
2822654012fSReza Sabdar  *   body       (input) - request message body.
2832654012fSReza Sabdar  *
2842654012fSReza Sabdar  * Returns:
2852654012fSReza Sabdar  *   void
2862654012fSReza Sabdar  */
2872654012fSReza Sabdar /*ARGSUSED*/
2882654012fSReza Sabdar void
2892654012fSReza Sabdar ndmpd_config_get_host_info_v3(ndmp_connection_t *connection, void *body)
2902654012fSReza Sabdar {
2912654012fSReza Sabdar 	ndmp_config_get_host_info_reply_v3 reply;
2922654012fSReza Sabdar 	char buf[HOSTNAMELEN+1];
2932654012fSReza Sabdar 	struct utsname uts;
2942654012fSReza Sabdar 	char hostidstr[16];
2952654012fSReza Sabdar 	ulong_t hostid;
2962654012fSReza Sabdar 
2972654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
2982654012fSReza Sabdar 	(void) memset(buf, 0, sizeof (buf));
2992654012fSReza Sabdar 	(void) gethostname(buf, sizeof (buf));
3002654012fSReza Sabdar 
3012654012fSReza Sabdar 
3022654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
3032654012fSReza Sabdar 	reply.hostname = buf;
3042654012fSReza Sabdar 	(void) uname(&uts);
3052654012fSReza Sabdar 	reply.os_type = uts.sysname;
3062654012fSReza Sabdar 	reply.os_vers = uts.release;
3072654012fSReza Sabdar 
3082654012fSReza Sabdar 	if (sysinfo(SI_HW_SERIAL, hostidstr, sizeof (hostidstr)) < 0) {
3092654012fSReza Sabdar 
3102654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "sysinfo error: %m.");
3112654012fSReza Sabdar 		reply.error = NDMP_UNDEFINED_ERR;
3122654012fSReza Sabdar 	}
3132654012fSReza Sabdar 
3142654012fSReza Sabdar 	/*
3152654012fSReza Sabdar 	 * Convert the hostid to hex. The returned string must match
3162654012fSReza Sabdar 	 * the string returned by hostid(1).
3172654012fSReza Sabdar 	 */
3182654012fSReza Sabdar 	hostid = strtoul(hostidstr, 0, 0);
3192654012fSReza Sabdar 	(void) snprintf(hostidstr, sizeof (hostidstr), "%lx", hostid);
3202654012fSReza Sabdar 	reply.hostid = hostidstr;
3212654012fSReza Sabdar 
3222654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
3232654012fSReza Sabdar 	    "sending ndmp_config_get_host_info reply");
3242654012fSReza Sabdar }
3252654012fSReza Sabdar 
3262654012fSReza Sabdar 
3272654012fSReza Sabdar /*
3282654012fSReza Sabdar  * ndmpd_config_get_connection_type_v3
3292654012fSReza Sabdar  *
3302654012fSReza Sabdar  * This handler handles the ndmp_config_get_connection_type_request.
3312654012fSReza Sabdar  * A list of supported data connection types is returned.
3322654012fSReza Sabdar  *
3332654012fSReza Sabdar  * Parameters:
3342654012fSReza Sabdar  *   connection (input) - connection handle.
3352654012fSReza Sabdar  *   body       (input) - request message body.
3362654012fSReza Sabdar  *
3372654012fSReza Sabdar  * Returns:
3382654012fSReza Sabdar  *   void
3392654012fSReza Sabdar  */
3402654012fSReza Sabdar /*ARGSUSED*/
3412654012fSReza Sabdar void
3422654012fSReza Sabdar ndmpd_config_get_connection_type_v3(ndmp_connection_t *connection,
3432654012fSReza Sabdar     void *body)
3442654012fSReza Sabdar {
3452654012fSReza Sabdar 	ndmp_config_get_connection_type_reply_v3 reply;
3462654012fSReza Sabdar 	ndmp_addr_type addr_types[2];
3472654012fSReza Sabdar 
3482654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
3492654012fSReza Sabdar 
3502654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
3512654012fSReza Sabdar 
3522654012fSReza Sabdar 	addr_types[0] = NDMP_ADDR_LOCAL;
3532654012fSReza Sabdar 	addr_types[1] = NDMP_ADDR_TCP;
3542654012fSReza Sabdar 	reply.addr_types.addr_types_len = 2;
3552654012fSReza Sabdar 	reply.addr_types.addr_types_val = addr_types;
3562654012fSReza Sabdar 
3572654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
3582654012fSReza Sabdar 	    "sending config_get_connection_type_v3 reply");
3592654012fSReza Sabdar }
3602654012fSReza Sabdar 
3612654012fSReza Sabdar 
3622654012fSReza Sabdar 
3632654012fSReza Sabdar /*
3642654012fSReza Sabdar  * ndmpd_config_get_auth_attr_v3
3652654012fSReza Sabdar  *
3662654012fSReza Sabdar  * This handler handles the ndmp_config_get_auth_attr request.
3672654012fSReza Sabdar  * Authorization type specific information is returned.
3682654012fSReza Sabdar  *
3692654012fSReza Sabdar  * Parameters:
3702654012fSReza Sabdar  *   connection (input) - connection handle.
3712654012fSReza Sabdar  *   body       (input) - request message body.
3722654012fSReza Sabdar  *
3732654012fSReza Sabdar  * Returns:
3742654012fSReza Sabdar  *   void
3752654012fSReza Sabdar  */
3762654012fSReza Sabdar void
3772654012fSReza Sabdar ndmpd_config_get_auth_attr_v3(ndmp_connection_t *connection, void *body)
3782654012fSReza Sabdar {
3792654012fSReza Sabdar 	ndmp_config_get_auth_attr_request *request;
3802654012fSReza Sabdar 	ndmp_config_get_auth_attr_reply reply;
3812654012fSReza Sabdar 	ndmpd_session_t *session = ndmp_get_client_data(connection);
3822654012fSReza Sabdar 
3832654012fSReza Sabdar 	request = (ndmp_config_get_auth_attr_request *)body;
3842654012fSReza Sabdar 
3852654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
3862654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
3872654012fSReza Sabdar 	reply.server_attr.auth_type = request->auth_type;
3882654012fSReza Sabdar 
3892654012fSReza Sabdar 	switch (request->auth_type) {
3902654012fSReza Sabdar 	case NDMP_AUTH_TEXT:
3912654012fSReza Sabdar 		break;
3922654012fSReza Sabdar 	case NDMP_AUTH_MD5:
3932654012fSReza Sabdar 		/* Create a 64 bytes random session challenge */
3942654012fSReza Sabdar 		randomize(session->ns_challenge, MD5_CHALLENGE_SIZE);
3952654012fSReza Sabdar 		(void) memcpy(reply.server_attr.ndmp_auth_attr_u.challenge,
3962654012fSReza Sabdar 		    session->ns_challenge, MD5_CHALLENGE_SIZE);
3972654012fSReza Sabdar 		break;
3982654012fSReza Sabdar 	case NDMP_AUTH_NONE:
3992654012fSReza Sabdar 		/* FALL THROUGH */
4002654012fSReza Sabdar 	default:
4012654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "Invalid authentication type: %d.",
4022654012fSReza Sabdar 		    request->auth_type);
4032654012fSReza Sabdar 		NDMP_LOG(LOG_ERR,
4042654012fSReza Sabdar 		    "Supported authentication types are md5 and cleartext.");
4052654012fSReza Sabdar 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
4062654012fSReza Sabdar 		break;
4072654012fSReza Sabdar 	}
4082654012fSReza Sabdar 
4092654012fSReza Sabdar 	ndmp_send_reply(connection, (void *) &reply,
4102654012fSReza Sabdar 	    "sending ndmp_config_get_auth_attr_v3 reply");
4112654012fSReza Sabdar }
4122654012fSReza Sabdar 
4132654012fSReza Sabdar 
4142654012fSReza Sabdar /*
4152654012fSReza Sabdar  * ndmpd_config_get_butype_info_v3
4162654012fSReza Sabdar  *
4172654012fSReza Sabdar  * This handler handles the ndmp_config_get_butype_info_request.
4182654012fSReza Sabdar  * Information about all supported backup types are returned.
4192654012fSReza Sabdar  *
4202654012fSReza Sabdar  * Parameters:
4212654012fSReza Sabdar  *   connection (input) - connection handle.
4222654012fSReza Sabdar  *   body       (input) - request message body.
4232654012fSReza Sabdar  *
4242654012fSReza Sabdar  * Returns:
4252654012fSReza Sabdar  *   void
4262654012fSReza Sabdar  */
4272654012fSReza Sabdar /*ARGSUSED*/
4282654012fSReza Sabdar void
4292654012fSReza Sabdar ndmpd_config_get_butype_info_v3(ndmp_connection_t *connection, void *body)
4302654012fSReza Sabdar {
4312654012fSReza Sabdar 	ndmp_config_get_butype_info_reply_v3 reply;
4328c4f9701SJanice Chang 	ndmp_butype_info info[3];
4332654012fSReza Sabdar 	ndmp_pval envs[8];
4342654012fSReza Sabdar 	ulong_t attrs;
4352654012fSReza Sabdar 	ndmp_pval *envp = envs;
4362654012fSReza Sabdar 
4378c4f9701SJanice Chang 	ndmp_pval zfs_envs[9];
4388c4f9701SJanice Chang 	ulong_t zfs_attrs;
4398c4f9701SJanice Chang 	ndmp_pval *zfs_envp = zfs_envs;
4408c4f9701SJanice Chang 
4412654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
4422654012fSReza Sabdar 
4432654012fSReza Sabdar 	/*
4448c4f9701SJanice Chang 	 * Supported environment variables and their default values
4458c4f9701SJanice Chang 	 * for dump and tar.
4468c4f9701SJanice Chang 	 *
4472654012fSReza Sabdar 	 * The environment variables for dump and tar format are the
4482654012fSReza Sabdar 	 * same, because we use the same backup engine for both.
4492654012fSReza Sabdar 	 */
4502654012fSReza Sabdar 	NDMP_SETENV(envp, "PREFIX", "");
4512654012fSReza Sabdar 	NDMP_SETENV(envp, "TYPE", "");
4522654012fSReza Sabdar 	NDMP_SETENV(envp, "DIRECT", "n");
4532654012fSReza Sabdar 	NDMP_SETENV(envp, "HIST", "n");
4542654012fSReza Sabdar 	NDMP_SETENV(envp, "FILESYSTEM", "");
4552654012fSReza Sabdar 	NDMP_SETENV(envp, "LEVEL", "0");
4562654012fSReza Sabdar 	NDMP_SETENV(envp, "UPDATE", "TRUE");
4572654012fSReza Sabdar 	NDMP_SETENV(envp, "BASE_DATE", "");
4582654012fSReza Sabdar 
4592654012fSReza Sabdar 	attrs = NDMP_BUTYPE_BACKUP_FILE_HISTORY |
4602654012fSReza Sabdar 	    NDMP_BUTYPE_RECOVER_FILELIST |
4612654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_DIRECT |
4622654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_INCREMENTAL |
4632654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_UTF8 |
4642654012fSReza Sabdar 	    NDMP_BUTYPE_RECOVER_UTF8;
4652654012fSReza Sabdar 
4662654012fSReza Sabdar 	/* If DAR supported */
4672654012fSReza Sabdar 	if (ndmp_dar_support)
4682654012fSReza Sabdar 		attrs |= NDMP_BUTYPE_RECOVER_DIRECT;
4692654012fSReza Sabdar 
4702654012fSReza Sabdar 	/* tar backup type */
4712654012fSReza Sabdar 	info[0].butype_name = "tar";
4722654012fSReza Sabdar 	info[0].default_env.default_env_len = ARRAY_LEN(envs, ndmp_pval);
4732654012fSReza Sabdar 	info[0].default_env.default_env_val = envs;
4742654012fSReza Sabdar 	info[0].attrs = attrs;
4752654012fSReza Sabdar 
4762654012fSReza Sabdar 	/* dump backup type */
4772654012fSReza Sabdar 	info[1].butype_name = "dump";
4782654012fSReza Sabdar 	info[1].default_env.default_env_len = ARRAY_LEN(envs, ndmp_pval);
4792654012fSReza Sabdar 	info[1].default_env.default_env_val = envs;
4802654012fSReza Sabdar 	info[1].attrs = attrs;
4812654012fSReza Sabdar 
4828c4f9701SJanice Chang 	/*
4838c4f9701SJanice Chang 	 * Supported environment variables and their default values
4848c4f9701SJanice Chang 	 * for type "zfs."
4858c4f9701SJanice Chang 	 */
4868c4f9701SJanice Chang 
4878c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "PREFIX", "");
4888c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "FILESYSTEM", "");
4898c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "TYPE", "zfs");
4908c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "HIST", "n");
4918c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "LEVEL", "0");
4928c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "ZFS_MODE", "recursive");
4938c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "ZFS_FORCE", "FALSE");
4948c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "UPDATE", "TRUE");
4958c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "DMP_NAME", "level");
4968c4f9701SJanice Chang 
4978c4f9701SJanice Chang 	zfs_attrs = NDMP_BUTYPE_BACKUP_UTF8 |
4988c4f9701SJanice Chang 	    NDMP_BUTYPE_RECOVER_UTF8 |
499f9708870SReza Sabdar 	    NDMP_BUTYPE_BACKUP_DIRECT |
5008c4f9701SJanice Chang 	    NDMP_BUTYPE_BACKUP_INCREMENTAL;
5018c4f9701SJanice Chang 
5028c4f9701SJanice Chang 	/* zfs backup type */
5038c4f9701SJanice Chang 	info[2].butype_name = "zfs";
5048c4f9701SJanice Chang 	info[2].default_env.default_env_len = ARRAY_LEN(zfs_envs, ndmp_pval);
5058c4f9701SJanice Chang 	info[2].default_env.default_env_val = zfs_envs;
5068c4f9701SJanice Chang 	info[2].attrs = zfs_attrs;
5078c4f9701SJanice Chang 
5082654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
5092654012fSReza Sabdar 	reply.butype_info.butype_info_len = ARRAY_LEN(info, ndmp_butype_info);
5102654012fSReza Sabdar 	reply.butype_info.butype_info_val = info;
5112654012fSReza Sabdar 
5122654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
5132654012fSReza Sabdar 	    "sending ndmp_config_get_butype_info reply");
5142654012fSReza Sabdar }
5152654012fSReza Sabdar 
5162654012fSReza Sabdar /*
5172654012fSReza Sabdar  * ndmpd_config_get_fs_info_v3
5182654012fSReza Sabdar  *
5192654012fSReza Sabdar  * This handler handles the ndmp_config_get_fs_info_request.
5202654012fSReza Sabdar  * Information about all mounted file systems is returned.
5212654012fSReza Sabdar  *
5222654012fSReza Sabdar  * Parameters:
5232654012fSReza Sabdar  *   connection (input) - connection handle.
5242654012fSReza Sabdar  *   body       (input) - request message body.
5252654012fSReza Sabdar  *
5262654012fSReza Sabdar  * Returns:
5272654012fSReza Sabdar  *   void
5282654012fSReza Sabdar  */
5292654012fSReza Sabdar /*ARGSUSED*/
5302654012fSReza Sabdar void
5312654012fSReza Sabdar ndmpd_config_get_fs_info_v3(ndmp_connection_t *connection, void *body)
5322654012fSReza Sabdar {
5332654012fSReza Sabdar 	ndmp_config_get_fs_info_reply_v3 reply;
5343ed73a35SAlbert Lee 	ndmp_fs_info_v3 *fsip = NULL, *fsip_save = NULL; /* FS info pointer */
5353ed73a35SAlbert Lee 	int len = 0, nmnt, fd;
5362654012fSReza Sabdar 	int log_dev_len;
5372654012fSReza Sabdar 	FILE *fp = NULL;
5382654012fSReza Sabdar 	struct mnttab mt, *fs;
5392654012fSReza Sabdar 	struct statvfs64 stat_buf;
5402654012fSReza Sabdar 	ndmp_pval *envp, *save;
5412654012fSReza Sabdar 
5422654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
5432654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
5442654012fSReza Sabdar 
5452654012fSReza Sabdar 	if ((fd = open(MNTTAB, O_RDONLY)) == -1) {
5462654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "File mnttab open error: %m.");
5472654012fSReza Sabdar 		reply.error = NDMP_UNDEFINED_ERR;
5483ed73a35SAlbert Lee 		goto send_reply;
5492654012fSReza Sabdar 	}
5502654012fSReza Sabdar 
5512654012fSReza Sabdar 	/* nothing was found, send an empty reply */
5522654012fSReza Sabdar 	if (ioctl(fd, MNTIOC_NMNTS, &nmnt) != 0 || nmnt <= 0) {
5533ed73a35SAlbert Lee 		(void) close(fd);
5542654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "No file system found.");
5553ed73a35SAlbert Lee 		goto send_reply;
5562654012fSReza Sabdar 	}
5572654012fSReza Sabdar 
5583ed73a35SAlbert Lee 	fp = fdopen(fd, "r");
5592654012fSReza Sabdar 	if (!fp) {
5603ed73a35SAlbert Lee 		(void) close(fd);
5612654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "File mnttab open error: %m.");
5622654012fSReza Sabdar 		reply.error = NDMP_UNDEFINED_ERR;
5633ed73a35SAlbert Lee 		goto send_reply;
5642654012fSReza Sabdar 	}
5652654012fSReza Sabdar 
5662654012fSReza Sabdar 	fsip_save = fsip = ndmp_malloc(sizeof (ndmp_fs_info_v3) * nmnt);
5672654012fSReza Sabdar 	if (!fsip) {
5682654012fSReza Sabdar 		(void) fclose(fp);
5692654012fSReza Sabdar 		reply.error = NDMP_NO_MEM_ERR;
5703ed73a35SAlbert Lee 		goto send_reply;
5712654012fSReza Sabdar 	}
5722654012fSReza Sabdar 
5732654012fSReza Sabdar 	/*
5742654012fSReza Sabdar 	 * Re-read the directory and set up file system information.
5752654012fSReza Sabdar 	 */
5762654012fSReza Sabdar 	rewind(fp);
5773ed73a35SAlbert Lee 	while (len < nmnt && (getmntent(fp, &mt) == 0))
5782654012fSReza Sabdar 
5792654012fSReza Sabdar 	{
5802654012fSReza Sabdar 		fs = &mt;
5812654012fSReza Sabdar 		log_dev_len = strlen(mt.mnt_mountp)+2;
5822654012fSReza Sabdar 		if (!IS_VALID_FS(fs))
5832654012fSReza Sabdar 			continue;
5842654012fSReza Sabdar 
5852654012fSReza Sabdar 		fsip->fs_logical_device = ndmp_malloc(log_dev_len);
5862654012fSReza Sabdar 		fsip->fs_type = ndmp_malloc(MNTTYPE_LEN);
5872654012fSReza Sabdar 		if (!fsip->fs_logical_device || !fsip->fs_type) {
5882654012fSReza Sabdar 			free(fsip->fs_logical_device);
5892654012fSReza Sabdar 			free(fsip->fs_type);
5903ed73a35SAlbert Lee 			reply.error = NDMP_NO_MEM_ERR;
5912654012fSReza Sabdar 			break;
5922654012fSReza Sabdar 		}
5932654012fSReza Sabdar 		(void) snprintf(fsip->fs_type, MNTTYPE_LEN, "%s",
5942654012fSReza Sabdar 		    fs->mnt_fstype);
5952654012fSReza Sabdar 		(void) snprintf(fsip->fs_logical_device, log_dev_len, "%s",
5962654012fSReza Sabdar 		    fs->mnt_mountp);
5972654012fSReza Sabdar 		fsip->invalid = 0;
5982654012fSReza Sabdar 
5992654012fSReza Sabdar 		if (statvfs64(fs->mnt_mountp, &stat_buf) < 0) {
6002654012fSReza Sabdar 			NDMP_LOG(LOG_DEBUG,
6012654012fSReza Sabdar 			    "statvfs(%s) error.", fs->mnt_mountp);
6022654012fSReza Sabdar 			fsip->fs_status =
6032654012fSReza Sabdar 			    "statvfs error: unable to determine filesystem"
6042654012fSReza Sabdar 			    " attributes";
6052654012fSReza Sabdar 		} else {
6062654012fSReza Sabdar 			fsip->invalid = 0;
6072654012fSReza Sabdar 			fsip->total_size =
6082654012fSReza Sabdar 			    long_long_to_quad((u_longlong_t)stat_buf.f_frsize *
6092654012fSReza Sabdar 			    (u_longlong_t)stat_buf.f_blocks);
6102654012fSReza Sabdar 			fsip->used_size =
6112654012fSReza Sabdar 			    long_long_to_quad((u_longlong_t)stat_buf.f_frsize *
6122654012fSReza Sabdar 			    (u_longlong_t)(stat_buf.f_blocks-stat_buf.f_bfree));
6132654012fSReza Sabdar 
6142654012fSReza Sabdar 			fsip->avail_size =
6152654012fSReza Sabdar 			    long_long_to_quad((u_longlong_t)stat_buf.f_frsize *
6162654012fSReza Sabdar 			    (u_longlong_t)stat_buf.f_bfree);
6172654012fSReza Sabdar 			fsip->total_inodes =
6182654012fSReza Sabdar 			    long_long_to_quad((u_longlong_t)stat_buf.f_files);
6192654012fSReza Sabdar 			fsip->used_inodes =
6202654012fSReza Sabdar 			    long_long_to_quad((u_longlong_t)(stat_buf.f_files -
6212654012fSReza Sabdar 			    stat_buf.f_ffree));
6222654012fSReza Sabdar 			fsip->fs_status = "";
6232654012fSReza Sabdar 		}
6242654012fSReza Sabdar 		save = envp = ndmp_malloc(sizeof (ndmp_pval) * V3_N_FS_ENVS);
6252654012fSReza Sabdar 		if (!envp) {
6263ed73a35SAlbert Lee 			free(fsip->fs_logical_device);
6273ed73a35SAlbert Lee 			free(fsip->fs_type);
6282654012fSReza Sabdar 			reply.error = NDMP_NO_MEM_ERR;
6292654012fSReza Sabdar 			break;
6302654012fSReza Sabdar 		}
6312654012fSReza Sabdar 		(void) memset((void*)save, 0,
6322654012fSReza Sabdar 		    V3_N_FS_ENVS * sizeof (ndmp_pval));
6332654012fSReza Sabdar 
6342654012fSReza Sabdar 		fsip->fs_env.fs_env_val = envp;
6352654012fSReza Sabdar 		NDMP_SETENV(envp, "LOCAL", "y");
6362654012fSReza Sabdar 		NDMP_SETENV(envp, "TYPE", fsip->fs_type);
6372654012fSReza Sabdar 		NDMP_SETENV(envp, "AVAILABLE_BACKUP", "tar,dump");
6382654012fSReza Sabdar 
6392654012fSReza Sabdar 		if (FS_READONLY(fs) == 0) {
6402654012fSReza Sabdar 			NDMP_SETENV(envp, "AVAILABLE_RECOVERY", "tar,dump");
6412654012fSReza Sabdar 		}
6422654012fSReza Sabdar 
6432654012fSReza Sabdar 		fsip->fs_env.fs_env_len = envp - save;
6443ed73a35SAlbert Lee 		len++;
6452654012fSReza Sabdar 		fsip++;
6462654012fSReza Sabdar 	}
6472654012fSReza Sabdar 	(void) fclose(fp);
6483ed73a35SAlbert Lee 
6493ed73a35SAlbert Lee send_reply:
6502654012fSReza Sabdar 	if (reply.error == NDMP_NO_ERR) {
6513ed73a35SAlbert Lee 		reply.fs_info.fs_info_len = len;
6522654012fSReza Sabdar 		reply.fs_info.fs_info_val = fsip_save;
6532654012fSReza Sabdar 	}
6542654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
6552654012fSReza Sabdar 	    "error sending ndmp_config_get_fs_info reply");
6562654012fSReza Sabdar 
6573ed73a35SAlbert Lee 	while (fsip > fsip_save) {
6583ed73a35SAlbert Lee 		fsip--;
6592654012fSReza Sabdar 		free(fsip->fs_logical_device);
6602654012fSReza Sabdar 		free(fsip->fs_env.fs_env_val);
6612654012fSReza Sabdar 		free(fsip->fs_type);
6622654012fSReza Sabdar 	}
6632654012fSReza Sabdar 
6643ed73a35SAlbert Lee 	free(fsip);
6652654012fSReza Sabdar }
6662654012fSReza Sabdar 
6672654012fSReza Sabdar 
6682654012fSReza Sabdar /*
6692654012fSReza Sabdar  * ndmpd_config_get_tape_info_v3
6702654012fSReza Sabdar  *
6712654012fSReza Sabdar  * This handler handles the ndmp_config_get_tape_info_request.
6722654012fSReza Sabdar  * Information about all connected tape drives is returned.
6732654012fSReza Sabdar  *
6742654012fSReza Sabdar  * Parameters:
6752654012fSReza Sabdar  *   connection (input) - connection handle.
6762654012fSReza Sabdar  *   body       (input) - request message body.
6772654012fSReza Sabdar  *
6782654012fSReza Sabdar  * Returns:
6792654012fSReza Sabdar  *   void
6802654012fSReza Sabdar  */
6812654012fSReza Sabdar /*ARGSUSED*/
6822654012fSReza Sabdar void
6832654012fSReza Sabdar ndmpd_config_get_tape_info_v3(ndmp_connection_t *connection, void *body)
6842654012fSReza Sabdar {
6852654012fSReza Sabdar 	ndmp_config_get_tape_info_reply_v3 reply;
6862654012fSReza Sabdar 	ndmp_device_info_v3 *tip, *tip_save = NULL; /* tape info pointer */
6872654012fSReza Sabdar 	ndmp_device_capability_v3 *dcp;
6882654012fSReza Sabdar 	ndmp_device_capability_v3 *dcp_save = NULL; /* dev capability pointer */
6892654012fSReza Sabdar 	int i, n, max;
6902654012fSReza Sabdar 	sasd_drive_t *sd;
6912654012fSReza Sabdar 	scsi_link_t *sl;
6927bc22e45SReza Sabdar 	ndmp_pval *envp, *envp_save = NULL;
6937bc22e45SReza Sabdar 	ndmp_pval *envp_head;
6942654012fSReza Sabdar 
6952654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
6962654012fSReza Sabdar 	max = sasd_dev_count();
6972654012fSReza Sabdar 
6982654012fSReza Sabdar 	tip_save = tip = ndmp_malloc(sizeof (ndmp_device_info_v3) * max);
6992654012fSReza Sabdar 	dcp_save = dcp = ndmp_malloc(sizeof (ndmp_device_capability_v3) * max);
7007bc22e45SReza Sabdar 	envp_save = envp = ndmp_malloc(sizeof (ndmp_pval) * max * 3);
7017bc22e45SReza Sabdar 	if (!tip_save || !dcp_save || !envp_save) {
7022654012fSReza Sabdar 		free(tip_save);
7032654012fSReza Sabdar 		free(dcp_save);
7047bc22e45SReza Sabdar 		free(envp_save);
7052654012fSReza Sabdar 		reply.error = NDMP_NO_MEM_ERR;
7062654012fSReza Sabdar 		ndmp_send_reply(connection, (void *)&reply,
7072654012fSReza Sabdar 		    "error sending ndmp_config_get_tape_info reply");
7082654012fSReza Sabdar 		return;
7092654012fSReza Sabdar 	}
7102654012fSReza Sabdar 
7112654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
7122654012fSReza Sabdar 
7132654012fSReza Sabdar 	for (i = n = 0; i < max; i++) {
7142654012fSReza Sabdar 		if (!(sl = sasd_dev_slink(i)) || !(sd = sasd_drive(i)))
7152654012fSReza Sabdar 			continue;
7162654012fSReza Sabdar 		if (sl->sl_type != DTYPE_SEQUENTIAL)
7172654012fSReza Sabdar 			continue;
718e461e790SRandall Ralphs 		/*
719e461e790SRandall Ralphs 		 * Don't report dead links.
720e461e790SRandall Ralphs 		 */
721e461e790SRandall Ralphs 		if ((access(sd->sd_name, F_OK) == -1) && (errno == ENOENT))
722e461e790SRandall Ralphs 			continue;
7232654012fSReza Sabdar 
7242654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG,
7252654012fSReza Sabdar 		    "model \"%s\" dev \"%s\"", sd->sd_id, sd->sd_name);
7262654012fSReza Sabdar 
7277bc22e45SReza Sabdar 		envp_head = envp;
7287bc22e45SReza Sabdar 		NDMP_SETENV(envp, "EXECUTE_CDB", "b");
7297bc22e45SReza Sabdar 		NDMP_SETENV(envp, "SERIAL_NUMBER", sd->sd_serial);
7307bc22e45SReza Sabdar 		NDMP_SETENV(envp, "WORLD_WIDE_NAME", sd->sd_wwn);
7317bc22e45SReza Sabdar 
7322654012fSReza Sabdar 		tip->model = sd->sd_id; /* like "DLT7000	 " */
7332654012fSReza Sabdar 		tip->caplist.caplist_len = 1;
7342654012fSReza Sabdar 		tip->caplist.caplist_val = dcp;
7352654012fSReza Sabdar 		dcp->device = sd->sd_name; /* like "isp1t060" */
7362654012fSReza Sabdar 		dcp->attr = 0;
7377bc22e45SReza Sabdar 		dcp->capability.capability_len = 3;
7387bc22e45SReza Sabdar 		dcp->capability.capability_val = envp_head;
7392654012fSReza Sabdar 		tip++;
7402654012fSReza Sabdar 		dcp++;
7412654012fSReza Sabdar 		n++;
7422654012fSReza Sabdar 	}
7432654012fSReza Sabdar 
7442654012fSReza Sabdar 	NDMP_LOG(LOG_DEBUG, "n %d", n);
7452654012fSReza Sabdar 
7462654012fSReza Sabdar 	/*
7472654012fSReza Sabdar 	 * We should not receive the get_tape_info when three-way backup is
7482654012fSReza Sabdar 	 * running and we are acting as just data, but some clients try
7492654012fSReza Sabdar 	 * to get the Tape information anyway.
7502654012fSReza Sabdar 	 */
7512654012fSReza Sabdar 	if (n == 0 || max <= 0) {
7522654012fSReza Sabdar 		reply.error = NDMP_NO_DEVICE_ERR;
7532654012fSReza Sabdar 		ndmp_send_reply(connection, (void *)&reply,
7542654012fSReza Sabdar 		    "error sending ndmp_config_get_tape_info reply");
7557bc22e45SReza Sabdar 		free(tip_save); free(dcp_save); free(envp_save);
7562654012fSReza Sabdar 		return;
7572654012fSReza Sabdar 	}
7582654012fSReza Sabdar 
7592654012fSReza Sabdar 
7602654012fSReza Sabdar 	reply.tape_info.tape_info_len = n;
7612654012fSReza Sabdar 	reply.tape_info.tape_info_val = tip_save;
7622654012fSReza Sabdar 
7632654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
7642654012fSReza Sabdar 	    "error sending ndmp_config_get_tape_info reply");
7652654012fSReza Sabdar 
7662654012fSReza Sabdar 	free(tip_save);
7672654012fSReza Sabdar 	free(dcp_save);
7687bc22e45SReza Sabdar 	free(envp_save);
7692654012fSReza Sabdar }
7702654012fSReza Sabdar 
7712654012fSReza Sabdar 
7722654012fSReza Sabdar /*
7732654012fSReza Sabdar  * ndmpd_config_get_scsi_info_v3
7742654012fSReza Sabdar  *
7752654012fSReza Sabdar  * This handler handles the ndmp_config_get_tape_scsi_request.
7762654012fSReza Sabdar  * Information about all connected scsi tape stacker and jukeboxes
7772654012fSReza Sabdar  * is returned.
7782654012fSReza Sabdar  *
7792654012fSReza Sabdar  * Parameters:
7802654012fSReza Sabdar  *   connection (input) - connection handle.
7812654012fSReza Sabdar  *   body       (input) - request message body.
7822654012fSReza Sabdar  *
7832654012fSReza Sabdar  * Returns:
7842654012fSReza Sabdar  *   void
7852654012fSReza Sabdar  */
7862654012fSReza Sabdar /*ARGSUSED*/
7872654012fSReza Sabdar void
7882654012fSReza Sabdar ndmpd_config_get_scsi_info_v3(ndmp_connection_t *connection, void *body)
7892654012fSReza Sabdar {
7902654012fSReza Sabdar 	ndmp_config_get_scsi_info_reply_v3 reply;
7912654012fSReza Sabdar 	ndmp_device_info_v3 *sip, *sip_save;
7922654012fSReza Sabdar 	ndmp_device_capability_v3 *dcp, *dcp_save;
7932654012fSReza Sabdar 	int i, n, max;
7942654012fSReza Sabdar 	sasd_drive_t *sd;
7952654012fSReza Sabdar 	scsi_link_t *sl;
7967bc22e45SReza Sabdar 	ndmp_pval *envp, *envp_save = NULL;
7977bc22e45SReza Sabdar 	ndmp_pval *envp_head;
7982654012fSReza Sabdar 
7992654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
8002654012fSReza Sabdar 	max = sasd_dev_count();
8012654012fSReza Sabdar 	sip_save = sip = ndmp_malloc(sizeof (ndmp_device_info_v3) * max);
8022654012fSReza Sabdar 	dcp_save = dcp = ndmp_malloc(sizeof (ndmp_device_capability_v3) * max);
8037bc22e45SReza Sabdar 	envp_save = envp = ndmp_malloc(sizeof (ndmp_pval) * max * 2);
8047bc22e45SReza Sabdar 	if (!sip_save || !dcp_save || !envp_save) {
8052654012fSReza Sabdar 		free(sip_save);
8062654012fSReza Sabdar 		free(dcp_save);
8077bc22e45SReza Sabdar 		free(envp_save);
8082654012fSReza Sabdar 		reply.error = NDMP_NO_MEM_ERR;
8092654012fSReza Sabdar 		ndmp_send_reply(connection, (void *)&reply,
8107bc22e45SReza Sabdar 		    "error sending ndmp_config_get_scsi_info reply");
8112654012fSReza Sabdar 		return;
8122654012fSReza Sabdar 	}
8132654012fSReza Sabdar 
8142654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
8152654012fSReza Sabdar 	for (i = n = 0; i < max; i++) {
8162654012fSReza Sabdar 		if (!(sl = sasd_dev_slink(i)) || !(sd = sasd_drive(i)))
8172654012fSReza Sabdar 			continue;
8182654012fSReza Sabdar 		if (sl->sl_type != DTYPE_CHANGER)
8192654012fSReza Sabdar 			continue;
820e461e790SRandall Ralphs 		/*
821e461e790SRandall Ralphs 		 * Don't report dead links.
822e461e790SRandall Ralphs 		 */
823e461e790SRandall Ralphs 		if ((access(sd->sd_name, F_OK) == -1) && (errno == ENOENT))
824e461e790SRandall Ralphs 			continue;
8252654012fSReza Sabdar 
8262654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG,
8272654012fSReza Sabdar 		    "model \"%s\" dev \"%s\"", sd->sd_id, sd->sd_name);
8282654012fSReza Sabdar 
8297bc22e45SReza Sabdar 		envp_head = envp;
8307bc22e45SReza Sabdar 		NDMP_SETENV(envp, "SERIAL_NUMBER", sd->sd_serial);
8317bc22e45SReza Sabdar 		NDMP_SETENV(envp, "WORLD_WIDE_NAME", sd->sd_wwn);
8327bc22e45SReza Sabdar 
8332654012fSReza Sabdar 		sip->model = sd->sd_id; /* like "Powerstor L200  " */
8342654012fSReza Sabdar 		sip->caplist.caplist_len = 1;
8352654012fSReza Sabdar 		sip->caplist.caplist_val = dcp;
8362654012fSReza Sabdar 		dcp->device = sd->sd_name; /* like "isp1m000" */
8372654012fSReza Sabdar 
8382654012fSReza Sabdar 		dcp->attr = 0;
8397bc22e45SReza Sabdar 		dcp->capability.capability_len = 2;
8407bc22e45SReza Sabdar 		dcp->capability.capability_val = envp_head;
8412654012fSReza Sabdar 		sip++;
8422654012fSReza Sabdar 		dcp++;
8432654012fSReza Sabdar 		n++;
8442654012fSReza Sabdar 	}
8452654012fSReza Sabdar 
8462654012fSReza Sabdar 	NDMP_LOG(LOG_DEBUG, "n %d", n);
8472654012fSReza Sabdar 
8482654012fSReza Sabdar 	reply.scsi_info.scsi_info_len = n;
8492654012fSReza Sabdar 	reply.scsi_info.scsi_info_val = sip_save;
8502654012fSReza Sabdar 
8512654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
8522654012fSReza Sabdar 	    "error sending ndmp_config_get_scsi_info reply");
8532654012fSReza Sabdar 
8542654012fSReza Sabdar 	free(sip_save);
8552654012fSReza Sabdar 	free(dcp_save);
8567bc22e45SReza Sabdar 	free(envp_save);
8572654012fSReza Sabdar }
8582654012fSReza Sabdar 
8592654012fSReza Sabdar 
8602654012fSReza Sabdar /*
8612654012fSReza Sabdar  * ndmpd_config_get_server_info_v3
8622654012fSReza Sabdar  *
8632654012fSReza Sabdar  * This handler handles the ndmp_config_get_server_info request.
8642654012fSReza Sabdar  * Host specific information is returned.
8652654012fSReza Sabdar  *
8662654012fSReza Sabdar  * Parameters:
8672654012fSReza Sabdar  *   connection (input) - connection handle.
8682654012fSReza Sabdar  *   body       (input) - request message body.
8692654012fSReza Sabdar  *
8702654012fSReza Sabdar  * Returns:
8712654012fSReza Sabdar  *   void
8722654012fSReza Sabdar  */
8732654012fSReza Sabdar /*ARGSUSED*/
8742654012fSReza Sabdar void
8752654012fSReza Sabdar ndmpd_config_get_server_info_v3(ndmp_connection_t *connection, void *body)
8762654012fSReza Sabdar {
8772654012fSReza Sabdar 	ndmp_config_get_server_info_reply_v3 reply;
8782654012fSReza Sabdar 	ndmp_auth_type auth_types[2];
8792654012fSReza Sabdar 	char rev_number[10];
8802654012fSReza Sabdar 	ndmpd_session_t *session = ndmp_get_client_data(connection);
8812654012fSReza Sabdar 
8822654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
8832654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
8842654012fSReza Sabdar 
8852654012fSReza Sabdar 	if (connection->conn_authorized ||
8862654012fSReza Sabdar 	    session->ns_protocol_version != NDMPV4) {
8872654012fSReza Sabdar 		reply.vendor_name = VENDOR_NAME;
8882654012fSReza Sabdar 		reply.product_name = PRODUCT_NAME;
8892654012fSReza Sabdar 		(void) snprintf(rev_number, sizeof (rev_number), "%d",
8902654012fSReza Sabdar 		    ndmp_ver);
8912654012fSReza Sabdar 		reply.revision_number = rev_number;
8922654012fSReza Sabdar 	} else {
8932654012fSReza Sabdar 		reply.vendor_name = "\0";
8942654012fSReza Sabdar 		reply.product_name = "\0";
8952654012fSReza Sabdar 		reply.revision_number = "\0";
8962654012fSReza Sabdar 	}
8972654012fSReza Sabdar 
8982654012fSReza Sabdar 	NDMP_LOG(LOG_DEBUG,
8992654012fSReza Sabdar 	    "vendor \"%s\", product \"%s\" rev \"%s\"",
9002654012fSReza Sabdar 	    reply.vendor_name, reply.product_name, reply.revision_number);
9012654012fSReza Sabdar 
9022654012fSReza Sabdar 	auth_types[0] = NDMP_AUTH_TEXT;
9032654012fSReza Sabdar 	auth_types[1] = NDMP_AUTH_MD5;
9042654012fSReza Sabdar 	reply.auth_type.auth_type_len = ARRAY_LEN(auth_types, ndmp_auth_type);
9052654012fSReza Sabdar 	reply.auth_type.auth_type_val = auth_types;
9062654012fSReza Sabdar 
9072654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
9082654012fSReza Sabdar 	    "error sending ndmp_config_get_server_info reply");
9092654012fSReza Sabdar }
9102654012fSReza Sabdar 
9112654012fSReza Sabdar 
9122654012fSReza Sabdar 
9132654012fSReza Sabdar /*
9142654012fSReza Sabdar  * ************************************************************************
9152654012fSReza Sabdar  * NDMP V4 HANDLERS
9162654012fSReza Sabdar  * ************************************************************************
9172654012fSReza Sabdar  */
9182654012fSReza Sabdar 
9192654012fSReza Sabdar /*
9202654012fSReza Sabdar  * ndmpd_config_get_butype_info_v4
9212654012fSReza Sabdar  *
9222654012fSReza Sabdar  * This handler handles the ndmp_config_get_butype_info_request.
9232654012fSReza Sabdar  * Information about all supported backup types are returned.
9242654012fSReza Sabdar  *
9252654012fSReza Sabdar  * Parameters:
9262654012fSReza Sabdar  *   connection (input) - connection handle.
9272654012fSReza Sabdar  *   body       (input) - request message body.
9282654012fSReza Sabdar  *
9292654012fSReza Sabdar  * Returns:
9302654012fSReza Sabdar  *   void
9312654012fSReza Sabdar  */
9322654012fSReza Sabdar /*ARGSUSED*/
9332654012fSReza Sabdar void
9342654012fSReza Sabdar ndmpd_config_get_butype_info_v4(ndmp_connection_t *connection, void *body)
9352654012fSReza Sabdar {
9362654012fSReza Sabdar 	ndmp_config_get_butype_info_reply_v4 reply;
9378c4f9701SJanice Chang 	ndmp_butype_info info[3];
9388c4f9701SJanice Chang 
9392654012fSReza Sabdar 	ndmp_pval envs[12];
9402654012fSReza Sabdar 	ulong_t attrs;
9412654012fSReza Sabdar 	ndmp_pval *envp = envs;
9422654012fSReza Sabdar 
9438c4f9701SJanice Chang 	ndmp_pval zfs_envs[11];
9448c4f9701SJanice Chang 	ulong_t zfs_attrs;
9458c4f9701SJanice Chang 	ndmp_pval *zfs_envp = zfs_envs;
9468c4f9701SJanice Chang 
9478c4f9701SJanice Chang 
9482654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
9492654012fSReza Sabdar 
9502654012fSReza Sabdar 	/*
9518c4f9701SJanice Chang 	 * Supported environment variables and their default values
9528c4f9701SJanice Chang 	 * for dump and tar.
9538c4f9701SJanice Chang 	 *
9542654012fSReza Sabdar 	 * The environment variables for dump and tar format are the
9552654012fSReza Sabdar 	 * same, because we use the same backup engine for both.
9562654012fSReza Sabdar 	 */
9572654012fSReza Sabdar 	NDMP_SETENV(envp, "FILESYSTEM", "");
9582654012fSReza Sabdar 	NDMP_SETENV(envp, "DIRECT", "n");
9592654012fSReza Sabdar 	NDMP_SETENV(envp, "RECURSIVE", "n");
9602654012fSReza Sabdar 	NDMP_SETENV(envp, "TYPE", "");
9612654012fSReza Sabdar 	NDMP_SETENV(envp, "USER", "");
9622654012fSReza Sabdar 	NDMP_SETENV(envp, "HIST", "n");
9632654012fSReza Sabdar 	NDMP_SETENV(envp, "PATHNAME_SEPARATOR", "/");
9642654012fSReza Sabdar 	NDMP_SETENV(envp, "LEVEL", "0");
9652654012fSReza Sabdar 	NDMP_SETENV(envp, "EXTRACT", "y");
9662654012fSReza Sabdar 	NDMP_SETENV(envp, "UPDATE", "y");
9672654012fSReza Sabdar 	NDMP_SETENV(envp, "CMD", "");
9682654012fSReza Sabdar 	NDMP_SETENV(envp, "BASE_DATE", "");
9692654012fSReza Sabdar 
9702654012fSReza Sabdar 	attrs = NDMP_BUTYPE_RECOVER_FILELIST |
9712654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_DIRECT |
9722654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_INCREMENTAL |
9732654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_UTF8 |
9742654012fSReza Sabdar 	    NDMP_BUTYPE_RECOVER_UTF8 |
9752654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_FH_FILE |
9762654012fSReza Sabdar 	    NDMP_BUTYPE_BACKUP_FH_DIR |
9772654012fSReza Sabdar 	    NDMP_BUTYPE_RECOVER_FH_FILE |
9782654012fSReza Sabdar 	    NDMP_BUTYPE_RECOVER_FH_DIR;
9792654012fSReza Sabdar 
9802654012fSReza Sabdar 	/* If DAR supported */
9812654012fSReza Sabdar 	if (ndmp_dar_support)
9822654012fSReza Sabdar 		attrs |= NDMP_BUTYPE_RECOVER_DIRECT;
9832654012fSReza Sabdar 
9842654012fSReza Sabdar 	/* tar backup type */
9852654012fSReza Sabdar 	info[0].butype_name = "tar";
9862654012fSReza Sabdar 	info[0].default_env.default_env_len = ARRAY_LEN(envs, ndmp_pval);
9872654012fSReza Sabdar 	info[0].default_env.default_env_val = envs;
9882654012fSReza Sabdar 	info[0].attrs = attrs;
9892654012fSReza Sabdar 
9902654012fSReza Sabdar 	/* dump backup type */
9912654012fSReza Sabdar 	info[1].butype_name = "dump";
9922654012fSReza Sabdar 	info[1].default_env.default_env_len = ARRAY_LEN(envs, ndmp_pval);
9932654012fSReza Sabdar 	info[1].default_env.default_env_val = envs;
9942654012fSReza Sabdar 	info[1].attrs = attrs;
9952654012fSReza Sabdar 
9968c4f9701SJanice Chang 	/*
9978c4f9701SJanice Chang 	 * Supported environment variables and their default values
9988c4f9701SJanice Chang 	 * for type "zfs."
9998c4f9701SJanice Chang 	 */
10008c4f9701SJanice Chang 
10018c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "USER", "");
10028c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "CMD", "");
10038c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "FILESYSTEM", "");
10048c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "PATHNAME_SEPARATOR", "/");
10058c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "TYPE", "zfs");
10068c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "HIST", "n");
10078c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "LEVEL", "0");
10088c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "ZFS_MODE", "recursive");
10098c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "ZFS_FORCE", "n");
10108c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "UPDATE", "y");
10118c4f9701SJanice Chang 	NDMP_SETENV(zfs_envp, "DMP_NAME", "level");
10128c4f9701SJanice Chang 
10138c4f9701SJanice Chang 	zfs_attrs = NDMP_BUTYPE_BACKUP_UTF8 |
10148c4f9701SJanice Chang 	    NDMP_BUTYPE_RECOVER_UTF8 |
1015f9708870SReza Sabdar 	    NDMP_BUTYPE_BACKUP_DIRECT |
10168c4f9701SJanice Chang 	    NDMP_BUTYPE_BACKUP_INCREMENTAL;
10178c4f9701SJanice Chang 
10188c4f9701SJanice Chang 	/* zfs backup type */
10198c4f9701SJanice Chang 	info[2].butype_name = "zfs";
10208c4f9701SJanice Chang 	info[2].default_env.default_env_len = ARRAY_LEN(zfs_envs, ndmp_pval);
10218c4f9701SJanice Chang 	info[2].default_env.default_env_val = zfs_envs;
10228c4f9701SJanice Chang 	info[2].attrs = zfs_attrs;
10238c4f9701SJanice Chang 
10242654012fSReza Sabdar 	reply.error = NDMP_NO_ERR;
10252654012fSReza Sabdar 	reply.butype_info.butype_info_len = ARRAY_LEN(info, ndmp_butype_info);
10262654012fSReza Sabdar 	reply.butype_info.butype_info_val = info;
10272654012fSReza Sabdar 
10282654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
10292654012fSReza Sabdar 	    "sending ndmp_config_get_butype_info reply");
10302654012fSReza Sabdar }
10312654012fSReza Sabdar 
10322654012fSReza Sabdar 
10332654012fSReza Sabdar /*
10342654012fSReza Sabdar  * ndmpd_config_get_ext_list_v4
10352654012fSReza Sabdar  *
10362654012fSReza Sabdar  * This handler handles the ndmpd_config_get_ext_list_v4 request.
10372654012fSReza Sabdar  *
10382654012fSReza Sabdar  * Parameters:
10392654012fSReza Sabdar  *   connection (input) - connection handle.
10402654012fSReza Sabdar  *   body       (input) - request message body.
10412654012fSReza Sabdar  *
10422654012fSReza Sabdar  * Returns:
10432654012fSReza Sabdar  *   void
10442654012fSReza Sabdar  */
10452654012fSReza Sabdar /*ARGSUSED*/
10462654012fSReza Sabdar void
10472654012fSReza Sabdar ndmpd_config_get_ext_list_v4(ndmp_connection_t *connection, void *body)
10482654012fSReza Sabdar {
10492654012fSReza Sabdar 	ndmp_config_get_ext_list_reply_v4 reply;
10502654012fSReza Sabdar 	ndmpd_session_t *session = ndmp_get_client_data(connection);
10512654012fSReza Sabdar 
10522654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
10532654012fSReza Sabdar 
1054*5bc1e222SAlbert Lee 	if (session->ns_set_ext_list) {
1055*5bc1e222SAlbert Lee 		/*
1056*5bc1e222SAlbert Lee 		 * Illegal request if extensions have already been selected.
1057*5bc1e222SAlbert Lee 		 */
1058*5bc1e222SAlbert Lee 		NDMP_LOG(LOG_ERR, "Extensions have already been selected.");
10592654012fSReza Sabdar 		reply.error = NDMP_EXT_DANDN_ILLEGAL_ERR;
1060*5bc1e222SAlbert Lee 	} else {
1061*5bc1e222SAlbert Lee 		/*
1062*5bc1e222SAlbert Lee 		 * Reply with an empty set of extensions.
1063*5bc1e222SAlbert Lee 		 */
1064*5bc1e222SAlbert Lee 		session->ns_get_ext_list = B_TRUE;
10652654012fSReza Sabdar 		reply.error = NDMP_NO_ERR;
1066*5bc1e222SAlbert Lee 	}
10672654012fSReza Sabdar 
10682654012fSReza Sabdar 	reply.class_list.class_list_val = NULL;
10692654012fSReza Sabdar 	reply.class_list.class_list_len = 0;
10702654012fSReza Sabdar 
10712654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
10722654012fSReza Sabdar 	    "error sending ndmp_config_get_ext_list reply");
10732654012fSReza Sabdar }
10742654012fSReza Sabdar 
10752654012fSReza Sabdar /*
10762654012fSReza Sabdar  * ndmpd_config_set_ext_list_v4
10772654012fSReza Sabdar  *
10782654012fSReza Sabdar  * This handler handles the ndmpd_config_get_ext_list_v4 request.
10792654012fSReza Sabdar  *
10802654012fSReza Sabdar  * Parameters:
10812654012fSReza Sabdar  *   connection (input) - connection handle.
10822654012fSReza Sabdar  *   body       (input) - request message body.
10832654012fSReza Sabdar  *
10842654012fSReza Sabdar  * Returns:
10852654012fSReza Sabdar  *   void
10862654012fSReza Sabdar  */
10872654012fSReza Sabdar void
10882654012fSReza Sabdar ndmpd_config_set_ext_list_v4(ndmp_connection_t *connection, void *body)
10892654012fSReza Sabdar {
10902654012fSReza Sabdar 	ndmp_config_set_ext_list_reply_v4 reply;
1091*5bc1e222SAlbert Lee 	ndmp_config_set_ext_list_request_v4 *request;
10922654012fSReza Sabdar 	ndmpd_session_t *session = ndmp_get_client_data(connection);
10932654012fSReza Sabdar 
1094*5bc1e222SAlbert Lee 	request = (ndmp_config_set_ext_list_request_v4 *)body;
1095*5bc1e222SAlbert Lee 
10962654012fSReza Sabdar 	(void) memset((void*)&reply, 0, sizeof (reply));
1097*5bc1e222SAlbert Lee 
1098*5bc1e222SAlbert Lee 	if (!session->ns_get_ext_list) {
1099*5bc1e222SAlbert Lee 		/*
1100*5bc1e222SAlbert Lee 		 * The DMA is required to issue a NDMP_GET_EXT_LIST request
1101*5bc1e222SAlbert Lee 		 * prior sending a NDMP_SET_EXT_LIST request.
1102*5bc1e222SAlbert Lee 		 */
1103*5bc1e222SAlbert Lee 		NDMP_LOG(LOG_ERR, "No prior ndmp_config_get_ext_list issued.");
1104*5bc1e222SAlbert Lee 		reply.error = NDMP_PRECONDITION_ERR;
1105*5bc1e222SAlbert Lee 	} else if (session->ns_set_ext_list) {
1106*5bc1e222SAlbert Lee 		/*
1107*5bc1e222SAlbert Lee 		 * Illegal request if extensions have already been selected.
1108*5bc1e222SAlbert Lee 		 */
1109*5bc1e222SAlbert Lee 		NDMP_LOG(LOG_ERR, "Extensions have already been selected.");
11102654012fSReza Sabdar 		reply.error = NDMP_EXT_DANDN_ILLEGAL_ERR;
11112654012fSReza Sabdar 	} else {
11122654012fSReza Sabdar 		/*
1113*5bc1e222SAlbert Lee 		 * We currently do not support any extensions, but the DMA
1114*5bc1e222SAlbert Lee 		 * may test NDMP_CONFIG_SET_EXT_LIST with an empty list.
11152654012fSReza Sabdar 		 */
1116*5bc1e222SAlbert Lee 		if (request->ndmp_selected_ext.ndmp_selected_ext_len != 0) {
1117*5bc1e222SAlbert Lee 			reply.error = NDMP_CLASS_NOT_SUPPORTED_ERR;
1118*5bc1e222SAlbert Lee 		} else {
1119*5bc1e222SAlbert Lee 			session->ns_set_ext_list = B_TRUE;
1120*5bc1e222SAlbert Lee 			reply.error = NDMP_NO_ERR;
1121*5bc1e222SAlbert Lee 		}
11222654012fSReza Sabdar 	}
11232654012fSReza Sabdar 
11242654012fSReza Sabdar 	ndmp_send_reply(connection, (void *)&reply,
11252654012fSReza Sabdar 	    "error sending ndmp_config_set_ext_list reply");
11262654012fSReza Sabdar }
11272654012fSReza Sabdar 
11282654012fSReza Sabdar 
11292654012fSReza Sabdar 
11302654012fSReza Sabdar /*
11312654012fSReza Sabdar  * ************************************************************************
11322654012fSReza Sabdar  * LOCALS
11332654012fSReza Sabdar  * ************************************************************************
11342654012fSReza Sabdar  */
11352654012fSReza Sabdar 
11362654012fSReza Sabdar /*
11372654012fSReza Sabdar  * simple_get_attrs
11382654012fSReza Sabdar  *
11392654012fSReza Sabdar  * Set the default attrs for dump mode
11402654012fSReza Sabdar  *
11412654012fSReza Sabdar  * Parameters:
11422654012fSReza Sabdar  *   attributes (output) - the attributes for dump mode
11432654012fSReza Sabdar  *
11442654012fSReza Sabdar  * Returns:
11452654012fSReza Sabdar  *   void
11462654012fSReza Sabdar  */
11472654012fSReza Sabdar static void
11482654012fSReza Sabdar simple_get_attrs(ulong_t *attributes)
11492654012fSReza Sabdar {
11502654012fSReza Sabdar 	*attributes = NDMP_NO_RECOVER_FHINFO;
11512654012fSReza Sabdar }
1152