xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c (revision 12186:046583e770b7)
17917SReza.Sabdar@Sun.COM /*
2*12186SJanice.Chang@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
37917SReza.Sabdar@Sun.COM  */
47917SReza.Sabdar@Sun.COM 
57917SReza.Sabdar@Sun.COM /*
67917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
77917SReza.Sabdar@Sun.COM  *
87917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
97917SReza.Sabdar@Sun.COM  *
107917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
117917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
127917SReza.Sabdar@Sun.COM  * are met:
137917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
147917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
157917SReza.Sabdar@Sun.COM  *
167917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
177917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
187917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
197917SReza.Sabdar@Sun.COM  *	  distribution.
207917SReza.Sabdar@Sun.COM  *
217917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
227917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
237917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
247917SReza.Sabdar@Sun.COM  *	  permission.
257917SReza.Sabdar@Sun.COM  *
267917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
277917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
307917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
317917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
327917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
337917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
347917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
357917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
367917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
377917SReza.Sabdar@Sun.COM  */
387917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
397917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
407917SReza.Sabdar@Sun.COM #include <sys/types.h>
417917SReza.Sabdar@Sun.COM #include <sys/param.h>
427917SReza.Sabdar@Sun.COM #include <sys/socket.h>
437917SReza.Sabdar@Sun.COM #include <netinet/in.h>
447917SReza.Sabdar@Sun.COM #include <errno.h>
457917SReza.Sabdar@Sun.COM #include <arpa/inet.h>
467917SReza.Sabdar@Sun.COM #include <stdlib.h>
477917SReza.Sabdar@Sun.COM #include <string.h>
487917SReza.Sabdar@Sun.COM #include "ndmpd_common.h"
497917SReza.Sabdar@Sun.COM #include "ndmpd.h"
507917SReza.Sabdar@Sun.COM 
517917SReza.Sabdar@Sun.COM static int ndmpd_data_error_send_v4(ndmpd_session_t *session,
527917SReza.Sabdar@Sun.COM     ndmp_data_halt_reason reason);
537917SReza.Sabdar@Sun.COM static int ndmpd_data_error_send(ndmpd_session_t *session,
547917SReza.Sabdar@Sun.COM     ndmp_data_halt_reason reason);
557917SReza.Sabdar@Sun.COM static void data_accept_connection_v3(void *cookie, int fd, ulong_t mode);
567917SReza.Sabdar@Sun.COM static int create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr,
577917SReza.Sabdar@Sun.COM     ushort_t *port);
587917SReza.Sabdar@Sun.COM static ndmp_error data_connect_sock_v3(ndmpd_session_t *session, ulong_t addr,
597917SReza.Sabdar@Sun.COM     ushort_t port);
607917SReza.Sabdar@Sun.COM static int discard_data_v3(ndmpd_session_t *session, ulong_t length);
617917SReza.Sabdar@Sun.COM static void nlp_release_job_stat(ndmpd_session_t *session);
627917SReza.Sabdar@Sun.COM static u_longlong_t ndmpd_data_get_info(ndmpd_session_t *session);
63*12186SJanice.Chang@Sun.COM 
64*12186SJanice.Chang@Sun.COM static ndmp_error ndmpd_tar_start_backup_v2(ndmpd_session_t *, char *,
65*12186SJanice.Chang@Sun.COM     ndmp_pval *, ulong_t);
66*12186SJanice.Chang@Sun.COM static ndmp_error ndmpd_tar_start_recover_v2(ndmpd_session_t *, char *,
67*12186SJanice.Chang@Sun.COM     ndmp_pval *, ulong_t, ndmp_name *, ulong_t);
68*12186SJanice.Chang@Sun.COM static ndmp_error ndmpd_tar_start_backup_v3(ndmpd_session_t *, char *,
69*12186SJanice.Chang@Sun.COM     ndmp_pval *, ulong_t);
70*12186SJanice.Chang@Sun.COM static ndmp_error ndmpd_tar_start_recover_v3(ndmpd_session_t *,
71*12186SJanice.Chang@Sun.COM     ndmp_pval *, ulong_t, ndmp_name_v3 *, ulong_t);
72*12186SJanice.Chang@Sun.COM 
73*12186SJanice.Chang@Sun.COM static ndmp_error ndmpd_zfs_start_op(ndmpd_session_t *,
74*12186SJanice.Chang@Sun.COM     ndmp_pval *, ulong_t, ndmp_name_v3 *, ulong_t, enum ndmp_data_operation);
757917SReza.Sabdar@Sun.COM 
767917SReza.Sabdar@Sun.COM 
777917SReza.Sabdar@Sun.COM /*
787917SReza.Sabdar@Sun.COM  * ************************************************************************
797917SReza.Sabdar@Sun.COM  * NDMP V2 HANDLERS
807917SReza.Sabdar@Sun.COM  * ************************************************************************
817917SReza.Sabdar@Sun.COM  */
827917SReza.Sabdar@Sun.COM 
837917SReza.Sabdar@Sun.COM /*
847917SReza.Sabdar@Sun.COM  * ndmpd_data_get_state_v2
857917SReza.Sabdar@Sun.COM  *
867917SReza.Sabdar@Sun.COM  * Request handler. Returns current data state.
877917SReza.Sabdar@Sun.COM  *
887917SReza.Sabdar@Sun.COM  * Parameters:
897917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
907917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
917917SReza.Sabdar@Sun.COM  *
927917SReza.Sabdar@Sun.COM  * Returns:
937917SReza.Sabdar@Sun.COM  *   void
947917SReza.Sabdar@Sun.COM  */
957917SReza.Sabdar@Sun.COM /*ARGSUSED*/
967917SReza.Sabdar@Sun.COM void
ndmpd_data_get_state_v2(ndmp_connection_t * connection,void * body)977917SReza.Sabdar@Sun.COM ndmpd_data_get_state_v2(ndmp_connection_t *connection, void *body)
987917SReza.Sabdar@Sun.COM {
997917SReza.Sabdar@Sun.COM 	ndmp_data_get_state_reply_v2 reply;
1007917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
1017917SReza.Sabdar@Sun.COM 
1027917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
1037917SReza.Sabdar@Sun.COM 	reply.operation = session->ns_data.dd_operation;
1047917SReza.Sabdar@Sun.COM 	reply.state = session->ns_data.dd_state;
1057917SReza.Sabdar@Sun.COM 	reply.halt_reason = session->ns_data.dd_halt_reason;
1067917SReza.Sabdar@Sun.COM 
1077917SReza.Sabdar@Sun.COM 	reply.est_time_remain =
1087917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_module.dm_stats.ms_est_time_remaining;
1097917SReza.Sabdar@Sun.COM 	reply.est_bytes_remain =
1107917SReza.Sabdar@Sun.COM 	    long_long_to_quad(
1117917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining);
1127917SReza.Sabdar@Sun.COM 
1137917SReza.Sabdar@Sun.COM 	reply.bytes_processed =
1147917SReza.Sabdar@Sun.COM 	    long_long_to_quad(ndmpd_data_get_info(session));
1157917SReza.Sabdar@Sun.COM 
1167917SReza.Sabdar@Sun.COM 	reply.mover = session->ns_data.dd_mover;
1177917SReza.Sabdar@Sun.COM 	reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset);
1187917SReza.Sabdar@Sun.COM 	reply.read_length = long_long_to_quad(session->ns_data.dd_read_length);
1197917SReza.Sabdar@Sun.COM 
1207917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
1217917SReza.Sabdar@Sun.COM 	    "sending data_get_state reply");
1227917SReza.Sabdar@Sun.COM }
1237917SReza.Sabdar@Sun.COM 
1247917SReza.Sabdar@Sun.COM 
1257917SReza.Sabdar@Sun.COM /*
1267917SReza.Sabdar@Sun.COM  * ndmpd_data_start_backup_v2
1277917SReza.Sabdar@Sun.COM  *
1287917SReza.Sabdar@Sun.COM  * Request handler. Starts a backup.
1297917SReza.Sabdar@Sun.COM  *
1307917SReza.Sabdar@Sun.COM  * Parameters:
1317917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
1327917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
1337917SReza.Sabdar@Sun.COM  *
1347917SReza.Sabdar@Sun.COM  * Returns:
1357917SReza.Sabdar@Sun.COM  *   void
1367917SReza.Sabdar@Sun.COM  */
1377917SReza.Sabdar@Sun.COM void
ndmpd_data_start_backup_v2(ndmp_connection_t * connection,void * body)1387917SReza.Sabdar@Sun.COM ndmpd_data_start_backup_v2(ndmp_connection_t *connection, void *body)
1397917SReza.Sabdar@Sun.COM {
1407917SReza.Sabdar@Sun.COM 	ndmp_data_start_backup_request_v2 *request;
1417917SReza.Sabdar@Sun.COM 	ndmp_data_start_backup_reply_v2 reply;
1427917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
1437917SReza.Sabdar@Sun.COM 	ndmp_error err;
1447917SReza.Sabdar@Sun.COM 
1457917SReza.Sabdar@Sun.COM 	request = (ndmp_data_start_backup_request_v2 *)body;
1467917SReza.Sabdar@Sun.COM 
1477917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
1487917SReza.Sabdar@Sun.COM 	session->ns_data.dd_mover = request->mover;
1497917SReza.Sabdar@Sun.COM 
150*12186SJanice.Chang@Sun.COM 	err = ndmpd_tar_start_backup_v2(session, request->bu_type,
151*12186SJanice.Chang@Sun.COM 	    request->env.env_val, request->env.env_len);
1527917SReza.Sabdar@Sun.COM 
1537917SReza.Sabdar@Sun.COM 	/*
1547917SReza.Sabdar@Sun.COM 	 * start_backup sends the reply if the backup is successfully started.
1557917SReza.Sabdar@Sun.COM 	 * Otherwise, send the reply containing the error here.
1567917SReza.Sabdar@Sun.COM 	 */
1577917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
1587917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "err: %d", err);
1597917SReza.Sabdar@Sun.COM 		reply.error = err;
1607917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
1617917SReza.Sabdar@Sun.COM 		    "sending data_start_backup reply");
1627917SReza.Sabdar@Sun.COM 		ndmpd_data_cleanup(session);
1637917SReza.Sabdar@Sun.COM 	}
1647917SReza.Sabdar@Sun.COM }
1657917SReza.Sabdar@Sun.COM 
1667917SReza.Sabdar@Sun.COM /*
1677917SReza.Sabdar@Sun.COM  * ndmpd_data_start_recover_v2
1687917SReza.Sabdar@Sun.COM  *
1697917SReza.Sabdar@Sun.COM  * Request handler. Starts a restore.
1707917SReza.Sabdar@Sun.COM  *
1717917SReza.Sabdar@Sun.COM  * Parameters:
1727917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
1737917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
1747917SReza.Sabdar@Sun.COM  *
1757917SReza.Sabdar@Sun.COM  * Returns:
1767917SReza.Sabdar@Sun.COM  *   void
1777917SReza.Sabdar@Sun.COM  */
1787917SReza.Sabdar@Sun.COM void
ndmpd_data_start_recover_v2(ndmp_connection_t * connection,void * body)1797917SReza.Sabdar@Sun.COM ndmpd_data_start_recover_v2(ndmp_connection_t *connection, void *body)
1807917SReza.Sabdar@Sun.COM {
1817917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_request_v2 *request;
1827917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_reply_v2 reply;
1837917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
1847917SReza.Sabdar@Sun.COM 	ndmp_error err;
1857917SReza.Sabdar@Sun.COM 
1867917SReza.Sabdar@Sun.COM 	request = (ndmp_data_start_recover_request_v2 *) body;
1877917SReza.Sabdar@Sun.COM 	session->ns_data.dd_mover = request->mover;
1887917SReza.Sabdar@Sun.COM 
189*12186SJanice.Chang@Sun.COM 	err = ndmpd_tar_start_recover_v2(session, request->bu_type,
190*12186SJanice.Chang@Sun.COM 	    request->env.env_val, request->env.env_len,
191*12186SJanice.Chang@Sun.COM 	    request->nlist.nlist_val, request->nlist.nlist_len);
192*12186SJanice.Chang@Sun.COM 
1937917SReza.Sabdar@Sun.COM 	/*
1947917SReza.Sabdar@Sun.COM 	 * start_recover sends the reply if the recover is successfully started.
1957917SReza.Sabdar@Sun.COM 	 * Otherwise, send the reply containing the error here.
1967917SReza.Sabdar@Sun.COM 	 */
1977917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
1987917SReza.Sabdar@Sun.COM 		reply.error = err;
1997917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
2007917SReza.Sabdar@Sun.COM 		    "sending ndmp_data_start_recover_request_v2 reply");
2017917SReza.Sabdar@Sun.COM 		ndmpd_data_cleanup(session);
2027917SReza.Sabdar@Sun.COM 	}
2037917SReza.Sabdar@Sun.COM }
2047917SReza.Sabdar@Sun.COM 
2057917SReza.Sabdar@Sun.COM /*
2067917SReza.Sabdar@Sun.COM  * ndmpd_data_get_env_v2
2077917SReza.Sabdar@Sun.COM  *
2087917SReza.Sabdar@Sun.COM  * Request handler. Returns the environment variable array sent
2097917SReza.Sabdar@Sun.COM  * with the backup request. This request may only be sent with
2107917SReza.Sabdar@Sun.COM  * a backup operation is in progress.
2117917SReza.Sabdar@Sun.COM  *
2127917SReza.Sabdar@Sun.COM  * Parameters:
2137917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
2147917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
2157917SReza.Sabdar@Sun.COM  *
2167917SReza.Sabdar@Sun.COM  * Returns:
2177917SReza.Sabdar@Sun.COM  *   void
2187917SReza.Sabdar@Sun.COM  */
2197917SReza.Sabdar@Sun.COM /*ARGSUSED*/
2207917SReza.Sabdar@Sun.COM void
ndmpd_data_get_env_v2(ndmp_connection_t * connection,void * body)2217917SReza.Sabdar@Sun.COM ndmpd_data_get_env_v2(ndmp_connection_t *connection, void *body)
2227917SReza.Sabdar@Sun.COM {
2237917SReza.Sabdar@Sun.COM 	ndmp_data_get_env_reply reply;
2247917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
2257917SReza.Sabdar@Sun.COM 
2267917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
2277917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_operation != NDMP_DATA_OP_BACKUP) {
2287917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Backup operation not active.");
2297917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
2307917SReza.Sabdar@Sun.COM 		reply.env.env_len = 0;
2317917SReza.Sabdar@Sun.COM 	} else {
2327917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
2337917SReza.Sabdar@Sun.COM 		reply.env.env_len = session->ns_data.dd_env_len;
2347917SReza.Sabdar@Sun.COM 		reply.env.env_val = session->ns_data.dd_env;
2357917SReza.Sabdar@Sun.COM 	}
2367917SReza.Sabdar@Sun.COM 
2377917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply, "sending data_get_env reply");
2387917SReza.Sabdar@Sun.COM }
2397917SReza.Sabdar@Sun.COM 
2407917SReza.Sabdar@Sun.COM 
2417917SReza.Sabdar@Sun.COM /*
2427917SReza.Sabdar@Sun.COM  * ndmpd_data_stop_v2
2437917SReza.Sabdar@Sun.COM  *
2447917SReza.Sabdar@Sun.COM  * Request handler. Stops the current data operation.
2457917SReza.Sabdar@Sun.COM  *
2467917SReza.Sabdar@Sun.COM  * Parameters:
2477917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
2487917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
2497917SReza.Sabdar@Sun.COM  *
2507917SReza.Sabdar@Sun.COM  * Returns:
2517917SReza.Sabdar@Sun.COM  *   void
2527917SReza.Sabdar@Sun.COM  */
2537917SReza.Sabdar@Sun.COM /*ARGSUSED*/
2547917SReza.Sabdar@Sun.COM void
ndmpd_data_stop_v2(ndmp_connection_t * connection,void * body)2557917SReza.Sabdar@Sun.COM ndmpd_data_stop_v2(ndmp_connection_t *connection, void *body)
2567917SReza.Sabdar@Sun.COM {
2577917SReza.Sabdar@Sun.COM 	ndmp_data_stop_reply reply;
2587917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
2597917SReza.Sabdar@Sun.COM 
2607917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) {
2617917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state to process stop request.");
2627917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
2637917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
2647917SReza.Sabdar@Sun.COM 		    "sending data_stop reply");
2657917SReza.Sabdar@Sun.COM 		return;
2667917SReza.Sabdar@Sun.COM 	}
2677917SReza.Sabdar@Sun.COM 	ndmp_waitfor_op(session);
2687917SReza.Sabdar@Sun.COM 	ndmpd_data_cleanup(session);
2697917SReza.Sabdar@Sun.COM 	ndmpd_file_history_cleanup(session, FALSE);
2707917SReza.Sabdar@Sun.COM 
2717917SReza.Sabdar@Sun.COM 	nlp_release_job_stat(session);
2727917SReza.Sabdar@Sun.COM 
2737917SReza.Sabdar@Sun.COM 	/* prepare for another data operation */
2747917SReza.Sabdar@Sun.COM 	(void) ndmpd_data_init(session);
2757917SReza.Sabdar@Sun.COM 	ndmpd_file_history_init(session);
2767917SReza.Sabdar@Sun.COM 
2777917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
2787917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply, "sending data_stop reply");
2797917SReza.Sabdar@Sun.COM }
2807917SReza.Sabdar@Sun.COM 
2817917SReza.Sabdar@Sun.COM 
2827917SReza.Sabdar@Sun.COM /*
2837917SReza.Sabdar@Sun.COM  * ndmpd_data_abort_v2
2847917SReza.Sabdar@Sun.COM  *
2857917SReza.Sabdar@Sun.COM  * Request handler. Aborts the current backup/restore. The operation
2867917SReza.Sabdar@Sun.COM  * state is not changed to the halted state until after the operation
2877917SReza.Sabdar@Sun.COM  * has actually been aborted and the notify_halt request has been sent.
2887917SReza.Sabdar@Sun.COM  *
2897917SReza.Sabdar@Sun.COM  * Parameters:
2907917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
2917917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
2927917SReza.Sabdar@Sun.COM  *
2937917SReza.Sabdar@Sun.COM  * Returns:
2947917SReza.Sabdar@Sun.COM  *   void
2957917SReza.Sabdar@Sun.COM  */
2967917SReza.Sabdar@Sun.COM /*ARGSUSED*/
2977917SReza.Sabdar@Sun.COM void
ndmpd_data_abort_v2(ndmp_connection_t * connection,void * body)2987917SReza.Sabdar@Sun.COM ndmpd_data_abort_v2(ndmp_connection_t *connection, void *body)
2997917SReza.Sabdar@Sun.COM {
3007917SReza.Sabdar@Sun.COM 	ndmp_data_abort_reply reply;
3017917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
3027917SReza.Sabdar@Sun.COM 
3037917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
3047917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_state == NDMP_DATA_STATE_HALTED) {
3057917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state to process abort request.");
3067917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
3077917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
3087917SReza.Sabdar@Sun.COM 		    "sending data_abort reply");
3097917SReza.Sabdar@Sun.COM 		return;
3107917SReza.Sabdar@Sun.COM 	}
3117917SReza.Sabdar@Sun.COM 	/*
3127917SReza.Sabdar@Sun.COM 	 * Don't go to HALTED state yet. Need to wait for data operation to
3137917SReza.Sabdar@Sun.COM 	 * abort. When this happens, ndmpd_done will get called and will
3147917SReza.Sabdar@Sun.COM 	 * perform the halt processing.
3157917SReza.Sabdar@Sun.COM 	 */
3167917SReza.Sabdar@Sun.COM 	session->ns_data.dd_abort = TRUE;
3177917SReza.Sabdar@Sun.COM 	(*session->ns_data.dd_module.dm_abort_func)(
3187917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_module.dm_module_cookie);
3197917SReza.Sabdar@Sun.COM 
3207917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
3217917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply, "sending data_abort reply");
3227917SReza.Sabdar@Sun.COM }
3237917SReza.Sabdar@Sun.COM 
3247917SReza.Sabdar@Sun.COM /*
3257917SReza.Sabdar@Sun.COM  * ************************************************************************
3267917SReza.Sabdar@Sun.COM  * NDMP V3 HANDLERS
3277917SReza.Sabdar@Sun.COM  * ************************************************************************
3287917SReza.Sabdar@Sun.COM  */
3297917SReza.Sabdar@Sun.COM 
3307917SReza.Sabdar@Sun.COM /*
3317917SReza.Sabdar@Sun.COM  * ndmpd_data_get_state_v3
3327917SReza.Sabdar@Sun.COM  *
3337917SReza.Sabdar@Sun.COM  * Request handler. Returns current data state.
3347917SReza.Sabdar@Sun.COM  *
3357917SReza.Sabdar@Sun.COM  * Parameters:
3367917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
3377917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
3387917SReza.Sabdar@Sun.COM  *
3397917SReza.Sabdar@Sun.COM  * Returns:
3407917SReza.Sabdar@Sun.COM  *   void
3417917SReza.Sabdar@Sun.COM  */
3427917SReza.Sabdar@Sun.COM /*ARGSUSED*/
3437917SReza.Sabdar@Sun.COM void
ndmpd_data_get_state_v3(ndmp_connection_t * connection,void * body)3447917SReza.Sabdar@Sun.COM ndmpd_data_get_state_v3(ndmp_connection_t *connection, void *body)
3457917SReza.Sabdar@Sun.COM {
3467917SReza.Sabdar@Sun.COM 	ndmp_data_get_state_reply_v3 reply;
3477917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
3487917SReza.Sabdar@Sun.COM 
3497917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
3507917SReza.Sabdar@Sun.COM 
3517917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
3527917SReza.Sabdar@Sun.COM 	reply.invalid = NDMP_DATA_STATE_EST_BYTES_REMAIN_INVALID
3537917SReza.Sabdar@Sun.COM 	    | NDMP_DATA_STATE_EST_TIME_REMAIN_INVALID;
3547917SReza.Sabdar@Sun.COM 	reply.operation = session->ns_data.dd_operation;
3557917SReza.Sabdar@Sun.COM 	reply.state = session->ns_data.dd_state;
3567917SReza.Sabdar@Sun.COM 	reply.halt_reason = session->ns_data.dd_halt_reason;
3577917SReza.Sabdar@Sun.COM 
3587917SReza.Sabdar@Sun.COM 	if (reply.operation == NDMP_DATA_OP_BACKUP)
3597917SReza.Sabdar@Sun.COM 		reply.bytes_processed =
3607917SReza.Sabdar@Sun.COM 		    long_long_to_quad(
3617917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_module.dm_stats.ms_bytes_processed);
3627917SReza.Sabdar@Sun.COM 	else
3637917SReza.Sabdar@Sun.COM 		reply.bytes_processed =
3647917SReza.Sabdar@Sun.COM 		    long_long_to_quad(ndmpd_data_get_info(session));
3657917SReza.Sabdar@Sun.COM 
3667917SReza.Sabdar@Sun.COM 	reply.est_bytes_remain = long_long_to_quad(0LL);
3677917SReza.Sabdar@Sun.COM 	reply.est_time_remain = 0;
3687917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE)
3697917SReza.Sabdar@Sun.COM 		ndmp_copy_addr_v3(&reply.data_connection_addr,
3707917SReza.Sabdar@Sun.COM 		    &session->ns_data.dd_data_addr);
3717917SReza.Sabdar@Sun.COM 	reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset);
3727917SReza.Sabdar@Sun.COM 	reply.read_length = long_long_to_quad(session->ns_data.dd_read_length);
3737917SReza.Sabdar@Sun.COM 
3747917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
3757917SReza.Sabdar@Sun.COM 	    "sending ndmp_data_get_state_v3 reply");
3767917SReza.Sabdar@Sun.COM }
3777917SReza.Sabdar@Sun.COM 
3787917SReza.Sabdar@Sun.COM 
3797917SReza.Sabdar@Sun.COM /*
3807917SReza.Sabdar@Sun.COM  * ndmpd_data_start_backup_v3
3817917SReza.Sabdar@Sun.COM  *
3827917SReza.Sabdar@Sun.COM  * Request handler. Starts a backup.
3837917SReza.Sabdar@Sun.COM  *
3847917SReza.Sabdar@Sun.COM  * Parameters:
3857917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
3867917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
3877917SReza.Sabdar@Sun.COM  *
3887917SReza.Sabdar@Sun.COM  * Returns:
3897917SReza.Sabdar@Sun.COM  *   void
3907917SReza.Sabdar@Sun.COM  */
3917917SReza.Sabdar@Sun.COM void
ndmpd_data_start_backup_v3(ndmp_connection_t * connection,void * body)3927917SReza.Sabdar@Sun.COM ndmpd_data_start_backup_v3(ndmp_connection_t *connection, void *body)
3937917SReza.Sabdar@Sun.COM {
3947917SReza.Sabdar@Sun.COM 	ndmp_data_start_backup_request_v3 *request;
3957917SReza.Sabdar@Sun.COM 	ndmp_data_start_backup_reply_v3 reply;
3967917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
3977917SReza.Sabdar@Sun.COM 
3987917SReza.Sabdar@Sun.COM 	request = (ndmp_data_start_backup_request_v3 *)body;
3997917SReza.Sabdar@Sun.COM 
4007917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
4017917SReza.Sabdar@Sun.COM 
402*12186SJanice.Chang@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_CONNECTED) {
403*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR,
404*12186SJanice.Chang@Sun.COM 		    "Can't start new backup in current state.");
405*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR,
406*12186SJanice.Chang@Sun.COM 		    "Connection to the mover is not established.");
407*12186SJanice.Chang@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
408*12186SJanice.Chang@Sun.COM 		goto _error;
409*12186SJanice.Chang@Sun.COM 	}
410*12186SJanice.Chang@Sun.COM 
411*12186SJanice.Chang@Sun.COM 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL) {
412*12186SJanice.Chang@Sun.COM 		if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
413*12186SJanice.Chang@Sun.COM 			NDMP_LOG(LOG_ERR, "Write protected device.");
414*12186SJanice.Chang@Sun.COM 			reply.error = NDMP_WRITE_PROTECT_ERR;
415*12186SJanice.Chang@Sun.COM 			goto _error;
416*12186SJanice.Chang@Sun.COM 		}
417*12186SJanice.Chang@Sun.COM 	}
418*12186SJanice.Chang@Sun.COM 
419*12186SJanice.Chang@Sun.COM 	if (strcasecmp(request->bu_type, NDMP_TAR_TYPE) == 0) {
420*12186SJanice.Chang@Sun.COM 		session->ns_butype = NDMP_BUTYPE_TAR;
421*12186SJanice.Chang@Sun.COM 	} else if (strcasecmp(request->bu_type, NDMP_DUMP_TYPE) == 0) {
422*12186SJanice.Chang@Sun.COM 		session->ns_butype = NDMP_BUTYPE_DUMP;
423*12186SJanice.Chang@Sun.COM 	} else if (strcasecmp(request->bu_type, NDMP_ZFS_TYPE) == 0) {
424*12186SJanice.Chang@Sun.COM 		session->ns_butype = NDMP_BUTYPE_ZFS;
425*12186SJanice.Chang@Sun.COM 	} else {
426*12186SJanice.Chang@Sun.COM 		char msg_invalid[32];
427*12186SJanice.Chang@Sun.COM 		char msg_types[32];
428*12186SJanice.Chang@Sun.COM 
429*12186SJanice.Chang@Sun.COM 		(void) snprintf(msg_invalid, 32, "Invalid backup type: %s.",
430*12186SJanice.Chang@Sun.COM 		    request->bu_type);
431*12186SJanice.Chang@Sun.COM 		(void) snprintf(msg_types, 32,
432*12186SJanice.Chang@Sun.COM 		    "Supported backup types are tar, dump, and zfs.");
433*12186SJanice.Chang@Sun.COM 
434*12186SJanice.Chang@Sun.COM 		NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id,
435*12186SJanice.Chang@Sun.COM 		    msg_invalid);
436*12186SJanice.Chang@Sun.COM 		NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id,
437*12186SJanice.Chang@Sun.COM 		    msg_types);
438*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR, msg_invalid);
439*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR, msg_types);
440*12186SJanice.Chang@Sun.COM 
441*12186SJanice.Chang@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
442*12186SJanice.Chang@Sun.COM 		goto _error;
443*12186SJanice.Chang@Sun.COM 	}
444*12186SJanice.Chang@Sun.COM 
445*12186SJanice.Chang@Sun.COM 	if (session->ns_butype == NDMP_BUTYPE_ZFS) {
446*12186SJanice.Chang@Sun.COM 		reply.error = ndmpd_zfs_start_op(session, request->env.env_val,
447*12186SJanice.Chang@Sun.COM 		    request->env.env_len, NULL, 0, NDMP_DATA_OP_BACKUP);
448*12186SJanice.Chang@Sun.COM 	} else {
449*12186SJanice.Chang@Sun.COM 		reply.error = ndmpd_tar_start_backup_v3(session,
450*12186SJanice.Chang@Sun.COM 		    request->bu_type, request->env.env_val,
451*12186SJanice.Chang@Sun.COM 		    request->env.env_len);
452*12186SJanice.Chang@Sun.COM 	}
4537917SReza.Sabdar@Sun.COM 
4547917SReza.Sabdar@Sun.COM 	/*
455*12186SJanice.Chang@Sun.COM 	 * *_start_backup* sends the reply if the backup is
4567917SReza.Sabdar@Sun.COM 	 * successfully started.  Otherwise, send the reply
4577917SReza.Sabdar@Sun.COM 	 * containing the error here.
4587917SReza.Sabdar@Sun.COM 	 */
459*12186SJanice.Chang@Sun.COM 
460*12186SJanice.Chang@Sun.COM _error:
461*12186SJanice.Chang@Sun.COM 
462*12186SJanice.Chang@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
4637917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
4647917SReza.Sabdar@Sun.COM 		    "sending data_start_backup_v3 reply");
4657917SReza.Sabdar@Sun.COM 		ndmpd_data_cleanup(session);
4667917SReza.Sabdar@Sun.COM 	}
4677917SReza.Sabdar@Sun.COM }
4687917SReza.Sabdar@Sun.COM 
4697917SReza.Sabdar@Sun.COM /*
4707917SReza.Sabdar@Sun.COM  * ndmpd_data_start_recover_v3
4717917SReza.Sabdar@Sun.COM  *
4727917SReza.Sabdar@Sun.COM  * Request handler. Starts a restore.
4737917SReza.Sabdar@Sun.COM  *
4747917SReza.Sabdar@Sun.COM  * Parameters:
4757917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
4767917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
4777917SReza.Sabdar@Sun.COM  *
4787917SReza.Sabdar@Sun.COM  * Returns:
4797917SReza.Sabdar@Sun.COM  *   void
4807917SReza.Sabdar@Sun.COM  */
4817917SReza.Sabdar@Sun.COM void
ndmpd_data_start_recover_v3(ndmp_connection_t * connection,void * body)4827917SReza.Sabdar@Sun.COM ndmpd_data_start_recover_v3(ndmp_connection_t *connection, void *body)
4837917SReza.Sabdar@Sun.COM {
4847917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_request_v3 *request;
4857917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_reply_v3 reply;
4867917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
4877917SReza.Sabdar@Sun.COM 
4887917SReza.Sabdar@Sun.COM 	request = (ndmp_data_start_recover_request_v3 *)body;
4897917SReza.Sabdar@Sun.COM 
4907917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
4917917SReza.Sabdar@Sun.COM 
492*12186SJanice.Chang@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_CONNECTED) {
493*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR, "Can't start new recover in current state.");
494*12186SJanice.Chang@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
495*12186SJanice.Chang@Sun.COM 		goto _error;
496*12186SJanice.Chang@Sun.COM 	}
497*12186SJanice.Chang@Sun.COM 
498*12186SJanice.Chang@Sun.COM 	if (strcasecmp(request->bu_type, NDMP_TAR_TYPE) == 0) {
499*12186SJanice.Chang@Sun.COM 		session->ns_butype = NDMP_BUTYPE_TAR;
500*12186SJanice.Chang@Sun.COM 	} else if (strcasecmp(request->bu_type, NDMP_DUMP_TYPE) == 0) {
501*12186SJanice.Chang@Sun.COM 		session->ns_butype = NDMP_BUTYPE_DUMP;
502*12186SJanice.Chang@Sun.COM 	} else if (strcasecmp(request->bu_type, NDMP_ZFS_TYPE) == 0) {
503*12186SJanice.Chang@Sun.COM 		session->ns_butype = NDMP_BUTYPE_ZFS;
504*12186SJanice.Chang@Sun.COM 	} else {
505*12186SJanice.Chang@Sun.COM 		char msg_invalid[32];
506*12186SJanice.Chang@Sun.COM 		char msg_types[32];
507*12186SJanice.Chang@Sun.COM 
508*12186SJanice.Chang@Sun.COM 		(void) snprintf(msg_invalid, 32, "Invalid backup type: %s.",
509*12186SJanice.Chang@Sun.COM 		    request->bu_type);
510*12186SJanice.Chang@Sun.COM 		(void) snprintf(msg_types, 32,
511*12186SJanice.Chang@Sun.COM 		    "Supported backup types are tar, dump, and zfs.");
512*12186SJanice.Chang@Sun.COM 
513*12186SJanice.Chang@Sun.COM 		NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id,
514*12186SJanice.Chang@Sun.COM 		    msg_invalid);
515*12186SJanice.Chang@Sun.COM 		NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id,
516*12186SJanice.Chang@Sun.COM 		    msg_types);
517*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR, msg_invalid);
518*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR, msg_types);
519*12186SJanice.Chang@Sun.COM 
520*12186SJanice.Chang@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
521*12186SJanice.Chang@Sun.COM 		goto _error;
522*12186SJanice.Chang@Sun.COM 	}
523*12186SJanice.Chang@Sun.COM 
524*12186SJanice.Chang@Sun.COM 	if (session->ns_butype == NDMP_BUTYPE_ZFS) {
525*12186SJanice.Chang@Sun.COM 		reply.error = ndmpd_zfs_start_op(session, request->env.env_val,
526*12186SJanice.Chang@Sun.COM 		    request->env.env_len, request->nlist.nlist_val,
527*12186SJanice.Chang@Sun.COM 		    request->nlist.nlist_len, NDMP_DATA_OP_RECOVER);
528*12186SJanice.Chang@Sun.COM 	} else {
529*12186SJanice.Chang@Sun.COM 		reply.error = ndmpd_tar_start_recover_v3(session,
530*12186SJanice.Chang@Sun.COM 		    request->env.env_val, request->env.env_len,
531*12186SJanice.Chang@Sun.COM 		    request->nlist.nlist_val, request->nlist.nlist_len);
532*12186SJanice.Chang@Sun.COM 	}
5337917SReza.Sabdar@Sun.COM 
5347917SReza.Sabdar@Sun.COM 	/*
535*12186SJanice.Chang@Sun.COM 	 * *_start_recover* sends the reply if the recover is
5367917SReza.Sabdar@Sun.COM 	 * successfully started.  Otherwise, send the reply
5377917SReza.Sabdar@Sun.COM 	 * containing the error here.
5387917SReza.Sabdar@Sun.COM 	 */
539*12186SJanice.Chang@Sun.COM 
540*12186SJanice.Chang@Sun.COM _error:
541*12186SJanice.Chang@Sun.COM 
542*12186SJanice.Chang@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
5437917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
5447917SReza.Sabdar@Sun.COM 		    "sending data_start_recover_v3 reply");
5457917SReza.Sabdar@Sun.COM 		ndmpd_data_error(session, NDMP_DATA_HALT_INTERNAL_ERROR);
5467917SReza.Sabdar@Sun.COM 		ndmpd_data_cleanup(session);
5477917SReza.Sabdar@Sun.COM 	}
5487917SReza.Sabdar@Sun.COM }
5497917SReza.Sabdar@Sun.COM 
5507917SReza.Sabdar@Sun.COM /*
5517917SReza.Sabdar@Sun.COM  * ndmpd_data_abort_v3
5527917SReza.Sabdar@Sun.COM  *
5537917SReza.Sabdar@Sun.COM  * Request handler. Aborts the current backup/restore. The operation
5547917SReza.Sabdar@Sun.COM  * state is not changed to the halted state until after the operation
5557917SReza.Sabdar@Sun.COM  * has actually been aborted and the notify_halt request has been sent.
5567917SReza.Sabdar@Sun.COM  *
5577917SReza.Sabdar@Sun.COM  * Parameters:
5587917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
5597917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
5607917SReza.Sabdar@Sun.COM  *
5617917SReza.Sabdar@Sun.COM  * Returns:
5627917SReza.Sabdar@Sun.COM  *   void
5637917SReza.Sabdar@Sun.COM  */
5647917SReza.Sabdar@Sun.COM /*ARGSUSED*/
5657917SReza.Sabdar@Sun.COM void
ndmpd_data_abort_v3(ndmp_connection_t * connection,void * body)5667917SReza.Sabdar@Sun.COM ndmpd_data_abort_v3(ndmp_connection_t *connection, void *body)
5677917SReza.Sabdar@Sun.COM {
5687917SReza.Sabdar@Sun.COM 	ndmp_data_abort_reply reply;
5697917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
5707917SReza.Sabdar@Sun.COM 
5717917SReza.Sabdar@Sun.COM 	switch (session->ns_data.dd_state) {
5727917SReza.Sabdar@Sun.COM 	case NDMP_DATA_STATE_IDLE:
5737917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
5747917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state to process abort request.");
5757917SReza.Sabdar@Sun.COM 		break;
5767917SReza.Sabdar@Sun.COM 
5777917SReza.Sabdar@Sun.COM 	case NDMP_DATA_STATE_ACTIVE:
5787917SReza.Sabdar@Sun.COM 		/*
5797917SReza.Sabdar@Sun.COM 		 * Don't go to HALTED state yet.  Need to wait for data
5807917SReza.Sabdar@Sun.COM 		 * operation to abort.  When this happens, ndmpd_done_v3
5817917SReza.Sabdar@Sun.COM 		 * will get called and will perform the halt processing.
5827917SReza.Sabdar@Sun.COM 		 */
5837917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
5847917SReza.Sabdar@Sun.COM 		session->ns_data.dd_abort = TRUE;
5857917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_module.dm_abort_func)
5867917SReza.Sabdar@Sun.COM 			(*session->ns_data.dd_module.dm_abort_func)(
5877917SReza.Sabdar@Sun.COM 			    session->ns_data.dd_module.dm_module_cookie);
5887917SReza.Sabdar@Sun.COM 		break;
5897917SReza.Sabdar@Sun.COM 
5907917SReza.Sabdar@Sun.COM 	case NDMP_DATA_STATE_HALTED:
5917917SReza.Sabdar@Sun.COM 	case NDMP_DATA_STATE_LISTEN:
5927917SReza.Sabdar@Sun.COM 	case NDMP_DATA_STATE_CONNECTED:
5937917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
5947917SReza.Sabdar@Sun.COM 		session->ns_data.dd_abort = TRUE;
5957917SReza.Sabdar@Sun.COM 		ndmpd_data_error(session, NDMP_DATA_HALT_ABORTED);
5967917SReza.Sabdar@Sun.COM 		break;
5977917SReza.Sabdar@Sun.COM 	default:
5987917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
5997917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Unknown data V3 state %d",
6007917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_state);
6017917SReza.Sabdar@Sun.COM 	}
6027917SReza.Sabdar@Sun.COM 
6037917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
6047917SReza.Sabdar@Sun.COM 	    "sending data_abort_v3 reply");
6057917SReza.Sabdar@Sun.COM }
6067917SReza.Sabdar@Sun.COM 
6077917SReza.Sabdar@Sun.COM 
6087917SReza.Sabdar@Sun.COM /*
6097917SReza.Sabdar@Sun.COM  * ndmpd_data_stop_v3
6107917SReza.Sabdar@Sun.COM  *
6117917SReza.Sabdar@Sun.COM  * Request handler. Stops the current data operation.
6127917SReza.Sabdar@Sun.COM  *
6137917SReza.Sabdar@Sun.COM  * Parameters:
6147917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
6157917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
6167917SReza.Sabdar@Sun.COM  *
6177917SReza.Sabdar@Sun.COM  * Returns:
6187917SReza.Sabdar@Sun.COM  *   void
6197917SReza.Sabdar@Sun.COM  */
6207917SReza.Sabdar@Sun.COM /*ARGSUSED*/
6217917SReza.Sabdar@Sun.COM void
ndmpd_data_stop_v3(ndmp_connection_t * connection,void * body)6227917SReza.Sabdar@Sun.COM ndmpd_data_stop_v3(ndmp_connection_t *connection, void *body)
6237917SReza.Sabdar@Sun.COM {
6247917SReza.Sabdar@Sun.COM 	ndmp_data_stop_reply reply;
6257917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
6267917SReza.Sabdar@Sun.COM 
6277917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) {
6287917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state to process stop request.");
6297917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
6307917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
6317917SReza.Sabdar@Sun.COM 		    "sending data_stop_v3 reply");
6327917SReza.Sabdar@Sun.COM 		return;
6337917SReza.Sabdar@Sun.COM 	}
6347917SReza.Sabdar@Sun.COM 	ndmp_waitfor_op(session);
6357917SReza.Sabdar@Sun.COM 	ndmpd_data_cleanup(session);
6367917SReza.Sabdar@Sun.COM 	ndmpd_file_history_cleanup(session, FALSE);
6377917SReza.Sabdar@Sun.COM 
6387917SReza.Sabdar@Sun.COM 	/* prepare for another data operation */
6397917SReza.Sabdar@Sun.COM 	(void) ndmpd_data_init(session);
6407917SReza.Sabdar@Sun.COM 	ndmpd_file_history_init(session);
6417917SReza.Sabdar@Sun.COM 
6427917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
6437917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
6447917SReza.Sabdar@Sun.COM 	    "sending data_stop_v3 reply");
6457917SReza.Sabdar@Sun.COM }
6467917SReza.Sabdar@Sun.COM 
6477917SReza.Sabdar@Sun.COM 
6487917SReza.Sabdar@Sun.COM /*
6497917SReza.Sabdar@Sun.COM  * ndmpd_data_listen_v3
6507917SReza.Sabdar@Sun.COM  *
6517917SReza.Sabdar@Sun.COM  * Request handler. Configures the server to listen for a connection
6527917SReza.Sabdar@Sun.COM  * from a remote mover.
6537917SReza.Sabdar@Sun.COM  *
6547917SReza.Sabdar@Sun.COM  * Parameters:
6557917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
6567917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
6577917SReza.Sabdar@Sun.COM  *
6587917SReza.Sabdar@Sun.COM  * Returns:
6597917SReza.Sabdar@Sun.COM  *   void
6607917SReza.Sabdar@Sun.COM  */
6617917SReza.Sabdar@Sun.COM void
ndmpd_data_listen_v3(ndmp_connection_t * connection,void * body)6627917SReza.Sabdar@Sun.COM ndmpd_data_listen_v3(ndmp_connection_t *connection, void *body)
6637917SReza.Sabdar@Sun.COM {
6647917SReza.Sabdar@Sun.COM 	ndmp_data_listen_request_v3 *request;
6657917SReza.Sabdar@Sun.COM 	ndmp_data_listen_reply_v3 reply;
6667917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
6677917SReza.Sabdar@Sun.COM 	ulong_t addr;
6687917SReza.Sabdar@Sun.COM 	ushort_t port;
6697917SReza.Sabdar@Sun.COM 
6707917SReza.Sabdar@Sun.COM 	request = (ndmp_data_listen_request_v3 *)body;
6717917SReza.Sabdar@Sun.COM 
6727917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
6737917SReza.Sabdar@Sun.COM 
6747917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
6757917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
6767917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
6777917SReza.Sabdar@Sun.COM 		    "Invalid internal data state to process listen request.");
6787917SReza.Sabdar@Sun.COM 	} else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
6797917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
6807917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
6817917SReza.Sabdar@Sun.COM 		    "Invalid mover state to process listen request.");
6827917SReza.Sabdar@Sun.COM 	} else {
6837917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
6847917SReza.Sabdar@Sun.COM 	}
6857917SReza.Sabdar@Sun.COM 
6867917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
6877917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
6887917SReza.Sabdar@Sun.COM 		    "ndmp_data_listen_request_v3 reply");
6897917SReza.Sabdar@Sun.COM 		return;
6907917SReza.Sabdar@Sun.COM 	}
6917917SReza.Sabdar@Sun.COM 
6927917SReza.Sabdar@Sun.COM 	switch (request->addr_type) {
6937917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_LOCAL:
6947917SReza.Sabdar@Sun.COM 		reply.data_connection_addr.addr_type = request->addr_type;
6957917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL;
6967917SReza.Sabdar@Sun.COM 		break;
6977917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_TCP:
6987917SReza.Sabdar@Sun.COM 		if (create_listen_socket_v3(session, &addr, &port) < 0) {
6997917SReza.Sabdar@Sun.COM 			reply.error = NDMP_IO_ERR;
7007917SReza.Sabdar@Sun.COM 			break;
7017917SReza.Sabdar@Sun.COM 		}
7027917SReza.Sabdar@Sun.COM 
7037917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
7047917SReza.Sabdar@Sun.COM 		reply.data_connection_addr.addr_type = request->addr_type;
7057917SReza.Sabdar@Sun.COM 		reply.data_connection_addr.tcp_ip_v3 = htonl(addr);
7067917SReza.Sabdar@Sun.COM 		reply.data_connection_addr.tcp_port_v3 = htons(port);
7077917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP;
7087917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.tcp_ip_v3 = addr;
7097917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(port);
7107917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "listen_socket: %d",
7117917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_listen_sock);
7127917SReza.Sabdar@Sun.COM 		break;
7137917SReza.Sabdar@Sun.COM 
7147917SReza.Sabdar@Sun.COM 	default:
7157917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid address type: %d",
7167917SReza.Sabdar@Sun.COM 		    request->addr_type);
7177917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
7187917SReza.Sabdar@Sun.COM 		break;
7197917SReza.Sabdar@Sun.COM 	}
7207917SReza.Sabdar@Sun.COM 
7217917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR)
7227917SReza.Sabdar@Sun.COM 		session->ns_data.dd_state = NDMP_DATA_STATE_LISTEN;
7237917SReza.Sabdar@Sun.COM 
7247917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
7257917SReza.Sabdar@Sun.COM 	    "ndmp_data_listen_request_v3 reply");
7267917SReza.Sabdar@Sun.COM }
7277917SReza.Sabdar@Sun.COM 
7287917SReza.Sabdar@Sun.COM 
7297917SReza.Sabdar@Sun.COM /*
7307917SReza.Sabdar@Sun.COM  * ndmpd_data_connect_v3
7317917SReza.Sabdar@Sun.COM  *
7327917SReza.Sabdar@Sun.COM  * Request handler. Connects the data server to either a local
7337917SReza.Sabdar@Sun.COM  * or remote mover.
7347917SReza.Sabdar@Sun.COM  *
7357917SReza.Sabdar@Sun.COM  * Parameters:
7367917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
7377917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
7387917SReza.Sabdar@Sun.COM  *
7397917SReza.Sabdar@Sun.COM  * Returns:
7407917SReza.Sabdar@Sun.COM  *   void
7417917SReza.Sabdar@Sun.COM  */
7427917SReza.Sabdar@Sun.COM void
ndmpd_data_connect_v3(ndmp_connection_t * connection,void * body)7437917SReza.Sabdar@Sun.COM ndmpd_data_connect_v3(ndmp_connection_t *connection, void *body)
7447917SReza.Sabdar@Sun.COM {
7457917SReza.Sabdar@Sun.COM 	ndmp_data_connect_request_v3 *request;
7467917SReza.Sabdar@Sun.COM 	ndmp_data_connect_reply_v3 reply;
7477917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
7487917SReza.Sabdar@Sun.COM 
7497917SReza.Sabdar@Sun.COM 	request = (ndmp_data_connect_request_v3 *)body;
7507917SReza.Sabdar@Sun.COM 
7517917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
7527917SReza.Sabdar@Sun.COM 
7537917SReza.Sabdar@Sun.COM 	if (!ndmp_valid_v3addr_type(request->addr.addr_type)) {
7547917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
7557917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
7567917SReza.Sabdar@Sun.COM 		    request->addr.addr_type);
7577917SReza.Sabdar@Sun.COM 	} else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
7587917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
7597917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state to process connect request.");
7607917SReza.Sabdar@Sun.COM 	} else {
7617917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
7627917SReza.Sabdar@Sun.COM 	}
7637917SReza.Sabdar@Sun.COM 
7647917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
7657917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
7667917SReza.Sabdar@Sun.COM 		    "sending ndmp_data_connect_v3 reply");
7677917SReza.Sabdar@Sun.COM 		return;
7687917SReza.Sabdar@Sun.COM 	}
7697917SReza.Sabdar@Sun.COM 
7707917SReza.Sabdar@Sun.COM 	switch (request->addr.addr_type) {
7717917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_LOCAL:
7727917SReza.Sabdar@Sun.COM 		/*
7737917SReza.Sabdar@Sun.COM 		 * Verify that the mover is listening for a
7747917SReza.Sabdar@Sun.COM 		 * local connection
7757917SReza.Sabdar@Sun.COM 		 */
7767917SReza.Sabdar@Sun.COM 		if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN ||
7777917SReza.Sabdar@Sun.COM 		    session->ns_mover.md_listen_sock != -1) {
7787917SReza.Sabdar@Sun.COM 			reply.error = NDMP_ILLEGAL_STATE_ERR;
7797917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
7807917SReza.Sabdar@Sun.COM 			    "Mover is not in local listen state.");
7817917SReza.Sabdar@Sun.COM 		} else {
7827917SReza.Sabdar@Sun.COM 			session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
7837917SReza.Sabdar@Sun.COM 		}
7847917SReza.Sabdar@Sun.COM 		break;
7857917SReza.Sabdar@Sun.COM 
7867917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_TCP:
7877917SReza.Sabdar@Sun.COM 		reply.error = data_connect_sock_v3(session,
7887917SReza.Sabdar@Sun.COM 		    request->addr.tcp_ip_v3, request->addr.tcp_port_v3);
7897917SReza.Sabdar@Sun.COM 		break;
7907917SReza.Sabdar@Sun.COM 
7917917SReza.Sabdar@Sun.COM 	default:
7927917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
7937917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
7947917SReza.Sabdar@Sun.COM 		    request->addr.addr_type);
7957917SReza.Sabdar@Sun.COM 	}
7967917SReza.Sabdar@Sun.COM 
7977917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR)
7987917SReza.Sabdar@Sun.COM 		session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED;
7997917SReza.Sabdar@Sun.COM 
8007917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
8017917SReza.Sabdar@Sun.COM 	    "sending ndmp_data_connect_v3 reply");
8027917SReza.Sabdar@Sun.COM }
8037917SReza.Sabdar@Sun.COM 
8047917SReza.Sabdar@Sun.COM 
8057917SReza.Sabdar@Sun.COM /*
8067917SReza.Sabdar@Sun.COM  * ************************************************************************
8077917SReza.Sabdar@Sun.COM  * NDMP V4 HANDLERS
8087917SReza.Sabdar@Sun.COM  * ************************************************************************
8097917SReza.Sabdar@Sun.COM  */
8107917SReza.Sabdar@Sun.COM 
8117917SReza.Sabdar@Sun.COM /*
8127917SReza.Sabdar@Sun.COM  * ndmpd_data_get_env_v4
8137917SReza.Sabdar@Sun.COM  *
8147917SReza.Sabdar@Sun.COM  * Request handler. Returns the environment variable array sent
8157917SReza.Sabdar@Sun.COM  * with the backup request. This request may only be sent with
8167917SReza.Sabdar@Sun.COM  * a backup operation is in progress.
8177917SReza.Sabdar@Sun.COM  *
8187917SReza.Sabdar@Sun.COM  * Parameters:
8197917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
8207917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
8217917SReza.Sabdar@Sun.COM  *
8227917SReza.Sabdar@Sun.COM  * Returns:
8237917SReza.Sabdar@Sun.COM  *   void
8247917SReza.Sabdar@Sun.COM  */
8257917SReza.Sabdar@Sun.COM /*ARGSUSED*/
8267917SReza.Sabdar@Sun.COM void
ndmpd_data_get_env_v4(ndmp_connection_t * connection,void * body)8277917SReza.Sabdar@Sun.COM ndmpd_data_get_env_v4(ndmp_connection_t *connection, void *body)
8287917SReza.Sabdar@Sun.COM {
8297917SReza.Sabdar@Sun.COM 	ndmp_data_get_env_reply reply;
8307917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
8317917SReza.Sabdar@Sun.COM 
8327917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
8337917SReza.Sabdar@Sun.COM 
8347917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_ACTIVE &&
8357917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) {
8367917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state for the data server.");
8377917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
8387917SReza.Sabdar@Sun.COM 		reply.env.env_len = 0;
8397917SReza.Sabdar@Sun.COM 	} else if (session->ns_data.dd_operation != NDMP_DATA_OP_BACKUP) {
8407917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Backup operation not active.");
8417917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
8427917SReza.Sabdar@Sun.COM 		reply.env.env_len = 0;
8437917SReza.Sabdar@Sun.COM 	} else {
8447917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
8457917SReza.Sabdar@Sun.COM 		reply.env.env_len = session->ns_data.dd_env_len;
8467917SReza.Sabdar@Sun.COM 		reply.env.env_val = session->ns_data.dd_env;
8477917SReza.Sabdar@Sun.COM 	}
8487917SReza.Sabdar@Sun.COM 
8497917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply, "sending data_get_env reply");
8507917SReza.Sabdar@Sun.COM }
8517917SReza.Sabdar@Sun.COM 
8527917SReza.Sabdar@Sun.COM /*
8537917SReza.Sabdar@Sun.COM  * ndmpd_data_get_state_v4
8547917SReza.Sabdar@Sun.COM  *
8557917SReza.Sabdar@Sun.COM  * Request handler. Returns current data state.
8567917SReza.Sabdar@Sun.COM  *
8577917SReza.Sabdar@Sun.COM  * Parameters:
8587917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
8597917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
8607917SReza.Sabdar@Sun.COM  *
8617917SReza.Sabdar@Sun.COM  * Returns:
8627917SReza.Sabdar@Sun.COM  *   void
8637917SReza.Sabdar@Sun.COM  */
8647917SReza.Sabdar@Sun.COM /*ARGSUSED*/
8657917SReza.Sabdar@Sun.COM void
ndmpd_data_get_state_v4(ndmp_connection_t * connection,void * body)8667917SReza.Sabdar@Sun.COM ndmpd_data_get_state_v4(ndmp_connection_t *connection, void *body)
8677917SReza.Sabdar@Sun.COM {
8687917SReza.Sabdar@Sun.COM 	ndmp_data_get_state_reply_v4 reply;
8697917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
8707917SReza.Sabdar@Sun.COM 
8717917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
8727917SReza.Sabdar@Sun.COM 
8737917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
8747917SReza.Sabdar@Sun.COM 	reply.unsupported = NDMP_DATA_STATE_EST_BYTES_REMAIN_INVALID
8757917SReza.Sabdar@Sun.COM 	    | NDMP_DATA_STATE_EST_TIME_REMAIN_INVALID;
8767917SReza.Sabdar@Sun.COM 	reply.operation = session->ns_data.dd_operation;
8777917SReza.Sabdar@Sun.COM 	reply.state = session->ns_data.dd_state;
8787917SReza.Sabdar@Sun.COM 	reply.halt_reason = session->ns_data.dd_halt_reason;
8797917SReza.Sabdar@Sun.COM 
8807917SReza.Sabdar@Sun.COM 	if (reply.operation == NDMP_DATA_OP_BACKUP)
8817917SReza.Sabdar@Sun.COM 		reply.bytes_processed = long_long_to_quad(
8827917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_module.dm_stats.ms_bytes_processed);
8837917SReza.Sabdar@Sun.COM 	else
8847917SReza.Sabdar@Sun.COM 		reply.bytes_processed =
8857917SReza.Sabdar@Sun.COM 		    long_long_to_quad(ndmpd_data_get_info(session));
8867917SReza.Sabdar@Sun.COM 
8877917SReza.Sabdar@Sun.COM 	reply.est_bytes_remain = long_long_to_quad(0LL);
8887917SReza.Sabdar@Sun.COM 	reply.est_time_remain = 0;
8897917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE)
8907917SReza.Sabdar@Sun.COM 		ndmp_copy_addr_v4(&reply.data_connection_addr,
8917917SReza.Sabdar@Sun.COM 		    &session->ns_data.dd_data_addr_v4);
8927917SReza.Sabdar@Sun.COM 
8937917SReza.Sabdar@Sun.COM 	reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset);
8947917SReza.Sabdar@Sun.COM 	reply.read_length = long_long_to_quad(session->ns_data.dd_read_length);
8957917SReza.Sabdar@Sun.COM 
8967917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
8977917SReza.Sabdar@Sun.COM 	    "sending ndmp_data_get_state_v4 reply");
8987917SReza.Sabdar@Sun.COM 	free(reply.data_connection_addr.tcp_addr_v4);
8997917SReza.Sabdar@Sun.COM }
9007917SReza.Sabdar@Sun.COM 
9017917SReza.Sabdar@Sun.COM 
9027917SReza.Sabdar@Sun.COM /*
9037917SReza.Sabdar@Sun.COM  * ndmpd_data_connect_v4
9047917SReza.Sabdar@Sun.COM  *
9057917SReza.Sabdar@Sun.COM  * Request handler. Connects the data server to either a local
9067917SReza.Sabdar@Sun.COM  * or remote mover.
9077917SReza.Sabdar@Sun.COM  *
9087917SReza.Sabdar@Sun.COM  * Parameters:
9097917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
9107917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
9117917SReza.Sabdar@Sun.COM  *
9127917SReza.Sabdar@Sun.COM  * Returns:
9137917SReza.Sabdar@Sun.COM  *   void
9147917SReza.Sabdar@Sun.COM  */
9157917SReza.Sabdar@Sun.COM void
ndmpd_data_connect_v4(ndmp_connection_t * connection,void * body)9167917SReza.Sabdar@Sun.COM ndmpd_data_connect_v4(ndmp_connection_t *connection, void *body)
9177917SReza.Sabdar@Sun.COM {
9187917SReza.Sabdar@Sun.COM 	ndmp_data_connect_request_v4 *request;
9197917SReza.Sabdar@Sun.COM 	ndmp_data_connect_reply_v4 reply;
9207917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
9217917SReza.Sabdar@Sun.COM 
9227917SReza.Sabdar@Sun.COM 	request = (ndmp_data_connect_request_v4 *)body;
9237917SReza.Sabdar@Sun.COM 
9247917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
9257917SReza.Sabdar@Sun.COM 
9267917SReza.Sabdar@Sun.COM 	if (!ndmp_valid_v3addr_type(request->addr.addr_type)) {
9277917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
9287917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
9297917SReza.Sabdar@Sun.COM 		    request->addr.addr_type);
9307917SReza.Sabdar@Sun.COM 	} else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
9317917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
9327917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid state to process connect request.");
9337917SReza.Sabdar@Sun.COM 	} else {
9347917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
9357917SReza.Sabdar@Sun.COM 	}
9367917SReza.Sabdar@Sun.COM 
9377917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
9387917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
9397917SReza.Sabdar@Sun.COM 		    "sending ndmp_data_connect_v4 reply");
9407917SReza.Sabdar@Sun.COM 		return;
9417917SReza.Sabdar@Sun.COM 	}
9427917SReza.Sabdar@Sun.COM 
9437917SReza.Sabdar@Sun.COM 	switch (request->addr.addr_type) {
9447917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_LOCAL:
9457917SReza.Sabdar@Sun.COM 		/*
9467917SReza.Sabdar@Sun.COM 		 * Verify that the mover is listening for a
9477917SReza.Sabdar@Sun.COM 		 * local connection
9487917SReza.Sabdar@Sun.COM 		 */
9497917SReza.Sabdar@Sun.COM 		if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN ||
9507917SReza.Sabdar@Sun.COM 		    session->ns_mover.md_listen_sock != -1) {
9517917SReza.Sabdar@Sun.COM 			reply.error = NDMP_ILLEGAL_STATE_ERR;
9527917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
9537917SReza.Sabdar@Sun.COM 			    "Mover is not in local listen state.");
9547917SReza.Sabdar@Sun.COM 		} else {
9557917SReza.Sabdar@Sun.COM 			session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
9567917SReza.Sabdar@Sun.COM 		}
9577917SReza.Sabdar@Sun.COM 		break;
9587917SReza.Sabdar@Sun.COM 
9597917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_TCP:
9607917SReza.Sabdar@Sun.COM 		reply.error = data_connect_sock_v3(session,
9617917SReza.Sabdar@Sun.COM 		    request->addr.tcp_ip_v4(0), request->addr.tcp_port_v4(0));
9627917SReza.Sabdar@Sun.COM 		break;
9637917SReza.Sabdar@Sun.COM 
9647917SReza.Sabdar@Sun.COM 	default:
9657917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
9667917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
9677917SReza.Sabdar@Sun.COM 		    request->addr.addr_type);
9687917SReza.Sabdar@Sun.COM 	}
9697917SReza.Sabdar@Sun.COM 
9707917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR)
9717917SReza.Sabdar@Sun.COM 		session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED;
9727917SReza.Sabdar@Sun.COM 
9737917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
9747917SReza.Sabdar@Sun.COM 	    "sending ndmp_data_connect_v4 reply");
9757917SReza.Sabdar@Sun.COM }
9767917SReza.Sabdar@Sun.COM 
9777917SReza.Sabdar@Sun.COM /*
9787917SReza.Sabdar@Sun.COM  * ndmpd_data_listen_v4
9797917SReza.Sabdar@Sun.COM  *
9807917SReza.Sabdar@Sun.COM  * Request handler. Configures the server to listen for a connection
9817917SReza.Sabdar@Sun.COM  * from a remote mover.
9827917SReza.Sabdar@Sun.COM  *
9837917SReza.Sabdar@Sun.COM  * Parameters:
9847917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
9857917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
9867917SReza.Sabdar@Sun.COM  *
9877917SReza.Sabdar@Sun.COM  * Returns:
9887917SReza.Sabdar@Sun.COM  *   void
9897917SReza.Sabdar@Sun.COM  */
9907917SReza.Sabdar@Sun.COM void
ndmpd_data_listen_v4(ndmp_connection_t * connection,void * body)9917917SReza.Sabdar@Sun.COM ndmpd_data_listen_v4(ndmp_connection_t *connection, void *body)
9927917SReza.Sabdar@Sun.COM {
9937917SReza.Sabdar@Sun.COM 	ndmp_data_listen_request_v4 *request;
9947917SReza.Sabdar@Sun.COM 	ndmp_data_listen_reply_v4 reply;
9957917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
9967917SReza.Sabdar@Sun.COM 	ulong_t addr;
9977917SReza.Sabdar@Sun.COM 	ushort_t port;
9987917SReza.Sabdar@Sun.COM 
9997917SReza.Sabdar@Sun.COM 	request = (ndmp_data_listen_request_v4 *)body;
10007917SReza.Sabdar@Sun.COM 
10017917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
10027917SReza.Sabdar@Sun.COM 
10037917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
10047917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
10057917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
10067917SReza.Sabdar@Sun.COM 		    "Invalid internal data state to process listen request.");
10077917SReza.Sabdar@Sun.COM 	} else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
10087917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
10097917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
10107917SReza.Sabdar@Sun.COM 		    "Invalid mover state to process listen request.");
10117917SReza.Sabdar@Sun.COM 	} else {
10127917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
10137917SReza.Sabdar@Sun.COM 	}
10147917SReza.Sabdar@Sun.COM 
10157917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
10167917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, &reply,
10177917SReza.Sabdar@Sun.COM 		    "ndmp_data_listen_request_v4 reply");
10187917SReza.Sabdar@Sun.COM 		return;
10197917SReza.Sabdar@Sun.COM 	}
10207917SReza.Sabdar@Sun.COM 
10217917SReza.Sabdar@Sun.COM 	switch (request->addr_type) {
10227917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_LOCAL:
10237917SReza.Sabdar@Sun.COM 		reply.connect_addr.addr_type = request->addr_type;
10247917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL;
10257917SReza.Sabdar@Sun.COM 		break;
10267917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_TCP:
10277917SReza.Sabdar@Sun.COM 		if (create_listen_socket_v3(session, &addr, &port) < 0) {
10287917SReza.Sabdar@Sun.COM 			reply.error = NDMP_IO_ERR;
10297917SReza.Sabdar@Sun.COM 			break;
10307917SReza.Sabdar@Sun.COM 		}
10317917SReza.Sabdar@Sun.COM 
10327917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
10337917SReza.Sabdar@Sun.COM 		reply.connect_addr.addr_type = request->addr_type;
10347917SReza.Sabdar@Sun.COM 		reply.connect_addr.tcp_addr_v4 =
10357917SReza.Sabdar@Sun.COM 		    ndmp_malloc(sizeof (ndmp_tcp_addr_v4));
10367917SReza.Sabdar@Sun.COM 
10377917SReza.Sabdar@Sun.COM 		reply.connect_addr.tcp_ip_v4(0) = htonl(addr);
10387917SReza.Sabdar@Sun.COM 		reply.connect_addr.tcp_port_v4(0) = htons(port);
10397917SReza.Sabdar@Sun.COM 		reply.connect_addr.tcp_len_v4 = 1;
10407917SReza.Sabdar@Sun.COM 
10417917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr_v4.addr_type = NDMP_ADDR_TCP;
10427917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr_v4.tcp_addr_v4 =
10437917SReza.Sabdar@Sun.COM 		    ndmp_malloc(sizeof (ndmp_tcp_addr_v4));
10447917SReza.Sabdar@Sun.COM 
10457917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr_v4.tcp_ip_v4(0) = addr;
10467917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr_v4.tcp_port_v4(0) = ntohs(port);
10477917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr_v4.tcp_len_v4 = 1;
10487917SReza.Sabdar@Sun.COM 
10497917SReza.Sabdar@Sun.COM 		/* Copy that to data_addr for compatibility */
10507917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP;
10517917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.tcp_ip_v3 = addr;
10527917SReza.Sabdar@Sun.COM 		session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(port);
10537917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "listen_socket: %d",
10547917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_listen_sock);
10557917SReza.Sabdar@Sun.COM 		break;
10567917SReza.Sabdar@Sun.COM 
10577917SReza.Sabdar@Sun.COM 	default:
10587917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid address type: %d",
10597917SReza.Sabdar@Sun.COM 		    request->addr_type);
10607917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
10617917SReza.Sabdar@Sun.COM 		break;
10627917SReza.Sabdar@Sun.COM 	}
10637917SReza.Sabdar@Sun.COM 
10647917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR)
10657917SReza.Sabdar@Sun.COM 		session->ns_data.dd_state = NDMP_DATA_STATE_LISTEN;
10667917SReza.Sabdar@Sun.COM 
10677917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
10687917SReza.Sabdar@Sun.COM 	    "ndmp_data_listen_request_v4 reply");
10697917SReza.Sabdar@Sun.COM }
10707917SReza.Sabdar@Sun.COM 
10717917SReza.Sabdar@Sun.COM 
10727917SReza.Sabdar@Sun.COM /*
10737917SReza.Sabdar@Sun.COM  * ndmpd_data_start_recover_filehist_v4
10747917SReza.Sabdar@Sun.COM  *
10757917SReza.Sabdar@Sun.COM  * Request handler. Recovers the file history (not supported yet)
10767917SReza.Sabdar@Sun.COM  * This command has an optional support in V4.
10777917SReza.Sabdar@Sun.COM  *
10787917SReza.Sabdar@Sun.COM  * Parameters:
10797917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
10807917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
10817917SReza.Sabdar@Sun.COM  *
10827917SReza.Sabdar@Sun.COM  * Returns:
10837917SReza.Sabdar@Sun.COM  *   void
10847917SReza.Sabdar@Sun.COM  */
10857917SReza.Sabdar@Sun.COM /*ARGSUSED*/
10867917SReza.Sabdar@Sun.COM void
ndmpd_data_start_recover_filehist_v4(ndmp_connection_t * connection,void * body)10877917SReza.Sabdar@Sun.COM ndmpd_data_start_recover_filehist_v4(ndmp_connection_t *connection, void *body)
10887917SReza.Sabdar@Sun.COM {
10897917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_filehist_reply_v4 reply;
10907917SReza.Sabdar@Sun.COM 
10917917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "Request not supported");
10927917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NOT_SUPPORTED_ERR;
10937917SReza.Sabdar@Sun.COM 
10947917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, &reply,
10957917SReza.Sabdar@Sun.COM 	    "sending ndmp_data_start_recover_filehist_reply_v4 reply");
10967917SReza.Sabdar@Sun.COM }
10977917SReza.Sabdar@Sun.COM 
10987917SReza.Sabdar@Sun.COM /*
10997917SReza.Sabdar@Sun.COM  * ************************************************************************
11007917SReza.Sabdar@Sun.COM  * LOCALS
11017917SReza.Sabdar@Sun.COM  * ************************************************************************
11027917SReza.Sabdar@Sun.COM  */
11037917SReza.Sabdar@Sun.COM 
11047917SReza.Sabdar@Sun.COM /*
11057917SReza.Sabdar@Sun.COM  * ndmpd_data_error_send
11067917SReza.Sabdar@Sun.COM  *
11077917SReza.Sabdar@Sun.COM  * This function sends the notify message to the client.
11087917SReza.Sabdar@Sun.COM  *
11097917SReza.Sabdar@Sun.COM  * Parameters:
11107917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
11117917SReza.Sabdar@Sun.COM  *   reason  (input) - halt reason.
11127917SReza.Sabdar@Sun.COM  *
11137917SReza.Sabdar@Sun.COM  * Returns:
11147917SReza.Sabdar@Sun.COM  *   Error code
11157917SReza.Sabdar@Sun.COM  */
11167917SReza.Sabdar@Sun.COM /*ARGSUSED*/
11177917SReza.Sabdar@Sun.COM static int
ndmpd_data_error_send(ndmpd_session_t * session,ndmp_data_halt_reason reason)11187917SReza.Sabdar@Sun.COM ndmpd_data_error_send(ndmpd_session_t *session, ndmp_data_halt_reason reason)
11197917SReza.Sabdar@Sun.COM {
11207917SReza.Sabdar@Sun.COM 	ndmp_notify_data_halted_request req;
11217917SReza.Sabdar@Sun.COM 
11227917SReza.Sabdar@Sun.COM 	req.reason = session->ns_data.dd_halt_reason;
11237917SReza.Sabdar@Sun.COM 	req.text_reason = "";
11247917SReza.Sabdar@Sun.COM 
11257917SReza.Sabdar@Sun.COM 	return (ndmp_send_request(session->ns_connection,
11267917SReza.Sabdar@Sun.COM 	    NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, &req, 0));
11277917SReza.Sabdar@Sun.COM }
11287917SReza.Sabdar@Sun.COM 
11297917SReza.Sabdar@Sun.COM 
11307917SReza.Sabdar@Sun.COM /*
11317917SReza.Sabdar@Sun.COM  * ndmpd_data_error_send_v4
11327917SReza.Sabdar@Sun.COM  *
11337917SReza.Sabdar@Sun.COM  * This function sends the notify message to the client.
11347917SReza.Sabdar@Sun.COM  *
11357917SReza.Sabdar@Sun.COM  * Parameters:
11367917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
11377917SReza.Sabdar@Sun.COM  *   reason  (input) - halt reason.
11387917SReza.Sabdar@Sun.COM  *
11397917SReza.Sabdar@Sun.COM  * Returns:
11407917SReza.Sabdar@Sun.COM  *   Error code
11417917SReza.Sabdar@Sun.COM  */
11427917SReza.Sabdar@Sun.COM /*ARGSUSED*/
11437917SReza.Sabdar@Sun.COM static int
ndmpd_data_error_send_v4(ndmpd_session_t * session,ndmp_data_halt_reason reason)11447917SReza.Sabdar@Sun.COM ndmpd_data_error_send_v4(ndmpd_session_t *session, ndmp_data_halt_reason reason)
11457917SReza.Sabdar@Sun.COM {
11467917SReza.Sabdar@Sun.COM 	ndmp_notify_data_halted_request_v4 req;
11477917SReza.Sabdar@Sun.COM 
11487917SReza.Sabdar@Sun.COM 	req.reason = session->ns_data.dd_halt_reason;
11497917SReza.Sabdar@Sun.COM 
11507917SReza.Sabdar@Sun.COM 	return ndmp_send_request(session->ns_connection,
11517917SReza.Sabdar@Sun.COM 	    NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, &req, 0);
11527917SReza.Sabdar@Sun.COM }
11537917SReza.Sabdar@Sun.COM 
11547917SReza.Sabdar@Sun.COM 
11557917SReza.Sabdar@Sun.COM /*
11567917SReza.Sabdar@Sun.COM  * ndmpd_data_error
11577917SReza.Sabdar@Sun.COM  *
11587917SReza.Sabdar@Sun.COM  * This function is called when a data error has been detected.
11597917SReza.Sabdar@Sun.COM  * A notify message is sent to the client and the data server is
11607917SReza.Sabdar@Sun.COM  * placed into the halted state.
11617917SReza.Sabdar@Sun.COM  *
11627917SReza.Sabdar@Sun.COM  * Parameters:
11637917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
11647917SReza.Sabdar@Sun.COM  *   reason  (input) - halt reason.
11657917SReza.Sabdar@Sun.COM  *
11667917SReza.Sabdar@Sun.COM  * Returns:
11677917SReza.Sabdar@Sun.COM  *   void
11687917SReza.Sabdar@Sun.COM  */
11697917SReza.Sabdar@Sun.COM void
ndmpd_data_error(ndmpd_session_t * session,ndmp_data_halt_reason reason)11707917SReza.Sabdar@Sun.COM ndmpd_data_error(ndmpd_session_t *session, ndmp_data_halt_reason reason)
11717917SReza.Sabdar@Sun.COM {
11727917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
11737917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
11747917SReza.Sabdar@Sun.COM 		return;
11757917SReza.Sabdar@Sun.COM 
11767917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
11777917SReza.Sabdar@Sun.COM 		/*
11787917SReza.Sabdar@Sun.COM 		 * Send/discard any buffered file history data.
11797917SReza.Sabdar@Sun.COM 		 */
11807917SReza.Sabdar@Sun.COM 		ndmpd_file_history_cleanup(session,
11817917SReza.Sabdar@Sun.COM 		    (reason == NDMP_DATA_HALT_SUCCESSFUL ? TRUE : FALSE));
11827917SReza.Sabdar@Sun.COM 
11837917SReza.Sabdar@Sun.COM 		/*
11847917SReza.Sabdar@Sun.COM 		 * If mover local and successful backup, write any
11857917SReza.Sabdar@Sun.COM 		 * remaining buffered data to tape.
11867917SReza.Sabdar@Sun.COM 		 */
11877917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_data_addr.addr_type
11887917SReza.Sabdar@Sun.COM 		    == NDMP_ADDR_LOCAL && reason == NDMP_DATA_HALT_SUCCESSFUL)
11897917SReza.Sabdar@Sun.COM 			(void) ndmpd_local_write_v3(session, 0, 0);
11907917SReza.Sabdar@Sun.COM 	}
11917917SReza.Sabdar@Sun.COM 
11927917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
11937917SReza.Sabdar@Sun.COM 	session->ns_data.dd_halt_reason = reason;
11947917SReza.Sabdar@Sun.COM 
11957917SReza.Sabdar@Sun.COM 	if (session->ns_protocol_version == NDMPV4) {
11967917SReza.Sabdar@Sun.COM 		if (ndmpd_data_error_send_v4(session, reason) < 0)
11977917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
11987917SReza.Sabdar@Sun.COM 			    "Error sending notify_data_halted request");
11997917SReza.Sabdar@Sun.COM 	} else {
12007917SReza.Sabdar@Sun.COM 		if (ndmpd_data_error_send(session, reason) < 0)
12017917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
12027917SReza.Sabdar@Sun.COM 			    "Error sending notify_data_halted request");
12037917SReza.Sabdar@Sun.COM 	}
12047917SReza.Sabdar@Sun.COM 
12057917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP) {
12067917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_sock != -1) {
12077917SReza.Sabdar@Sun.COM 			(void) ndmpd_remove_file_handler(session,
12087917SReza.Sabdar@Sun.COM 			    session->ns_data.dd_sock);
12097917SReza.Sabdar@Sun.COM 			/*
12107917SReza.Sabdar@Sun.COM 			 * ndmpcopy: we use the same socket for the mover,
12117917SReza.Sabdar@Sun.COM 			 * so expect to close when mover is done!
12127917SReza.Sabdar@Sun.COM 			 */
12137917SReza.Sabdar@Sun.COM 			if (session->ns_data.dd_sock !=
12147917SReza.Sabdar@Sun.COM 			    session->ns_mover.md_sock)
12157917SReza.Sabdar@Sun.COM 				(void) close(session->ns_data.dd_sock);
12167917SReza.Sabdar@Sun.COM 
12177917SReza.Sabdar@Sun.COM 			session->ns_data.dd_sock = -1;
12187917SReza.Sabdar@Sun.COM 		}
12197917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_listen_sock != -1) {
12207917SReza.Sabdar@Sun.COM 			(void) ndmpd_remove_file_handler(session,
12217917SReza.Sabdar@Sun.COM 			    session->ns_data.dd_listen_sock);
12227917SReza.Sabdar@Sun.COM 
12237917SReza.Sabdar@Sun.COM 			(void) close(session->ns_data.dd_listen_sock);
12247917SReza.Sabdar@Sun.COM 			session->ns_data.dd_listen_sock = -1;
12257917SReza.Sabdar@Sun.COM 		}
12267917SReza.Sabdar@Sun.COM 	} else {
12277917SReza.Sabdar@Sun.COM 		ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
12287917SReza.Sabdar@Sun.COM 	}
12297917SReza.Sabdar@Sun.COM }
12307917SReza.Sabdar@Sun.COM 
12317917SReza.Sabdar@Sun.COM 
12327917SReza.Sabdar@Sun.COM /*
12337917SReza.Sabdar@Sun.COM  * data_accept_connection_v3
12347917SReza.Sabdar@Sun.COM  *
12357917SReza.Sabdar@Sun.COM  * Accept a data connection from a remote mover.
12367917SReza.Sabdar@Sun.COM  * Called by ndmpd_select when a connection is pending on
12377917SReza.Sabdar@Sun.COM  * the data listen socket.
12387917SReza.Sabdar@Sun.COM  *
12397917SReza.Sabdar@Sun.COM  * Parameters:
12407917SReza.Sabdar@Sun.COM  *   cookie  (input) - session pointer.
12417917SReza.Sabdar@Sun.COM  *   fd      (input) - file descriptor.
12427917SReza.Sabdar@Sun.COM  *   mode    (input) - select mode.
12437917SReza.Sabdar@Sun.COM  *
12447917SReza.Sabdar@Sun.COM  * Returns:
12457917SReza.Sabdar@Sun.COM  *   void
12467917SReza.Sabdar@Sun.COM  */
12477917SReza.Sabdar@Sun.COM /*ARGSUSED*/
12487917SReza.Sabdar@Sun.COM static void
data_accept_connection_v3(void * cookie,int fd,ulong_t mode)12497917SReza.Sabdar@Sun.COM data_accept_connection_v3(void *cookie, int fd, ulong_t mode)
12507917SReza.Sabdar@Sun.COM {
12517917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
12527917SReza.Sabdar@Sun.COM 	int from_len;
12537917SReza.Sabdar@Sun.COM 	struct sockaddr_in from;
12547917SReza.Sabdar@Sun.COM 	int flag = 1;
12557917SReza.Sabdar@Sun.COM 
12567917SReza.Sabdar@Sun.COM 	from_len = sizeof (from);
12577917SReza.Sabdar@Sun.COM 	session->ns_data.dd_sock = accept(fd, (struct sockaddr *)&from,
12587917SReza.Sabdar@Sun.COM 	    &from_len);
12597917SReza.Sabdar@Sun.COM 
12607917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "sock fd: %d",
12617917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_sock);
12627917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "sin: port %d addr %s",
12637917SReza.Sabdar@Sun.COM 	    ntohs(from.sin_port),
12647917SReza.Sabdar@Sun.COM 	    inet_ntoa(IN_ADDR(from.sin_addr.s_addr)));
12657917SReza.Sabdar@Sun.COM 
12667917SReza.Sabdar@Sun.COM 	(void) ndmpd_remove_file_handler(session, fd);
12677917SReza.Sabdar@Sun.COM 	(void) close(session->ns_data.dd_listen_sock);
12687917SReza.Sabdar@Sun.COM 	session->ns_data.dd_listen_sock = -1;
12697917SReza.Sabdar@Sun.COM 
12707917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_sock < 0) {
12717917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Accept error: %m");
12727917SReza.Sabdar@Sun.COM 		ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR);
12737917SReza.Sabdar@Sun.COM 		return;
12747917SReza.Sabdar@Sun.COM 	}
12757917SReza.Sabdar@Sun.COM 
12767917SReza.Sabdar@Sun.COM 	/*
12777917SReza.Sabdar@Sun.COM 	 * Save the peer address.
12787917SReza.Sabdar@Sun.COM 	 */
12797917SReza.Sabdar@Sun.COM 	session->ns_data.dd_data_addr.tcp_ip_v3 = from.sin_addr.s_addr;
12807917SReza.Sabdar@Sun.COM 	session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(from.sin_port);
12817917SReza.Sabdar@Sun.COM 
12827917SReza.Sabdar@Sun.COM 	/*
12837917SReza.Sabdar@Sun.COM 	 * Set the parameter of the new socket.
12847917SReza.Sabdar@Sun.COM 	 */
12857917SReza.Sabdar@Sun.COM 	(void) setsockopt(session->ns_data.dd_sock, SOL_SOCKET, SO_KEEPALIVE,
12867917SReza.Sabdar@Sun.COM 	    &flag, sizeof (flag));
12877917SReza.Sabdar@Sun.COM 	ndmp_set_socket_nodelay(session->ns_data.dd_sock);
12887917SReza.Sabdar@Sun.COM 	if (ndmp_sbs > 0)
12897917SReza.Sabdar@Sun.COM 		ndmp_set_socket_snd_buf(session->ns_data.dd_sock,
12907917SReza.Sabdar@Sun.COM 		    ndmp_sbs * KILOBYTE);
12917917SReza.Sabdar@Sun.COM 	if (ndmp_rbs > 0)
12927917SReza.Sabdar@Sun.COM 		ndmp_set_socket_rcv_buf(session->ns_data.dd_sock,
12937917SReza.Sabdar@Sun.COM 		    ndmp_rbs * KILOBYTE);
12947917SReza.Sabdar@Sun.COM 
12957917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED;
12967917SReza.Sabdar@Sun.COM }
12977917SReza.Sabdar@Sun.COM 
12987917SReza.Sabdar@Sun.COM 
12997917SReza.Sabdar@Sun.COM /*
13007917SReza.Sabdar@Sun.COM  * create_listen_socket_v3
13017917SReza.Sabdar@Sun.COM  *
13027917SReza.Sabdar@Sun.COM  * Creates the data sockets for listening for a remote mover/data
13037917SReza.Sabdar@Sun.COM  * incoming connections.
13047917SReza.Sabdar@Sun.COM  */
13057917SReza.Sabdar@Sun.COM static int
create_listen_socket_v3(ndmpd_session_t * session,ulong_t * addr,ushort_t * port)13067917SReza.Sabdar@Sun.COM create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, ushort_t *port)
13077917SReza.Sabdar@Sun.COM {
13087917SReza.Sabdar@Sun.COM 	session->ns_data.dd_listen_sock = ndmp_create_socket(addr, port);
13097917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_listen_sock < 0)
13107917SReza.Sabdar@Sun.COM 		return (-1);
13117917SReza.Sabdar@Sun.COM 
13127917SReza.Sabdar@Sun.COM 	/*
13137917SReza.Sabdar@Sun.COM 	 * Add a file handler for the listen socket.
13147917SReza.Sabdar@Sun.COM 	 * ndmpd_select will call data_accept_connection when a
13157917SReza.Sabdar@Sun.COM 	 * connection is ready to be accepted.
13167917SReza.Sabdar@Sun.COM 	 */
13177917SReza.Sabdar@Sun.COM 	if (ndmpd_add_file_handler(session, (void*)session,
13187917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_listen_sock, NDMPD_SELECT_MODE_READ, HC_MOVER,
13197917SReza.Sabdar@Sun.COM 	    data_accept_connection_v3) < 0) {
13207917SReza.Sabdar@Sun.COM 		(void) close(session->ns_data.dd_listen_sock);
13217917SReza.Sabdar@Sun.COM 		session->ns_data.dd_listen_sock = -1;
13227917SReza.Sabdar@Sun.COM 		return (-1);
13237917SReza.Sabdar@Sun.COM 	}
13247917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "addr: %s:%d",
13257917SReza.Sabdar@Sun.COM 	    inet_ntoa(IN_ADDR(*addr)), ntohs(*port));
13267917SReza.Sabdar@Sun.COM 
13277917SReza.Sabdar@Sun.COM 	return (0);
13287917SReza.Sabdar@Sun.COM }
13297917SReza.Sabdar@Sun.COM 
13307917SReza.Sabdar@Sun.COM 
13317917SReza.Sabdar@Sun.COM /*
13327917SReza.Sabdar@Sun.COM  * data_connect_sock_v3
13337917SReza.Sabdar@Sun.COM  *
13347917SReza.Sabdar@Sun.COM  * Connect the data interface socket to the specified ip/port
13357917SReza.Sabdar@Sun.COM  *
13367917SReza.Sabdar@Sun.COM  * Parameters:
13377917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
13387917SReza.Sabdar@Sun.COM  *   addr    (input) - IP address
13397917SReza.Sabdar@Sun.COM  *   port    (input) - port number
13407917SReza.Sabdar@Sun.COM  *
13417917SReza.Sabdar@Sun.COM  * Returns:
13427917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR - backup successfully started.
13437917SReza.Sabdar@Sun.COM  *   otherwise - error code of backup start error.
13447917SReza.Sabdar@Sun.COM  */
13457917SReza.Sabdar@Sun.COM static ndmp_error
data_connect_sock_v3(ndmpd_session_t * session,ulong_t addr,ushort_t port)13467917SReza.Sabdar@Sun.COM data_connect_sock_v3(ndmpd_session_t *session, ulong_t addr, ushort_t port)
13477917SReza.Sabdar@Sun.COM {
13487917SReza.Sabdar@Sun.COM 	int sock;
13497917SReza.Sabdar@Sun.COM 
13507917SReza.Sabdar@Sun.COM 	sock = ndmp_connect_sock_v3(addr, port);
13517917SReza.Sabdar@Sun.COM 	if (sock < 0)
13527917SReza.Sabdar@Sun.COM 		return (NDMP_CONNECT_ERR);
13537917SReza.Sabdar@Sun.COM 
13547917SReza.Sabdar@Sun.COM 	session->ns_data.dd_sock = sock;
13557917SReza.Sabdar@Sun.COM 	session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP;
13567917SReza.Sabdar@Sun.COM 	session->ns_data.dd_data_addr.tcp_ip_v3 = ntohl(addr);
13577917SReza.Sabdar@Sun.COM 	session->ns_data.dd_data_addr.tcp_port_v3 = port;
13587917SReza.Sabdar@Sun.COM 
13597917SReza.Sabdar@Sun.COM 	return (NDMP_NO_ERR);
13607917SReza.Sabdar@Sun.COM }
13617917SReza.Sabdar@Sun.COM 
13627917SReza.Sabdar@Sun.COM 
13637917SReza.Sabdar@Sun.COM /*
1364*12186SJanice.Chang@Sun.COM  * ndmpd_tar_start_backup_v3
13657917SReza.Sabdar@Sun.COM  *
13667917SReza.Sabdar@Sun.COM  * Start the backup work
13677917SReza.Sabdar@Sun.COM  *
13687917SReza.Sabdar@Sun.COM  * Parameters:
1369*12186SJanice.Chang@Sun.COM  *   session   (input) - session pointer.
1370*12186SJanice.Chang@Sun.COM  *   bu_type   (input) - backup type.
1371*12186SJanice.Chang@Sun.COM  *   env_val   (input) - environment variable array.
1372*12186SJanice.Chang@Sun.COM  *   env_len   (input) - length of env_val.
13737917SReza.Sabdar@Sun.COM  *
13747917SReza.Sabdar@Sun.COM  * Returns:
13757917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR - backup successfully started.
13767917SReza.Sabdar@Sun.COM  *   otherwise - error code of backup start error.
13777917SReza.Sabdar@Sun.COM  */
13787917SReza.Sabdar@Sun.COM static ndmp_error
ndmpd_tar_start_backup_v3(ndmpd_session_t * session,char * bu_type,ndmp_pval * env_val,ulong_t env_len)1379*12186SJanice.Chang@Sun.COM ndmpd_tar_start_backup_v3(ndmpd_session_t *session, char *bu_type,
1380*12186SJanice.Chang@Sun.COM     ndmp_pval *env_val, ulong_t env_len)
13817917SReza.Sabdar@Sun.COM {
13827917SReza.Sabdar@Sun.COM 	int err;
13837917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
13847917SReza.Sabdar@Sun.COM 	ndmpd_module_params_t *params;
13857917SReza.Sabdar@Sun.COM 	ndmp_data_start_backup_reply_v3 reply;
13867917SReza.Sabdar@Sun.COM 
13877917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
13887917SReza.Sabdar@Sun.COM 
13897917SReza.Sabdar@Sun.COM 	err = ndmpd_save_env(session, env_val, env_len);
13907917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR)
13917917SReza.Sabdar@Sun.COM 		return (err);
13927917SReza.Sabdar@Sun.COM 
13937917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
13947917SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_params);
13957917SReza.Sabdar@Sun.COM 	params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t));
13967917SReza.Sabdar@Sun.COM 	if (!params)
13977917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
13987917SReza.Sabdar@Sun.COM 
13997917SReza.Sabdar@Sun.COM 	params->mp_daemon_cookie = (void *)session;
14007917SReza.Sabdar@Sun.COM 	params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie;
14017917SReza.Sabdar@Sun.COM 	params->mp_protocol_version = session->ns_protocol_version;
14027917SReza.Sabdar@Sun.COM 	params->mp_operation = NDMP_DATA_OP_BACKUP;
14037917SReza.Sabdar@Sun.COM 	params->mp_get_env_func = ndmpd_api_get_env;
14047917SReza.Sabdar@Sun.COM 	params->mp_add_env_func = ndmpd_api_add_env;
14057917SReza.Sabdar@Sun.COM 	params->mp_set_env_func = ndmpd_api_set_env;
14067917SReza.Sabdar@Sun.COM 	params->mp_get_name_func = 0;
14077917SReza.Sabdar@Sun.COM 	params->mp_dispatch_func = ndmpd_api_dispatch;
14087917SReza.Sabdar@Sun.COM 	params->mp_done_func = ndmpd_api_done_v3;
14097917SReza.Sabdar@Sun.COM 	if (session->ns_protocol_version == NDMPV4)
14107917SReza.Sabdar@Sun.COM 		params->mp_log_func_v3 = ndmpd_api_log_v4;
14117917SReza.Sabdar@Sun.COM 	else
14127917SReza.Sabdar@Sun.COM 		params->mp_log_func_v3 = ndmpd_api_log_v3;
14137917SReza.Sabdar@Sun.COM 
14147917SReza.Sabdar@Sun.COM 	params->mp_add_file_handler_func = ndmpd_api_add_file_handler;
14157917SReza.Sabdar@Sun.COM 	params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler;
14167917SReza.Sabdar@Sun.COM 	params->mp_write_func = ndmpd_api_write_v3;
14177917SReza.Sabdar@Sun.COM 	params->mp_read_func = 0;
14187917SReza.Sabdar@Sun.COM 	params->mp_file_recovered_func = 0;
14197917SReza.Sabdar@Sun.COM 	params->mp_stats = &session->ns_data.dd_module.dm_stats;
14207917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_module_cookie = 0;
14217917SReza.Sabdar@Sun.COM 
14227917SReza.Sabdar@Sun.COM 	if (strcmp(bu_type, NDMP_DUMP_TYPE) == 0) {
14237917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_DUMP);
14247917SReza.Sabdar@Sun.COM 		params->mp_file_history_path_func = 0;
14257917SReza.Sabdar@Sun.COM 		params->mp_file_history_dir_func =
14267917SReza.Sabdar@Sun.COM 		    ndmpd_api_file_history_dir_v3;
14277917SReza.Sabdar@Sun.COM 		params->mp_file_history_node_func =
14287917SReza.Sabdar@Sun.COM 		    ndmpd_api_file_history_node_v3;
14297917SReza.Sabdar@Sun.COM 	} else if (strcmp(bu_type, NDMP_TAR_TYPE) == 0) {
14307917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_TAR);
14317917SReza.Sabdar@Sun.COM 		params->mp_file_history_path_func =
14327917SReza.Sabdar@Sun.COM 		    ndmpd_api_file_history_file_v3;
14337917SReza.Sabdar@Sun.COM 		params->mp_file_history_dir_func = 0;
14347917SReza.Sabdar@Sun.COM 		params->mp_file_history_node_func = 0;
14357917SReza.Sabdar@Sun.COM 	} else {
14367917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_DUMP);
14377917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_TAR);
14387917SReza.Sabdar@Sun.COM 	}
14397917SReza.Sabdar@Sun.COM 
14407917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_start_func = ndmpd_tar_backup_starter_v3;
14417917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_abort_func = ndmpd_tar_backup_abort_v3;
14427917SReza.Sabdar@Sun.COM 
14437917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0;
14447917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_time_remaining  = 0;
14457917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist_v3 = 0;
14467917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist_len = 0;
14477917SReza.Sabdar@Sun.COM 	session->ns_data.dd_bytes_left_to_read = 0;
14487917SReza.Sabdar@Sun.COM 	session->ns_data.dd_position = 0;
14497917SReza.Sabdar@Sun.COM 	session->ns_data.dd_discard_length = 0;
14507917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = 0;
14517917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = 0;
14527917SReza.Sabdar@Sun.COM 
14537917SReza.Sabdar@Sun.COM 	reply.error = ndmp_backup_get_params_v3(session, params);
14547917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
14557917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "err: %d", err);
14567917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
14577917SReza.Sabdar@Sun.COM 		return (reply.error);
14587917SReza.Sabdar@Sun.COM 	}
14597917SReza.Sabdar@Sun.COM 
14607917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
14617917SReza.Sabdar@Sun.COM 	if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
14627917SReza.Sabdar@Sun.COM 	    &reply) < 0) {
14637917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending data_start_backup_v3 reply");
14647917SReza.Sabdar@Sun.COM 		return (NDMP_NO_ERR);
14657917SReza.Sabdar@Sun.COM 	}
14667917SReza.Sabdar@Sun.COM 
14677917SReza.Sabdar@Sun.COM 	NS_INC(nbk);
14687917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE;
14697917SReza.Sabdar@Sun.COM 	session->ns_data.dd_operation = NDMP_DATA_OP_BACKUP;
14707917SReza.Sabdar@Sun.COM 	session->ns_data.dd_abort = FALSE;
14717917SReza.Sabdar@Sun.COM 
14727917SReza.Sabdar@Sun.COM 	/*
14737917SReza.Sabdar@Sun.COM 	 * perform the backup
14747917SReza.Sabdar@Sun.COM 	 *
1475*12186SJanice.Chang@Sun.COM 	 * Cannot wait for the thread to exit as we are replying to the
14767917SReza.Sabdar@Sun.COM 	 * client request here.
14777917SReza.Sabdar@Sun.COM 	 */
14787917SReza.Sabdar@Sun.COM 	err = pthread_create(NULL, NULL,
14797917SReza.Sabdar@Sun.COM 	    (funct_t)session->ns_data.dd_module.dm_start_func,
14807917SReza.Sabdar@Sun.COM 	    params);
14817917SReza.Sabdar@Sun.COM 	if (err != 0) {
14827917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Can't start backup session.");
14837917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
14847917SReza.Sabdar@Sun.COM 	}
14857917SReza.Sabdar@Sun.COM 
14867917SReza.Sabdar@Sun.COM 	return (NDMP_NO_ERR);
14877917SReza.Sabdar@Sun.COM }
14887917SReza.Sabdar@Sun.COM 
14897917SReza.Sabdar@Sun.COM /*
1490*12186SJanice.Chang@Sun.COM  * ndmpd_tar_start_recover_v3
14917917SReza.Sabdar@Sun.COM  *
14927917SReza.Sabdar@Sun.COM  * Start the restore work
14937917SReza.Sabdar@Sun.COM  *
14947917SReza.Sabdar@Sun.COM  * Parameters:
1495*12186SJanice.Chang@Sun.COM  *   session   (input) - session pointer.
14967917SReza.Sabdar@Sun.COM  *   bu_type   (input) - backup type.
14977917SReza.Sabdar@Sun.COM  *   env_val   (input) - environment variable array.
14987917SReza.Sabdar@Sun.COM  *   env_len   (input) - length of env_val.
1499*12186SJanice.Chang@Sun.COM  *   nlist_val (input) - list of files.
1500*12186SJanice.Chang@Sun.COM  *   nlist_len (input) - length of nlist_val.
15017917SReza.Sabdar@Sun.COM  *
15027917SReza.Sabdar@Sun.COM  * Returns:
15037917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR - recover successfully started.
15047917SReza.Sabdar@Sun.COM  *   otherwise   - error code of recover start error.
15057917SReza.Sabdar@Sun.COM  */
15067917SReza.Sabdar@Sun.COM static ndmp_error
ndmpd_tar_start_recover_v3(ndmpd_session_t * session,ndmp_pval * env_val,ulong_t env_len,ndmp_name_v3 * nlist_val,ulong_t nlist_len)1507*12186SJanice.Chang@Sun.COM ndmpd_tar_start_recover_v3(ndmpd_session_t *session,
1508*12186SJanice.Chang@Sun.COM     ndmp_pval *env_val, ulong_t env_len, ndmp_name_v3 *nlist_val,
1509*12186SJanice.Chang@Sun.COM     ulong_t nlist_len)
15107917SReza.Sabdar@Sun.COM {
15117917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_reply_v3 reply;
15127917SReza.Sabdar@Sun.COM 	ndmpd_module_params_t *params;
15137917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
15147917SReza.Sabdar@Sun.COM 	int err;
15157917SReza.Sabdar@Sun.COM 
15167917SReza.Sabdar@Sun.COM 	(void) memset((void*)&reply, 0, sizeof (reply));
15177917SReza.Sabdar@Sun.COM 
15187917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
15197917SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_params);
15207917SReza.Sabdar@Sun.COM 	params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t));
15217917SReza.Sabdar@Sun.COM 	if (!params) {
15227917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
15237917SReza.Sabdar@Sun.COM 	}
15247917SReza.Sabdar@Sun.COM 
15257917SReza.Sabdar@Sun.COM 	reply.error = ndmpd_save_env(session, env_val, env_len);
15267917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
15277917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
15287917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
15297917SReza.Sabdar@Sun.COM 	}
15307917SReza.Sabdar@Sun.COM 
15317917SReza.Sabdar@Sun.COM 	reply.error = ndmpd_save_nlist_v3(session, nlist_val, nlist_len);
15327917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
15337917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
15347917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
15357917SReza.Sabdar@Sun.COM 	}
15367917SReza.Sabdar@Sun.COM 
15377917SReza.Sabdar@Sun.COM 	/*
15387917SReza.Sabdar@Sun.COM 	 * Setup restore parameters.
15397917SReza.Sabdar@Sun.COM 	 */
15407917SReza.Sabdar@Sun.COM 	params->mp_daemon_cookie = (void *)session;
15417917SReza.Sabdar@Sun.COM 	params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie;
15427917SReza.Sabdar@Sun.COM 	params->mp_protocol_version = session->ns_protocol_version;
15437917SReza.Sabdar@Sun.COM 	params->mp_operation = NDMP_DATA_OP_RECOVER;
15447917SReza.Sabdar@Sun.COM 	params->mp_get_env_func = ndmpd_api_get_env;
15457917SReza.Sabdar@Sun.COM 	params->mp_add_env_func = ndmpd_api_add_env;
15467917SReza.Sabdar@Sun.COM 	params->mp_set_env_func = ndmpd_api_set_env;
15477917SReza.Sabdar@Sun.COM 	params->mp_get_name_func = ndmpd_api_get_name_v3;
15487917SReza.Sabdar@Sun.COM 	params->mp_dispatch_func = ndmpd_api_dispatch;
15497917SReza.Sabdar@Sun.COM 	params->mp_done_func = ndmpd_api_done_v3;
15507917SReza.Sabdar@Sun.COM 	if (session->ns_protocol_version == NDMPV4) {
15517917SReza.Sabdar@Sun.COM 		params->mp_log_func_v3 = ndmpd_api_log_v4;
15527917SReza.Sabdar@Sun.COM 		params->mp_file_recovered_func = ndmpd_api_file_recovered_v4;
15537917SReza.Sabdar@Sun.COM 	} else {
15547917SReza.Sabdar@Sun.COM 		params->mp_log_func_v3 = ndmpd_api_log_v3;
15557917SReza.Sabdar@Sun.COM 		params->mp_file_recovered_func = ndmpd_api_file_recovered_v3;
15567917SReza.Sabdar@Sun.COM 	}
15577917SReza.Sabdar@Sun.COM 
15587917SReza.Sabdar@Sun.COM 	params->mp_add_file_handler_func = ndmpd_api_add_file_handler;
15597917SReza.Sabdar@Sun.COM 	params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler;
15607917SReza.Sabdar@Sun.COM 	params->mp_write_func = 0;
15617917SReza.Sabdar@Sun.COM 	params->mp_file_history_path_func = 0;
15627917SReza.Sabdar@Sun.COM 	params->mp_file_history_dir_func = 0;
15637917SReza.Sabdar@Sun.COM 	params->mp_file_history_node_func = 0;
15647917SReza.Sabdar@Sun.COM 	params->mp_read_func = ndmpd_api_read_v3;
15657917SReza.Sabdar@Sun.COM 	params->mp_seek_func = ndmpd_api_seek_v3;
15667917SReza.Sabdar@Sun.COM 	params->mp_stats = &session->ns_data.dd_module.dm_stats;
15677917SReza.Sabdar@Sun.COM 
15687917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_module_cookie = 0;
15697917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_start_func = ndmpd_tar_restore_starter_v3;
15707917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_abort_func = ndmpd_tar_restore_abort_v3;
15717917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0;
15727917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0;
15737917SReza.Sabdar@Sun.COM 	session->ns_data.dd_bytes_left_to_read = 0;
15747917SReza.Sabdar@Sun.COM 	session->ns_data.dd_position = 0;
15757917SReza.Sabdar@Sun.COM 	session->ns_data.dd_discard_length = 0;
15767917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = 0;
15777917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = 0;
15787917SReza.Sabdar@Sun.COM 
15797917SReza.Sabdar@Sun.COM 	err = ndmp_restore_get_params_v3(session, params);
15807917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
15817917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
15827917SReza.Sabdar@Sun.COM 		return (err);
15837917SReza.Sabdar@Sun.COM 	}
15847917SReza.Sabdar@Sun.COM 
15857917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
15867917SReza.Sabdar@Sun.COM 	if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
15877917SReza.Sabdar@Sun.COM 	    &reply) < 0) {
15887917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
15897917SReza.Sabdar@Sun.COM 		ndmpd_free_nlist_v3(session);
15907917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
15917917SReza.Sabdar@Sun.COM 		    "Error sending ndmp_data_start_recover_reply");
15927917SReza.Sabdar@Sun.COM 		ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR);
15937917SReza.Sabdar@Sun.COM 		return (NDMP_NO_ERR);
15947917SReza.Sabdar@Sun.COM 	}
15957917SReza.Sabdar@Sun.COM 
15967917SReza.Sabdar@Sun.COM 	NS_INC(nrs);
15977917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE;
15987917SReza.Sabdar@Sun.COM 	session->ns_data.dd_operation = NDMP_DATA_OP_RECOVER;
15997917SReza.Sabdar@Sun.COM 	session->ns_data.dd_abort = FALSE;
16007917SReza.Sabdar@Sun.COM 
16017917SReza.Sabdar@Sun.COM 	/*
16027917SReza.Sabdar@Sun.COM 	 * perform the restore
16037917SReza.Sabdar@Sun.COM 	 *
16047917SReza.Sabdar@Sun.COM 	 * Cannot wait for the thread to exit as we are replying to the
16057917SReza.Sabdar@Sun.COM 	 * client request here.
16067917SReza.Sabdar@Sun.COM 	 */
16077917SReza.Sabdar@Sun.COM 	err = pthread_create(NULL, NULL,
16087917SReza.Sabdar@Sun.COM 	    (funct_t)session->ns_data.dd_module.dm_start_func,
16097917SReza.Sabdar@Sun.COM 	    params);
16107917SReza.Sabdar@Sun.COM 
16117917SReza.Sabdar@Sun.COM 	if (err != 0) {
16127917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Can't start recover session.");
16137917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
16147917SReza.Sabdar@Sun.COM 	}
16157917SReza.Sabdar@Sun.COM 	return (NDMP_NO_ERR);
16167917SReza.Sabdar@Sun.COM }
16177917SReza.Sabdar@Sun.COM 
1618*12186SJanice.Chang@Sun.COM static ndmp_error
ndmpd_zfs_start_op(ndmpd_session_t * session,ndmp_pval * env_val,ulong_t env_len,ndmp_name_v3 * nlist_val,ulong_t nlist_len,enum ndmp_data_operation op)1619*12186SJanice.Chang@Sun.COM ndmpd_zfs_start_op(ndmpd_session_t *session, ndmp_pval *env_val,
1620*12186SJanice.Chang@Sun.COM     ulong_t env_len, ndmp_name_v3 *nlist_val, ulong_t nlist_len,
1621*12186SJanice.Chang@Sun.COM     enum ndmp_data_operation op)
1622*12186SJanice.Chang@Sun.COM {
1623*12186SJanice.Chang@Sun.COM 	ndmpd_zfs_args_t *ndmpd_zfs_args = &session->ns_ndmpd_zfs_args;
1624*12186SJanice.Chang@Sun.COM 	ndmp_data_start_backup_reply_v3 backup_reply;
1625*12186SJanice.Chang@Sun.COM 	ndmp_data_start_recover_reply_v3 recover_reply;
1626*12186SJanice.Chang@Sun.COM 	pthread_t tid;
1627*12186SJanice.Chang@Sun.COM 	void *reply;
1628*12186SJanice.Chang@Sun.COM 	char str[8];
1629*12186SJanice.Chang@Sun.COM 	int err;
1630*12186SJanice.Chang@Sun.COM 
1631*12186SJanice.Chang@Sun.COM 	if (ndmpd_zfs_init(session) != 0)
1632*12186SJanice.Chang@Sun.COM 		return (NDMP_UNDEFINED_ERR);
1633*12186SJanice.Chang@Sun.COM 
1634*12186SJanice.Chang@Sun.COM 	err = ndmpd_save_env(session, env_val, env_len);
1635*12186SJanice.Chang@Sun.COM 	if (err != NDMP_NO_ERR) {
1636*12186SJanice.Chang@Sun.COM 		ndmpd_zfs_fini(ndmpd_zfs_args);
1637*12186SJanice.Chang@Sun.COM 		return (err);
1638*12186SJanice.Chang@Sun.COM 	}
1639*12186SJanice.Chang@Sun.COM 
1640*12186SJanice.Chang@Sun.COM 	switch (op) {
1641*12186SJanice.Chang@Sun.COM 	case NDMP_DATA_OP_BACKUP:
1642*12186SJanice.Chang@Sun.COM 		if (!ndmpd_zfs_backup_parms_valid(ndmpd_zfs_args)) {
1643*12186SJanice.Chang@Sun.COM 			ndmpd_zfs_fini(ndmpd_zfs_args);
1644*12186SJanice.Chang@Sun.COM 			return (NDMP_ILLEGAL_ARGS_ERR);
1645*12186SJanice.Chang@Sun.COM 		}
1646*12186SJanice.Chang@Sun.COM 
1647*12186SJanice.Chang@Sun.COM 		if (ndmpd_zfs_pre_backup(ndmpd_zfs_args)) {
1648*12186SJanice.Chang@Sun.COM 			NDMP_LOG(LOG_ERR, "pre_backup error");
1649*12186SJanice.Chang@Sun.COM 			return (NDMP_ILLEGAL_ARGS_ERR);
1650*12186SJanice.Chang@Sun.COM 		}
1651*12186SJanice.Chang@Sun.COM 
1652*12186SJanice.Chang@Sun.COM 		session->ns_data.dd_module.dm_start_func =
1653*12186SJanice.Chang@Sun.COM 		    ndmpd_zfs_backup_starter;
1654*12186SJanice.Chang@Sun.COM 		(void) strlcpy(str, "backup", 8);
1655*12186SJanice.Chang@Sun.COM 		break;
1656*12186SJanice.Chang@Sun.COM 	case NDMP_DATA_OP_RECOVER:
1657*12186SJanice.Chang@Sun.COM 		err = ndmpd_save_nlist_v3(session, nlist_val, nlist_len);
1658*12186SJanice.Chang@Sun.COM 		if (err != NDMP_NO_ERR) {
1659*12186SJanice.Chang@Sun.COM 			ndmpd_zfs_fini(ndmpd_zfs_args);
1660*12186SJanice.Chang@Sun.COM 			return (NDMP_NO_MEM_ERR);
1661*12186SJanice.Chang@Sun.COM 		}
1662*12186SJanice.Chang@Sun.COM 
1663*12186SJanice.Chang@Sun.COM 		if (!ndmpd_zfs_restore_parms_valid(ndmpd_zfs_args)) {
1664*12186SJanice.Chang@Sun.COM 			ndmpd_zfs_fini(ndmpd_zfs_args);
1665*12186SJanice.Chang@Sun.COM 			return (NDMP_ILLEGAL_ARGS_ERR);
1666*12186SJanice.Chang@Sun.COM 		}
1667*12186SJanice.Chang@Sun.COM 
1668*12186SJanice.Chang@Sun.COM 		if (ndmpd_zfs_pre_restore(ndmpd_zfs_args)) {
1669*12186SJanice.Chang@Sun.COM 			NDMP_LOG(LOG_ERR, "pre_restore error");
1670*12186SJanice.Chang@Sun.COM 			(void) ndmpd_zfs_post_restore(ndmpd_zfs_args);
1671*12186SJanice.Chang@Sun.COM 			return (NDMP_ILLEGAL_ARGS_ERR);
1672*12186SJanice.Chang@Sun.COM 		}
1673*12186SJanice.Chang@Sun.COM 		session->ns_data.dd_module.dm_start_func =
1674*12186SJanice.Chang@Sun.COM 		    ndmpd_zfs_restore_starter;
1675*12186SJanice.Chang@Sun.COM 		(void) strlcpy(str, "recover", 8);
1676*12186SJanice.Chang@Sun.COM 		break;
1677*12186SJanice.Chang@Sun.COM 	}
1678*12186SJanice.Chang@Sun.COM 
1679*12186SJanice.Chang@Sun.COM 	ndmpd_zfs_params->mp_operation = op;
1680*12186SJanice.Chang@Sun.COM 	session->ns_data.dd_operation = op;
1681*12186SJanice.Chang@Sun.COM 	session->ns_data.dd_module.dm_abort_func = ndmpd_zfs_abort;
1682*12186SJanice.Chang@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE;
1683*12186SJanice.Chang@Sun.COM 	session->ns_data.dd_abort = FALSE;
1684*12186SJanice.Chang@Sun.COM 
1685*12186SJanice.Chang@Sun.COM 	if (op == NDMP_DATA_OP_BACKUP) {
1686*12186SJanice.Chang@Sun.COM 		(void) memset((void*)&backup_reply, 0, sizeof (backup_reply));
1687*12186SJanice.Chang@Sun.COM 		backup_reply.error = NDMP_NO_ERR;
1688*12186SJanice.Chang@Sun.COM 		reply = &backup_reply;
1689*12186SJanice.Chang@Sun.COM 	} else {
1690*12186SJanice.Chang@Sun.COM 		(void) memset((void*)&recover_reply, 0, sizeof (recover_reply));
1691*12186SJanice.Chang@Sun.COM 		recover_reply.error = NDMP_NO_ERR;
1692*12186SJanice.Chang@Sun.COM 		reply = &recover_reply;
1693*12186SJanice.Chang@Sun.COM 	}
1694*12186SJanice.Chang@Sun.COM 
1695*12186SJanice.Chang@Sun.COM 	if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
1696*12186SJanice.Chang@Sun.COM 	    reply) < 0) {
1697*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending data_start_%s_v3 reply", str);
1698*12186SJanice.Chang@Sun.COM 		if (op == NDMP_DATA_OP_RECOVER)
1699*12186SJanice.Chang@Sun.COM 			ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR);
1700*12186SJanice.Chang@Sun.COM 		ndmpd_zfs_fini(ndmpd_zfs_args);
1701*12186SJanice.Chang@Sun.COM 		return (NDMP_NO_ERR);
1702*12186SJanice.Chang@Sun.COM 	}
1703*12186SJanice.Chang@Sun.COM 
1704*12186SJanice.Chang@Sun.COM 	err = pthread_create(&tid, NULL,
1705*12186SJanice.Chang@Sun.COM 	    (funct_t)session->ns_data.dd_module.dm_start_func, ndmpd_zfs_args);
1706*12186SJanice.Chang@Sun.COM 
1707*12186SJanice.Chang@Sun.COM 	if (err) {
1708*12186SJanice.Chang@Sun.COM 		NDMP_LOG(LOG_ERR, "Can't start %s session (errno %d)",
1709*12186SJanice.Chang@Sun.COM 		    str, err);
1710*12186SJanice.Chang@Sun.COM 		ndmpd_zfs_fini(ndmpd_zfs_args);
1711*12186SJanice.Chang@Sun.COM 		MOD_DONE(ndmpd_zfs_params, -1);
1712*12186SJanice.Chang@Sun.COM 		return (NDMP_NO_ERR);
1713*12186SJanice.Chang@Sun.COM 	}
1714*12186SJanice.Chang@Sun.COM 
1715*12186SJanice.Chang@Sun.COM 	(void) pthread_detach(tid);
1716*12186SJanice.Chang@Sun.COM 
1717*12186SJanice.Chang@Sun.COM 	if (op == NDMP_DATA_OP_BACKUP)
1718*12186SJanice.Chang@Sun.COM 		NS_INC(nbk);
1719*12186SJanice.Chang@Sun.COM 	else
1720*12186SJanice.Chang@Sun.COM 		NS_INC(nrs);
1721*12186SJanice.Chang@Sun.COM 
1722*12186SJanice.Chang@Sun.COM 	ndmpd_zfs_dma_log(ndmpd_zfs_args, NDMP_LOG_NORMAL,
1723*12186SJanice.Chang@Sun.COM 	    "'zfs' %s starting\n", str);
1724*12186SJanice.Chang@Sun.COM 
1725*12186SJanice.Chang@Sun.COM 	return (NDMP_NO_ERR);
1726*12186SJanice.Chang@Sun.COM }
17277917SReza.Sabdar@Sun.COM 
17287917SReza.Sabdar@Sun.COM /*
17297917SReza.Sabdar@Sun.COM  * discard_data_v3
17307917SReza.Sabdar@Sun.COM  *
17317917SReza.Sabdar@Sun.COM  * Read and discard data from the data connection.
17327917SReza.Sabdar@Sun.COM  * Called when a module has called ndmpd_seek() prior to
17337917SReza.Sabdar@Sun.COM  * reading all of the data from the previous seek.
17347917SReza.Sabdar@Sun.COM  *
17357917SReza.Sabdar@Sun.COM  * Parameters:
17367917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
17377917SReza.Sabdar@Sun.COM  *
17387917SReza.Sabdar@Sun.COM  * Returns:
17397917SReza.Sabdar@Sun.COM  *   number of bytes read and discarded.
17407917SReza.Sabdar@Sun.COM  *  -1 - error.
17417917SReza.Sabdar@Sun.COM  */
17427917SReza.Sabdar@Sun.COM static int
discard_data_v3(ndmpd_session_t * session,ulong_t length)17437917SReza.Sabdar@Sun.COM discard_data_v3(ndmpd_session_t *session, ulong_t length)
17447917SReza.Sabdar@Sun.COM {
17457917SReza.Sabdar@Sun.COM 	static char buf[MAX_RECORD_SIZE];
17467917SReza.Sabdar@Sun.COM 	int n, toread;
17477917SReza.Sabdar@Sun.COM 
17487917SReza.Sabdar@Sun.COM 	toread = (length < MAX_RECORD_SIZE) ? length :
17497917SReza.Sabdar@Sun.COM 	    MAX_RECORD_SIZE;
17507917SReza.Sabdar@Sun.COM 
17517917SReza.Sabdar@Sun.COM 	/* Read and discard the data. */
17527917SReza.Sabdar@Sun.COM 	n = read(session->ns_data.dd_sock, buf, toread);
17537917SReza.Sabdar@Sun.COM 	if (n < 0) {
17547917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Socket read error: %m.");
17557917SReza.Sabdar@Sun.COM 		n = -1;
17567917SReza.Sabdar@Sun.COM 	}
17577917SReza.Sabdar@Sun.COM 
17587917SReza.Sabdar@Sun.COM 	return (n);
17597917SReza.Sabdar@Sun.COM }
17607917SReza.Sabdar@Sun.COM 
17617917SReza.Sabdar@Sun.COM 
17627917SReza.Sabdar@Sun.COM /*
17637917SReza.Sabdar@Sun.COM  * ndmpd_remote_read_v3
17647917SReza.Sabdar@Sun.COM  *
17657917SReza.Sabdar@Sun.COM  * Reads data from the remote mover.
17667917SReza.Sabdar@Sun.COM  *
17677917SReza.Sabdar@Sun.COM  * Parameters:
17687917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
17697917SReza.Sabdar@Sun.COM  *   data    (input) - data to be written.
17707917SReza.Sabdar@Sun.COM  *   length  (input) - data length.
17717917SReza.Sabdar@Sun.COM  *
17727917SReza.Sabdar@Sun.COM  * Returns:
17737917SReza.Sabdar@Sun.COM  *   0 - data successfully read.
17747917SReza.Sabdar@Sun.COM  *  -1 - error.
17757917SReza.Sabdar@Sun.COM  */
17767917SReza.Sabdar@Sun.COM int
ndmpd_remote_read_v3(ndmpd_session_t * session,char * data,ulong_t length)17777917SReza.Sabdar@Sun.COM ndmpd_remote_read_v3(ndmpd_session_t *session, char *data, ulong_t length)
17787917SReza.Sabdar@Sun.COM {
17797917SReza.Sabdar@Sun.COM 	ulong_t count;
17807917SReza.Sabdar@Sun.COM 	ulong_t len;
17817917SReza.Sabdar@Sun.COM 	ssize_t n;
17827917SReza.Sabdar@Sun.COM 	ndmp_notify_data_read_request request;
17837917SReza.Sabdar@Sun.COM 	tlm_job_stats_t *jstat;
17847917SReza.Sabdar@Sun.COM 	longlong_t fsize;
17857917SReza.Sabdar@Sun.COM 
17867917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "ns_data.dd_xx: [%llu, %llu, %llu, %llu, %llu]",
17877917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_bytes_left_to_read,
17887917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_read_offset,
17897917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_read_length,
17907917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_position,
17917917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_discard_length);
17927917SReza.Sabdar@Sun.COM 
17937917SReza.Sabdar@Sun.COM 	count = 0;
17947917SReza.Sabdar@Sun.COM 	while (count < length) {
17957917SReza.Sabdar@Sun.COM 		len = length - count;
17967917SReza.Sabdar@Sun.COM 
17977917SReza.Sabdar@Sun.COM 		/*
17987917SReza.Sabdar@Sun.COM 		 * If the end of the seek window has been reached then
17997917SReza.Sabdar@Sun.COM 		 * send an ndmp_read request to the client.
18007917SReza.Sabdar@Sun.COM 		 * The NDMP client will then send a mover_data_read request to
18017917SReza.Sabdar@Sun.COM 		 * the remote mover and the mover will send more data.
18027917SReza.Sabdar@Sun.COM 		 * This condition can occur if the module attempts to read past
18037917SReza.Sabdar@Sun.COM 		 * a seek window set via a prior call to ndmpd_seek() or
18047917SReza.Sabdar@Sun.COM 		 * the module has not issued a seek. If no seek was issued then
18057917SReza.Sabdar@Sun.COM 		 * pretend that a seek was issued to read the entire tape.
18067917SReza.Sabdar@Sun.COM 		 */
18077917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_bytes_left_to_read == 0) {
18087917SReza.Sabdar@Sun.COM 			/* ndmpd_seek() never called? */
18097917SReza.Sabdar@Sun.COM 			if (session->ns_data.dd_read_length == 0) {
18107917SReza.Sabdar@Sun.COM 				session->ns_data.dd_bytes_left_to_read = ~0LL;
18117917SReza.Sabdar@Sun.COM 				session->ns_data.dd_read_offset = 0LL;
18127917SReza.Sabdar@Sun.COM 				session->ns_data.dd_read_length = ~0LL;
18137917SReza.Sabdar@Sun.COM 			} else {
18147917SReza.Sabdar@Sun.COM 				/*
18157917SReza.Sabdar@Sun.COM 				 * While restoring a file, restoreFile()
18167917SReza.Sabdar@Sun.COM 				 * records the number of bytes still need to
18177917SReza.Sabdar@Sun.COM 				 * be restored.  We use this as a guidance
18187917SReza.Sabdar@Sun.COM 				 * when asking for data from the tape.
18197917SReza.Sabdar@Sun.COM 				 */
18207917SReza.Sabdar@Sun.COM 				jstat = session->ns_ndmp_lbr_params->nlp_jstat;
18217917SReza.Sabdar@Sun.COM 				fsize = jstat->js_bytes_in_file;
18227917SReza.Sabdar@Sun.COM 
18237917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG, "bytes_left [%llu / %u]",
18247917SReza.Sabdar@Sun.COM 				    fsize, len);
18257917SReza.Sabdar@Sun.COM 
18267917SReza.Sabdar@Sun.COM 				/*
18277917SReza.Sabdar@Sun.COM 				 * Fall back to the old way if fsize if too
18287917SReza.Sabdar@Sun.COM 				 * small.
18297917SReza.Sabdar@Sun.COM 				 */
18307917SReza.Sabdar@Sun.COM 				if (fsize < len)
18317917SReza.Sabdar@Sun.COM 					fsize = len;
18327917SReza.Sabdar@Sun.COM 
18337917SReza.Sabdar@Sun.COM 				session->ns_data.dd_bytes_left_to_read = fsize;
18347917SReza.Sabdar@Sun.COM 				session->ns_data.dd_read_offset =
18357917SReza.Sabdar@Sun.COM 				    session->ns_data.dd_position;
18367917SReza.Sabdar@Sun.COM 				session->ns_data.dd_read_length = fsize;
18377917SReza.Sabdar@Sun.COM 			}
18387917SReza.Sabdar@Sun.COM 
18397917SReza.Sabdar@Sun.COM 			request.offset =
18407917SReza.Sabdar@Sun.COM 			    long_long_to_quad(session->ns_data.dd_read_offset);
18417917SReza.Sabdar@Sun.COM 			request.length =
18427917SReza.Sabdar@Sun.COM 			    long_long_to_quad(session->ns_data.dd_read_length);
18437917SReza.Sabdar@Sun.COM 
18447917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "to NOTIFY_DATA_READ [%llu, %llu]",
18457917SReza.Sabdar@Sun.COM 			    session->ns_data.dd_read_offset,
18467917SReza.Sabdar@Sun.COM 			    session->ns_data.dd_read_length);
18477917SReza.Sabdar@Sun.COM 
18488193SReza.Sabdar@Sun.COM 			if (ndmp_send_request_lock(session->ns_connection,
18497917SReza.Sabdar@Sun.COM 			    NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
18507917SReza.Sabdar@Sun.COM 			    &request, 0) < 0) {
18517917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
18527917SReza.Sabdar@Sun.COM 				    "Sending notify_data_read request");
18537917SReza.Sabdar@Sun.COM 				return (-1);
18547917SReza.Sabdar@Sun.COM 			}
18557917SReza.Sabdar@Sun.COM 		}
18567917SReza.Sabdar@Sun.COM 
18577917SReza.Sabdar@Sun.COM 		/*
18587917SReza.Sabdar@Sun.COM 		 * If the module called ndmpd_seek() prior to reading all of the
18597917SReza.Sabdar@Sun.COM 		 * data that the remote mover was requested to send, then the
18607917SReza.Sabdar@Sun.COM 		 * excess data from the seek has to be discarded.
18617917SReza.Sabdar@Sun.COM 		 */
18627917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_discard_length != 0) {
18637917SReza.Sabdar@Sun.COM 			n = discard_data_v3(session,
18647917SReza.Sabdar@Sun.COM 			    (ulong_t)session->ns_data.dd_discard_length);
18657917SReza.Sabdar@Sun.COM 			if (n < 0)
18667917SReza.Sabdar@Sun.COM 				return (-1);
18677917SReza.Sabdar@Sun.COM 
18687917SReza.Sabdar@Sun.COM 			session->ns_data.dd_discard_length -= n;
18697917SReza.Sabdar@Sun.COM 			continue;
18707917SReza.Sabdar@Sun.COM 		}
18717917SReza.Sabdar@Sun.COM 
18727917SReza.Sabdar@Sun.COM 		/*
18737917SReza.Sabdar@Sun.COM 		 * Don't attempt to read more data than the remote is sending.
18747917SReza.Sabdar@Sun.COM 		 */
18757917SReza.Sabdar@Sun.COM 		if (len > session->ns_data.dd_bytes_left_to_read)
18767917SReza.Sabdar@Sun.COM 			len = session->ns_data.dd_bytes_left_to_read;
18777917SReza.Sabdar@Sun.COM 
18787917SReza.Sabdar@Sun.COM 		if ((n = read(session->ns_data.dd_sock, &data[count],
18797917SReza.Sabdar@Sun.COM 		    len)) < 0) {
18807917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Socket read error: %m.");
18817917SReza.Sabdar@Sun.COM 			return (-1);
18827917SReza.Sabdar@Sun.COM 		}
18837917SReza.Sabdar@Sun.COM 
18847917SReza.Sabdar@Sun.COM 		/* read returns 0 if the connection was closed */
18857917SReza.Sabdar@Sun.COM 		if (n == 0) {
18867917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "n 0 errno %d",
18877917SReza.Sabdar@Sun.COM 			    errno);
18887917SReza.Sabdar@Sun.COM 			return (-1);
18897917SReza.Sabdar@Sun.COM 		}
18907917SReza.Sabdar@Sun.COM 
18917917SReza.Sabdar@Sun.COM 		count += n;
18927917SReza.Sabdar@Sun.COM 		session->ns_data.dd_bytes_left_to_read -= n;
18937917SReza.Sabdar@Sun.COM 		session->ns_data.dd_position += n;
18947917SReza.Sabdar@Sun.COM 	}
18957917SReza.Sabdar@Sun.COM 	return (0);
18967917SReza.Sabdar@Sun.COM }
18977917SReza.Sabdar@Sun.COM 
18987917SReza.Sabdar@Sun.COM /*
18997917SReza.Sabdar@Sun.COM  * nlp_release_job_stat
19007917SReza.Sabdar@Sun.COM  *
19017917SReza.Sabdar@Sun.COM  * Unreference the job statistics
19027917SReza.Sabdar@Sun.COM  *
19037917SReza.Sabdar@Sun.COM  * Parameters:
19047917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
19057917SReza.Sabdar@Sun.COM  *
19067917SReza.Sabdar@Sun.COM  * Returns:
19077917SReza.Sabdar@Sun.COM  *   void
19087917SReza.Sabdar@Sun.COM  */
19097917SReza.Sabdar@Sun.COM static void
nlp_release_job_stat(ndmpd_session_t * session)19107917SReza.Sabdar@Sun.COM nlp_release_job_stat(ndmpd_session_t *session)
19117917SReza.Sabdar@Sun.COM {
19127917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
19137917SReza.Sabdar@Sun.COM 
19147917SReza.Sabdar@Sun.COM 	if ((nlp = ndmp_get_nlp(session)) == NULL) {
19157917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
19167917SReza.Sabdar@Sun.COM 		return;
19177917SReza.Sabdar@Sun.COM 	}
19187917SReza.Sabdar@Sun.COM 	if (nlp->nlp_jstat != NULL) {
19197917SReza.Sabdar@Sun.COM 		nlp->nlp_bytes_total =
19207917SReza.Sabdar@Sun.COM 		    (u_longlong_t)nlp->nlp_jstat->js_bytes_total;
19217917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(nlp->nlp_jstat->js_job_name);
19227917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat = NULL;
19237917SReza.Sabdar@Sun.COM 	} else
19247917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "JSTAT == NULL");
19257917SReza.Sabdar@Sun.COM }
19267917SReza.Sabdar@Sun.COM 
19277917SReza.Sabdar@Sun.COM 
19287917SReza.Sabdar@Sun.COM /* *** ndmpd global internal functions *********************************** */
19297917SReza.Sabdar@Sun.COM 
19307917SReza.Sabdar@Sun.COM /*
19317917SReza.Sabdar@Sun.COM  * ndmpd_data_init
19327917SReza.Sabdar@Sun.COM  *
19337917SReza.Sabdar@Sun.COM  * Initializes data specific session variables.
19347917SReza.Sabdar@Sun.COM  *
19357917SReza.Sabdar@Sun.COM  * Parameters:
19367917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
19377917SReza.Sabdar@Sun.COM  *
19387917SReza.Sabdar@Sun.COM  * Returns:
19397917SReza.Sabdar@Sun.COM  *   void
19407917SReza.Sabdar@Sun.COM  */
19417917SReza.Sabdar@Sun.COM int
ndmpd_data_init(ndmpd_session_t * session)19427917SReza.Sabdar@Sun.COM ndmpd_data_init(ndmpd_session_t *session)
19437917SReza.Sabdar@Sun.COM {
19447917SReza.Sabdar@Sun.COM 	session->ns_data.dd_operation = NDMP_DATA_OP_NOACTION;
19457917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_IDLE;
19467917SReza.Sabdar@Sun.COM 	session->ns_data.dd_halt_reason = NDMP_DATA_HALT_NA;
19477917SReza.Sabdar@Sun.COM 	session->ns_data.dd_abort = FALSE;
19487917SReza.Sabdar@Sun.COM 	session->ns_data.dd_env = 0;
19497917SReza.Sabdar@Sun.COM 	session->ns_data.dd_env_len = 0;
19507917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist = 0;
19517917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist_len = 0;
19527917SReza.Sabdar@Sun.COM 	session->ns_data.dd_mover.addr_type = NDMP_ADDR_LOCAL;
19537917SReza.Sabdar@Sun.COM 	session->ns_data.dd_sock = -1;
19547917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = 0;
19557917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = 0;
19567917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0;
19577917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0;
19587917SReza.Sabdar@Sun.COM 	/*
19597917SReza.Sabdar@Sun.COM 	 * NDMP V3
19607917SReza.Sabdar@Sun.COM 	 */
19617917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_IDLE;
19627917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist_v3 = 0;
19637917SReza.Sabdar@Sun.COM 	session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL;
19647917SReza.Sabdar@Sun.COM 	session->ns_data.dd_listen_sock = -1;
19657917SReza.Sabdar@Sun.COM 	session->ns_data.dd_bytes_left_to_read = 0LL;
19667917SReza.Sabdar@Sun.COM 	session->ns_data.dd_position = 0LL;
19677917SReza.Sabdar@Sun.COM 	session->ns_data.dd_discard_length = 0LL;
19687917SReza.Sabdar@Sun.COM 	return (0);
19697917SReza.Sabdar@Sun.COM }
19707917SReza.Sabdar@Sun.COM 
19717917SReza.Sabdar@Sun.COM 
19727917SReza.Sabdar@Sun.COM 
19737917SReza.Sabdar@Sun.COM /*
19747917SReza.Sabdar@Sun.COM  * ndmpd_data_cleanup
19757917SReza.Sabdar@Sun.COM  *
19767917SReza.Sabdar@Sun.COM  * Releases resources allocated during a data operation.
19777917SReza.Sabdar@Sun.COM  *
19787917SReza.Sabdar@Sun.COM  * Parameters:
19797917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
19807917SReza.Sabdar@Sun.COM  *
19817917SReza.Sabdar@Sun.COM  * Returns:
19827917SReza.Sabdar@Sun.COM  *   void
19837917SReza.Sabdar@Sun.COM  */
19847917SReza.Sabdar@Sun.COM void
ndmpd_data_cleanup(ndmpd_session_t * session)19857917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(ndmpd_session_t *session)
19867917SReza.Sabdar@Sun.COM {
19877917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_listen_sock != -1) {
19887917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "data.listen_sock: %d",
19897917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_listen_sock);
19907917SReza.Sabdar@Sun.COM 		(void) ndmpd_remove_file_handler(session,
19917917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_listen_sock);
19927917SReza.Sabdar@Sun.COM 		(void) close(session->ns_data.dd_listen_sock);
19937917SReza.Sabdar@Sun.COM 		session->ns_data.dd_listen_sock = -1;
19947917SReza.Sabdar@Sun.COM 	}
19957917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_sock != -1) {
19967917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "data.sock: %d",
19977917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_sock);
19987917SReza.Sabdar@Sun.COM 
19997917SReza.Sabdar@Sun.COM 		/*
20007917SReza.Sabdar@Sun.COM 		 * ndmpcopy: we use the same socket for the mover,
20017917SReza.Sabdar@Sun.COM 		 * so expect to close when mover is done!
20027917SReza.Sabdar@Sun.COM 		 */
20037917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_sock != session->ns_mover.md_sock)
20047917SReza.Sabdar@Sun.COM 			(void) close(session->ns_data.dd_sock);
20057917SReza.Sabdar@Sun.COM 
20067917SReza.Sabdar@Sun.COM 		session->ns_data.dd_sock = -1;
20077917SReza.Sabdar@Sun.COM 	}
20087917SReza.Sabdar@Sun.COM 
20097917SReza.Sabdar@Sun.COM 	ndmpd_free_env(session);
20107917SReza.Sabdar@Sun.COM 	ndmpd_free_nlist(session);
20117917SReza.Sabdar@Sun.COM }
20127917SReza.Sabdar@Sun.COM 
20137917SReza.Sabdar@Sun.COM 
20147917SReza.Sabdar@Sun.COM /*
20157917SReza.Sabdar@Sun.COM  * ndmp_data_get_mover_mode
20167917SReza.Sabdar@Sun.COM  *
20177917SReza.Sabdar@Sun.COM  * Return the mover mode
20187917SReza.Sabdar@Sun.COM  *
20197917SReza.Sabdar@Sun.COM  * Parameters:
20207917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
20217917SReza.Sabdar@Sun.COM  *
20227917SReza.Sabdar@Sun.COM  * Returns:
20237917SReza.Sabdar@Sun.COM  *   remote - remote backup
20247917SReza.Sabdar@Sun.COM  *   local  - local backup
20257917SReza.Sabdar@Sun.COM  */
20267917SReza.Sabdar@Sun.COM char *
ndmp_data_get_mover_mode(ndmpd_session_t * session)20277917SReza.Sabdar@Sun.COM ndmp_data_get_mover_mode(ndmpd_session_t *session)
20287917SReza.Sabdar@Sun.COM {
20297917SReza.Sabdar@Sun.COM 	char *rv;
20307917SReza.Sabdar@Sun.COM 
20317917SReza.Sabdar@Sun.COM 	switch (session->ns_protocol_version) {
20327917SReza.Sabdar@Sun.COM 	case NDMPV2:
20337917SReza.Sabdar@Sun.COM 		rv = ((session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
20347917SReza.Sabdar@Sun.COM 		    ? "remote" : "local");
20357917SReza.Sabdar@Sun.COM 		break;
20367917SReza.Sabdar@Sun.COM 	case NDMPV3:
20377917SReza.Sabdar@Sun.COM 		rv = ((session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP)
20387917SReza.Sabdar@Sun.COM 		    ? "remote" : "local");
20397917SReza.Sabdar@Sun.COM 		break;
20407917SReza.Sabdar@Sun.COM 	case NDMPV4:
20417917SReza.Sabdar@Sun.COM 		rv = ((session->ns_data.dd_data_addr.addr_type ==
20427917SReza.Sabdar@Sun.COM 		    NDMP_ADDR_TCP ||
20437917SReza.Sabdar@Sun.COM 		    (session->ns_data.dd_data_addr_v4.addr_type ==
20447917SReza.Sabdar@Sun.COM 		    NDMP_ADDR_TCP)) ? "remote" : "local");
20457917SReza.Sabdar@Sun.COM 		break;
20467917SReza.Sabdar@Sun.COM 	default:
2047*12186SJanice.Chang@Sun.COM 		rv = "Unknown";
20487917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid protocol version %d.",
20497917SReza.Sabdar@Sun.COM 		    session->ns_protocol_version);
20507917SReza.Sabdar@Sun.COM 	}
20517917SReza.Sabdar@Sun.COM 
20527917SReza.Sabdar@Sun.COM 	return (rv);
20537917SReza.Sabdar@Sun.COM }
20547917SReza.Sabdar@Sun.COM 
20557917SReza.Sabdar@Sun.COM /* *** static functions ******************************************** */
20567917SReza.Sabdar@Sun.COM 
20577917SReza.Sabdar@Sun.COM /*
2058*12186SJanice.Chang@Sun.COM  * ndmpd_tar_start_backup_v2
20597917SReza.Sabdar@Sun.COM  *
20607917SReza.Sabdar@Sun.COM  * Request handling code common to version 1 and
20617917SReza.Sabdar@Sun.COM  * version 2 data_start_backup request handlers.
20627917SReza.Sabdar@Sun.COM  *
20637917SReza.Sabdar@Sun.COM  * Parameters:
20647917SReza.Sabdar@Sun.COM  *   session   (input) - session pointer.
20657917SReza.Sabdar@Sun.COM  *   bu_type   (input) - backup type.
20667917SReza.Sabdar@Sun.COM  *   env_val   (input) - environment variable array.
20677917SReza.Sabdar@Sun.COM  *   env_len   (input) - length of env_val.
20687917SReza.Sabdar@Sun.COM  *
20697917SReza.Sabdar@Sun.COM  * Returns:
20707917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR - backup successfully started.
20717917SReza.Sabdar@Sun.COM  *   otherwise - error code of backup start error.
20727917SReza.Sabdar@Sun.COM  */
20737917SReza.Sabdar@Sun.COM static ndmp_error
ndmpd_tar_start_backup_v2(ndmpd_session_t * session,char * bu_type,ndmp_pval * env_val,ulong_t env_len)2074*12186SJanice.Chang@Sun.COM ndmpd_tar_start_backup_v2(ndmpd_session_t *session, char *bu_type,
2075*12186SJanice.Chang@Sun.COM     ndmp_pval *env_val, ulong_t env_len)
20767917SReza.Sabdar@Sun.COM {
20777917SReza.Sabdar@Sun.COM 	ndmp_data_start_backup_reply reply;
20787917SReza.Sabdar@Sun.COM 	ndmpd_module_params_t *params;
20797917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
20807917SReza.Sabdar@Sun.COM 	int err;
20817917SReza.Sabdar@Sun.COM 
20827917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
20837917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Can't start new backup in current state.");
20847917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_STATE_ERR);
20857917SReza.Sabdar@Sun.COM 	}
20867917SReza.Sabdar@Sun.COM 	if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 &&
20877917SReza.Sabdar@Sun.COM 	    strcmp(bu_type, NDMP_TAR_TYPE) != 0) {
20887917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type);
20897917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump.");
20907917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
20917917SReza.Sabdar@Sun.COM 	}
20927917SReza.Sabdar@Sun.COM 	if ((err = ndmpd_save_env(session, env_val, env_len)) != NDMP_NO_ERR)
20937917SReza.Sabdar@Sun.COM 		return (err);
20947917SReza.Sabdar@Sun.COM 
20957917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
20967917SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_params);
20977917SReza.Sabdar@Sun.COM 	params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t));
20987917SReza.Sabdar@Sun.COM 	if (params == NULL)
20997917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
21007917SReza.Sabdar@Sun.COM 
21017917SReza.Sabdar@Sun.COM 	params->mp_daemon_cookie = (void *)session;
21027917SReza.Sabdar@Sun.COM 	params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie;
21037917SReza.Sabdar@Sun.COM 	params->mp_protocol_version = session->ns_protocol_version;
21047917SReza.Sabdar@Sun.COM 	params->mp_operation = NDMP_DATA_OP_BACKUP;
21057917SReza.Sabdar@Sun.COM 	params->mp_get_env_func = ndmpd_api_get_env;
21067917SReza.Sabdar@Sun.COM 	params->mp_add_env_func = ndmpd_api_add_env;
21077917SReza.Sabdar@Sun.COM 	params->mp_get_name_func = ndmpd_api_get_name;
21087917SReza.Sabdar@Sun.COM 	params->mp_dispatch_func = ndmpd_api_dispatch;
21097917SReza.Sabdar@Sun.COM 	params->mp_done_func = ndmpd_api_done_v2;
21107917SReza.Sabdar@Sun.COM 	params->mp_log_func = ndmpd_api_log_v2;
21117917SReza.Sabdar@Sun.COM 	params->mp_add_file_handler_func = ndmpd_api_add_file_handler;
21127917SReza.Sabdar@Sun.COM 	params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler;
21137917SReza.Sabdar@Sun.COM 	params->mp_write_func = ndmpd_api_write_v2;
21147917SReza.Sabdar@Sun.COM 	params->mp_read_func = 0;
21157917SReza.Sabdar@Sun.COM 	params->mp_file_recovered_func = 0;
21167917SReza.Sabdar@Sun.COM 	params->mp_stats = &session->ns_data.dd_module.dm_stats;
21177917SReza.Sabdar@Sun.COM 
21187917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_module_cookie = 0;
21197917SReza.Sabdar@Sun.COM 	if (strcmp(bu_type, NDMP_DUMP_TYPE) == 0) {
21207917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_DUMP);
21217917SReza.Sabdar@Sun.COM 		params->mp_file_history_path_func = 0;
21227917SReza.Sabdar@Sun.COM 		params->mp_file_history_dir_func =
21237917SReza.Sabdar@Sun.COM 		    ndmpd_api_file_history_dir_v2;
21247917SReza.Sabdar@Sun.COM 		params->mp_file_history_node_func =
21257917SReza.Sabdar@Sun.COM 		    ndmpd_api_file_history_node_v2;
21267917SReza.Sabdar@Sun.COM 	} else if (strcmp(bu_type, NDMP_TAR_TYPE) == 0) {
21277917SReza.Sabdar@Sun.COM 		/* backup type == NDMP_TAR_TYPE */
21287917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_TAR);
21297917SReza.Sabdar@Sun.COM 		params->mp_file_history_path_func =
21307917SReza.Sabdar@Sun.COM 		    ndmpd_api_file_history_path_v2;
21317917SReza.Sabdar@Sun.COM 		params->mp_file_history_dir_func = 0;
21327917SReza.Sabdar@Sun.COM 		params->mp_file_history_node_func = 0;
21337917SReza.Sabdar@Sun.COM 	} else {
21347917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_DUMP);
21357917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_TAR);
21367917SReza.Sabdar@Sun.COM 	}
21377917SReza.Sabdar@Sun.COM 
21387917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_start_func = ndmpd_tar_backup_starter;
21397917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_abort_func = ndmpd_tar_backup_abort;
21407917SReza.Sabdar@Sun.COM 
21417917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0;
21427917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0;
21437917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist = 0;
21447917SReza.Sabdar@Sun.COM 	session->ns_data.dd_nlist_len = 0;
21457917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = 0;
21467917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = 0;
21477917SReza.Sabdar@Sun.COM 
21487917SReza.Sabdar@Sun.COM 	if ((err = ndmp_backup_extract_params(session,
21497917SReza.Sabdar@Sun.COM 	    params)) != NDMP_NO_ERR) {
21507917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "err: %d", err);
21517917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
21527917SReza.Sabdar@Sun.COM 		return (err);
21537917SReza.Sabdar@Sun.COM 	}
21547917SReza.Sabdar@Sun.COM 
21557917SReza.Sabdar@Sun.COM 	err = ndmpd_mover_connect(session, NDMP_MOVER_MODE_READ);
21567917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
21577917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
21587917SReza.Sabdar@Sun.COM 		    "mover connect err: %d", err);
21597917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
21607917SReza.Sabdar@Sun.COM 		return (err);
21617917SReza.Sabdar@Sun.COM 	}
21627917SReza.Sabdar@Sun.COM 
21637917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE;
21647917SReza.Sabdar@Sun.COM 
21657917SReza.Sabdar@Sun.COM 	session->ns_data.dd_operation = NDMP_DATA_OP_BACKUP;
21667917SReza.Sabdar@Sun.COM 	session->ns_data.dd_abort = FALSE;
21677917SReza.Sabdar@Sun.COM 
21687917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "starting backup");
21697917SReza.Sabdar@Sun.COM 
21707917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
21717917SReza.Sabdar@Sun.COM 	if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
21727917SReza.Sabdar@Sun.COM 	    &reply) < 0) {
21737917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending data_start_backup reply");
21747917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
21757917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
21767917SReza.Sabdar@Sun.COM 			/*
21777917SReza.Sabdar@Sun.COM 			 * ndmpcopy: we use the same socket for the mover,
21787917SReza.Sabdar@Sun.COM 			 * so expect to close when mover is done!
21797917SReza.Sabdar@Sun.COM 			 */
21807917SReza.Sabdar@Sun.COM 			if (session->ns_data.dd_sock !=
21817917SReza.Sabdar@Sun.COM 			    session->ns_mover.md_sock)
21827917SReza.Sabdar@Sun.COM 				(void) close(session->ns_data.dd_sock);
21837917SReza.Sabdar@Sun.COM 
21847917SReza.Sabdar@Sun.COM 			session->ns_data.dd_sock = -1;
21857917SReza.Sabdar@Sun.COM 		} else
21867917SReza.Sabdar@Sun.COM 			ndmpd_mover_error(session,
21877917SReza.Sabdar@Sun.COM 			    NDMP_MOVER_HALT_CONNECT_CLOSED);
21887917SReza.Sabdar@Sun.COM 		return (NDMP_NO_ERR);
21897917SReza.Sabdar@Sun.COM 	}
21907917SReza.Sabdar@Sun.COM 
21917917SReza.Sabdar@Sun.COM 	/*
21927917SReza.Sabdar@Sun.COM 	 * perform the backup
21937917SReza.Sabdar@Sun.COM 	 *
21947917SReza.Sabdar@Sun.COM 	 * Cannot wait for the thread to exit as we are replying to the
21957917SReza.Sabdar@Sun.COM 	 * client request here.
21967917SReza.Sabdar@Sun.COM 	 */
21977917SReza.Sabdar@Sun.COM 	(void) pthread_create(NULL, NULL,
21987917SReza.Sabdar@Sun.COM 	    (funct_t)session->ns_data.dd_module.dm_start_func,
21997917SReza.Sabdar@Sun.COM 	    params);
22007917SReza.Sabdar@Sun.COM 
22017917SReza.Sabdar@Sun.COM 	return (NDMP_NO_ERR);
22027917SReza.Sabdar@Sun.COM }
22037917SReza.Sabdar@Sun.COM 
22047917SReza.Sabdar@Sun.COM /*
2205*12186SJanice.Chang@Sun.COM  * ndmpd_tar_start_recover_v2
22067917SReza.Sabdar@Sun.COM  *
22077917SReza.Sabdar@Sun.COM  * The main recover/restore function
22087917SReza.Sabdar@Sun.COM  *
22097917SReza.Sabdar@Sun.COM  * Parameters:
22107917SReza.Sabdar@Sun.COM  *   session   (input) - session pointer.
22117917SReza.Sabdar@Sun.COM  *   bu_type   (input) - backup type.
22127917SReza.Sabdar@Sun.COM  *   env_val   (input) - environment variable array.
22137917SReza.Sabdar@Sun.COM  *   env_len   (input) - length of env_val.
2214*12186SJanice.Chang@Sun.COM  *   nlist_val (input) - list of files.
2215*12186SJanice.Chang@Sun.COM  *   nlist_len (input) - length of nlist_val.
22167917SReza.Sabdar@Sun.COM  *
22177917SReza.Sabdar@Sun.COM  * Returns:
22187917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR - recover successfully started.
22197917SReza.Sabdar@Sun.COM  *   otherwise - error code of backup start error.
22207917SReza.Sabdar@Sun.COM  */
22217917SReza.Sabdar@Sun.COM static ndmp_error
ndmpd_tar_start_recover_v2(ndmpd_session_t * session,char * bu_type,ndmp_pval * env_val,ulong_t env_len,ndmp_name * nlist_val,ulong_t nlist_len)2222*12186SJanice.Chang@Sun.COM ndmpd_tar_start_recover_v2(ndmpd_session_t *session, char *bu_type,
2223*12186SJanice.Chang@Sun.COM     ndmp_pval *env_val, ulong_t env_len, ndmp_name *nlist_val,
2224*12186SJanice.Chang@Sun.COM     ulong_t nlist_len)
22257917SReza.Sabdar@Sun.COM {
22267917SReza.Sabdar@Sun.COM 	ndmp_data_start_recover_reply_v2 reply;
22277917SReza.Sabdar@Sun.COM 	ndmpd_module_params_t *params;
22287917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
22297917SReza.Sabdar@Sun.COM 	int err;
22307917SReza.Sabdar@Sun.COM 
22317917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
22327917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Can't start new recover in current state.");
22337917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_STATE_ERR);
22347917SReza.Sabdar@Sun.COM 	}
22357917SReza.Sabdar@Sun.COM 
22367917SReza.Sabdar@Sun.COM 	if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 &&
22377917SReza.Sabdar@Sun.COM 	    strcmp(bu_type, NDMP_TAR_TYPE) != 0) {
22387917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type);
22397917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump.");
22407917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
22417917SReza.Sabdar@Sun.COM 	}
22427917SReza.Sabdar@Sun.COM 
22437917SReza.Sabdar@Sun.COM 	reply.error = ndmpd_save_env(session, env_val, env_len);
22447917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR)
22457917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
22467917SReza.Sabdar@Sun.COM 
22477917SReza.Sabdar@Sun.COM 	reply.error = ndmpd_save_nlist_v2(session, nlist_val, nlist_len);
22487917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR)
22497917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
22507917SReza.Sabdar@Sun.COM 
22517917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
22527917SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_params);
22537917SReza.Sabdar@Sun.COM 	params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t));
22547917SReza.Sabdar@Sun.COM 	if (params == NULL)
22557917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
22567917SReza.Sabdar@Sun.COM 
22577917SReza.Sabdar@Sun.COM 	/*
22587917SReza.Sabdar@Sun.COM 	 * Setup restore parameters.
22597917SReza.Sabdar@Sun.COM 	 */
22607917SReza.Sabdar@Sun.COM 	params->mp_daemon_cookie = (void *)session;
22617917SReza.Sabdar@Sun.COM 	params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie;
22627917SReza.Sabdar@Sun.COM 	params->mp_protocol_version = session->ns_protocol_version;
22637917SReza.Sabdar@Sun.COM 	params->mp_operation = NDMP_DATA_OP_RECOVER;
22647917SReza.Sabdar@Sun.COM 	params->mp_get_env_func = ndmpd_api_get_env;
22657917SReza.Sabdar@Sun.COM 	params->mp_add_env_func = ndmpd_api_add_env;
22667917SReza.Sabdar@Sun.COM 	params->mp_get_name_func = ndmpd_api_get_name;
22677917SReza.Sabdar@Sun.COM 	params->mp_dispatch_func = ndmpd_api_dispatch;
22687917SReza.Sabdar@Sun.COM 	params->mp_done_func = ndmpd_api_done_v2;
22697917SReza.Sabdar@Sun.COM 	params->mp_log_func = ndmpd_api_log_v2;
22707917SReza.Sabdar@Sun.COM 	params->mp_add_file_handler_func = ndmpd_api_add_file_handler;
22717917SReza.Sabdar@Sun.COM 	params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler;
22727917SReza.Sabdar@Sun.COM 	params->mp_write_func = 0;
22737917SReza.Sabdar@Sun.COM 	params->mp_file_history_path_func = 0;
22747917SReza.Sabdar@Sun.COM 	params->mp_file_history_dir_func = 0;
22757917SReza.Sabdar@Sun.COM 	params->mp_file_history_node_func = 0;
22767917SReza.Sabdar@Sun.COM 	params->mp_read_func = ndmpd_api_read_v2;
22777917SReza.Sabdar@Sun.COM 	params->mp_seek_func = ndmpd_api_seek_v2;
22787917SReza.Sabdar@Sun.COM 	params->mp_file_recovered_func = ndmpd_api_file_recovered_v2;
22797917SReza.Sabdar@Sun.COM 	params->mp_stats = &session->ns_data.dd_module.dm_stats;
22807917SReza.Sabdar@Sun.COM 
22817917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_module_cookie = 0;
22827917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_start_func = ndmpd_tar_restore_starter;
22837917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_abort_func = ndmpd_tar_restore_abort;
22847917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0;
22857917SReza.Sabdar@Sun.COM 	session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0;
22867917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = 0;
22877917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = 0;
22887917SReza.Sabdar@Sun.COM 
22897917SReza.Sabdar@Sun.COM 	if ((err = ndmp_restore_extract_params(session,
22907917SReza.Sabdar@Sun.COM 	    params)) != NDMP_NO_ERR) {
22917917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
22927917SReza.Sabdar@Sun.COM 		return (err);
22937917SReza.Sabdar@Sun.COM 	}
22947917SReza.Sabdar@Sun.COM 
22957917SReza.Sabdar@Sun.COM 	err = ndmpd_mover_connect(session, NDMP_MOVER_MODE_WRITE);
22967917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
22977917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
22987917SReza.Sabdar@Sun.COM 		return (err);
22997917SReza.Sabdar@Sun.COM 	}
23007917SReza.Sabdar@Sun.COM 
23017917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE;
23027917SReza.Sabdar@Sun.COM 	session->ns_data.dd_operation = NDMP_DATA_OP_RECOVER;
23037917SReza.Sabdar@Sun.COM 	session->ns_data.dd_abort = FALSE;
23047917SReza.Sabdar@Sun.COM 
23057917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
23067917SReza.Sabdar@Sun.COM 	if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
23077917SReza.Sabdar@Sun.COM 	    &reply) < 0) {
23087917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending data_start_recover reply");
23097917SReza.Sabdar@Sun.COM 		NDMP_FREE(nlp->nlp_params);
23107917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
23117917SReza.Sabdar@Sun.COM 			/*
23127917SReza.Sabdar@Sun.COM 			 * ndmpcopy: we use the same socket for the mover,
23137917SReza.Sabdar@Sun.COM 			 * so expect to close when mover is done!
23147917SReza.Sabdar@Sun.COM 			 */
23157917SReza.Sabdar@Sun.COM 			if (session->ns_data.dd_sock !=
23167917SReza.Sabdar@Sun.COM 			    session->ns_mover.md_sock)
23177917SReza.Sabdar@Sun.COM 				(void) close(session->ns_data.dd_sock);
23187917SReza.Sabdar@Sun.COM 
23197917SReza.Sabdar@Sun.COM 			session->ns_data.dd_sock = -1;
23207917SReza.Sabdar@Sun.COM 		} else {
23217917SReza.Sabdar@Sun.COM 			ndmpd_mover_error(session,
23227917SReza.Sabdar@Sun.COM 			    NDMP_MOVER_HALT_CONNECT_CLOSED);
23237917SReza.Sabdar@Sun.COM 		}
23247917SReza.Sabdar@Sun.COM 		return (NDMP_NO_ERR);
23257917SReza.Sabdar@Sun.COM 	}
23267917SReza.Sabdar@Sun.COM 
23277917SReza.Sabdar@Sun.COM 
23287917SReza.Sabdar@Sun.COM 	/*
23297917SReza.Sabdar@Sun.COM 	 * perform the restore
23307917SReza.Sabdar@Sun.COM 	 *
2331*12186SJanice.Chang@Sun.COM 	 * Cannot wait for the thread to exit as we are replying to the
23327917SReza.Sabdar@Sun.COM 	 * client request here.
23337917SReza.Sabdar@Sun.COM 	 */
23347917SReza.Sabdar@Sun.COM 	(void) pthread_create(NULL, NULL,
23357917SReza.Sabdar@Sun.COM 	    (funct_t)session->ns_data.dd_module.dm_start_func,
23367917SReza.Sabdar@Sun.COM 	    params);
23377917SReza.Sabdar@Sun.COM 
23387917SReza.Sabdar@Sun.COM 	return (NDMP_NO_ERR);
23397917SReza.Sabdar@Sun.COM }
23407917SReza.Sabdar@Sun.COM 
23417917SReza.Sabdar@Sun.COM /*
23427917SReza.Sabdar@Sun.COM  * ndmpd_data_get_info
23437917SReza.Sabdar@Sun.COM  *
23447917SReza.Sabdar@Sun.COM  * Return the total number of bytes processed
23457917SReza.Sabdar@Sun.COM  *
23467917SReza.Sabdar@Sun.COM  * Parameters:
23477917SReza.Sabdar@Sun.COM  *   session   (input) - session pointer.
23487917SReza.Sabdar@Sun.COM  *
23497917SReza.Sabdar@Sun.COM  * Returns:
23507917SReza.Sabdar@Sun.COM  *   the number of bytes processed
23517917SReza.Sabdar@Sun.COM  */
23527917SReza.Sabdar@Sun.COM static u_longlong_t
ndmpd_data_get_info(ndmpd_session_t * session)23537917SReza.Sabdar@Sun.COM ndmpd_data_get_info(ndmpd_session_t *session)
23547917SReza.Sabdar@Sun.COM {
23557917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
23567917SReza.Sabdar@Sun.COM 
23577917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
23587917SReza.Sabdar@Sun.COM 	if (nlp == NULL)
23597917SReza.Sabdar@Sun.COM 		return ((u_longlong_t)0);
23607917SReza.Sabdar@Sun.COM 
23617917SReza.Sabdar@Sun.COM 	if (nlp->nlp_jstat == NULL)
23627917SReza.Sabdar@Sun.COM 		return (nlp->nlp_bytes_total);
23637917SReza.Sabdar@Sun.COM 
23647917SReza.Sabdar@Sun.COM 	return ((u_longlong_t)nlp->nlp_jstat->js_bytes_total);
23657917SReza.Sabdar@Sun.COM }
2366