12654012fSReza Sabdar /*
28a5de3ffSReza Sabdar  * Copyright (c) 2008, 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:
13*78d23b23SToomas Soome  *	- Redistributions of source code must retain the above copyright
142654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
152654012fSReza Sabdar  *
16*78d23b23SToomas Soome  *	- 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 */
40a23888a3SJan Kryl /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
412654012fSReza Sabdar 
422654012fSReza Sabdar #include <sys/types.h>
432654012fSReza Sabdar #include <stdlib.h>
442654012fSReza Sabdar #include <errno.h>
452654012fSReza Sabdar #include <stdarg.h>
462654012fSReza Sabdar #include <stdio.h>
472654012fSReza Sabdar #include <string.h>
482654012fSReza Sabdar #include "ndmpd.h"
492654012fSReza Sabdar 
502654012fSReza Sabdar 
512654012fSReza Sabdar /*
522654012fSReza Sabdar  * Message Id counter.  This number is increased by MOD_LOGV3 macro.
532654012fSReza Sabdar  * MOD_LOGCONTV3 macro uses the number generated by the last MOD_LOGV3.
542654012fSReza Sabdar  *
552654012fSReza Sabdar  */
562654012fSReza Sabdar int ndmp_log_msg_id = 0;
572654012fSReza Sabdar 
582654012fSReza Sabdar 
592654012fSReza Sabdar /*
602654012fSReza Sabdar  * ************************************************************************
612654012fSReza Sabdar  * NDMP V2 CALLBACKS
622654012fSReza Sabdar  * ************************************************************************
632654012fSReza Sabdar  */
642654012fSReza Sabdar 
652654012fSReza Sabdar /*
662654012fSReza Sabdar  * ndmpd_api_done_v2
672654012fSReza Sabdar  *
682654012fSReza Sabdar  * Called when dump/restore has completed.
692654012fSReza Sabdar  * Sends a notify_halt request to the NDMP client.
702654012fSReza Sabdar  *
712654012fSReza Sabdar  * Parameters:
722654012fSReza Sabdar  *   session (input) - session pointer.
732654012fSReza Sabdar  *   err     (input) - UNIX error code.
742654012fSReza Sabdar  *
752654012fSReza Sabdar  * Returns:
762654012fSReza Sabdar  *   void
772654012fSReza Sabdar  */
782654012fSReza Sabdar void
ndmpd_api_done_v2(void * cookie,int err)792654012fSReza Sabdar ndmpd_api_done_v2(void *cookie, int err)
802654012fSReza Sabdar {
812654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
822654012fSReza Sabdar 	ndmp_notify_data_halted_request req_v2;
832654012fSReza Sabdar 
842654012fSReza Sabdar 	if (session == NULL)
852654012fSReza Sabdar 		return;
862654012fSReza Sabdar 
872654012fSReza Sabdar 	if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
882654012fSReza Sabdar 	    session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
892654012fSReza Sabdar 		return;
902654012fSReza Sabdar 
912654012fSReza Sabdar 	NDMP_LOG(LOG_DEBUG, "data.operation: %d",
922654012fSReza Sabdar 	    session->ns_data.dd_operation);
932654012fSReza Sabdar 
942654012fSReza Sabdar 	if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
952654012fSReza Sabdar 		/*
962654012fSReza Sabdar 		 * Send/discard any buffered file history data.
972654012fSReza Sabdar 		 */
982654012fSReza Sabdar 		ndmpd_file_history_cleanup(session, (err == 0 ? TRUE : FALSE));
992654012fSReza Sabdar 
1002654012fSReza Sabdar 		/*
1012654012fSReza Sabdar 		 * If mover local and successfull backup, write any
1022654012fSReza Sabdar 		 * remaining buffered data to tape.
1032654012fSReza Sabdar 		 */
1042654012fSReza Sabdar 		if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_LOCAL &&
1052654012fSReza Sabdar 		    err == 0) {
1062654012fSReza Sabdar 			if (ndmpd_local_write(session, 0, 0) < 0)
1072654012fSReza Sabdar 				err = EIO;
1082654012fSReza Sabdar 		}
1092654012fSReza Sabdar 	}
1102654012fSReza Sabdar 
1112654012fSReza Sabdar 	session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
1122654012fSReza Sabdar 
1132654012fSReza Sabdar 	switch (err) {
1142654012fSReza Sabdar 	case 0:
1152654012fSReza Sabdar 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_SUCCESSFUL;
1162654012fSReza Sabdar 		break;
1172654012fSReza Sabdar 	case EINTR:
1182654012fSReza Sabdar 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_ABORTED;
1192654012fSReza Sabdar 		break;
1202654012fSReza Sabdar 	case EIO:
1212654012fSReza Sabdar 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_CONNECT_ERROR;
1222654012fSReza Sabdar 		break;
1232654012fSReza Sabdar 	default:
1242654012fSReza Sabdar 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_INTERNAL_ERROR;
1252654012fSReza Sabdar 	}
1262654012fSReza Sabdar 
1272654012fSReza Sabdar 	req_v2.reason = session->ns_data.dd_halt_reason;
1282654012fSReza Sabdar 	req_v2.text_reason = "";
1292654012fSReza Sabdar 
1302654012fSReza Sabdar 	NDMP_LOG(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
1312654012fSReza Sabdar 
1322654012fSReza Sabdar 	if (ndmp_send_request_lock(session->ns_connection,
1332654012fSReza Sabdar 	    NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, (void *)&req_v2, 0) < 0)
1342654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Sending notify_data_halted request");
1352654012fSReza Sabdar 
1362654012fSReza Sabdar 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
1372654012fSReza Sabdar 
1382654012fSReza Sabdar 		if (session->ns_mover.md_sock != session->ns_data.dd_sock) {
1392654012fSReza Sabdar 			(void) close(session->ns_data.dd_sock);
1402654012fSReza Sabdar 		} else {
1412654012fSReza Sabdar 			NDMP_LOG(LOG_DEBUG, "Not closing as used by mover");
1422654012fSReza Sabdar 		}
1432654012fSReza Sabdar 
1442654012fSReza Sabdar 		session->ns_data.dd_sock = -1;
1452654012fSReza Sabdar 	} else {
1462654012fSReza Sabdar 		ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
1472654012fSReza Sabdar 	}
1482654012fSReza Sabdar }
1492654012fSReza Sabdar 
1502654012fSReza Sabdar 
1512654012fSReza Sabdar /*
1522654012fSReza Sabdar  * ndmpd_api_log_v2
1532654012fSReza Sabdar  *
1542654012fSReza Sabdar  * Sends a log request to the NDMP client.
1552654012fSReza Sabdar  *
1562654012fSReza Sabdar  * Parameters:
1572654012fSReza Sabdar  *   cookie (input) - session pointer.
1582654012fSReza Sabdar  *   str    (input) - null terminated string
1592654012fSReza Sabdar  *   format (input) - printf style format.
1602654012fSReza Sabdar  *   ...    (input) - format arguments.
1612654012fSReza Sabdar  *
1622654012fSReza Sabdar  * Returns:
1632654012fSReza Sabdar  *   0 - success.
1642654012fSReza Sabdar  *  -1 - error.
1652654012fSReza Sabdar  */
1662654012fSReza Sabdar /*ARGSUSED*/
1672654012fSReza Sabdar int
ndmpd_api_log_v2(void * cookie,char * format,...)1682654012fSReza Sabdar ndmpd_api_log_v2(void *cookie, char *format, ...)
1692654012fSReza Sabdar {
1702654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1712654012fSReza Sabdar 	ndmp_log_log_request request;
1722654012fSReza Sabdar 	static char buf[1024];
1732654012fSReza Sabdar 	va_list ap;
1742654012fSReza Sabdar 
1752654012fSReza Sabdar 	if (session == NULL)
1762654012fSReza Sabdar 		return (-1);
1772654012fSReza Sabdar 
1782654012fSReza Sabdar 	va_start(ap, format);
1792654012fSReza Sabdar 
1802654012fSReza Sabdar 	/*LINTED variable format specifier */
1812654012fSReza Sabdar 	(void) vsnprintf(buf, sizeof (buf), format, ap);
1822654012fSReza Sabdar 	va_end(ap);
1832654012fSReza Sabdar 
1842654012fSReza Sabdar 	request.entry = buf;
1852654012fSReza Sabdar 
1862654012fSReza Sabdar 
1872654012fSReza Sabdar 	if (ndmp_send_request(session->ns_connection, _NDMP_LOG_LOG,
1882654012fSReza Sabdar 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
1892654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Sending log request");
1902654012fSReza Sabdar 		return (-1);
1912654012fSReza Sabdar 	}
1922654012fSReza Sabdar 	return (0);
1932654012fSReza Sabdar 
1942654012fSReza Sabdar }
1952654012fSReza Sabdar 
1962654012fSReza Sabdar 
1972654012fSReza Sabdar /*
1982654012fSReza Sabdar  * ndmpd_api_read_v2
1992654012fSReza Sabdar  *
2002654012fSReza Sabdar  * Callback function called by the backup/recover module.
2012654012fSReza Sabdar  * Reads data from the mover.
2022654012fSReza Sabdar  * If the mover is remote, the data is read from the data connection.
2032654012fSReza Sabdar  * If the mover is local, the data is read from the tape device.
2042654012fSReza Sabdar  *
2052654012fSReza Sabdar  * Parameters:
2062654012fSReza Sabdar  *   client_data (input) - session pointer.
2072654012fSReza Sabdar  *   data       (input) - data to be written.
2082654012fSReza Sabdar  *   length     (input) - data length.
2092654012fSReza Sabdar  *
2102654012fSReza Sabdar  * Returns:
2112654012fSReza Sabdar  *   0 - data successfully read.
2122654012fSReza Sabdar  *  -1 - error.
2132654012fSReza Sabdar  *   1 - session terminated or operation aborted.
2142654012fSReza Sabdar  */
2152654012fSReza Sabdar int
ndmpd_api_read_v2(void * client_data,char * data,ulong_t length)2162654012fSReza Sabdar ndmpd_api_read_v2(void *client_data, char *data, ulong_t length)
2172654012fSReza Sabdar {
2182654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
2192654012fSReza Sabdar 
2202654012fSReza Sabdar 	if (session == NULL)
2212654012fSReza Sabdar 		return (-1);
2222654012fSReza Sabdar 
2232654012fSReza Sabdar 	/*
2242654012fSReza Sabdar 	 * Read the data from the data connection if the mover is remote.
2252654012fSReza Sabdar 	 */
2262654012fSReza Sabdar 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
2272654012fSReza Sabdar 		return (ndmpd_remote_read(session, data, length));
2282654012fSReza Sabdar 	else
2292654012fSReza Sabdar 		return (ndmpd_local_read(session, data, length));
2302654012fSReza Sabdar }
2312654012fSReza Sabdar 
2322654012fSReza Sabdar 
2332654012fSReza Sabdar /*
2342654012fSReza Sabdar  * ndmpd_api_seek_v2
2352654012fSReza Sabdar  *
2362654012fSReza Sabdar  * Seek to the specified position in the data stream and start a
2372654012fSReza Sabdar  * read for the specified amount of data.
2382654012fSReza Sabdar  *
2392654012fSReza Sabdar  * Parameters:
2402654012fSReza Sabdar  *   cookie (input) - session pointer.
2412654012fSReza Sabdar  *   offset (input) - stream position to seek to.
2422654012fSReza Sabdar  *   length (input) - amount of data that will be read using ndmpd_api_read
2432654012fSReza Sabdar  *
2442654012fSReza Sabdar  * Returns:
2452654012fSReza Sabdar  *   0 - seek successful.
2462654012fSReza Sabdar  *  -1 - error.
2472654012fSReza Sabdar  */
2482654012fSReza Sabdar int
ndmpd_api_seek_v2(void * cookie,u_longlong_t offset,u_longlong_t length)2492654012fSReza Sabdar ndmpd_api_seek_v2(void *cookie, u_longlong_t offset, u_longlong_t length)
2502654012fSReza Sabdar {
2512654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
2522654012fSReza Sabdar 	int err;
2532654012fSReza Sabdar 
2542654012fSReza Sabdar 	if (session == NULL)
2552654012fSReza Sabdar 		return (-1);
2562654012fSReza Sabdar 
2572654012fSReza Sabdar 	session->ns_data.dd_read_offset = offset;
2582654012fSReza Sabdar 	session->ns_data.dd_read_length = length;
2592654012fSReza Sabdar 
2602654012fSReza Sabdar 	/*
2612654012fSReza Sabdar 	 * Send a notify_data_read request if the mover is remote.
2622654012fSReza Sabdar 	 */
2632654012fSReza Sabdar 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
2642654012fSReza Sabdar 		ndmp_notify_data_read_request request;
2652654012fSReza Sabdar 
2662654012fSReza Sabdar 		session->ns_mover.md_discard_length =
2672654012fSReza Sabdar 		    session->ns_mover.md_bytes_left_to_read;
2682654012fSReza Sabdar 		session->ns_mover.md_bytes_left_to_read = length;
2692654012fSReza Sabdar 		session->ns_mover.md_position = offset;
2702654012fSReza Sabdar 
2712654012fSReza Sabdar 		request.offset = long_long_to_quad(offset);
2722654012fSReza Sabdar 		request.length = long_long_to_quad(length);
2732654012fSReza Sabdar 
2747bc22e45SReza Sabdar 		if (ndmp_send_request_lock(session->ns_connection,
2752654012fSReza Sabdar 		    NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
2762654012fSReza Sabdar 		    (void *)&request, 0) < 0) {
2777bc22e45SReza Sabdar 
2782654012fSReza Sabdar 			NDMP_LOG(LOG_DEBUG,
2792654012fSReza Sabdar 			    "Sending notify_data_read request");
2802654012fSReza Sabdar 			return (-1);
2812654012fSReza Sabdar 		}
2822654012fSReza Sabdar 		return (0);
2832654012fSReza Sabdar 	}
2842654012fSReza Sabdar 	/* Mover is local. */
2852654012fSReza Sabdar 
2862654012fSReza Sabdar 	err = ndmpd_mover_seek(session, offset, length);
2872654012fSReza Sabdar 	if (err < 0) {
2882654012fSReza Sabdar 		ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
2892654012fSReza Sabdar 		return (-1);
2902654012fSReza Sabdar 	}
2912654012fSReza Sabdar 	if (err == 0)
2922654012fSReza Sabdar 		return (0);
2932654012fSReza Sabdar 
2942654012fSReza Sabdar 	/*
2952654012fSReza Sabdar 	 * NDMP client intervention is required to perform the seek.
2962654012fSReza Sabdar 	 * Wait for the client to either do the seek and send a continue
2972654012fSReza Sabdar 	 * request or send an abort request.
2982654012fSReza Sabdar 	 */
299a23888a3SJan Kryl 	return (ndmp_wait_for_mover(session));
3002654012fSReza Sabdar }
3012654012fSReza Sabdar 
3022654012fSReza Sabdar 
3032654012fSReza Sabdar /*
3042654012fSReza Sabdar  * ndmpd_api_file_recovered_v2
3052654012fSReza Sabdar  *
3062654012fSReza Sabdar  * Notify the NDMP client that the specified file was recovered.
3072654012fSReza Sabdar  *
3082654012fSReza Sabdar  * Parameters:
3092654012fSReza Sabdar  *   cookie (input) - session pointer.
3102654012fSReza Sabdar  *   name   (input) - name of recovered file.
3112654012fSReza Sabdar  *   error  (input) - 0 if file successfully recovered.
3122654012fSReza Sabdar  *		    otherwise, error code indicating why recovery failed.
3132654012fSReza Sabdar  *
3142654012fSReza Sabdar  * Returns:
3152654012fSReza Sabdar  *   void.
3162654012fSReza Sabdar  */
3172654012fSReza Sabdar int
ndmpd_api_file_recovered_v2(void * cookie,char * name,int error)3182654012fSReza Sabdar ndmpd_api_file_recovered_v2(void *cookie, char *name, int error)
3192654012fSReza Sabdar {
3202654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
3212654012fSReza Sabdar 	ndmp_log_file_request_v2 request;
3222654012fSReza Sabdar 
3232654012fSReza Sabdar 	if (session == NULL)
3242654012fSReza Sabdar 		return (-1);
3252654012fSReza Sabdar 
3262654012fSReza Sabdar 	request.name = name;
3272654012fSReza Sabdar 	request.ssid = 0;
3282654012fSReza Sabdar 
3292654012fSReza Sabdar 	switch (error) {
3302654012fSReza Sabdar 	case 0:
3312654012fSReza Sabdar 		request.error = NDMP_NO_ERR;
3322654012fSReza Sabdar 		break;
3332654012fSReza Sabdar 	case ENOENT:
3342654012fSReza Sabdar 		request.error = NDMP_FILE_NOT_FOUND_ERR;
3352654012fSReza Sabdar 		break;
3362654012fSReza Sabdar 	default:
3372654012fSReza Sabdar 		request.error = NDMP_PERMISSION_ERR;
3382654012fSReza Sabdar 	}
3392654012fSReza Sabdar 
3408a5de3ffSReza Sabdar 	if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
3412654012fSReza Sabdar 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
3422654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Sending log file request");
3432654012fSReza Sabdar 		return (-1);
3442654012fSReza Sabdar 	}
3452654012fSReza Sabdar 	return (0);
3462654012fSReza Sabdar }
3472654012fSReza Sabdar 
3482654012fSReza Sabdar 
3492654012fSReza Sabdar /*
3502654012fSReza Sabdar  * ndmpd_api_write_v2
3512654012fSReza Sabdar  *
3522654012fSReza Sabdar  * Callback function called by the backup/restore module.
3532654012fSReza Sabdar  * Writes data to the mover.
3542654012fSReza Sabdar  * If the mover is remote, the data is written to the data connection.
3552654012fSReza Sabdar  * If the mover is local, the data is buffered and written to the
3562654012fSReza Sabdar  * tape device after a full record has been buffered.
3572654012fSReza Sabdar  *
3582654012fSReza Sabdar  * Parameters:
3592654012fSReza Sabdar  *   client_data (input) - session pointer.
3602654012fSReza Sabdar  *   data       (input) - data to be written.
3612654012fSReza Sabdar  *   length     (input) - data length.
3622654012fSReza Sabdar  *
3632654012fSReza Sabdar  * Returns:
3642654012fSReza Sabdar  *   0 - data successfully written.
3652654012fSReza Sabdar  *  -1 - error.
3662654012fSReza Sabdar  */
3672654012fSReza Sabdar int
ndmpd_api_write_v2(void * client_data,char * data,ulong_t length)3682654012fSReza Sabdar ndmpd_api_write_v2(void *client_data, char *data, ulong_t length)
3692654012fSReza Sabdar {
3702654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
3712654012fSReza Sabdar 
3722654012fSReza Sabdar 	if (session == NULL)
3732654012fSReza Sabdar 		return (-1);
3742654012fSReza Sabdar 
3752654012fSReza Sabdar 	/*
3762654012fSReza Sabdar 	 * Write the data to the data connection if the mover is remote.
3772654012fSReza Sabdar 	 */
3782654012fSReza Sabdar 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
3792654012fSReza Sabdar 		return (ndmpd_remote_write(session, data, length));
3802654012fSReza Sabdar 	else
3812654012fSReza Sabdar 		return (ndmpd_local_write(session, data, length));
3822654012fSReza Sabdar }
3832654012fSReza Sabdar 
3842654012fSReza Sabdar 
3852654012fSReza Sabdar /*
3862654012fSReza Sabdar  * ************************************************************************
3872654012fSReza Sabdar  * NDMP V3 CALLBACKS
3882654012fSReza Sabdar  * ************************************************************************
3892654012fSReza Sabdar  */
3902654012fSReza Sabdar 
3912654012fSReza Sabdar /*
3922654012fSReza Sabdar  * ndmpd_api_done_v3
3932654012fSReza Sabdar  *
3942654012fSReza Sabdar  * Called when the data module has completed.
3952654012fSReza Sabdar  * Sends a notify_halt request to the NDMP client.
3962654012fSReza Sabdar  *
3972654012fSReza Sabdar  * Parameters:
3982654012fSReza Sabdar  *   session (input) - session pointer.
3992654012fSReza Sabdar  *   err     (input) - UNIX error code.
4002654012fSReza Sabdar  *
4012654012fSReza Sabdar  * Returns:
4022654012fSReza Sabdar  *   void
4032654012fSReza Sabdar  */
4042654012fSReza Sabdar void
ndmpd_api_done_v3(void * cookie,int err)4052654012fSReza Sabdar ndmpd_api_done_v3(void *cookie, int err)
4062654012fSReza Sabdar {
4072654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
4082654012fSReza Sabdar 	ndmp_data_halt_reason reason;
4092654012fSReza Sabdar 
4102654012fSReza Sabdar 	switch (err) {
4112654012fSReza Sabdar 	case 0:
4122654012fSReza Sabdar 		reason = NDMP_DATA_HALT_SUCCESSFUL;
4132654012fSReza Sabdar 		break;
4142654012fSReza Sabdar 
4152654012fSReza Sabdar 	case EINTR:
4162654012fSReza Sabdar 		reason = NDMP_DATA_HALT_ABORTED;
4172654012fSReza Sabdar 		break;
4182654012fSReza Sabdar 
4192654012fSReza Sabdar 	case EIO:
4202654012fSReza Sabdar 		reason = NDMP_DATA_HALT_CONNECT_ERROR;
4212654012fSReza Sabdar 		break;
4222654012fSReza Sabdar 
4232654012fSReza Sabdar 	default:
4242654012fSReza Sabdar 		reason = NDMP_DATA_HALT_INTERNAL_ERROR;
4252654012fSReza Sabdar 	}
4262654012fSReza Sabdar 
4272654012fSReza Sabdar 	ndmpd_data_error(session, reason);
4282654012fSReza Sabdar }
4292654012fSReza Sabdar 
4302654012fSReza Sabdar /*
4312654012fSReza Sabdar  * ndmpd_api_log_v3
4322654012fSReza Sabdar  *
4332654012fSReza Sabdar  * Sends a log request to the NDMP client.
4342654012fSReza Sabdar  *
4352654012fSReza Sabdar  * Parameters:
4362654012fSReza Sabdar  *   cookie (input) - session pointer.
4372654012fSReza Sabdar  *   format (input) - printf style format.
4382654012fSReza Sabdar  *   ...    (input) - format arguments.
4392654012fSReza Sabdar  *
4402654012fSReza Sabdar  * Returns:
4412654012fSReza Sabdar  *   0 - success.
4422654012fSReza Sabdar  *  -1 - error.
4432654012fSReza Sabdar  */
4442654012fSReza Sabdar /*ARGSUSED*/
4452654012fSReza Sabdar int
ndmpd_api_log_v3(void * cookie,ndmp_log_type type,ulong_t msg_id,char * format,...)4462654012fSReza Sabdar ndmpd_api_log_v3(void *cookie, ndmp_log_type type, ulong_t msg_id,
4472654012fSReza Sabdar     char *format, ...)
4482654012fSReza Sabdar {
4492654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
4502654012fSReza Sabdar 	ndmp_log_message_request_v3 request;
4512654012fSReza Sabdar 	static char buf[1024];
4522654012fSReza Sabdar 	va_list ap;
4532654012fSReza Sabdar 
4542654012fSReza Sabdar 	if (session == NULL)
4552654012fSReza Sabdar 		return (-1);
4562654012fSReza Sabdar 
4572654012fSReza Sabdar 	va_start(ap, format);
4582654012fSReza Sabdar 
4592654012fSReza Sabdar 	/*LINTED variable format specifier */
4602654012fSReza Sabdar 	(void) vsnprintf(buf, sizeof (buf), format, ap);
4612654012fSReza Sabdar 	va_end(ap);
4622654012fSReza Sabdar 
4632654012fSReza Sabdar 	request.entry = buf;
4642654012fSReza Sabdar 	request.log_type = type;
4652654012fSReza Sabdar 	request.message_id = msg_id;
4662654012fSReza Sabdar 
4672654012fSReza Sabdar 	if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
4682654012fSReza Sabdar 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
4692654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
4702654012fSReza Sabdar 		return (-1);
4712654012fSReza Sabdar 	}
4722654012fSReza Sabdar 	return (0);
4732654012fSReza Sabdar }
4742654012fSReza Sabdar 
4752654012fSReza Sabdar 
4762654012fSReza Sabdar /*
4772654012fSReza Sabdar  * ndmpd_api_write_v3
4782654012fSReza Sabdar  *
4792654012fSReza Sabdar  * Callback function called by the backup/restore module.
4802654012fSReza Sabdar  * Writes data to the mover.
4812654012fSReza Sabdar  * If the mover is remote, the data is written to the data connection.
4822654012fSReza Sabdar  * If the mover is local, the data is buffered and written to the
4832654012fSReza Sabdar  * tape device after a full record has been buffered.
4842654012fSReza Sabdar  *
4852654012fSReza Sabdar  * Parameters:
4862654012fSReza Sabdar  *   client_data (input) - session pointer.
4872654012fSReza Sabdar  *   data       (input) - data to be written.
4882654012fSReza Sabdar  *   length     (input) - data length.
4892654012fSReza Sabdar  *
4902654012fSReza Sabdar  * Returns:
4912654012fSReza Sabdar  *   0 - data successfully written.
4922654012fSReza Sabdar  *  -1 - error.
4932654012fSReza Sabdar  */
4942654012fSReza Sabdar int
ndmpd_api_write_v3(void * client_data,char * data,ulong_t length)4952654012fSReza Sabdar ndmpd_api_write_v3(void *client_data, char *data, ulong_t length)
4962654012fSReza Sabdar {
4972654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
4982654012fSReza Sabdar 
4992654012fSReza Sabdar 	if (session == NULL)
5002654012fSReza Sabdar 		return (-1);
5012654012fSReza Sabdar 
5022654012fSReza Sabdar 	/*
5032654012fSReza Sabdar 	 * Write the data to the tape if the mover is local, otherwise,
5042654012fSReza Sabdar 	 * write the data to the data connection.
5052654012fSReza Sabdar 	 *
5062654012fSReza Sabdar 	 * The same write function for of v2 can be used in V3
5072654012fSReza Sabdar 	 * for writing data to the data connection to the mover.
5082654012fSReza Sabdar 	 * So we don't need ndmpd_remote_write_v3().
5092654012fSReza Sabdar 	 */
5102654012fSReza Sabdar 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
5112654012fSReza Sabdar 		return (ndmpd_local_write_v3(session, data, length));
5122654012fSReza Sabdar 	else
5132654012fSReza Sabdar 		return (ndmpd_remote_write(session, data, length));
5142654012fSReza Sabdar }
5152654012fSReza Sabdar 
5162654012fSReza Sabdar 
5172654012fSReza Sabdar /*
5182654012fSReza Sabdar  * ndmpd_api_read_v3
5192654012fSReza Sabdar  *
5202654012fSReza Sabdar  * Callback function called by the backup/recover module.
5212654012fSReza Sabdar  * Reads data from the mover.
5222654012fSReza Sabdar  * If the mover is remote, the data is read from the data connection.
5232654012fSReza Sabdar  * If the mover is local, the data is read from the tape device.
5242654012fSReza Sabdar  *
5252654012fSReza Sabdar  * Parameters:
5262654012fSReza Sabdar  *   client_data (input) - session pointer.
5272654012fSReza Sabdar  *   data       (input) - data to be written.
5282654012fSReza Sabdar  *   length     (input) - data length.
5292654012fSReza Sabdar  *
5302654012fSReza Sabdar  * Returns:
5312654012fSReza Sabdar  *   0 - data successfully read.
5322654012fSReza Sabdar  *  -1 - error.
5332654012fSReza Sabdar  *   1 - session terminated or operation aborted.
5342654012fSReza Sabdar  */
5352654012fSReza Sabdar int
ndmpd_api_read_v3(void * client_data,char * data,ulong_t length)5362654012fSReza Sabdar ndmpd_api_read_v3(void *client_data, char *data, ulong_t length)
5372654012fSReza Sabdar {
5382654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
5392654012fSReza Sabdar 
5402654012fSReza Sabdar 	if (session == NULL)
5412654012fSReza Sabdar 		return (-1);
5422654012fSReza Sabdar 
5432654012fSReza Sabdar 	/*
5442654012fSReza Sabdar 	 * Read the data from the data connection if the mover is remote.
5452654012fSReza Sabdar 	 */
5462654012fSReza Sabdar 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
5472654012fSReza Sabdar 		return (ndmpd_local_read_v3(session, data, length));
5482654012fSReza Sabdar 	else
5492654012fSReza Sabdar 		return (ndmpd_remote_read_v3(session, data, length));
5502654012fSReza Sabdar }
5512654012fSReza Sabdar 
5522654012fSReza Sabdar 
5532654012fSReza Sabdar /*
5542654012fSReza Sabdar  * ndmpd_api_get_name_v3
5552654012fSReza Sabdar  *
5562654012fSReza Sabdar  * Return the name entry at the specified index from the
5572654012fSReza Sabdar  * recover file name list.
5582654012fSReza Sabdar  *
5592654012fSReza Sabdar  * Parameters:
5602654012fSReza Sabdar  *       cookie    (input) - NDMP session pointer.
5612654012fSReza Sabdar  *       name_index (input) - index of entry to be returned.
5622654012fSReza Sabdar  *
5632654012fSReza Sabdar  * Returns:
5642654012fSReza Sabdar  *   Pointer to name entry.
5652654012fSReza Sabdar  *   0 if requested entry does not exist.
5662654012fSReza Sabdar  */
5672654012fSReza Sabdar void *
ndmpd_api_get_name_v3(void * cookie,ulong_t name_index)5682654012fSReza Sabdar ndmpd_api_get_name_v3(void *cookie, ulong_t name_index)
5692654012fSReza Sabdar {
5702654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
5712654012fSReza Sabdar 
5722654012fSReza Sabdar 	if (session == NULL)
5732654012fSReza Sabdar 		return (NULL);
5742654012fSReza Sabdar 
5752654012fSReza Sabdar 	if (name_index >= session->ns_data.dd_nlist_len)
5762654012fSReza Sabdar 		return (NULL);
5772654012fSReza Sabdar 
5782654012fSReza Sabdar 	return (&session->ns_data.dd_nlist_v3[name_index]);
5792654012fSReza Sabdar }
5802654012fSReza Sabdar 
5812654012fSReza Sabdar 
5822654012fSReza Sabdar /*
5832654012fSReza Sabdar  * ndmpd_api_file_recovered_v3
5842654012fSReza Sabdar  *
5852654012fSReza Sabdar  * Notify the NDMP client that the specified file was recovered.
5862654012fSReza Sabdar  *
5872654012fSReza Sabdar  * Parameters:
5882654012fSReza Sabdar  *   cookie (input) - session pointer.
5892654012fSReza Sabdar  *   name   (input) - name of recovered file.
5902654012fSReza Sabdar  *   ssid   (input) - selection set id.
5912654012fSReza Sabdar  *   error  (input) - 0 if file successfully recovered.
5922654012fSReza Sabdar  *		    otherwise, error code indicating why recovery failed.
5932654012fSReza Sabdar  *
5942654012fSReza Sabdar  * Returns:
5952654012fSReza Sabdar  *   0 - success.
5962654012fSReza Sabdar  *  -1 - error.
5972654012fSReza Sabdar  */
5982654012fSReza Sabdar int
ndmpd_api_file_recovered_v3(void * cookie,char * name,int error)5992654012fSReza Sabdar ndmpd_api_file_recovered_v3(void *cookie, char *name, int error)
6002654012fSReza Sabdar {
6012654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
6022654012fSReza Sabdar 	ndmp_log_file_request_v3 request;
6032654012fSReza Sabdar 
6042654012fSReza Sabdar 	if (session == NULL)
6052654012fSReza Sabdar 		return (-1);
6062654012fSReza Sabdar 
6072654012fSReza Sabdar 	request.name  = name;
6082654012fSReza Sabdar 
6092654012fSReza Sabdar 	switch (error) {
6102654012fSReza Sabdar 	case 0:
6112654012fSReza Sabdar 		request.error = NDMP_NO_ERR;
6122654012fSReza Sabdar 		break;
6132654012fSReza Sabdar 	case ENOENT:
6142654012fSReza Sabdar 		request.error = NDMP_FILE_NOT_FOUND_ERR;
6152654012fSReza Sabdar 		break;
6162654012fSReza Sabdar 	default:
6172654012fSReza Sabdar 		request.error = NDMP_PERMISSION_ERR;
6182654012fSReza Sabdar 	}
6192654012fSReza Sabdar 
6208a5de3ffSReza Sabdar 	if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
6212654012fSReza Sabdar 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
6222654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Error sending log file request");
6232654012fSReza Sabdar 		return (-1);
6242654012fSReza Sabdar 	}
6252654012fSReza Sabdar 
6262654012fSReza Sabdar 	return (0);
6272654012fSReza Sabdar }
6282654012fSReza Sabdar 
6292654012fSReza Sabdar 
6302654012fSReza Sabdar /*
6312654012fSReza Sabdar  * ndmpd_api_seek_v3
6322654012fSReza Sabdar  *
6332654012fSReza Sabdar  * Seek to the specified position in the data stream and start a
6342654012fSReza Sabdar  * read for the specified amount of data.
6352654012fSReza Sabdar  *
6362654012fSReza Sabdar  * Parameters:
6372654012fSReza Sabdar  *   cookie (input) - session pointer.
6382654012fSReza Sabdar  *   offset (input) - stream position to seek to.
6392654012fSReza Sabdar  *   length (input) - amount of data that will be read using ndmpd_api_read
6402654012fSReza Sabdar  *
6412654012fSReza Sabdar  * Returns:
6422654012fSReza Sabdar  *   0 - seek successful.
6432654012fSReza Sabdar  *   1 - seek needed DMA(client) intervention.
6442654012fSReza Sabdar  *  -1 - error.
6452654012fSReza Sabdar  */
6462654012fSReza Sabdar int
ndmpd_api_seek_v3(void * cookie,u_longlong_t offset,u_longlong_t length)6472654012fSReza Sabdar ndmpd_api_seek_v3(void *cookie, u_longlong_t offset, u_longlong_t length)
6482654012fSReza Sabdar {
6492654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
6502654012fSReza Sabdar 	int err;
6512654012fSReza Sabdar 	ndmp_notify_data_read_request request;
6522654012fSReza Sabdar 
6532654012fSReza Sabdar 	if (session == NULL)
6542654012fSReza Sabdar 		return (-1);
6552654012fSReza Sabdar 
6562654012fSReza Sabdar 	session->ns_data.dd_read_offset = offset;
6572654012fSReza Sabdar 	session->ns_data.dd_read_length = length;
6582654012fSReza Sabdar 
6592654012fSReza Sabdar 	/*
6602654012fSReza Sabdar 	 * Send a notify_data_read request if the mover is remote.
6612654012fSReza Sabdar 	 */
6622654012fSReza Sabdar 	if (session->ns_data.dd_data_addr.addr_type != NDMP_ADDR_LOCAL) {
6632654012fSReza Sabdar 		session->ns_data.dd_discard_length =
6642654012fSReza Sabdar 		    session->ns_data.dd_bytes_left_to_read;
6652654012fSReza Sabdar 		session->ns_data.dd_bytes_left_to_read = length;
6662654012fSReza Sabdar 		session->ns_data.dd_position = offset;
6672654012fSReza Sabdar 
6682654012fSReza Sabdar 		request.offset = long_long_to_quad(offset);
6692654012fSReza Sabdar 		request.length = long_long_to_quad(length);
6702654012fSReza Sabdar 
6717bc22e45SReza Sabdar 		if (ndmp_send_request_lock(session->ns_connection,
6722654012fSReza Sabdar 		    NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
6732654012fSReza Sabdar 		    (void *)&request, 0) < 0) {
6742654012fSReza Sabdar 			NDMP_LOG(LOG_DEBUG,
6752654012fSReza Sabdar 			    "Sending notify_data_read request");
6762654012fSReza Sabdar 			return (-1);
6772654012fSReza Sabdar 		}
6782654012fSReza Sabdar 
6792654012fSReza Sabdar 		return (0);
6802654012fSReza Sabdar 	}
6812654012fSReza Sabdar 
6822654012fSReza Sabdar 	/* Mover is local. */
6832654012fSReza Sabdar 
6842654012fSReza Sabdar 	err = ndmpd_mover_seek(session, offset, length);
6852654012fSReza Sabdar 	if (err < 0) {
6862654012fSReza Sabdar 		ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
6872654012fSReza Sabdar 		return (-1);
6882654012fSReza Sabdar 	}
6892654012fSReza Sabdar 
6902654012fSReza Sabdar 	if (err == 0)
6912654012fSReza Sabdar 		return (0);
6922654012fSReza Sabdar 
6932654012fSReza Sabdar 	/*
6942654012fSReza Sabdar 	 * NDMP client intervention is required to perform the seek.
6952654012fSReza Sabdar 	 * Wait for the client to either do the seek and send a continue
6962654012fSReza Sabdar 	 * request or send an abort request.
6972654012fSReza Sabdar 	 */
698a23888a3SJan Kryl 	err = ndmp_wait_for_mover(session);
6992654012fSReza Sabdar 
7002654012fSReza Sabdar 	/*
7012654012fSReza Sabdar 	 * If we needed a client intervention, then we should be able to
7022654012fSReza Sabdar 	 * detect this in DAR.
7032654012fSReza Sabdar 	 */
7042654012fSReza Sabdar 	if (err == 0)
7052654012fSReza Sabdar 		err = 1;
7062654012fSReza Sabdar 	return (err);
7072654012fSReza Sabdar }
7082654012fSReza Sabdar 
7092654012fSReza Sabdar 
7102654012fSReza Sabdar /*
7112654012fSReza Sabdar  * ************************************************************************
7122654012fSReza Sabdar  * NDMP V4 CALLBACKS
7132654012fSReza Sabdar  * ************************************************************************
7142654012fSReza Sabdar  */
7152654012fSReza Sabdar 
7162654012fSReza Sabdar /*
7172654012fSReza Sabdar  * ndmpd_api_log_v4
7182654012fSReza Sabdar  *
7192654012fSReza Sabdar  * Sends a log request to the NDMP client.
7202654012fSReza Sabdar  * No message association is supported now, but can be added later on
7212654012fSReza Sabdar  * in this function.
7222654012fSReza Sabdar  *
7232654012fSReza Sabdar  * Parameters:
7242654012fSReza Sabdar  *   cookie (input) - session pointer.
7252654012fSReza Sabdar  *   format (input) - printf style format.
7262654012fSReza Sabdar  *   ...    (input) - format arguments.
7272654012fSReza Sabdar  *
7282654012fSReza Sabdar  * Returns:
7292654012fSReza Sabdar  *   0 - success.
7302654012fSReza Sabdar  *  -1 - error.
7312654012fSReza Sabdar  */
7322654012fSReza Sabdar /*ARGSUSED*/
7332654012fSReza Sabdar int
ndmpd_api_log_v4(void * cookie,ndmp_log_type type,ulong_t msg_id,char * format,...)7342654012fSReza Sabdar ndmpd_api_log_v4(void *cookie, ndmp_log_type type, ulong_t msg_id,
7352654012fSReza Sabdar     char *format, ...)
7362654012fSReza Sabdar {
7372654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
7382654012fSReza Sabdar 	ndmp_log_message_request_v4 request;
7392654012fSReza Sabdar 	static char buf[1024];
7402654012fSReza Sabdar 	va_list ap;
7412654012fSReza Sabdar 
7422654012fSReza Sabdar 	if (session == NULL)
7432654012fSReza Sabdar 		return (-1);
7442654012fSReza Sabdar 
7452654012fSReza Sabdar 	va_start(ap, format);
7462654012fSReza Sabdar 
7472654012fSReza Sabdar 	/*LINTED variable format specifier */
7482654012fSReza Sabdar 	(void) vsnprintf(buf, sizeof (buf), format, ap);
7492654012fSReza Sabdar 	va_end(ap);
7502654012fSReza Sabdar 
7512654012fSReza Sabdar 	request.entry = buf;
7522654012fSReza Sabdar 	request.log_type = type;
7532654012fSReza Sabdar 	request.message_id = msg_id;
7542654012fSReza Sabdar 	request.associated_message_valid = NDMP_NO_ASSOCIATED_MESSAGE;
7552654012fSReza Sabdar 	request.associated_message_sequence = 0;
7562654012fSReza Sabdar 
7572654012fSReza Sabdar 	if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
7582654012fSReza Sabdar 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
7592654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
7602654012fSReza Sabdar 		return (-1);
7612654012fSReza Sabdar 	}
7622654012fSReza Sabdar 	return (0);
7632654012fSReza Sabdar }
7642654012fSReza Sabdar 
7652654012fSReza Sabdar 
7662654012fSReza Sabdar /*
7672654012fSReza Sabdar  * ndmpd_api_file_recovered_v4
7682654012fSReza Sabdar  *
7692654012fSReza Sabdar  * Notify the NDMP client that the specified file was recovered.
7702654012fSReza Sabdar  *
7712654012fSReza Sabdar  * Parameters:
7722654012fSReza Sabdar  *   cookie (input) - session pointer.
7732654012fSReza Sabdar  *   name   (input) - name of recovered file.
7742654012fSReza Sabdar  *   ssid   (input) - selection set id.
7752654012fSReza Sabdar  *   error  (input) - 0 if file successfully recovered.
7762654012fSReza Sabdar  *		    otherwise, error code indicating why recovery failed.
7772654012fSReza Sabdar  *
7782654012fSReza Sabdar  * Returns:
7792654012fSReza Sabdar  *   void.
7802654012fSReza Sabdar  */
7812654012fSReza Sabdar int
ndmpd_api_file_recovered_v4(void * cookie,char * name,int error)7822654012fSReza Sabdar ndmpd_api_file_recovered_v4(void *cookie, char *name, int error)
7832654012fSReza Sabdar {
7842654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
7852654012fSReza Sabdar 	ndmp_log_file_request_v4 request;
7862654012fSReza Sabdar 
7872654012fSReza Sabdar 	if (session == NULL)
7882654012fSReza Sabdar 		return (-1);
7892654012fSReza Sabdar 
7902654012fSReza Sabdar 	request.name  = name;
7912654012fSReza Sabdar 
7922654012fSReza Sabdar 	switch (error) {
7932654012fSReza Sabdar 	case 0:
7942654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_SUCCESSFUL;
7952654012fSReza Sabdar 		break;
7962654012fSReza Sabdar 	case EPERM:
7972654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_PERMISSION;
7982654012fSReza Sabdar 		break;
7992654012fSReza Sabdar 	case ENOENT:
8002654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_NOT_FOUND;
8012654012fSReza Sabdar 		break;
8022654012fSReza Sabdar 	case ENOTDIR:
8032654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_NO_DIRECTORY;
8042654012fSReza Sabdar 		break;
8052654012fSReza Sabdar 	case ENOMEM:
8062654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_OUT_OF_MEMORY;
8072654012fSReza Sabdar 		break;
8082654012fSReza Sabdar 	case EIO:
8092654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_IO_ERROR;
8102654012fSReza Sabdar 		break;
8112654012fSReza Sabdar 	case EEXIST:
8122654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_FILE_PATH_EXISTS;
8132654012fSReza Sabdar 		break;
8142654012fSReza Sabdar 	default:
8152654012fSReza Sabdar 		request.recovery_status = NDMP_RECOVERY_FAILED_UNDEFINED_ERROR;
8162654012fSReza Sabdar 		break;
8172654012fSReza Sabdar 	}
8182654012fSReza Sabdar 
8198a5de3ffSReza Sabdar 	if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
8202654012fSReza Sabdar 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
8212654012fSReza Sabdar 		NDMP_LOG(LOG_DEBUG, "Error sending log file request");
8222654012fSReza Sabdar 		return (-1);
8232654012fSReza Sabdar 	}
8242654012fSReza Sabdar 
8252654012fSReza Sabdar 	return (0);
8262654012fSReza Sabdar }
8272654012fSReza Sabdar 
8282654012fSReza Sabdar 
8292654012fSReza Sabdar /*
8302654012fSReza Sabdar  * ************************************************************************
8312654012fSReza Sabdar  * LOCALS
8322654012fSReza Sabdar  * ************************************************************************
8332654012fSReza Sabdar  */
8342654012fSReza Sabdar 
8352654012fSReza Sabdar /*
8362654012fSReza Sabdar  * ndmpd_api_find_env
8372654012fSReza Sabdar  *
8382654012fSReza Sabdar  * Return the pointer of the environment variable from the variable
8392654012fSReza Sabdar  * array for the spcified environment variable.
8402654012fSReza Sabdar  *
8412654012fSReza Sabdar  * Parameters:
8422654012fSReza Sabdar  *       cookie (input) - NDMP session pointer.
8432654012fSReza Sabdar  *       name   (input) - name of variable.
8442654012fSReza Sabdar  *
8452654012fSReza Sabdar  * Returns:
8462654012fSReza Sabdar  *   Pointer to variable.
8472654012fSReza Sabdar  *   NULL if variable not found.
8482654012fSReza Sabdar  *
8492654012fSReza Sabdar  */
8502654012fSReza Sabdar ndmp_pval *
ndmpd_api_find_env(void * cookie,char * name)8512654012fSReza Sabdar ndmpd_api_find_env(void *cookie, char *name)
8522654012fSReza Sabdar {
8532654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
8542654012fSReza Sabdar 	ulong_t i;
8552654012fSReza Sabdar 	ndmp_pval *envp;
8562654012fSReza Sabdar 
8572654012fSReza Sabdar 	if (session == NULL)
8582654012fSReza Sabdar 		return (NULL);
8592654012fSReza Sabdar 
8602654012fSReza Sabdar 	envp = session->ns_data.dd_env;
8612654012fSReza Sabdar 	for (i = 0; envp && i < session->ns_data.dd_env_len; envp++, i++)
862*78d23b23SToomas Soome 		if (strcmp(name, envp->name) == 0)
8632654012fSReza Sabdar 			return (envp);
8642654012fSReza Sabdar 
8652654012fSReza Sabdar 	return (NULL);
8662654012fSReza Sabdar }
8672654012fSReza Sabdar 
8682654012fSReza Sabdar 
8692654012fSReza Sabdar /*
8702654012fSReza Sabdar  * ndmpd_api_get_env
8712654012fSReza Sabdar  *
8722654012fSReza Sabdar  * Return the value of an environment variable from the variable array.
8732654012fSReza Sabdar  *
8742654012fSReza Sabdar  * Parameters:
8752654012fSReza Sabdar  *       cookie (input) - NDMP session pointer.
8762654012fSReza Sabdar  *       name   (input) - name of variable.
8772654012fSReza Sabdar  *
8782654012fSReza Sabdar  * Returns:
8792654012fSReza Sabdar  *   Pointer to variable value.
8802654012fSReza Sabdar  *   0 if variable not found.
8812654012fSReza Sabdar  *
8822654012fSReza Sabdar  */
8832654012fSReza Sabdar char *
ndmpd_api_get_env(void * cookie,char * name)8842654012fSReza Sabdar ndmpd_api_get_env(void *cookie, char *name)
8852654012fSReza Sabdar {
8862654012fSReza Sabdar 	ndmp_pval *envp;
8872654012fSReza Sabdar 
8882654012fSReza Sabdar 	envp = ndmpd_api_find_env(cookie, name);
8892654012fSReza Sabdar 	if (envp)
8902654012fSReza Sabdar 		return (envp->value);
8912654012fSReza Sabdar 
8922654012fSReza Sabdar 	return (NULL);
8932654012fSReza Sabdar }
8942654012fSReza Sabdar 
8952654012fSReza Sabdar 
8962654012fSReza Sabdar /*
8972654012fSReza Sabdar  * ndmpd_api_add_env
8982654012fSReza Sabdar  *
8992654012fSReza Sabdar  * Adds an environment variable name/value pair to the environment
9002654012fSReza Sabdar  * variable list.
9012654012fSReza Sabdar  *
9022654012fSReza Sabdar  * Parameters:
9032654012fSReza Sabdar  *   session (input) - session pointer.
9042654012fSReza Sabdar  *   name    (input) - variable name.
9052654012fSReza Sabdar  *   val     (input) - value.
9062654012fSReza Sabdar  *
9072654012fSReza Sabdar  * Returns:
9082654012fSReza Sabdar  *   0 - success.
9092654012fSReza Sabdar  *  -1 - error.
9102654012fSReza Sabdar  */
9112654012fSReza Sabdar int
ndmpd_api_add_env(void * cookie,char * name,char * value)9122654012fSReza Sabdar ndmpd_api_add_env(void *cookie, char *name, char *value)
9132654012fSReza Sabdar {
9142654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
9152654012fSReza Sabdar 	char *namebuf;
9162654012fSReza Sabdar 	char *valbuf;
9172654012fSReza Sabdar 
9182654012fSReza Sabdar 	if (session == NULL)
9192654012fSReza Sabdar 		return (-1);
9202654012fSReza Sabdar 
9212654012fSReza Sabdar 	session->ns_data.dd_env = realloc((void *)session->ns_data.dd_env,
9222654012fSReza Sabdar 	    sizeof (ndmp_pval) * (session->ns_data.dd_env_len + 1));
9232654012fSReza Sabdar 
9242654012fSReza Sabdar 	if (session->ns_data.dd_env == NULL) {
9252654012fSReza Sabdar 		NDMP_LOG(LOG_ERR, "Out of memory.");
9262654012fSReza Sabdar 		return (-1);
9272654012fSReza Sabdar 	}
9282654012fSReza Sabdar 	namebuf = strdup(name);
9292654012fSReza Sabdar 	if (namebuf == NULL)
9302654012fSReza Sabdar 		return (-1);
9312654012fSReza Sabdar 
9322654012fSReza Sabdar 	valbuf = strdup(value);
9332654012fSReza Sabdar 	if (valbuf == NULL) {
9342654012fSReza Sabdar 		free(namebuf);
9352654012fSReza Sabdar 		return (-1);
9362654012fSReza Sabdar 	}
9372654012fSReza Sabdar 
9382654012fSReza Sabdar 	(void) mutex_lock(&session->ns_lock);
9392654012fSReza Sabdar 	session->ns_data.dd_env[session->ns_data.dd_env_len].name = namebuf;
9402654012fSReza Sabdar 	session->ns_data.dd_env[session->ns_data.dd_env_len].value = valbuf;
9412654012fSReza Sabdar 	session->ns_data.dd_env_len++;
9422654012fSReza Sabdar 	(void) mutex_unlock(&session->ns_lock);
9432654012fSReza Sabdar 
9442654012fSReza Sabdar 	return (0);
9452654012fSReza Sabdar }
9462654012fSReza Sabdar 
9472654012fSReza Sabdar 
9482654012fSReza Sabdar /*
9492654012fSReza Sabdar  * ndmpd_api_set_env
9502654012fSReza Sabdar  *
9512654012fSReza Sabdar  * Sets an environment variable name/value pair in the environment
9522654012fSReza Sabdar  * variable list.  If the variable exists, it gets the new value,
9532654012fSReza Sabdar  * otherwise it's added as a new variable.
9542654012fSReza Sabdar  *
9552654012fSReza Sabdar  * Parameters:
9562654012fSReza Sabdar  *   session (input) - session pointer.
9572654012fSReza Sabdar  *   name    (input) - variable name.
9582654012fSReza Sabdar  *   val     (input) - value.
9592654012fSReza Sabdar  *
9602654012fSReza Sabdar  * Returns:
9612654012fSReza Sabdar  *   0 - success.
9622654012fSReza Sabdar  *  -1 - error.
9632654012fSReza Sabdar  */
9642654012fSReza Sabdar int
ndmpd_api_set_env(void * cookie,char * name,char * value)9652654012fSReza Sabdar ndmpd_api_set_env(void *cookie, char *name, char *value)
9662654012fSReza Sabdar {
9672654012fSReza Sabdar 	char *valbuf;
9682654012fSReza Sabdar 	int rv;
9692654012fSReza Sabdar 	ndmp_pval *envp;
9702654012fSReza Sabdar 
9712654012fSReza Sabdar 	envp = ndmpd_api_find_env(cookie, name);
9722654012fSReza Sabdar 	if (!envp) {
9732654012fSReza Sabdar 		rv = ndmpd_api_add_env(cookie, name, value);
9742654012fSReza Sabdar 	} else if (!(valbuf = strdup(value))) {
9752654012fSReza Sabdar 		rv = -1;
9762654012fSReza Sabdar 	} else {
9772654012fSReza Sabdar 		rv = 0;
9782654012fSReza Sabdar 		free(envp->value);
9792654012fSReza Sabdar 		envp->value = valbuf;
9802654012fSReza Sabdar 	}
9812654012fSReza Sabdar 
9822654012fSReza Sabdar 	return (rv);
9832654012fSReza Sabdar }
9842654012fSReza Sabdar 
9852654012fSReza Sabdar 
9862654012fSReza Sabdar /*
9872654012fSReza Sabdar  * ndmpd_api_get_name
9882654012fSReza Sabdar  *
9892654012fSReza Sabdar  * Return the name entry at the specified index from the
9902654012fSReza Sabdar  * recover file name list.
9912654012fSReza Sabdar  *
9922654012fSReza Sabdar  * Parameters:
9932654012fSReza Sabdar  *   cookie    (input) - NDMP session pointer.
9942654012fSReza Sabdar  *   name_index (input) - index of entry to be returned.
9952654012fSReza Sabdar  *
9962654012fSReza Sabdar  * Returns:
9972654012fSReza Sabdar  *   Pointer to name entry.
9982654012fSReza Sabdar  *   0 if requested entry does not exist.
9992654012fSReza Sabdar  */
10002654012fSReza Sabdar void *
ndmpd_api_get_name(void * cookie,ulong_t name_index)10012654012fSReza Sabdar ndmpd_api_get_name(void *cookie, ulong_t name_index)
10022654012fSReza Sabdar {
10032654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
10042654012fSReza Sabdar 
10052654012fSReza Sabdar 	if (session == NULL)
10062654012fSReza Sabdar 		return (NULL);
10072654012fSReza Sabdar 
10082654012fSReza Sabdar 	if (name_index >= session->ns_data.dd_nlist_len)
10092654012fSReza Sabdar 		return (NULL);
10102654012fSReza Sabdar 
10112654012fSReza Sabdar 	return (&session->ns_data.dd_nlist[name_index]);
10122654012fSReza Sabdar }
10132654012fSReza Sabdar 
10142654012fSReza Sabdar 
10152654012fSReza Sabdar /*
10162654012fSReza Sabdar  * ndmpd_api_dispatch
10172654012fSReza Sabdar  *
10182654012fSReza Sabdar  * Process pending NDMP client requests and check registered files for
10192654012fSReza Sabdar  * data availability.
10202654012fSReza Sabdar  *
10212654012fSReza Sabdar  * Parameters:
10222654012fSReza Sabdar  *   cookie (input) - session pointer.
10232654012fSReza Sabdar  *   block  (input) -
1024*78d23b23SToomas Soome  *		TRUE	block until a request has been processed or
10252654012fSReza Sabdar  *			until a file handler has been called.
10262654012fSReza Sabdar  *		FALSE	don't block.
10272654012fSReza Sabdar  *
10282654012fSReza Sabdar  * Returns:
10292654012fSReza Sabdar  *  -1 - abort request received or connection closed.
10302654012fSReza Sabdar  *   0 - success.
10312654012fSReza Sabdar  */
10322654012fSReza Sabdar int
ndmpd_api_dispatch(void * cookie,boolean_t block)10332654012fSReza Sabdar ndmpd_api_dispatch(void *cookie, boolean_t block)
10342654012fSReza Sabdar {
10352654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
10362654012fSReza Sabdar 	int err;
10372654012fSReza Sabdar 
10382654012fSReza Sabdar 	if (session == NULL)
10392654012fSReza Sabdar 		return (-1);
10402654012fSReza Sabdar 
10412654012fSReza Sabdar 	for (; ; ) {
10422654012fSReza Sabdar 		err = ndmpd_select(session, block, HC_ALL);
10432654012fSReza Sabdar 		if (err < 0 || session->ns_data.dd_abort == TRUE ||
10442654012fSReza Sabdar 		    session->ns_eof)
10452654012fSReza Sabdar 			return (-1);
10462654012fSReza Sabdar 
10472654012fSReza Sabdar 		if (err == 0)
10482654012fSReza Sabdar 			return (0);
10492654012fSReza Sabdar 
10502654012fSReza Sabdar 		/*
10512654012fSReza Sabdar 		 * Something was processed.
10522654012fSReza Sabdar 		 * Set the block flag to false so that we will return as
10532654012fSReza Sabdar 		 * soon as everything available to be processed has been
10542654012fSReza Sabdar 		 * processed.
10552654012fSReza Sabdar 		 */
10562654012fSReza Sabdar 		block = FALSE;
10572654012fSReza Sabdar 	}
10582654012fSReza Sabdar }
10592654012fSReza Sabdar 
10602654012fSReza Sabdar 
10612654012fSReza Sabdar /*
10622654012fSReza Sabdar  * ndmpd_api_add_file_handler
10632654012fSReza Sabdar  *
10642654012fSReza Sabdar  * Adds a file handler to the file handler list.
10652654012fSReza Sabdar  * The file handler list is used by ndmpd_api_dispatch.
10662654012fSReza Sabdar  *
10672654012fSReza Sabdar  * Parameters:
10682654012fSReza Sabdar  *   daemon_cookie (input) - session pointer.
10692654012fSReza Sabdar  *   cookie  (input) - opaque data to be passed to file hander when called.
10702654012fSReza Sabdar  *   fd      (input) - file descriptor.
10712654012fSReza Sabdar  *   mode    (input) - bitmask of the following:
10722654012fSReza Sabdar  *	NDMP_SELECT_MODE_READ = watch file for ready for reading
10732654012fSReza Sabdar  *	NDMP_SELECT_MODE_WRITE = watch file for ready for writing
10742654012fSReza Sabdar  *	NDMP_SELECT_MODE_EXCEPTION = watch file for exception
10752654012fSReza Sabdar  *   func    (input) - function to call when the file meets one of the
10762654012fSReza Sabdar  *		     conditions specified by mode.
10772654012fSReza Sabdar  *
10782654012fSReza Sabdar  * Returns:
10792654012fSReza Sabdar  *   0 - success.
10802654012fSReza Sabdar  *  -1 - error.
10812654012fSReza Sabdar  */
10822654012fSReza Sabdar int
ndmpd_api_add_file_handler(void * daemon_cookie,void * cookie,int fd,ulong_t mode,ndmpd_file_handler_func_t * func)10832654012fSReza Sabdar ndmpd_api_add_file_handler(void *daemon_cookie, void *cookie, int fd,
10842654012fSReza Sabdar     ulong_t mode, ndmpd_file_handler_func_t *func)
10852654012fSReza Sabdar {
10862654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)daemon_cookie;
10872654012fSReza Sabdar 
10882654012fSReza Sabdar 	return (ndmpd_add_file_handler(session, cookie, fd, mode, HC_MODULE,
10892654012fSReza Sabdar 	    func));
10902654012fSReza Sabdar }
10912654012fSReza Sabdar 
10922654012fSReza Sabdar 
10932654012fSReza Sabdar /*
10942654012fSReza Sabdar  * ndmpd_api_remove_file_handler
10952654012fSReza Sabdar  *
10962654012fSReza Sabdar  * Removes a file handler from the file handler list.
10972654012fSReza Sabdar  *
10982654012fSReza Sabdar  * Parameters:
10992654012fSReza Sabdar  *   cookie  (input) - session pointer.
11002654012fSReza Sabdar  *   fd      (input) - file descriptor.
11012654012fSReza Sabdar  *
11022654012fSReza Sabdar  * Returns:
11032654012fSReza Sabdar  *   0 - success.
11042654012fSReza Sabdar  *  -1 - error.
11052654012fSReza Sabdar  */
11062654012fSReza Sabdar int
ndmpd_api_remove_file_handler(void * cookie,int fd)11072654012fSReza Sabdar ndmpd_api_remove_file_handler(void *cookie, int fd)
11082654012fSReza Sabdar {
11092654012fSReza Sabdar 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
11102654012fSReza Sabdar 
11112654012fSReza Sabdar 	return (ndmpd_remove_file_handler(session, fd));
11122654012fSReza Sabdar }
1113