12654012fSReza Sabdar /* 28c4f9701SJanice Chang * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 3*97f7c475SJan Kryl * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 42654012fSReza Sabdar */ 52654012fSReza Sabdar 62654012fSReza Sabdar /* 72654012fSReza Sabdar * BSD 3 Clause License 82654012fSReza Sabdar * 92654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 102654012fSReza Sabdar * 112654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 122654012fSReza Sabdar * modification, are permitted provided that the following conditions 132654012fSReza Sabdar * are met: 142654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 152654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 162654012fSReza Sabdar * 172654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 182654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 192654012fSReza Sabdar * the documentation and/or other materials provided with the 202654012fSReza Sabdar * distribution. 212654012fSReza Sabdar * 222654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 232654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 242654012fSReza Sabdar * products derived from this software without specific prior written 252654012fSReza Sabdar * permission. 262654012fSReza Sabdar * 272654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 282654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 292654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 302654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 312654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 322654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 332654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 342654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 352654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 362654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 372654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 382654012fSReza Sabdar */ 392654012fSReza Sabdar /* Copyright (c) 2007, The Storage Networking Industry Association. */ 402654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */ 412654012fSReza Sabdar #include <sys/types.h> 422654012fSReza Sabdar #include <sys/param.h> 432654012fSReza Sabdar #include <sys/socket.h> 442654012fSReza Sabdar #include <netinet/in.h> 452654012fSReza Sabdar #include <errno.h> 462654012fSReza Sabdar #include <arpa/inet.h> 472654012fSReza Sabdar #include <stdlib.h> 482654012fSReza Sabdar #include <string.h> 492654012fSReza Sabdar #include "ndmpd_common.h" 502654012fSReza Sabdar #include "ndmpd.h" 512654012fSReza Sabdar 522654012fSReza Sabdar static int ndmpd_data_error_send_v4(ndmpd_session_t *session, 532654012fSReza Sabdar ndmp_data_halt_reason reason); 542654012fSReza Sabdar static int ndmpd_data_error_send(ndmpd_session_t *session, 552654012fSReza Sabdar ndmp_data_halt_reason reason); 562654012fSReza Sabdar static void data_accept_connection_v3(void *cookie, int fd, ulong_t mode); 572654012fSReza Sabdar static int create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, 582654012fSReza Sabdar ushort_t *port); 592654012fSReza Sabdar static ndmp_error data_connect_sock_v3(ndmpd_session_t *session, ulong_t addr, 602654012fSReza Sabdar ushort_t port); 612654012fSReza Sabdar static int discard_data_v3(ndmpd_session_t *session, ulong_t length); 622654012fSReza Sabdar static void nlp_release_job_stat(ndmpd_session_t *session); 632654012fSReza Sabdar static u_longlong_t ndmpd_data_get_info(ndmpd_session_t *session); 648c4f9701SJanice Chang 658c4f9701SJanice Chang static ndmp_error ndmpd_tar_start_backup_v2(ndmpd_session_t *, char *, 668c4f9701SJanice Chang ndmp_pval *, ulong_t); 678c4f9701SJanice Chang static ndmp_error ndmpd_tar_start_recover_v2(ndmpd_session_t *, char *, 688c4f9701SJanice Chang ndmp_pval *, ulong_t, ndmp_name *, ulong_t); 698c4f9701SJanice Chang static ndmp_error ndmpd_tar_start_backup_v3(ndmpd_session_t *, char *, 708c4f9701SJanice Chang ndmp_pval *, ulong_t); 718c4f9701SJanice Chang static ndmp_error ndmpd_tar_start_recover_v3(ndmpd_session_t *, 728c4f9701SJanice Chang ndmp_pval *, ulong_t, ndmp_name_v3 *, ulong_t); 738c4f9701SJanice Chang 748c4f9701SJanice Chang static ndmp_error ndmpd_zfs_start_op(ndmpd_session_t *, 758c4f9701SJanice Chang ndmp_pval *, ulong_t, ndmp_name_v3 *, ulong_t, enum ndmp_data_operation); 762654012fSReza Sabdar 772654012fSReza Sabdar 782654012fSReza Sabdar /* 792654012fSReza Sabdar * ************************************************************************ 802654012fSReza Sabdar * NDMP V2 HANDLERS 812654012fSReza Sabdar * ************************************************************************ 822654012fSReza Sabdar */ 832654012fSReza Sabdar 842654012fSReza Sabdar /* 852654012fSReza Sabdar * ndmpd_data_get_state_v2 862654012fSReza Sabdar * 872654012fSReza Sabdar * Request handler. Returns current data state. 882654012fSReza Sabdar * 892654012fSReza Sabdar * Parameters: 902654012fSReza Sabdar * connection (input) - connection handle. 912654012fSReza Sabdar * body (input) - request message body. 922654012fSReza Sabdar * 932654012fSReza Sabdar * Returns: 942654012fSReza Sabdar * void 952654012fSReza Sabdar */ 962654012fSReza Sabdar /*ARGSUSED*/ 972654012fSReza Sabdar void 982654012fSReza Sabdar ndmpd_data_get_state_v2(ndmp_connection_t *connection, void *body) 992654012fSReza Sabdar { 1002654012fSReza Sabdar ndmp_data_get_state_reply_v2 reply; 1012654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 1022654012fSReza Sabdar 1032654012fSReza Sabdar reply.error = NDMP_NO_ERR; 1042654012fSReza Sabdar reply.operation = session->ns_data.dd_operation; 1052654012fSReza Sabdar reply.state = session->ns_data.dd_state; 1062654012fSReza Sabdar reply.halt_reason = session->ns_data.dd_halt_reason; 1072654012fSReza Sabdar 1082654012fSReza Sabdar reply.est_time_remain = 1092654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_time_remaining; 1102654012fSReza Sabdar reply.est_bytes_remain = 1112654012fSReza Sabdar long_long_to_quad( 1122654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining); 1132654012fSReza Sabdar 1142654012fSReza Sabdar reply.bytes_processed = 1152654012fSReza Sabdar long_long_to_quad(ndmpd_data_get_info(session)); 1162654012fSReza Sabdar 1172654012fSReza Sabdar reply.mover = session->ns_data.dd_mover; 1182654012fSReza Sabdar reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset); 1192654012fSReza Sabdar reply.read_length = long_long_to_quad(session->ns_data.dd_read_length); 1202654012fSReza Sabdar 1212654012fSReza Sabdar ndmp_send_reply(connection, &reply, 1222654012fSReza Sabdar "sending data_get_state reply"); 1232654012fSReza Sabdar } 1242654012fSReza Sabdar 1252654012fSReza Sabdar 1262654012fSReza Sabdar /* 1272654012fSReza Sabdar * ndmpd_data_start_backup_v2 1282654012fSReza Sabdar * 1292654012fSReza Sabdar * Request handler. Starts a backup. 1302654012fSReza Sabdar * 1312654012fSReza Sabdar * Parameters: 1322654012fSReza Sabdar * connection (input) - connection handle. 1332654012fSReza Sabdar * body (input) - request message body. 1342654012fSReza Sabdar * 1352654012fSReza Sabdar * Returns: 1362654012fSReza Sabdar * void 1372654012fSReza Sabdar */ 1382654012fSReza Sabdar void 1392654012fSReza Sabdar ndmpd_data_start_backup_v2(ndmp_connection_t *connection, void *body) 1402654012fSReza Sabdar { 1412654012fSReza Sabdar ndmp_data_start_backup_request_v2 *request; 1422654012fSReza Sabdar ndmp_data_start_backup_reply_v2 reply; 1432654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 1442654012fSReza Sabdar ndmp_error err; 1452654012fSReza Sabdar 1462654012fSReza Sabdar request = (ndmp_data_start_backup_request_v2 *)body; 1472654012fSReza Sabdar 1482654012fSReza Sabdar reply.error = NDMP_NO_ERR; 1492654012fSReza Sabdar session->ns_data.dd_mover = request->mover; 1502654012fSReza Sabdar 1518c4f9701SJanice Chang err = ndmpd_tar_start_backup_v2(session, request->bu_type, 1528c4f9701SJanice Chang request->env.env_val, request->env.env_len); 1532654012fSReza Sabdar 1542654012fSReza Sabdar /* 1552654012fSReza Sabdar * start_backup sends the reply if the backup is successfully started. 1562654012fSReza Sabdar * Otherwise, send the reply containing the error here. 1572654012fSReza Sabdar */ 1582654012fSReza Sabdar if (err != NDMP_NO_ERR) { 1592654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "err: %d", err); 1602654012fSReza Sabdar reply.error = err; 1612654012fSReza Sabdar ndmp_send_reply(connection, &reply, 1622654012fSReza Sabdar "sending data_start_backup reply"); 1632654012fSReza Sabdar ndmpd_data_cleanup(session); 1642654012fSReza Sabdar } 1652654012fSReza Sabdar } 1662654012fSReza Sabdar 1672654012fSReza Sabdar /* 1682654012fSReza Sabdar * ndmpd_data_start_recover_v2 1692654012fSReza Sabdar * 1702654012fSReza Sabdar * Request handler. Starts a restore. 1712654012fSReza Sabdar * 1722654012fSReza Sabdar * Parameters: 1732654012fSReza Sabdar * connection (input) - connection handle. 1742654012fSReza Sabdar * body (input) - request message body. 1752654012fSReza Sabdar * 1762654012fSReza Sabdar * Returns: 1772654012fSReza Sabdar * void 1782654012fSReza Sabdar */ 1792654012fSReza Sabdar void 1802654012fSReza Sabdar ndmpd_data_start_recover_v2(ndmp_connection_t *connection, void *body) 1812654012fSReza Sabdar { 1822654012fSReza Sabdar ndmp_data_start_recover_request_v2 *request; 1832654012fSReza Sabdar ndmp_data_start_recover_reply_v2 reply; 1842654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 1852654012fSReza Sabdar ndmp_error err; 1862654012fSReza Sabdar 1872654012fSReza Sabdar request = (ndmp_data_start_recover_request_v2 *) body; 1882654012fSReza Sabdar session->ns_data.dd_mover = request->mover; 1892654012fSReza Sabdar 1908c4f9701SJanice Chang err = ndmpd_tar_start_recover_v2(session, request->bu_type, 1918c4f9701SJanice Chang request->env.env_val, request->env.env_len, 1928c4f9701SJanice Chang request->nlist.nlist_val, request->nlist.nlist_len); 1938c4f9701SJanice Chang 1942654012fSReza Sabdar /* 1952654012fSReza Sabdar * start_recover sends the reply if the recover is successfully started. 1962654012fSReza Sabdar * Otherwise, send the reply containing the error here. 1972654012fSReza Sabdar */ 1982654012fSReza Sabdar if (err != NDMP_NO_ERR) { 1992654012fSReza Sabdar reply.error = err; 2002654012fSReza Sabdar ndmp_send_reply(connection, &reply, 2012654012fSReza Sabdar "sending ndmp_data_start_recover_request_v2 reply"); 2022654012fSReza Sabdar ndmpd_data_cleanup(session); 2032654012fSReza Sabdar } 2042654012fSReza Sabdar } 2052654012fSReza Sabdar 2062654012fSReza Sabdar /* 2072654012fSReza Sabdar * ndmpd_data_get_env_v2 2082654012fSReza Sabdar * 2092654012fSReza Sabdar * Request handler. Returns the environment variable array sent 2102654012fSReza Sabdar * with the backup request. This request may only be sent with 2112654012fSReza Sabdar * a backup operation is in progress. 2122654012fSReza Sabdar * 2132654012fSReza Sabdar * Parameters: 2142654012fSReza Sabdar * connection (input) - connection handle. 2152654012fSReza Sabdar * body (input) - request message body. 2162654012fSReza Sabdar * 2172654012fSReza Sabdar * Returns: 2182654012fSReza Sabdar * void 2192654012fSReza Sabdar */ 2202654012fSReza Sabdar /*ARGSUSED*/ 2212654012fSReza Sabdar void 2222654012fSReza Sabdar ndmpd_data_get_env_v2(ndmp_connection_t *connection, void *body) 2232654012fSReza Sabdar { 2242654012fSReza Sabdar ndmp_data_get_env_reply reply; 2252654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 2262654012fSReza Sabdar 2272654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 2282654012fSReza Sabdar if (session->ns_data.dd_operation != NDMP_DATA_OP_BACKUP) { 2292654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Backup operation not active."); 2302654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 2312654012fSReza Sabdar reply.env.env_len = 0; 2322654012fSReza Sabdar } else { 2332654012fSReza Sabdar reply.error = NDMP_NO_ERR; 2342654012fSReza Sabdar reply.env.env_len = session->ns_data.dd_env_len; 2352654012fSReza Sabdar reply.env.env_val = session->ns_data.dd_env; 2362654012fSReza Sabdar } 2372654012fSReza Sabdar 2382654012fSReza Sabdar ndmp_send_reply(connection, &reply, "sending data_get_env reply"); 2392654012fSReza Sabdar } 2402654012fSReza Sabdar 2412654012fSReza Sabdar 2422654012fSReza Sabdar /* 2432654012fSReza Sabdar * ndmpd_data_stop_v2 2442654012fSReza Sabdar * 2452654012fSReza Sabdar * Request handler. Stops the current data operation. 2462654012fSReza Sabdar * 2472654012fSReza Sabdar * Parameters: 2482654012fSReza Sabdar * connection (input) - connection handle. 2492654012fSReza Sabdar * body (input) - request message body. 2502654012fSReza Sabdar * 2512654012fSReza Sabdar * Returns: 2522654012fSReza Sabdar * void 2532654012fSReza Sabdar */ 2542654012fSReza Sabdar /*ARGSUSED*/ 2552654012fSReza Sabdar void 2562654012fSReza Sabdar ndmpd_data_stop_v2(ndmp_connection_t *connection, void *body) 2572654012fSReza Sabdar { 2582654012fSReza Sabdar ndmp_data_stop_reply reply; 2592654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 2602654012fSReza Sabdar 2612654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) { 2622654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state to process stop request."); 2632654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 2642654012fSReza Sabdar ndmp_send_reply(connection, &reply, 2652654012fSReza Sabdar "sending data_stop reply"); 2662654012fSReza Sabdar return; 2672654012fSReza Sabdar } 2682654012fSReza Sabdar ndmp_waitfor_op(session); 2692654012fSReza Sabdar ndmpd_data_cleanup(session); 2702654012fSReza Sabdar ndmpd_file_history_cleanup(session, FALSE); 2712654012fSReza Sabdar 2722654012fSReza Sabdar nlp_release_job_stat(session); 2732654012fSReza Sabdar 2742654012fSReza Sabdar /* prepare for another data operation */ 2752654012fSReza Sabdar (void) ndmpd_data_init(session); 2762654012fSReza Sabdar ndmpd_file_history_init(session); 2772654012fSReza Sabdar 2782654012fSReza Sabdar reply.error = NDMP_NO_ERR; 2792654012fSReza Sabdar ndmp_send_reply(connection, &reply, "sending data_stop reply"); 2802654012fSReza Sabdar } 2812654012fSReza Sabdar 2822654012fSReza Sabdar 2832654012fSReza Sabdar /* 2842654012fSReza Sabdar * ndmpd_data_abort_v2 2852654012fSReza Sabdar * 2862654012fSReza Sabdar * Request handler. Aborts the current backup/restore. The operation 2872654012fSReza Sabdar * state is not changed to the halted state until after the operation 2882654012fSReza Sabdar * has actually been aborted and the notify_halt request has been sent. 2892654012fSReza Sabdar * 2902654012fSReza Sabdar * Parameters: 2912654012fSReza Sabdar * connection (input) - connection handle. 2922654012fSReza Sabdar * body (input) - request message body. 2932654012fSReza Sabdar * 2942654012fSReza Sabdar * Returns: 2952654012fSReza Sabdar * void 2962654012fSReza Sabdar */ 2972654012fSReza Sabdar /*ARGSUSED*/ 2982654012fSReza Sabdar void 2992654012fSReza Sabdar ndmpd_data_abort_v2(ndmp_connection_t *connection, void *body) 3002654012fSReza Sabdar { 3012654012fSReza Sabdar ndmp_data_abort_reply reply; 3022654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 3032654012fSReza Sabdar 3042654012fSReza Sabdar if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE || 3052654012fSReza Sabdar session->ns_data.dd_state == NDMP_DATA_STATE_HALTED) { 3062654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state to process abort request."); 3072654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 3082654012fSReza Sabdar ndmp_send_reply(connection, &reply, 3092654012fSReza Sabdar "sending data_abort reply"); 3102654012fSReza Sabdar return; 3112654012fSReza Sabdar } 3122654012fSReza Sabdar /* 3132654012fSReza Sabdar * Don't go to HALTED state yet. Need to wait for data operation to 3142654012fSReza Sabdar * abort. When this happens, ndmpd_done will get called and will 3152654012fSReza Sabdar * perform the halt processing. 3162654012fSReza Sabdar */ 3172654012fSReza Sabdar session->ns_data.dd_abort = TRUE; 3182654012fSReza Sabdar (*session->ns_data.dd_module.dm_abort_func)( 3192654012fSReza Sabdar session->ns_data.dd_module.dm_module_cookie); 3202654012fSReza Sabdar 3212654012fSReza Sabdar reply.error = NDMP_NO_ERR; 3222654012fSReza Sabdar ndmp_send_reply(connection, &reply, "sending data_abort reply"); 3232654012fSReza Sabdar } 3242654012fSReza Sabdar 3252654012fSReza Sabdar /* 3262654012fSReza Sabdar * ************************************************************************ 3272654012fSReza Sabdar * NDMP V3 HANDLERS 3282654012fSReza Sabdar * ************************************************************************ 3292654012fSReza Sabdar */ 3302654012fSReza Sabdar 3312654012fSReza Sabdar /* 3322654012fSReza Sabdar * ndmpd_data_get_state_v3 3332654012fSReza Sabdar * 3342654012fSReza Sabdar * Request handler. Returns current data state. 3352654012fSReza Sabdar * 3362654012fSReza Sabdar * Parameters: 3372654012fSReza Sabdar * connection (input) - connection handle. 3382654012fSReza Sabdar * body (input) - request message body. 3392654012fSReza Sabdar * 3402654012fSReza Sabdar * Returns: 3412654012fSReza Sabdar * void 3422654012fSReza Sabdar */ 3432654012fSReza Sabdar /*ARGSUSED*/ 3442654012fSReza Sabdar void 3452654012fSReza Sabdar ndmpd_data_get_state_v3(ndmp_connection_t *connection, void *body) 3462654012fSReza Sabdar { 3472654012fSReza Sabdar ndmp_data_get_state_reply_v3 reply; 3482654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 3492654012fSReza Sabdar 3502654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 3512654012fSReza Sabdar 3522654012fSReza Sabdar reply.error = NDMP_NO_ERR; 3532654012fSReza Sabdar reply.invalid = NDMP_DATA_STATE_EST_BYTES_REMAIN_INVALID 3542654012fSReza Sabdar | NDMP_DATA_STATE_EST_TIME_REMAIN_INVALID; 3552654012fSReza Sabdar reply.operation = session->ns_data.dd_operation; 3562654012fSReza Sabdar reply.state = session->ns_data.dd_state; 3572654012fSReza Sabdar reply.halt_reason = session->ns_data.dd_halt_reason; 3582654012fSReza Sabdar 3592654012fSReza Sabdar if (reply.operation == NDMP_DATA_OP_BACKUP) 3602654012fSReza Sabdar reply.bytes_processed = 3612654012fSReza Sabdar long_long_to_quad( 3622654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_bytes_processed); 3632654012fSReza Sabdar else 3642654012fSReza Sabdar reply.bytes_processed = 3652654012fSReza Sabdar long_long_to_quad(ndmpd_data_get_info(session)); 3662654012fSReza Sabdar 3672654012fSReza Sabdar reply.est_bytes_remain = long_long_to_quad(0LL); 3682654012fSReza Sabdar reply.est_time_remain = 0; 3692654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) 3702654012fSReza Sabdar ndmp_copy_addr_v3(&reply.data_connection_addr, 3712654012fSReza Sabdar &session->ns_data.dd_data_addr); 3722654012fSReza Sabdar reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset); 3732654012fSReza Sabdar reply.read_length = long_long_to_quad(session->ns_data.dd_read_length); 3742654012fSReza Sabdar 3752654012fSReza Sabdar ndmp_send_reply(connection, &reply, 3762654012fSReza Sabdar "sending ndmp_data_get_state_v3 reply"); 3772654012fSReza Sabdar } 3782654012fSReza Sabdar 3792654012fSReza Sabdar 3802654012fSReza Sabdar /* 3812654012fSReza Sabdar * ndmpd_data_start_backup_v3 3822654012fSReza Sabdar * 3832654012fSReza Sabdar * Request handler. Starts a backup. 3842654012fSReza Sabdar * 3852654012fSReza Sabdar * Parameters: 3862654012fSReza Sabdar * connection (input) - connection handle. 3872654012fSReza Sabdar * body (input) - request message body. 3882654012fSReza Sabdar * 3892654012fSReza Sabdar * Returns: 3902654012fSReza Sabdar * void 3912654012fSReza Sabdar */ 3922654012fSReza Sabdar void 3932654012fSReza Sabdar ndmpd_data_start_backup_v3(ndmp_connection_t *connection, void *body) 3942654012fSReza Sabdar { 3952654012fSReza Sabdar ndmp_data_start_backup_request_v3 *request; 3962654012fSReza Sabdar ndmp_data_start_backup_reply_v3 reply; 3972654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 3982654012fSReza Sabdar 3992654012fSReza Sabdar request = (ndmp_data_start_backup_request_v3 *)body; 4002654012fSReza Sabdar 4012654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 4022654012fSReza Sabdar 4038c4f9701SJanice Chang if (session->ns_data.dd_state != NDMP_DATA_STATE_CONNECTED) { 4048c4f9701SJanice Chang NDMP_LOG(LOG_ERR, 4058c4f9701SJanice Chang "Can't start new backup in current state."); 4068c4f9701SJanice Chang NDMP_LOG(LOG_ERR, 4078c4f9701SJanice Chang "Connection to the mover is not established."); 4088c4f9701SJanice Chang reply.error = NDMP_ILLEGAL_STATE_ERR; 4098c4f9701SJanice Chang goto _error; 4108c4f9701SJanice Chang } 4118c4f9701SJanice Chang 4128c4f9701SJanice Chang if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL) { 4138c4f9701SJanice Chang if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) { 4148c4f9701SJanice Chang NDMP_LOG(LOG_ERR, "Write protected device."); 4158c4f9701SJanice Chang reply.error = NDMP_WRITE_PROTECT_ERR; 4168c4f9701SJanice Chang goto _error; 4178c4f9701SJanice Chang } 4188c4f9701SJanice Chang } 4198c4f9701SJanice Chang 4208c4f9701SJanice Chang if (strcasecmp(request->bu_type, NDMP_TAR_TYPE) == 0) { 4218c4f9701SJanice Chang session->ns_butype = NDMP_BUTYPE_TAR; 4228c4f9701SJanice Chang } else if (strcasecmp(request->bu_type, NDMP_DUMP_TYPE) == 0) { 4238c4f9701SJanice Chang session->ns_butype = NDMP_BUTYPE_DUMP; 4248c4f9701SJanice Chang } else if (strcasecmp(request->bu_type, NDMP_ZFS_TYPE) == 0) { 4258c4f9701SJanice Chang session->ns_butype = NDMP_BUTYPE_ZFS; 4268c4f9701SJanice Chang } else { 4278c4f9701SJanice Chang char msg_invalid[32]; 4288c4f9701SJanice Chang char msg_types[32]; 4298c4f9701SJanice Chang 4308c4f9701SJanice Chang (void) snprintf(msg_invalid, 32, "Invalid backup type: %s.", 4318c4f9701SJanice Chang request->bu_type); 4328c4f9701SJanice Chang (void) snprintf(msg_types, 32, 4338c4f9701SJanice Chang "Supported backup types are tar, dump, and zfs."); 4348c4f9701SJanice Chang 4358c4f9701SJanice Chang NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id, 4368c4f9701SJanice Chang msg_invalid); 4378c4f9701SJanice Chang NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id, 4388c4f9701SJanice Chang msg_types); 4398c4f9701SJanice Chang NDMP_LOG(LOG_ERR, msg_invalid); 4408c4f9701SJanice Chang NDMP_LOG(LOG_ERR, msg_types); 4418c4f9701SJanice Chang 4428c4f9701SJanice Chang reply.error = NDMP_ILLEGAL_ARGS_ERR; 4438c4f9701SJanice Chang goto _error; 4448c4f9701SJanice Chang } 4458c4f9701SJanice Chang 4468c4f9701SJanice Chang if (session->ns_butype == NDMP_BUTYPE_ZFS) { 4478c4f9701SJanice Chang reply.error = ndmpd_zfs_start_op(session, request->env.env_val, 4488c4f9701SJanice Chang request->env.env_len, NULL, 0, NDMP_DATA_OP_BACKUP); 4498c4f9701SJanice Chang } else { 4508c4f9701SJanice Chang reply.error = ndmpd_tar_start_backup_v3(session, 4518c4f9701SJanice Chang request->bu_type, request->env.env_val, 4522654012fSReza Sabdar request->env.env_len); 4538c4f9701SJanice Chang } 4542654012fSReza Sabdar 4552654012fSReza Sabdar /* 4568c4f9701SJanice Chang * *_start_backup* sends the reply if the backup is 4572654012fSReza Sabdar * successfully started. Otherwise, send the reply 4582654012fSReza Sabdar * containing the error here. 4592654012fSReza Sabdar */ 4608c4f9701SJanice Chang 4618c4f9701SJanice Chang _error: 4628c4f9701SJanice Chang 4638c4f9701SJanice Chang if (reply.error != NDMP_NO_ERR) { 4642654012fSReza Sabdar ndmp_send_reply(connection, &reply, 4652654012fSReza Sabdar "sending data_start_backup_v3 reply"); 4662654012fSReza Sabdar ndmpd_data_cleanup(session); 4672654012fSReza Sabdar } 4682654012fSReza Sabdar } 4692654012fSReza Sabdar 4702654012fSReza Sabdar /* 4712654012fSReza Sabdar * ndmpd_data_start_recover_v3 4722654012fSReza Sabdar * 4732654012fSReza Sabdar * Request handler. Starts a restore. 4742654012fSReza Sabdar * 4752654012fSReza Sabdar * Parameters: 4762654012fSReza Sabdar * connection (input) - connection handle. 4772654012fSReza Sabdar * body (input) - request message body. 4782654012fSReza Sabdar * 4792654012fSReza Sabdar * Returns: 4802654012fSReza Sabdar * void 4812654012fSReza Sabdar */ 4822654012fSReza Sabdar void 4832654012fSReza Sabdar ndmpd_data_start_recover_v3(ndmp_connection_t *connection, void *body) 4842654012fSReza Sabdar { 4852654012fSReza Sabdar ndmp_data_start_recover_request_v3 *request; 4862654012fSReza Sabdar ndmp_data_start_recover_reply_v3 reply; 4872654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 4882654012fSReza Sabdar 4892654012fSReza Sabdar request = (ndmp_data_start_recover_request_v3 *)body; 4902654012fSReza Sabdar 4912654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 4922654012fSReza Sabdar 4938c4f9701SJanice Chang if (session->ns_data.dd_state != NDMP_DATA_STATE_CONNECTED) { 4948c4f9701SJanice Chang NDMP_LOG(LOG_ERR, "Can't start new recover in current state."); 4958c4f9701SJanice Chang reply.error = NDMP_ILLEGAL_STATE_ERR; 4968c4f9701SJanice Chang goto _error; 4978c4f9701SJanice Chang } 4988c4f9701SJanice Chang 4998c4f9701SJanice Chang if (strcasecmp(request->bu_type, NDMP_TAR_TYPE) == 0) { 5008c4f9701SJanice Chang session->ns_butype = NDMP_BUTYPE_TAR; 5018c4f9701SJanice Chang } else if (strcasecmp(request->bu_type, NDMP_DUMP_TYPE) == 0) { 5028c4f9701SJanice Chang session->ns_butype = NDMP_BUTYPE_DUMP; 5038c4f9701SJanice Chang } else if (strcasecmp(request->bu_type, NDMP_ZFS_TYPE) == 0) { 5048c4f9701SJanice Chang session->ns_butype = NDMP_BUTYPE_ZFS; 5058c4f9701SJanice Chang } else { 5068c4f9701SJanice Chang char msg_invalid[32]; 5078c4f9701SJanice Chang char msg_types[32]; 5088c4f9701SJanice Chang 5098c4f9701SJanice Chang (void) snprintf(msg_invalid, 32, "Invalid backup type: %s.", 5108c4f9701SJanice Chang request->bu_type); 5118c4f9701SJanice Chang (void) snprintf(msg_types, 32, 5128c4f9701SJanice Chang "Supported backup types are tar, dump, and zfs."); 5138c4f9701SJanice Chang 5148c4f9701SJanice Chang NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id, 5158c4f9701SJanice Chang msg_invalid); 5168c4f9701SJanice Chang NDMP_APILOG((void *) session, NDMP_LOG_ERROR, ++ndmp_log_msg_id, 5178c4f9701SJanice Chang msg_types); 5188c4f9701SJanice Chang NDMP_LOG(LOG_ERR, msg_invalid); 5198c4f9701SJanice Chang NDMP_LOG(LOG_ERR, msg_types); 5208c4f9701SJanice Chang 5218c4f9701SJanice Chang reply.error = NDMP_ILLEGAL_ARGS_ERR; 5228c4f9701SJanice Chang goto _error; 5238c4f9701SJanice Chang } 5248c4f9701SJanice Chang 5258c4f9701SJanice Chang if (session->ns_butype == NDMP_BUTYPE_ZFS) { 5268c4f9701SJanice Chang reply.error = ndmpd_zfs_start_op(session, request->env.env_val, 5272654012fSReza Sabdar request->env.env_len, request->nlist.nlist_val, 5288c4f9701SJanice Chang request->nlist.nlist_len, NDMP_DATA_OP_RECOVER); 5298c4f9701SJanice Chang } else { 5308c4f9701SJanice Chang reply.error = ndmpd_tar_start_recover_v3(session, 5318c4f9701SJanice Chang request->env.env_val, request->env.env_len, 5328c4f9701SJanice Chang request->nlist.nlist_val, request->nlist.nlist_len); 5338c4f9701SJanice Chang } 5342654012fSReza Sabdar 5352654012fSReza Sabdar /* 5368c4f9701SJanice Chang * *_start_recover* sends the reply if the recover is 5372654012fSReza Sabdar * successfully started. Otherwise, send the reply 5382654012fSReza Sabdar * containing the error here. 5392654012fSReza Sabdar */ 5408c4f9701SJanice Chang 5418c4f9701SJanice Chang _error: 5428c4f9701SJanice Chang 5438c4f9701SJanice Chang if (reply.error != NDMP_NO_ERR) { 5442654012fSReza Sabdar ndmp_send_reply(connection, &reply, 5452654012fSReza Sabdar "sending data_start_recover_v3 reply"); 5462654012fSReza Sabdar ndmpd_data_error(session, NDMP_DATA_HALT_INTERNAL_ERROR); 5472654012fSReza Sabdar ndmpd_data_cleanup(session); 5482654012fSReza Sabdar } 5492654012fSReza Sabdar } 5502654012fSReza Sabdar 5512654012fSReza Sabdar /* 5522654012fSReza Sabdar * ndmpd_data_abort_v3 5532654012fSReza Sabdar * 5542654012fSReza Sabdar * Request handler. Aborts the current backup/restore. The operation 5552654012fSReza Sabdar * state is not changed to the halted state until after the operation 5562654012fSReza Sabdar * has actually been aborted and the notify_halt request has been sent. 5572654012fSReza Sabdar * 5582654012fSReza Sabdar * Parameters: 5592654012fSReza Sabdar * connection (input) - connection handle. 5602654012fSReza Sabdar * body (input) - request message body. 5612654012fSReza Sabdar * 5622654012fSReza Sabdar * Returns: 5632654012fSReza Sabdar * void 5642654012fSReza Sabdar */ 5652654012fSReza Sabdar /*ARGSUSED*/ 5662654012fSReza Sabdar void 5672654012fSReza Sabdar ndmpd_data_abort_v3(ndmp_connection_t *connection, void *body) 5682654012fSReza Sabdar { 5692654012fSReza Sabdar ndmp_data_abort_reply reply; 5702654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 5712654012fSReza Sabdar 5722654012fSReza Sabdar switch (session->ns_data.dd_state) { 5732654012fSReza Sabdar case NDMP_DATA_STATE_IDLE: 5742654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 5752654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state to process abort request."); 5762654012fSReza Sabdar break; 5772654012fSReza Sabdar 5782654012fSReza Sabdar case NDMP_DATA_STATE_ACTIVE: 5792654012fSReza Sabdar /* 5802654012fSReza Sabdar * Don't go to HALTED state yet. Need to wait for data 5812654012fSReza Sabdar * operation to abort. When this happens, ndmpd_done_v3 5822654012fSReza Sabdar * will get called and will perform the halt processing. 5832654012fSReza Sabdar */ 5842654012fSReza Sabdar reply.error = NDMP_NO_ERR; 5852654012fSReza Sabdar session->ns_data.dd_abort = TRUE; 5862654012fSReza Sabdar if (session->ns_data.dd_module.dm_abort_func) 5872654012fSReza Sabdar (*session->ns_data.dd_module.dm_abort_func)( 5882654012fSReza Sabdar session->ns_data.dd_module.dm_module_cookie); 5892654012fSReza Sabdar break; 5902654012fSReza Sabdar 5912654012fSReza Sabdar case NDMP_DATA_STATE_HALTED: 5922654012fSReza Sabdar case NDMP_DATA_STATE_LISTEN: 5932654012fSReza Sabdar case NDMP_DATA_STATE_CONNECTED: 5942654012fSReza Sabdar reply.error = NDMP_NO_ERR; 5952654012fSReza Sabdar session->ns_data.dd_abort = TRUE; 5962654012fSReza Sabdar ndmpd_data_error(session, NDMP_DATA_HALT_ABORTED); 5972654012fSReza Sabdar break; 5982654012fSReza Sabdar default: 5992654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 6002654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown data V3 state %d", 6012654012fSReza Sabdar session->ns_data.dd_state); 6022654012fSReza Sabdar } 6032654012fSReza Sabdar 6042654012fSReza Sabdar ndmp_send_reply(connection, &reply, 6052654012fSReza Sabdar "sending data_abort_v3 reply"); 6062654012fSReza Sabdar } 6072654012fSReza Sabdar 6082654012fSReza Sabdar 6092654012fSReza Sabdar /* 6102654012fSReza Sabdar * ndmpd_data_stop_v3 6112654012fSReza Sabdar * 6122654012fSReza Sabdar * Request handler. Stops the current data operation. 6132654012fSReza Sabdar * 6142654012fSReza Sabdar * Parameters: 6152654012fSReza Sabdar * connection (input) - connection handle. 6162654012fSReza Sabdar * body (input) - request message body. 6172654012fSReza Sabdar * 6182654012fSReza Sabdar * Returns: 6192654012fSReza Sabdar * void 6202654012fSReza Sabdar */ 6212654012fSReza Sabdar /*ARGSUSED*/ 6222654012fSReza Sabdar void 6232654012fSReza Sabdar ndmpd_data_stop_v3(ndmp_connection_t *connection, void *body) 6242654012fSReza Sabdar { 6252654012fSReza Sabdar ndmp_data_stop_reply reply; 6262654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 6272654012fSReza Sabdar 6282654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) { 6292654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state to process stop request."); 6302654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 6312654012fSReza Sabdar ndmp_send_reply(connection, &reply, 6322654012fSReza Sabdar "sending data_stop_v3 reply"); 6332654012fSReza Sabdar return; 6342654012fSReza Sabdar } 6352654012fSReza Sabdar ndmp_waitfor_op(session); 6362654012fSReza Sabdar ndmpd_data_cleanup(session); 6372654012fSReza Sabdar ndmpd_file_history_cleanup(session, FALSE); 6382654012fSReza Sabdar 6392654012fSReza Sabdar /* prepare for another data operation */ 6402654012fSReza Sabdar (void) ndmpd_data_init(session); 6412654012fSReza Sabdar ndmpd_file_history_init(session); 6422654012fSReza Sabdar 6432654012fSReza Sabdar reply.error = NDMP_NO_ERR; 6442654012fSReza Sabdar ndmp_send_reply(connection, &reply, 6452654012fSReza Sabdar "sending data_stop_v3 reply"); 6462654012fSReza Sabdar } 6472654012fSReza Sabdar 6482654012fSReza Sabdar 6492654012fSReza Sabdar /* 6502654012fSReza Sabdar * ndmpd_data_listen_v3 6512654012fSReza Sabdar * 6522654012fSReza Sabdar * Request handler. Configures the server to listen for a connection 6532654012fSReza Sabdar * from a remote mover. 6542654012fSReza Sabdar * 6552654012fSReza Sabdar * Parameters: 6562654012fSReza Sabdar * connection (input) - connection handle. 6572654012fSReza Sabdar * body (input) - request message body. 6582654012fSReza Sabdar * 6592654012fSReza Sabdar * Returns: 6602654012fSReza Sabdar * void 6612654012fSReza Sabdar */ 6622654012fSReza Sabdar void 6632654012fSReza Sabdar ndmpd_data_listen_v3(ndmp_connection_t *connection, void *body) 6642654012fSReza Sabdar { 6652654012fSReza Sabdar ndmp_data_listen_request_v3 *request; 6662654012fSReza Sabdar ndmp_data_listen_reply_v3 reply; 6672654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 6682654012fSReza Sabdar ulong_t addr; 6692654012fSReza Sabdar ushort_t port; 6702654012fSReza Sabdar 6712654012fSReza Sabdar request = (ndmp_data_listen_request_v3 *)body; 6722654012fSReza Sabdar 6732654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 6742654012fSReza Sabdar 6752654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 6762654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 6772654012fSReza Sabdar NDMP_LOG(LOG_ERR, 6782654012fSReza Sabdar "Invalid internal data state to process listen request."); 6792654012fSReza Sabdar } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) { 6802654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 6812654012fSReza Sabdar NDMP_LOG(LOG_ERR, 6822654012fSReza Sabdar "Invalid mover state to process listen request."); 6832654012fSReza Sabdar } else { 6842654012fSReza Sabdar reply.error = NDMP_NO_ERR; 6852654012fSReza Sabdar } 6862654012fSReza Sabdar 6872654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 6882654012fSReza Sabdar ndmp_send_reply(connection, &reply, 6892654012fSReza Sabdar "ndmp_data_listen_request_v3 reply"); 6902654012fSReza Sabdar return; 6912654012fSReza Sabdar } 6922654012fSReza Sabdar 6932654012fSReza Sabdar switch (request->addr_type) { 6942654012fSReza Sabdar case NDMP_ADDR_LOCAL: 6952654012fSReza Sabdar reply.data_connection_addr.addr_type = request->addr_type; 6962654012fSReza Sabdar session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL; 6972654012fSReza Sabdar break; 6982654012fSReza Sabdar case NDMP_ADDR_TCP: 6992654012fSReza Sabdar if (create_listen_socket_v3(session, &addr, &port) < 0) { 7002654012fSReza Sabdar reply.error = NDMP_IO_ERR; 7012654012fSReza Sabdar break; 7022654012fSReza Sabdar } 7032654012fSReza Sabdar 7042654012fSReza Sabdar reply.error = NDMP_NO_ERR; 7052654012fSReza Sabdar reply.data_connection_addr.addr_type = request->addr_type; 7062654012fSReza Sabdar reply.data_connection_addr.tcp_ip_v3 = htonl(addr); 7072654012fSReza Sabdar reply.data_connection_addr.tcp_port_v3 = htons(port); 7082654012fSReza Sabdar session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP; 7092654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_ip_v3 = addr; 7102654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(port); 7112654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "listen_socket: %d", 7122654012fSReza Sabdar session->ns_data.dd_listen_sock); 7132654012fSReza Sabdar break; 7142654012fSReza Sabdar 7152654012fSReza Sabdar default: 7162654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid address type: %d", 7172654012fSReza Sabdar request->addr_type); 7182654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 7192654012fSReza Sabdar break; 7202654012fSReza Sabdar } 7212654012fSReza Sabdar 7222654012fSReza Sabdar if (reply.error == NDMP_NO_ERR) 7232654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_LISTEN; 7242654012fSReza Sabdar 7252654012fSReza Sabdar ndmp_send_reply(connection, &reply, 7262654012fSReza Sabdar "ndmp_data_listen_request_v3 reply"); 7272654012fSReza Sabdar } 7282654012fSReza Sabdar 7292654012fSReza Sabdar 7302654012fSReza Sabdar /* 7312654012fSReza Sabdar * ndmpd_data_connect_v3 7322654012fSReza Sabdar * 7332654012fSReza Sabdar * Request handler. Connects the data server to either a local 7342654012fSReza Sabdar * or remote mover. 7352654012fSReza Sabdar * 7362654012fSReza Sabdar * Parameters: 7372654012fSReza Sabdar * connection (input) - connection handle. 7382654012fSReza Sabdar * body (input) - request message body. 7392654012fSReza Sabdar * 7402654012fSReza Sabdar * Returns: 7412654012fSReza Sabdar * void 7422654012fSReza Sabdar */ 7432654012fSReza Sabdar void 7442654012fSReza Sabdar ndmpd_data_connect_v3(ndmp_connection_t *connection, void *body) 7452654012fSReza Sabdar { 7462654012fSReza Sabdar ndmp_data_connect_request_v3 *request; 7472654012fSReza Sabdar ndmp_data_connect_reply_v3 reply; 7482654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 7492654012fSReza Sabdar 7502654012fSReza Sabdar request = (ndmp_data_connect_request_v3 *)body; 7512654012fSReza Sabdar 7522654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 7532654012fSReza Sabdar 7542654012fSReza Sabdar if (!ndmp_valid_v3addr_type(request->addr.addr_type)) { 7552654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 7562654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 7572654012fSReza Sabdar request->addr.addr_type); 7582654012fSReza Sabdar } else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 7592654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 7602654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state to process connect request."); 7612654012fSReza Sabdar } else { 7622654012fSReza Sabdar reply.error = NDMP_NO_ERR; 7632654012fSReza Sabdar } 7642654012fSReza Sabdar 7652654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 7662654012fSReza Sabdar ndmp_send_reply(connection, &reply, 7672654012fSReza Sabdar "sending ndmp_data_connect_v3 reply"); 7682654012fSReza Sabdar return; 7692654012fSReza Sabdar } 7702654012fSReza Sabdar 7712654012fSReza Sabdar switch (request->addr.addr_type) { 7722654012fSReza Sabdar case NDMP_ADDR_LOCAL: 7732654012fSReza Sabdar /* 7742654012fSReza Sabdar * Verify that the mover is listening for a 7752654012fSReza Sabdar * local connection 7762654012fSReza Sabdar */ 7772654012fSReza Sabdar if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN || 7782654012fSReza Sabdar session->ns_mover.md_listen_sock != -1) { 7792654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 7802654012fSReza Sabdar NDMP_LOG(LOG_ERR, 7812654012fSReza Sabdar "Mover is not in local listen state."); 7822654012fSReza Sabdar } else { 7832654012fSReza Sabdar session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE; 7842654012fSReza Sabdar } 7852654012fSReza Sabdar break; 7862654012fSReza Sabdar 7872654012fSReza Sabdar case NDMP_ADDR_TCP: 7882654012fSReza Sabdar reply.error = data_connect_sock_v3(session, 7892654012fSReza Sabdar request->addr.tcp_ip_v3, request->addr.tcp_port_v3); 7902654012fSReza Sabdar break; 7912654012fSReza Sabdar 7922654012fSReza Sabdar default: 7932654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 7942654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 7952654012fSReza Sabdar request->addr.addr_type); 7962654012fSReza Sabdar } 7972654012fSReza Sabdar 7982654012fSReza Sabdar if (reply.error == NDMP_NO_ERR) 7992654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED; 8002654012fSReza Sabdar 8012654012fSReza Sabdar ndmp_send_reply(connection, &reply, 8022654012fSReza Sabdar "sending ndmp_data_connect_v3 reply"); 8032654012fSReza Sabdar } 8042654012fSReza Sabdar 8052654012fSReza Sabdar 8062654012fSReza Sabdar /* 8072654012fSReza Sabdar * ************************************************************************ 8082654012fSReza Sabdar * NDMP V4 HANDLERS 8092654012fSReza Sabdar * ************************************************************************ 8102654012fSReza Sabdar */ 8112654012fSReza Sabdar 8122654012fSReza Sabdar /* 8132654012fSReza Sabdar * ndmpd_data_get_env_v4 8142654012fSReza Sabdar * 8152654012fSReza Sabdar * Request handler. Returns the environment variable array sent 8162654012fSReza Sabdar * with the backup request. This request may only be sent with 8172654012fSReza Sabdar * a backup operation is in progress. 8182654012fSReza Sabdar * 8192654012fSReza Sabdar * Parameters: 8202654012fSReza Sabdar * connection (input) - connection handle. 8212654012fSReza Sabdar * body (input) - request message body. 8222654012fSReza Sabdar * 8232654012fSReza Sabdar * Returns: 8242654012fSReza Sabdar * void 8252654012fSReza Sabdar */ 8262654012fSReza Sabdar /*ARGSUSED*/ 8272654012fSReza Sabdar void 8282654012fSReza Sabdar ndmpd_data_get_env_v4(ndmp_connection_t *connection, void *body) 8292654012fSReza Sabdar { 8302654012fSReza Sabdar ndmp_data_get_env_reply reply; 8312654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 8322654012fSReza Sabdar 8332654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 8342654012fSReza Sabdar 8352654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_ACTIVE && 8362654012fSReza Sabdar session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) { 8372654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state for the data server."); 8382654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 8392654012fSReza Sabdar reply.env.env_len = 0; 8402654012fSReza Sabdar } else if (session->ns_data.dd_operation != NDMP_DATA_OP_BACKUP) { 8412654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Backup operation not active."); 8422654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 8432654012fSReza Sabdar reply.env.env_len = 0; 8442654012fSReza Sabdar } else { 8452654012fSReza Sabdar reply.error = NDMP_NO_ERR; 8462654012fSReza Sabdar reply.env.env_len = session->ns_data.dd_env_len; 8472654012fSReza Sabdar reply.env.env_val = session->ns_data.dd_env; 8482654012fSReza Sabdar } 8492654012fSReza Sabdar 8502654012fSReza Sabdar ndmp_send_reply(connection, &reply, "sending data_get_env reply"); 8512654012fSReza Sabdar } 8522654012fSReza Sabdar 8532654012fSReza Sabdar /* 8542654012fSReza Sabdar * ndmpd_data_get_state_v4 8552654012fSReza Sabdar * 8562654012fSReza Sabdar * Request handler. Returns current data state. 8572654012fSReza Sabdar * 8582654012fSReza Sabdar * Parameters: 8592654012fSReza Sabdar * connection (input) - connection handle. 8602654012fSReza Sabdar * body (input) - request message body. 8612654012fSReza Sabdar * 8622654012fSReza Sabdar * Returns: 8632654012fSReza Sabdar * void 8642654012fSReza Sabdar */ 8652654012fSReza Sabdar /*ARGSUSED*/ 8662654012fSReza Sabdar void 8672654012fSReza Sabdar ndmpd_data_get_state_v4(ndmp_connection_t *connection, void *body) 8682654012fSReza Sabdar { 8692654012fSReza Sabdar ndmp_data_get_state_reply_v4 reply; 8702654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 8712654012fSReza Sabdar 8722654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 8732654012fSReza Sabdar 8742654012fSReza Sabdar reply.error = NDMP_NO_ERR; 8752654012fSReza Sabdar reply.unsupported = NDMP_DATA_STATE_EST_BYTES_REMAIN_INVALID 8762654012fSReza Sabdar | NDMP_DATA_STATE_EST_TIME_REMAIN_INVALID; 8772654012fSReza Sabdar reply.operation = session->ns_data.dd_operation; 8782654012fSReza Sabdar reply.state = session->ns_data.dd_state; 8792654012fSReza Sabdar reply.halt_reason = session->ns_data.dd_halt_reason; 8802654012fSReza Sabdar 8812654012fSReza Sabdar if (reply.operation == NDMP_DATA_OP_BACKUP) 8822654012fSReza Sabdar reply.bytes_processed = long_long_to_quad( 8832654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_bytes_processed); 8842654012fSReza Sabdar else 8852654012fSReza Sabdar reply.bytes_processed = 8862654012fSReza Sabdar long_long_to_quad(ndmpd_data_get_info(session)); 8872654012fSReza Sabdar 8882654012fSReza Sabdar reply.est_bytes_remain = long_long_to_quad(0LL); 8892654012fSReza Sabdar reply.est_time_remain = 0; 8902654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) 8912654012fSReza Sabdar ndmp_copy_addr_v4(&reply.data_connection_addr, 8922654012fSReza Sabdar &session->ns_data.dd_data_addr_v4); 8932654012fSReza Sabdar 8942654012fSReza Sabdar reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset); 8952654012fSReza Sabdar reply.read_length = long_long_to_quad(session->ns_data.dd_read_length); 8962654012fSReza Sabdar 8972654012fSReza Sabdar ndmp_send_reply(connection, &reply, 8982654012fSReza Sabdar "sending ndmp_data_get_state_v4 reply"); 8992654012fSReza Sabdar free(reply.data_connection_addr.tcp_addr_v4); 9002654012fSReza Sabdar } 9012654012fSReza Sabdar 9022654012fSReza Sabdar 9032654012fSReza Sabdar /* 9042654012fSReza Sabdar * ndmpd_data_connect_v4 9052654012fSReza Sabdar * 9062654012fSReza Sabdar * Request handler. Connects the data server to either a local 9072654012fSReza Sabdar * or remote mover. 9082654012fSReza Sabdar * 9092654012fSReza Sabdar * Parameters: 9102654012fSReza Sabdar * connection (input) - connection handle. 9112654012fSReza Sabdar * body (input) - request message body. 9122654012fSReza Sabdar * 9132654012fSReza Sabdar * Returns: 9142654012fSReza Sabdar * void 9152654012fSReza Sabdar */ 9162654012fSReza Sabdar void 9172654012fSReza Sabdar ndmpd_data_connect_v4(ndmp_connection_t *connection, void *body) 9182654012fSReza Sabdar { 9192654012fSReza Sabdar ndmp_data_connect_request_v4 *request; 9202654012fSReza Sabdar ndmp_data_connect_reply_v4 reply; 9212654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 9222654012fSReza Sabdar 9232654012fSReza Sabdar request = (ndmp_data_connect_request_v4 *)body; 9242654012fSReza Sabdar 9252654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 9262654012fSReza Sabdar 9272654012fSReza Sabdar if (!ndmp_valid_v3addr_type(request->addr.addr_type)) { 9282654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 9292654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 9302654012fSReza Sabdar request->addr.addr_type); 9312654012fSReza Sabdar } else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 9322654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 9332654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid state to process connect request."); 9342654012fSReza Sabdar } else { 9352654012fSReza Sabdar reply.error = NDMP_NO_ERR; 9362654012fSReza Sabdar } 9372654012fSReza Sabdar 9382654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 9392654012fSReza Sabdar ndmp_send_reply(connection, &reply, 9402654012fSReza Sabdar "sending ndmp_data_connect_v4 reply"); 9412654012fSReza Sabdar return; 9422654012fSReza Sabdar } 9432654012fSReza Sabdar 9442654012fSReza Sabdar switch (request->addr.addr_type) { 9452654012fSReza Sabdar case NDMP_ADDR_LOCAL: 9462654012fSReza Sabdar /* 9472654012fSReza Sabdar * Verify that the mover is listening for a 9482654012fSReza Sabdar * local connection 9492654012fSReza Sabdar */ 9502654012fSReza Sabdar if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN || 9512654012fSReza Sabdar session->ns_mover.md_listen_sock != -1) { 9522654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 9532654012fSReza Sabdar NDMP_LOG(LOG_ERR, 9542654012fSReza Sabdar "Mover is not in local listen state."); 9552654012fSReza Sabdar } else { 9562654012fSReza Sabdar session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE; 9572654012fSReza Sabdar } 9582654012fSReza Sabdar break; 9592654012fSReza Sabdar 9602654012fSReza Sabdar case NDMP_ADDR_TCP: 9612654012fSReza Sabdar reply.error = data_connect_sock_v3(session, 9622654012fSReza Sabdar request->addr.tcp_ip_v4(0), request->addr.tcp_port_v4(0)); 9632654012fSReza Sabdar break; 9642654012fSReza Sabdar 9652654012fSReza Sabdar default: 9662654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 9672654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 9682654012fSReza Sabdar request->addr.addr_type); 9692654012fSReza Sabdar } 9702654012fSReza Sabdar 9712654012fSReza Sabdar if (reply.error == NDMP_NO_ERR) 9722654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED; 9732654012fSReza Sabdar 9742654012fSReza Sabdar ndmp_send_reply(connection, &reply, 9752654012fSReza Sabdar "sending ndmp_data_connect_v4 reply"); 9762654012fSReza Sabdar } 9772654012fSReza Sabdar 9782654012fSReza Sabdar /* 9792654012fSReza Sabdar * ndmpd_data_listen_v4 9802654012fSReza Sabdar * 9812654012fSReza Sabdar * Request handler. Configures the server to listen for a connection 9822654012fSReza Sabdar * from a remote mover. 9832654012fSReza Sabdar * 9842654012fSReza Sabdar * Parameters: 9852654012fSReza Sabdar * connection (input) - connection handle. 9862654012fSReza Sabdar * body (input) - request message body. 9872654012fSReza Sabdar * 9882654012fSReza Sabdar * Returns: 9892654012fSReza Sabdar * void 9902654012fSReza Sabdar */ 9912654012fSReza Sabdar void 9922654012fSReza Sabdar ndmpd_data_listen_v4(ndmp_connection_t *connection, void *body) 9932654012fSReza Sabdar { 9942654012fSReza Sabdar ndmp_data_listen_request_v4 *request; 9952654012fSReza Sabdar ndmp_data_listen_reply_v4 reply; 9962654012fSReza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection); 9972654012fSReza Sabdar ulong_t addr; 9982654012fSReza Sabdar ushort_t port; 9992654012fSReza Sabdar 10002654012fSReza Sabdar request = (ndmp_data_listen_request_v4 *)body; 10012654012fSReza Sabdar 10022654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 10032654012fSReza Sabdar 10042654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 10052654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 10062654012fSReza Sabdar NDMP_LOG(LOG_ERR, 10072654012fSReza Sabdar "Invalid internal data state to process listen request."); 10082654012fSReza Sabdar } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) { 10092654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR; 10102654012fSReza Sabdar NDMP_LOG(LOG_ERR, 10112654012fSReza Sabdar "Invalid mover state to process listen request."); 10122654012fSReza Sabdar } else { 10132654012fSReza Sabdar reply.error = NDMP_NO_ERR; 10142654012fSReza Sabdar } 10152654012fSReza Sabdar 10162654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 10172654012fSReza Sabdar ndmp_send_reply(connection, &reply, 10182654012fSReza Sabdar "ndmp_data_listen_request_v4 reply"); 10192654012fSReza Sabdar return; 10202654012fSReza Sabdar } 10212654012fSReza Sabdar 10222654012fSReza Sabdar switch (request->addr_type) { 10232654012fSReza Sabdar case NDMP_ADDR_LOCAL: 10242654012fSReza Sabdar reply.connect_addr.addr_type = request->addr_type; 10252654012fSReza Sabdar session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL; 10262654012fSReza Sabdar break; 10272654012fSReza Sabdar case NDMP_ADDR_TCP: 10282654012fSReza Sabdar if (create_listen_socket_v3(session, &addr, &port) < 0) { 10292654012fSReza Sabdar reply.error = NDMP_IO_ERR; 10302654012fSReza Sabdar break; 10312654012fSReza Sabdar } 10322654012fSReza Sabdar 10332654012fSReza Sabdar reply.error = NDMP_NO_ERR; 10342654012fSReza Sabdar reply.connect_addr.addr_type = request->addr_type; 10352654012fSReza Sabdar reply.connect_addr.tcp_addr_v4 = 10362654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_tcp_addr_v4)); 10372654012fSReza Sabdar 10382654012fSReza Sabdar reply.connect_addr.tcp_ip_v4(0) = htonl(addr); 10392654012fSReza Sabdar reply.connect_addr.tcp_port_v4(0) = htons(port); 10402654012fSReza Sabdar reply.connect_addr.tcp_len_v4 = 1; 10412654012fSReza Sabdar 10422654012fSReza Sabdar session->ns_data.dd_data_addr_v4.addr_type = NDMP_ADDR_TCP; 10432654012fSReza Sabdar session->ns_data.dd_data_addr_v4.tcp_addr_v4 = 10442654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_tcp_addr_v4)); 10452654012fSReza Sabdar 10462654012fSReza Sabdar session->ns_data.dd_data_addr_v4.tcp_ip_v4(0) = addr; 10472654012fSReza Sabdar session->ns_data.dd_data_addr_v4.tcp_port_v4(0) = ntohs(port); 10482654012fSReza Sabdar session->ns_data.dd_data_addr_v4.tcp_len_v4 = 1; 10492654012fSReza Sabdar 10502654012fSReza Sabdar /* Copy that to data_addr for compatibility */ 10512654012fSReza Sabdar session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP; 10522654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_ip_v3 = addr; 10532654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(port); 10542654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "listen_socket: %d", 10552654012fSReza Sabdar session->ns_data.dd_listen_sock); 10562654012fSReza Sabdar break; 10572654012fSReza Sabdar 10582654012fSReza Sabdar default: 10592654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid address type: %d", 10602654012fSReza Sabdar request->addr_type); 10612654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 10622654012fSReza Sabdar break; 10632654012fSReza Sabdar } 10642654012fSReza Sabdar 10652654012fSReza Sabdar if (reply.error == NDMP_NO_ERR) 10662654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_LISTEN; 10672654012fSReza Sabdar 10682654012fSReza Sabdar ndmp_send_reply(connection, &reply, 10692654012fSReza Sabdar "ndmp_data_listen_request_v4 reply"); 10702654012fSReza Sabdar } 10712654012fSReza Sabdar 10722654012fSReza Sabdar 10732654012fSReza Sabdar /* 10742654012fSReza Sabdar * ndmpd_data_start_recover_filehist_v4 10752654012fSReza Sabdar * 10762654012fSReza Sabdar * Request handler. Recovers the file history (not supported yet) 10772654012fSReza Sabdar * This command has an optional support in V4. 10782654012fSReza Sabdar * 10792654012fSReza Sabdar * Parameters: 10802654012fSReza Sabdar * connection (input) - connection handle. 10812654012fSReza Sabdar * body (input) - request message body. 10822654012fSReza Sabdar * 10832654012fSReza Sabdar * Returns: 10842654012fSReza Sabdar * void 10852654012fSReza Sabdar */ 10862654012fSReza Sabdar /*ARGSUSED*/ 10872654012fSReza Sabdar void 10882654012fSReza Sabdar ndmpd_data_start_recover_filehist_v4(ndmp_connection_t *connection, void *body) 10892654012fSReza Sabdar { 10902654012fSReza Sabdar ndmp_data_start_recover_filehist_reply_v4 reply; 10912654012fSReza Sabdar 10922654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Request not supported"); 10932654012fSReza Sabdar reply.error = NDMP_NOT_SUPPORTED_ERR; 10942654012fSReza Sabdar 10952654012fSReza Sabdar ndmp_send_reply(connection, &reply, 10962654012fSReza Sabdar "sending ndmp_data_start_recover_filehist_reply_v4 reply"); 10972654012fSReza Sabdar } 10982654012fSReza Sabdar 10992654012fSReza Sabdar /* 11002654012fSReza Sabdar * ************************************************************************ 11012654012fSReza Sabdar * LOCALS 11022654012fSReza Sabdar * ************************************************************************ 11032654012fSReza Sabdar */ 11042654012fSReza Sabdar 11052654012fSReza Sabdar /* 11062654012fSReza Sabdar * ndmpd_data_error_send 11072654012fSReza Sabdar * 11082654012fSReza Sabdar * This function sends the notify message to the client. 11092654012fSReza Sabdar * 11102654012fSReza Sabdar * Parameters: 11112654012fSReza Sabdar * session (input) - session pointer. 11122654012fSReza Sabdar * reason (input) - halt reason. 11132654012fSReza Sabdar * 11142654012fSReza Sabdar * Returns: 11152654012fSReza Sabdar * Error code 11162654012fSReza Sabdar */ 11172654012fSReza Sabdar /*ARGSUSED*/ 11182654012fSReza Sabdar static int 11192654012fSReza Sabdar ndmpd_data_error_send(ndmpd_session_t *session, ndmp_data_halt_reason reason) 11202654012fSReza Sabdar { 11212654012fSReza Sabdar ndmp_notify_data_halted_request req; 11222654012fSReza Sabdar 11232654012fSReza Sabdar req.reason = session->ns_data.dd_halt_reason; 11242654012fSReza Sabdar req.text_reason = ""; 11252654012fSReza Sabdar 11262654012fSReza Sabdar return (ndmp_send_request(session->ns_connection, 11272654012fSReza Sabdar NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, &req, 0)); 11282654012fSReza Sabdar } 11292654012fSReza Sabdar 11302654012fSReza Sabdar 11312654012fSReza Sabdar /* 11322654012fSReza Sabdar * ndmpd_data_error_send_v4 11332654012fSReza Sabdar * 11342654012fSReza Sabdar * This function sends the notify message to the client. 11352654012fSReza Sabdar * 11362654012fSReza Sabdar * Parameters: 11372654012fSReza Sabdar * session (input) - session pointer. 11382654012fSReza Sabdar * reason (input) - halt reason. 11392654012fSReza Sabdar * 11402654012fSReza Sabdar * Returns: 11412654012fSReza Sabdar * Error code 11422654012fSReza Sabdar */ 11432654012fSReza Sabdar /*ARGSUSED*/ 11442654012fSReza Sabdar static int 11452654012fSReza Sabdar ndmpd_data_error_send_v4(ndmpd_session_t *session, ndmp_data_halt_reason reason) 11462654012fSReza Sabdar { 11472654012fSReza Sabdar ndmp_notify_data_halted_request_v4 req; 11482654012fSReza Sabdar 11492654012fSReza Sabdar req.reason = session->ns_data.dd_halt_reason; 11502654012fSReza Sabdar 11512654012fSReza Sabdar return ndmp_send_request(session->ns_connection, 11522654012fSReza Sabdar NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, &req, 0); 11532654012fSReza Sabdar } 11542654012fSReza Sabdar 11552654012fSReza Sabdar 11562654012fSReza Sabdar /* 11572654012fSReza Sabdar * ndmpd_data_error 11582654012fSReza Sabdar * 11592654012fSReza Sabdar * This function is called when a data error has been detected. 11602654012fSReza Sabdar * A notify message is sent to the client and the data server is 11612654012fSReza Sabdar * placed into the halted state. 11622654012fSReza Sabdar * 11632654012fSReza Sabdar * Parameters: 11642654012fSReza Sabdar * session (input) - session pointer. 11652654012fSReza Sabdar * reason (input) - halt reason. 11662654012fSReza Sabdar * 11672654012fSReza Sabdar * Returns: 11682654012fSReza Sabdar * void 11692654012fSReza Sabdar */ 11702654012fSReza Sabdar void 11712654012fSReza Sabdar ndmpd_data_error(ndmpd_session_t *session, ndmp_data_halt_reason reason) 11722654012fSReza Sabdar { 11732654012fSReza Sabdar if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE || 11742654012fSReza Sabdar session->ns_data.dd_state == NDMP_DATA_STATE_HALTED) 11752654012fSReza Sabdar return; 11762654012fSReza Sabdar 11772654012fSReza Sabdar if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) { 11782654012fSReza Sabdar /* 11792654012fSReza Sabdar * Send/discard any buffered file history data. 11802654012fSReza Sabdar */ 11812654012fSReza Sabdar ndmpd_file_history_cleanup(session, 11822654012fSReza Sabdar (reason == NDMP_DATA_HALT_SUCCESSFUL ? TRUE : FALSE)); 11832654012fSReza Sabdar 11842654012fSReza Sabdar /* 11852654012fSReza Sabdar * If mover local and successful backup, write any 11862654012fSReza Sabdar * remaining buffered data to tape. 11872654012fSReza Sabdar */ 11882654012fSReza Sabdar if (session->ns_data.dd_data_addr.addr_type 11892654012fSReza Sabdar == NDMP_ADDR_LOCAL && reason == NDMP_DATA_HALT_SUCCESSFUL) 11902654012fSReza Sabdar (void) ndmpd_local_write_v3(session, 0, 0); 11912654012fSReza Sabdar } 11922654012fSReza Sabdar 11932654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_HALTED; 11942654012fSReza Sabdar session->ns_data.dd_halt_reason = reason; 11952654012fSReza Sabdar 11962654012fSReza Sabdar if (session->ns_protocol_version == NDMPV4) { 11972654012fSReza Sabdar if (ndmpd_data_error_send_v4(session, reason) < 0) 11982654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 11992654012fSReza Sabdar "Error sending notify_data_halted request"); 12002654012fSReza Sabdar } else { 12012654012fSReza Sabdar if (ndmpd_data_error_send(session, reason) < 0) 12022654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 12032654012fSReza Sabdar "Error sending notify_data_halted request"); 12042654012fSReza Sabdar } 12052654012fSReza Sabdar 12062654012fSReza Sabdar if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP) { 12072654012fSReza Sabdar if (session->ns_data.dd_sock != -1) { 12082654012fSReza Sabdar (void) ndmpd_remove_file_handler(session, 12092654012fSReza Sabdar session->ns_data.dd_sock); 12102654012fSReza Sabdar /* 12112654012fSReza Sabdar * ndmpcopy: we use the same socket for the mover, 12122654012fSReza Sabdar * so expect to close when mover is done! 12132654012fSReza Sabdar */ 12142654012fSReza Sabdar if (session->ns_data.dd_sock != 12152654012fSReza Sabdar session->ns_mover.md_sock) 12162654012fSReza Sabdar (void) close(session->ns_data.dd_sock); 12172654012fSReza Sabdar 12182654012fSReza Sabdar session->ns_data.dd_sock = -1; 12192654012fSReza Sabdar } 12202654012fSReza Sabdar if (session->ns_data.dd_listen_sock != -1) { 12212654012fSReza Sabdar (void) ndmpd_remove_file_handler(session, 12222654012fSReza Sabdar session->ns_data.dd_listen_sock); 12232654012fSReza Sabdar 12242654012fSReza Sabdar (void) close(session->ns_data.dd_listen_sock); 12252654012fSReza Sabdar session->ns_data.dd_listen_sock = -1; 12262654012fSReza Sabdar } 12272654012fSReza Sabdar } else { 12282654012fSReza Sabdar ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED); 12292654012fSReza Sabdar } 12302654012fSReza Sabdar } 12312654012fSReza Sabdar 12322654012fSReza Sabdar 12332654012fSReza Sabdar /* 12342654012fSReza Sabdar * data_accept_connection_v3 12352654012fSReza Sabdar * 12362654012fSReza Sabdar * Accept a data connection from a remote mover. 12372654012fSReza Sabdar * Called by ndmpd_select when a connection is pending on 12382654012fSReza Sabdar * the data listen socket. 12392654012fSReza Sabdar * 12402654012fSReza Sabdar * Parameters: 12412654012fSReza Sabdar * cookie (input) - session pointer. 12422654012fSReza Sabdar * fd (input) - file descriptor. 12432654012fSReza Sabdar * mode (input) - select mode. 12442654012fSReza Sabdar * 12452654012fSReza Sabdar * Returns: 12462654012fSReza Sabdar * void 12472654012fSReza Sabdar */ 12482654012fSReza Sabdar /*ARGSUSED*/ 12492654012fSReza Sabdar static void 12502654012fSReza Sabdar data_accept_connection_v3(void *cookie, int fd, ulong_t mode) 12512654012fSReza Sabdar { 12522654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie; 12532654012fSReza Sabdar int from_len; 12542654012fSReza Sabdar struct sockaddr_in from; 12552654012fSReza Sabdar 12562654012fSReza Sabdar from_len = sizeof (from); 12572654012fSReza Sabdar session->ns_data.dd_sock = accept(fd, (struct sockaddr *)&from, 12582654012fSReza Sabdar &from_len); 12592654012fSReza Sabdar 12602654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sock fd: %d", 12612654012fSReza Sabdar session->ns_data.dd_sock); 12622654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sin: port %d addr %s", 12632654012fSReza Sabdar ntohs(from.sin_port), 12642654012fSReza Sabdar inet_ntoa(IN_ADDR(from.sin_addr.s_addr))); 12652654012fSReza Sabdar 12662654012fSReza Sabdar (void) ndmpd_remove_file_handler(session, fd); 12672654012fSReza Sabdar (void) close(session->ns_data.dd_listen_sock); 12682654012fSReza Sabdar session->ns_data.dd_listen_sock = -1; 12692654012fSReza Sabdar 12702654012fSReza Sabdar if (session->ns_data.dd_sock < 0) { 12712654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Accept error: %m"); 12722654012fSReza Sabdar ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR); 12732654012fSReza Sabdar return; 12742654012fSReza Sabdar } 12752654012fSReza Sabdar 12762654012fSReza Sabdar /* 12772654012fSReza Sabdar * Save the peer address. 12782654012fSReza Sabdar */ 12792654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_ip_v3 = from.sin_addr.s_addr; 12802654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(from.sin_port); 12812654012fSReza Sabdar 1282*97f7c475SJan Kryl /* Set the parameter of the new socket */ 1283*97f7c475SJan Kryl set_socket_options(session->ns_data.dd_sock); 12842654012fSReza Sabdar 12852654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED; 12862654012fSReza Sabdar } 12872654012fSReza Sabdar 12882654012fSReza Sabdar 12892654012fSReza Sabdar /* 12902654012fSReza Sabdar * create_listen_socket_v3 12912654012fSReza Sabdar * 12922654012fSReza Sabdar * Creates the data sockets for listening for a remote mover/data 12932654012fSReza Sabdar * incoming connections. 12942654012fSReza Sabdar */ 12952654012fSReza Sabdar static int 12962654012fSReza Sabdar create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, ushort_t *port) 12972654012fSReza Sabdar { 12982654012fSReza Sabdar session->ns_data.dd_listen_sock = ndmp_create_socket(addr, port); 12992654012fSReza Sabdar if (session->ns_data.dd_listen_sock < 0) 13002654012fSReza Sabdar return (-1); 13012654012fSReza Sabdar 13022654012fSReza Sabdar /* 13032654012fSReza Sabdar * Add a file handler for the listen socket. 13042654012fSReza Sabdar * ndmpd_select will call data_accept_connection when a 13052654012fSReza Sabdar * connection is ready to be accepted. 13062654012fSReza Sabdar */ 13072654012fSReza Sabdar if (ndmpd_add_file_handler(session, (void*)session, 13082654012fSReza Sabdar session->ns_data.dd_listen_sock, NDMPD_SELECT_MODE_READ, HC_MOVER, 13092654012fSReza Sabdar data_accept_connection_v3) < 0) { 13102654012fSReza Sabdar (void) close(session->ns_data.dd_listen_sock); 13112654012fSReza Sabdar session->ns_data.dd_listen_sock = -1; 13122654012fSReza Sabdar return (-1); 13132654012fSReza Sabdar } 13142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "addr: %s:%d", 13152654012fSReza Sabdar inet_ntoa(IN_ADDR(*addr)), ntohs(*port)); 13162654012fSReza Sabdar 13172654012fSReza Sabdar return (0); 13182654012fSReza Sabdar } 13192654012fSReza Sabdar 13202654012fSReza Sabdar 13212654012fSReza Sabdar /* 13222654012fSReza Sabdar * data_connect_sock_v3 13232654012fSReza Sabdar * 13242654012fSReza Sabdar * Connect the data interface socket to the specified ip/port 13252654012fSReza Sabdar * 13262654012fSReza Sabdar * Parameters: 13272654012fSReza Sabdar * session (input) - session pointer. 13282654012fSReza Sabdar * addr (input) - IP address 13292654012fSReza Sabdar * port (input) - port number 13302654012fSReza Sabdar * 13312654012fSReza Sabdar * Returns: 13322654012fSReza Sabdar * NDMP_NO_ERR - backup successfully started. 13332654012fSReza Sabdar * otherwise - error code of backup start error. 13342654012fSReza Sabdar */ 13352654012fSReza Sabdar static ndmp_error 13362654012fSReza Sabdar data_connect_sock_v3(ndmpd_session_t *session, ulong_t addr, ushort_t port) 13372654012fSReza Sabdar { 13382654012fSReza Sabdar int sock; 13392654012fSReza Sabdar 13402654012fSReza Sabdar sock = ndmp_connect_sock_v3(addr, port); 13412654012fSReza Sabdar if (sock < 0) 13422654012fSReza Sabdar return (NDMP_CONNECT_ERR); 13432654012fSReza Sabdar 13442654012fSReza Sabdar session->ns_data.dd_sock = sock; 13452654012fSReza Sabdar session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP; 13462654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_ip_v3 = ntohl(addr); 13472654012fSReza Sabdar session->ns_data.dd_data_addr.tcp_port_v3 = port; 13482654012fSReza Sabdar 13492654012fSReza Sabdar return (NDMP_NO_ERR); 13502654012fSReza Sabdar } 13512654012fSReza Sabdar 13522654012fSReza Sabdar 13532654012fSReza Sabdar /* 13548c4f9701SJanice Chang * ndmpd_tar_start_backup_v3 13552654012fSReza Sabdar * 13562654012fSReza Sabdar * Start the backup work 13572654012fSReza Sabdar * 13582654012fSReza Sabdar * Parameters: 13592654012fSReza Sabdar * session (input) - session pointer. 13602654012fSReza Sabdar * bu_type (input) - backup type. 13612654012fSReza Sabdar * env_val (input) - environment variable array. 13622654012fSReza Sabdar * env_len (input) - length of env_val. 13632654012fSReza Sabdar * 13642654012fSReza Sabdar * Returns: 13652654012fSReza Sabdar * NDMP_NO_ERR - backup successfully started. 13662654012fSReza Sabdar * otherwise - error code of backup start error. 13672654012fSReza Sabdar */ 13682654012fSReza Sabdar static ndmp_error 13698c4f9701SJanice Chang ndmpd_tar_start_backup_v3(ndmpd_session_t *session, char *bu_type, 13708c4f9701SJanice Chang ndmp_pval *env_val, ulong_t env_len) 13712654012fSReza Sabdar { 13722654012fSReza Sabdar int err; 13732654012fSReza Sabdar ndmp_lbr_params_t *nlp; 13742654012fSReza Sabdar ndmpd_module_params_t *params; 13752654012fSReza Sabdar ndmp_data_start_backup_reply_v3 reply; 13762654012fSReza Sabdar 13772654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 13782654012fSReza Sabdar 13792654012fSReza Sabdar err = ndmpd_save_env(session, env_val, env_len); 13802654012fSReza Sabdar if (err != NDMP_NO_ERR) 13812654012fSReza Sabdar return (err); 13822654012fSReza Sabdar 13832654012fSReza Sabdar nlp = ndmp_get_nlp(session); 13842654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 13852654012fSReza Sabdar params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 13862654012fSReza Sabdar if (!params) 13872654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 13882654012fSReza Sabdar 13892654012fSReza Sabdar params->mp_daemon_cookie = (void *)session; 13902654012fSReza Sabdar params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 13912654012fSReza Sabdar params->mp_protocol_version = session->ns_protocol_version; 13922654012fSReza Sabdar params->mp_operation = NDMP_DATA_OP_BACKUP; 13932654012fSReza Sabdar params->mp_get_env_func = ndmpd_api_get_env; 13942654012fSReza Sabdar params->mp_add_env_func = ndmpd_api_add_env; 13952654012fSReza Sabdar params->mp_set_env_func = ndmpd_api_set_env; 13962654012fSReza Sabdar params->mp_get_name_func = 0; 13972654012fSReza Sabdar params->mp_dispatch_func = ndmpd_api_dispatch; 13982654012fSReza Sabdar params->mp_done_func = ndmpd_api_done_v3; 13992654012fSReza Sabdar if (session->ns_protocol_version == NDMPV4) 14002654012fSReza Sabdar params->mp_log_func_v3 = ndmpd_api_log_v4; 14012654012fSReza Sabdar else 14022654012fSReza Sabdar params->mp_log_func_v3 = ndmpd_api_log_v3; 14032654012fSReza Sabdar 14042654012fSReza Sabdar params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 14052654012fSReza Sabdar params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 14062654012fSReza Sabdar params->mp_write_func = ndmpd_api_write_v3; 14072654012fSReza Sabdar params->mp_read_func = 0; 14082654012fSReza Sabdar params->mp_file_recovered_func = 0; 14092654012fSReza Sabdar params->mp_stats = &session->ns_data.dd_module.dm_stats; 14102654012fSReza Sabdar session->ns_data.dd_module.dm_module_cookie = 0; 14112654012fSReza Sabdar 14122654012fSReza Sabdar if (strcmp(bu_type, NDMP_DUMP_TYPE) == 0) { 14132654012fSReza Sabdar NLP_SET(nlp, NLPF_DUMP); 14142654012fSReza Sabdar params->mp_file_history_path_func = 0; 14152654012fSReza Sabdar params->mp_file_history_dir_func = 14162654012fSReza Sabdar ndmpd_api_file_history_dir_v3; 14172654012fSReza Sabdar params->mp_file_history_node_func = 14182654012fSReza Sabdar ndmpd_api_file_history_node_v3; 14192654012fSReza Sabdar } else if (strcmp(bu_type, NDMP_TAR_TYPE) == 0) { 14202654012fSReza Sabdar NLP_SET(nlp, NLPF_TAR); 14212654012fSReza Sabdar params->mp_file_history_path_func = 14222654012fSReza Sabdar ndmpd_api_file_history_file_v3; 14232654012fSReza Sabdar params->mp_file_history_dir_func = 0; 14242654012fSReza Sabdar params->mp_file_history_node_func = 0; 14252654012fSReza Sabdar } else { 14262654012fSReza Sabdar NLP_UNSET(nlp, NLPF_DUMP); 14272654012fSReza Sabdar NLP_UNSET(nlp, NLPF_TAR); 14282654012fSReza Sabdar } 14292654012fSReza Sabdar 14302654012fSReza Sabdar session->ns_data.dd_module.dm_start_func = ndmpd_tar_backup_starter_v3; 14312654012fSReza Sabdar session->ns_data.dd_module.dm_abort_func = ndmpd_tar_backup_abort_v3; 14322654012fSReza Sabdar 14332654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 14342654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 14352654012fSReza Sabdar session->ns_data.dd_nlist_v3 = 0; 14362654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 14372654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read = 0; 14382654012fSReza Sabdar session->ns_data.dd_position = 0; 14392654012fSReza Sabdar session->ns_data.dd_discard_length = 0; 14402654012fSReza Sabdar session->ns_data.dd_read_offset = 0; 14412654012fSReza Sabdar session->ns_data.dd_read_length = 0; 14422654012fSReza Sabdar 14432654012fSReza Sabdar reply.error = ndmp_backup_get_params_v3(session, params); 14442654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 14452654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "err: %d", err); 14462654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 14472654012fSReza Sabdar return (reply.error); 14482654012fSReza Sabdar } 14492654012fSReza Sabdar 14502654012fSReza Sabdar reply.error = NDMP_NO_ERR; 14512654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 14522654012fSReza Sabdar &reply) < 0) { 14532654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Sending data_start_backup_v3 reply"); 14542654012fSReza Sabdar return (NDMP_NO_ERR); 14552654012fSReza Sabdar } 14562654012fSReza Sabdar 14572654012fSReza Sabdar NS_INC(nbk); 14582654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 14592654012fSReza Sabdar session->ns_data.dd_operation = NDMP_DATA_OP_BACKUP; 14602654012fSReza Sabdar session->ns_data.dd_abort = FALSE; 14612654012fSReza Sabdar 14622654012fSReza Sabdar /* 14632654012fSReza Sabdar * perform the backup 14642654012fSReza Sabdar * 14658c4f9701SJanice Chang * Cannot wait for the thread to exit as we are replying to the 14662654012fSReza Sabdar * client request here. 14672654012fSReza Sabdar */ 14682654012fSReza Sabdar err = pthread_create(NULL, NULL, 14692654012fSReza Sabdar (funct_t)session->ns_data.dd_module.dm_start_func, 14702654012fSReza Sabdar params); 14712654012fSReza Sabdar if (err != 0) { 14722654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Can't start backup session."); 14732654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 14742654012fSReza Sabdar } 14752654012fSReza Sabdar 14762654012fSReza Sabdar return (NDMP_NO_ERR); 14772654012fSReza Sabdar } 14782654012fSReza Sabdar 14792654012fSReza Sabdar /* 14808c4f9701SJanice Chang * ndmpd_tar_start_recover_v3 14812654012fSReza Sabdar * 14822654012fSReza Sabdar * Start the restore work 14832654012fSReza Sabdar * 14842654012fSReza Sabdar * Parameters: 14852654012fSReza Sabdar * session (input) - session pointer. 14862654012fSReza Sabdar * bu_type (input) - backup type. 14872654012fSReza Sabdar * env_val (input) - environment variable array. 14882654012fSReza Sabdar * env_len (input) - length of env_val. 14898c4f9701SJanice Chang * nlist_val (input) - list of files. 14908c4f9701SJanice Chang * nlist_len (input) - length of nlist_val. 14912654012fSReza Sabdar * 14922654012fSReza Sabdar * Returns: 14932654012fSReza Sabdar * NDMP_NO_ERR - recover successfully started. 14942654012fSReza Sabdar * otherwise - error code of recover start error. 14952654012fSReza Sabdar */ 14962654012fSReza Sabdar static ndmp_error 14978c4f9701SJanice Chang ndmpd_tar_start_recover_v3(ndmpd_session_t *session, 14988c4f9701SJanice Chang ndmp_pval *env_val, ulong_t env_len, ndmp_name_v3 *nlist_val, 14998c4f9701SJanice Chang ulong_t nlist_len) 15002654012fSReza Sabdar { 15012654012fSReza Sabdar ndmp_data_start_recover_reply_v3 reply; 15022654012fSReza Sabdar ndmpd_module_params_t *params; 15032654012fSReza Sabdar ndmp_lbr_params_t *nlp; 15042654012fSReza Sabdar int err; 15052654012fSReza Sabdar 15062654012fSReza Sabdar (void) memset((void*)&reply, 0, sizeof (reply)); 15072654012fSReza Sabdar 15082654012fSReza Sabdar nlp = ndmp_get_nlp(session); 15092654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 15102654012fSReza Sabdar params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 15112654012fSReza Sabdar if (!params) { 15122654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 15132654012fSReza Sabdar } 15142654012fSReza Sabdar 15152654012fSReza Sabdar reply.error = ndmpd_save_env(session, env_val, env_len); 15162654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 15172654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 15182654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 15192654012fSReza Sabdar } 15202654012fSReza Sabdar 15212654012fSReza Sabdar reply.error = ndmpd_save_nlist_v3(session, nlist_val, nlist_len); 15222654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) { 15232654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 15242654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 15252654012fSReza Sabdar } 15262654012fSReza Sabdar 15272654012fSReza Sabdar /* 15282654012fSReza Sabdar * Setup restore parameters. 15292654012fSReza Sabdar */ 15302654012fSReza Sabdar params->mp_daemon_cookie = (void *)session; 15312654012fSReza Sabdar params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 15322654012fSReza Sabdar params->mp_protocol_version = session->ns_protocol_version; 15332654012fSReza Sabdar params->mp_operation = NDMP_DATA_OP_RECOVER; 15342654012fSReza Sabdar params->mp_get_env_func = ndmpd_api_get_env; 15352654012fSReza Sabdar params->mp_add_env_func = ndmpd_api_add_env; 15362654012fSReza Sabdar params->mp_set_env_func = ndmpd_api_set_env; 15372654012fSReza Sabdar params->mp_get_name_func = ndmpd_api_get_name_v3; 15382654012fSReza Sabdar params->mp_dispatch_func = ndmpd_api_dispatch; 15392654012fSReza Sabdar params->mp_done_func = ndmpd_api_done_v3; 15402654012fSReza Sabdar if (session->ns_protocol_version == NDMPV4) { 15412654012fSReza Sabdar params->mp_log_func_v3 = ndmpd_api_log_v4; 15422654012fSReza Sabdar params->mp_file_recovered_func = ndmpd_api_file_recovered_v4; 15432654012fSReza Sabdar } else { 15442654012fSReza Sabdar params->mp_log_func_v3 = ndmpd_api_log_v3; 15452654012fSReza Sabdar params->mp_file_recovered_func = ndmpd_api_file_recovered_v3; 15462654012fSReza Sabdar } 15472654012fSReza Sabdar 15482654012fSReza Sabdar params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 15492654012fSReza Sabdar params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 15502654012fSReza Sabdar params->mp_write_func = 0; 15512654012fSReza Sabdar params->mp_file_history_path_func = 0; 15522654012fSReza Sabdar params->mp_file_history_dir_func = 0; 15532654012fSReza Sabdar params->mp_file_history_node_func = 0; 15542654012fSReza Sabdar params->mp_read_func = ndmpd_api_read_v3; 15552654012fSReza Sabdar params->mp_seek_func = ndmpd_api_seek_v3; 15562654012fSReza Sabdar params->mp_stats = &session->ns_data.dd_module.dm_stats; 15572654012fSReza Sabdar 15582654012fSReza Sabdar session->ns_data.dd_module.dm_module_cookie = 0; 15592654012fSReza Sabdar session->ns_data.dd_module.dm_start_func = ndmpd_tar_restore_starter_v3; 15602654012fSReza Sabdar session->ns_data.dd_module.dm_abort_func = ndmpd_tar_restore_abort_v3; 15612654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 15622654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 15632654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read = 0; 15642654012fSReza Sabdar session->ns_data.dd_position = 0; 15652654012fSReza Sabdar session->ns_data.dd_discard_length = 0; 15662654012fSReza Sabdar session->ns_data.dd_read_offset = 0; 15672654012fSReza Sabdar session->ns_data.dd_read_length = 0; 15682654012fSReza Sabdar 15692654012fSReza Sabdar err = ndmp_restore_get_params_v3(session, params); 15702654012fSReza Sabdar if (err != NDMP_NO_ERR) { 15712654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 15722654012fSReza Sabdar return (err); 15732654012fSReza Sabdar } 15742654012fSReza Sabdar 15752654012fSReza Sabdar reply.error = NDMP_NO_ERR; 15762654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 15772654012fSReza Sabdar &reply) < 0) { 15782654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 15792654012fSReza Sabdar ndmpd_free_nlist_v3(session); 15802654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15812654012fSReza Sabdar "Error sending ndmp_data_start_recover_reply"); 15822654012fSReza Sabdar ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR); 15832654012fSReza Sabdar return (NDMP_NO_ERR); 15842654012fSReza Sabdar } 15852654012fSReza Sabdar 15862654012fSReza Sabdar NS_INC(nrs); 15872654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 15882654012fSReza Sabdar session->ns_data.dd_operation = NDMP_DATA_OP_RECOVER; 15892654012fSReza Sabdar session->ns_data.dd_abort = FALSE; 15902654012fSReza Sabdar 15912654012fSReza Sabdar /* 15922654012fSReza Sabdar * perform the restore 15932654012fSReza Sabdar * 15942654012fSReza Sabdar * Cannot wait for the thread to exit as we are replying to the 15952654012fSReza Sabdar * client request here. 15962654012fSReza Sabdar */ 15972654012fSReza Sabdar err = pthread_create(NULL, NULL, 15982654012fSReza Sabdar (funct_t)session->ns_data.dd_module.dm_start_func, 15992654012fSReza Sabdar params); 16002654012fSReza Sabdar 16012654012fSReza Sabdar if (err != 0) { 16022654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Can't start recover session."); 16032654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 16042654012fSReza Sabdar } 16052654012fSReza Sabdar return (NDMP_NO_ERR); 16062654012fSReza Sabdar } 16072654012fSReza Sabdar 16088c4f9701SJanice Chang static ndmp_error 16098c4f9701SJanice Chang ndmpd_zfs_start_op(ndmpd_session_t *session, ndmp_pval *env_val, 16108c4f9701SJanice Chang ulong_t env_len, ndmp_name_v3 *nlist_val, ulong_t nlist_len, 16118c4f9701SJanice Chang enum ndmp_data_operation op) 16128c4f9701SJanice Chang { 16138c4f9701SJanice Chang ndmpd_zfs_args_t *ndmpd_zfs_args = &session->ns_ndmpd_zfs_args; 16148c4f9701SJanice Chang ndmp_data_start_backup_reply_v3 backup_reply; 16158c4f9701SJanice Chang ndmp_data_start_recover_reply_v3 recover_reply; 16168c4f9701SJanice Chang pthread_t tid; 16178c4f9701SJanice Chang void *reply; 16188c4f9701SJanice Chang char str[8]; 16198c4f9701SJanice Chang int err; 16208c4f9701SJanice Chang 16218c4f9701SJanice Chang if (ndmpd_zfs_init(session) != 0) 16228c4f9701SJanice Chang return (NDMP_UNDEFINED_ERR); 16238c4f9701SJanice Chang 16248c4f9701SJanice Chang err = ndmpd_save_env(session, env_val, env_len); 16258c4f9701SJanice Chang if (err != NDMP_NO_ERR) { 16268c4f9701SJanice Chang ndmpd_zfs_fini(ndmpd_zfs_args); 16278c4f9701SJanice Chang return (err); 16288c4f9701SJanice Chang } 16298c4f9701SJanice Chang 16308c4f9701SJanice Chang switch (op) { 16318c4f9701SJanice Chang case NDMP_DATA_OP_BACKUP: 16328c4f9701SJanice Chang if (!ndmpd_zfs_backup_parms_valid(ndmpd_zfs_args)) { 16338c4f9701SJanice Chang ndmpd_zfs_fini(ndmpd_zfs_args); 16348c4f9701SJanice Chang return (NDMP_ILLEGAL_ARGS_ERR); 16358c4f9701SJanice Chang } 16368c4f9701SJanice Chang 16378c4f9701SJanice Chang if (ndmpd_zfs_pre_backup(ndmpd_zfs_args)) { 16388c4f9701SJanice Chang NDMP_LOG(LOG_ERR, "pre_backup error"); 16398c4f9701SJanice Chang return (NDMP_ILLEGAL_ARGS_ERR); 16408c4f9701SJanice Chang } 16418c4f9701SJanice Chang 16428c4f9701SJanice Chang session->ns_data.dd_module.dm_start_func = 16438c4f9701SJanice Chang ndmpd_zfs_backup_starter; 16448c4f9701SJanice Chang (void) strlcpy(str, "backup", 8); 16458c4f9701SJanice Chang break; 16468c4f9701SJanice Chang case NDMP_DATA_OP_RECOVER: 16478c4f9701SJanice Chang err = ndmpd_save_nlist_v3(session, nlist_val, nlist_len); 16488c4f9701SJanice Chang if (err != NDMP_NO_ERR) { 16498c4f9701SJanice Chang ndmpd_zfs_fini(ndmpd_zfs_args); 16508c4f9701SJanice Chang return (NDMP_NO_MEM_ERR); 16518c4f9701SJanice Chang } 16528c4f9701SJanice Chang 16538c4f9701SJanice Chang if (!ndmpd_zfs_restore_parms_valid(ndmpd_zfs_args)) { 16548c4f9701SJanice Chang ndmpd_zfs_fini(ndmpd_zfs_args); 16558c4f9701SJanice Chang return (NDMP_ILLEGAL_ARGS_ERR); 16568c4f9701SJanice Chang } 16578c4f9701SJanice Chang 16588c4f9701SJanice Chang if (ndmpd_zfs_pre_restore(ndmpd_zfs_args)) { 16598c4f9701SJanice Chang NDMP_LOG(LOG_ERR, "pre_restore error"); 16608c4f9701SJanice Chang (void) ndmpd_zfs_post_restore(ndmpd_zfs_args); 16618c4f9701SJanice Chang return (NDMP_ILLEGAL_ARGS_ERR); 16628c4f9701SJanice Chang } 16638c4f9701SJanice Chang session->ns_data.dd_module.dm_start_func = 16648c4f9701SJanice Chang ndmpd_zfs_restore_starter; 16658c4f9701SJanice Chang (void) strlcpy(str, "recover", 8); 16668c4f9701SJanice Chang break; 16678c4f9701SJanice Chang } 16688c4f9701SJanice Chang 16698c4f9701SJanice Chang ndmpd_zfs_params->mp_operation = op; 16708c4f9701SJanice Chang session->ns_data.dd_operation = op; 16718c4f9701SJanice Chang session->ns_data.dd_module.dm_abort_func = ndmpd_zfs_abort; 16728c4f9701SJanice Chang session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 16738c4f9701SJanice Chang session->ns_data.dd_abort = FALSE; 16748c4f9701SJanice Chang 16758c4f9701SJanice Chang if (op == NDMP_DATA_OP_BACKUP) { 16768c4f9701SJanice Chang (void) memset((void*)&backup_reply, 0, sizeof (backup_reply)); 16778c4f9701SJanice Chang backup_reply.error = NDMP_NO_ERR; 16788c4f9701SJanice Chang reply = &backup_reply; 16798c4f9701SJanice Chang } else { 16808c4f9701SJanice Chang (void) memset((void*)&recover_reply, 0, sizeof (recover_reply)); 16818c4f9701SJanice Chang recover_reply.error = NDMP_NO_ERR; 16828c4f9701SJanice Chang reply = &recover_reply; 16838c4f9701SJanice Chang } 16848c4f9701SJanice Chang 16858c4f9701SJanice Chang if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 16868c4f9701SJanice Chang reply) < 0) { 16878c4f9701SJanice Chang NDMP_LOG(LOG_DEBUG, "Sending data_start_%s_v3 reply", str); 16888c4f9701SJanice Chang if (op == NDMP_DATA_OP_RECOVER) 16898c4f9701SJanice Chang ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR); 16908c4f9701SJanice Chang ndmpd_zfs_fini(ndmpd_zfs_args); 16918c4f9701SJanice Chang return (NDMP_NO_ERR); 16928c4f9701SJanice Chang } 16938c4f9701SJanice Chang 16948c4f9701SJanice Chang err = pthread_create(&tid, NULL, 16958c4f9701SJanice Chang (funct_t)session->ns_data.dd_module.dm_start_func, ndmpd_zfs_args); 16968c4f9701SJanice Chang 16978c4f9701SJanice Chang if (err) { 16988c4f9701SJanice Chang NDMP_LOG(LOG_ERR, "Can't start %s session (errno %d)", 16998c4f9701SJanice Chang str, err); 17008c4f9701SJanice Chang ndmpd_zfs_fini(ndmpd_zfs_args); 17018c4f9701SJanice Chang MOD_DONE(ndmpd_zfs_params, -1); 17028c4f9701SJanice Chang return (NDMP_NO_ERR); 17038c4f9701SJanice Chang } 17048c4f9701SJanice Chang 17058c4f9701SJanice Chang (void) pthread_detach(tid); 17068c4f9701SJanice Chang 17078c4f9701SJanice Chang if (op == NDMP_DATA_OP_BACKUP) 17088c4f9701SJanice Chang NS_INC(nbk); 17098c4f9701SJanice Chang else 17108c4f9701SJanice Chang NS_INC(nrs); 17118c4f9701SJanice Chang 17128c4f9701SJanice Chang ndmpd_zfs_dma_log(ndmpd_zfs_args, NDMP_LOG_NORMAL, 17138c4f9701SJanice Chang "'zfs' %s starting\n", str); 17148c4f9701SJanice Chang 17158c4f9701SJanice Chang return (NDMP_NO_ERR); 17168c4f9701SJanice Chang } 17172654012fSReza Sabdar 17182654012fSReza Sabdar /* 17192654012fSReza Sabdar * discard_data_v3 17202654012fSReza Sabdar * 17212654012fSReza Sabdar * Read and discard data from the data connection. 17222654012fSReza Sabdar * Called when a module has called ndmpd_seek() prior to 17232654012fSReza Sabdar * reading all of the data from the previous seek. 17242654012fSReza Sabdar * 17252654012fSReza Sabdar * Parameters: 17262654012fSReza Sabdar * session (input) - session pointer. 17272654012fSReza Sabdar * 17282654012fSReza Sabdar * Returns: 17292654012fSReza Sabdar * number of bytes read and discarded. 17302654012fSReza Sabdar * -1 - error. 17312654012fSReza Sabdar */ 17322654012fSReza Sabdar static int 17332654012fSReza Sabdar discard_data_v3(ndmpd_session_t *session, ulong_t length) 17342654012fSReza Sabdar { 17352654012fSReza Sabdar static char buf[MAX_RECORD_SIZE]; 17362654012fSReza Sabdar int n, toread; 17372654012fSReza Sabdar 17382654012fSReza Sabdar toread = (length < MAX_RECORD_SIZE) ? length : 17392654012fSReza Sabdar MAX_RECORD_SIZE; 17402654012fSReza Sabdar 17412654012fSReza Sabdar /* Read and discard the data. */ 17422654012fSReza Sabdar n = read(session->ns_data.dd_sock, buf, toread); 17432654012fSReza Sabdar if (n < 0) { 17442654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Socket read error: %m."); 17452654012fSReza Sabdar n = -1; 17462654012fSReza Sabdar } 17472654012fSReza Sabdar 17482654012fSReza Sabdar return (n); 17492654012fSReza Sabdar } 17502654012fSReza Sabdar 17512654012fSReza Sabdar 17522654012fSReza Sabdar /* 17532654012fSReza Sabdar * ndmpd_remote_read_v3 17542654012fSReza Sabdar * 17552654012fSReza Sabdar * Reads data from the remote mover. 17562654012fSReza Sabdar * 17572654012fSReza Sabdar * Parameters: 17582654012fSReza Sabdar * session (input) - session pointer. 17592654012fSReza Sabdar * data (input) - data to be written. 17602654012fSReza Sabdar * length (input) - data length. 17612654012fSReza Sabdar * 17622654012fSReza Sabdar * Returns: 17632654012fSReza Sabdar * 0 - data successfully read. 17642654012fSReza Sabdar * -1 - error. 17652654012fSReza Sabdar */ 17662654012fSReza Sabdar int 17672654012fSReza Sabdar ndmpd_remote_read_v3(ndmpd_session_t *session, char *data, ulong_t length) 17682654012fSReza Sabdar { 17692654012fSReza Sabdar ulong_t count; 17702654012fSReza Sabdar ulong_t len; 17712654012fSReza Sabdar ssize_t n; 17722654012fSReza Sabdar ndmp_notify_data_read_request request; 17732654012fSReza Sabdar tlm_job_stats_t *jstat; 17742654012fSReza Sabdar longlong_t fsize; 17752654012fSReza Sabdar 17762654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ns_data.dd_xx: [%llu, %llu, %llu, %llu, %llu]", 17772654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read, 17782654012fSReza Sabdar session->ns_data.dd_read_offset, 17792654012fSReza Sabdar session->ns_data.dd_read_length, 17802654012fSReza Sabdar session->ns_data.dd_position, 17812654012fSReza Sabdar session->ns_data.dd_discard_length); 17822654012fSReza Sabdar 17832654012fSReza Sabdar count = 0; 17842654012fSReza Sabdar while (count < length) { 17852654012fSReza Sabdar len = length - count; 17862654012fSReza Sabdar 17872654012fSReza Sabdar /* 17882654012fSReza Sabdar * If the end of the seek window has been reached then 17892654012fSReza Sabdar * send an ndmp_read request to the client. 17902654012fSReza Sabdar * The NDMP client will then send a mover_data_read request to 17912654012fSReza Sabdar * the remote mover and the mover will send more data. 17922654012fSReza Sabdar * This condition can occur if the module attempts to read past 17932654012fSReza Sabdar * a seek window set via a prior call to ndmpd_seek() or 17942654012fSReza Sabdar * the module has not issued a seek. If no seek was issued then 17952654012fSReza Sabdar * pretend that a seek was issued to read the entire tape. 17962654012fSReza Sabdar */ 17972654012fSReza Sabdar if (session->ns_data.dd_bytes_left_to_read == 0) { 17982654012fSReza Sabdar /* ndmpd_seek() never called? */ 17992654012fSReza Sabdar if (session->ns_data.dd_read_length == 0) { 18002654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read = ~0LL; 18012654012fSReza Sabdar session->ns_data.dd_read_offset = 0LL; 18022654012fSReza Sabdar session->ns_data.dd_read_length = ~0LL; 18032654012fSReza Sabdar } else { 18042654012fSReza Sabdar /* 18052654012fSReza Sabdar * While restoring a file, restoreFile() 18062654012fSReza Sabdar * records the number of bytes still need to 18072654012fSReza Sabdar * be restored. We use this as a guidance 18082654012fSReza Sabdar * when asking for data from the tape. 18092654012fSReza Sabdar */ 18102654012fSReza Sabdar jstat = session->ns_ndmp_lbr_params->nlp_jstat; 18112654012fSReza Sabdar fsize = jstat->js_bytes_in_file; 18122654012fSReza Sabdar 18132654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "bytes_left [%llu / %u]", 18142654012fSReza Sabdar fsize, len); 18152654012fSReza Sabdar 18162654012fSReza Sabdar /* 18172654012fSReza Sabdar * Fall back to the old way if fsize if too 18182654012fSReza Sabdar * small. 18192654012fSReza Sabdar */ 18202654012fSReza Sabdar if (fsize < len) 18212654012fSReza Sabdar fsize = len; 18222654012fSReza Sabdar 18232654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read = fsize; 18242654012fSReza Sabdar session->ns_data.dd_read_offset = 18252654012fSReza Sabdar session->ns_data.dd_position; 18262654012fSReza Sabdar session->ns_data.dd_read_length = fsize; 18272654012fSReza Sabdar } 18282654012fSReza Sabdar 18292654012fSReza Sabdar request.offset = 18302654012fSReza Sabdar long_long_to_quad(session->ns_data.dd_read_offset); 18312654012fSReza Sabdar request.length = 18322654012fSReza Sabdar long_long_to_quad(session->ns_data.dd_read_length); 18332654012fSReza Sabdar 18342654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "to NOTIFY_DATA_READ [%llu, %llu]", 18352654012fSReza Sabdar session->ns_data.dd_read_offset, 18362654012fSReza Sabdar session->ns_data.dd_read_length); 18372654012fSReza Sabdar 18387bc22e45SReza Sabdar if (ndmp_send_request_lock(session->ns_connection, 18392654012fSReza Sabdar NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR, 18402654012fSReza Sabdar &request, 0) < 0) { 18412654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 18422654012fSReza Sabdar "Sending notify_data_read request"); 18432654012fSReza Sabdar return (-1); 18442654012fSReza Sabdar } 18452654012fSReza Sabdar } 18462654012fSReza Sabdar 18472654012fSReza Sabdar /* 18482654012fSReza Sabdar * If the module called ndmpd_seek() prior to reading all of the 18492654012fSReza Sabdar * data that the remote mover was requested to send, then the 18502654012fSReza Sabdar * excess data from the seek has to be discarded. 18512654012fSReza Sabdar */ 18522654012fSReza Sabdar if (session->ns_data.dd_discard_length != 0) { 18532654012fSReza Sabdar n = discard_data_v3(session, 18542654012fSReza Sabdar (ulong_t)session->ns_data.dd_discard_length); 18552654012fSReza Sabdar if (n < 0) 18562654012fSReza Sabdar return (-1); 18572654012fSReza Sabdar 18582654012fSReza Sabdar session->ns_data.dd_discard_length -= n; 18592654012fSReza Sabdar continue; 18602654012fSReza Sabdar } 18612654012fSReza Sabdar 18622654012fSReza Sabdar /* 18632654012fSReza Sabdar * Don't attempt to read more data than the remote is sending. 18642654012fSReza Sabdar */ 18652654012fSReza Sabdar if (len > session->ns_data.dd_bytes_left_to_read) 18662654012fSReza Sabdar len = session->ns_data.dd_bytes_left_to_read; 18672654012fSReza Sabdar 18682654012fSReza Sabdar if ((n = read(session->ns_data.dd_sock, &data[count], 18692654012fSReza Sabdar len)) < 0) { 18702654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Socket read error: %m."); 18712654012fSReza Sabdar return (-1); 18722654012fSReza Sabdar } 18732654012fSReza Sabdar 18742654012fSReza Sabdar /* read returns 0 if the connection was closed */ 18752654012fSReza Sabdar if (n == 0) { 18762654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "n 0 errno %d", 18772654012fSReza Sabdar errno); 18782654012fSReza Sabdar return (-1); 18792654012fSReza Sabdar } 18802654012fSReza Sabdar 18812654012fSReza Sabdar count += n; 18822654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read -= n; 18832654012fSReza Sabdar session->ns_data.dd_position += n; 18842654012fSReza Sabdar } 18852654012fSReza Sabdar return (0); 18862654012fSReza Sabdar } 18872654012fSReza Sabdar 18882654012fSReza Sabdar /* 18892654012fSReza Sabdar * nlp_release_job_stat 18902654012fSReza Sabdar * 18912654012fSReza Sabdar * Unreference the job statistics 18922654012fSReza Sabdar * 18932654012fSReza Sabdar * Parameters: 18942654012fSReza Sabdar * session (input) - session pointer. 18952654012fSReza Sabdar * 18962654012fSReza Sabdar * Returns: 18972654012fSReza Sabdar * void 18982654012fSReza Sabdar */ 18992654012fSReza Sabdar static void 19002654012fSReza Sabdar nlp_release_job_stat(ndmpd_session_t *session) 19012654012fSReza Sabdar { 19022654012fSReza Sabdar ndmp_lbr_params_t *nlp; 19032654012fSReza Sabdar 19042654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 19052654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 19062654012fSReza Sabdar return; 19072654012fSReza Sabdar } 19082654012fSReza Sabdar if (nlp->nlp_jstat != NULL) { 19092654012fSReza Sabdar nlp->nlp_bytes_total = 19102654012fSReza Sabdar (u_longlong_t)nlp->nlp_jstat->js_bytes_total; 19112654012fSReza Sabdar tlm_un_ref_job_stats(nlp->nlp_jstat->js_job_name); 19122654012fSReza Sabdar nlp->nlp_jstat = NULL; 19132654012fSReza Sabdar } else 19142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "JSTAT == NULL"); 19152654012fSReza Sabdar } 19162654012fSReza Sabdar 19172654012fSReza Sabdar 19182654012fSReza Sabdar /* *** ndmpd global internal functions *********************************** */ 19192654012fSReza Sabdar 19202654012fSReza Sabdar /* 19212654012fSReza Sabdar * ndmpd_data_init 19222654012fSReza Sabdar * 19232654012fSReza Sabdar * Initializes data specific session variables. 19242654012fSReza Sabdar * 19252654012fSReza Sabdar * Parameters: 19262654012fSReza Sabdar * session (input) - session pointer. 19272654012fSReza Sabdar * 19282654012fSReza Sabdar * Returns: 19292654012fSReza Sabdar * void 19302654012fSReza Sabdar */ 19312654012fSReza Sabdar int 19322654012fSReza Sabdar ndmpd_data_init(ndmpd_session_t *session) 19332654012fSReza Sabdar { 19342654012fSReza Sabdar session->ns_data.dd_operation = NDMP_DATA_OP_NOACTION; 19352654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_IDLE; 19362654012fSReza Sabdar session->ns_data.dd_halt_reason = NDMP_DATA_HALT_NA; 19372654012fSReza Sabdar session->ns_data.dd_abort = FALSE; 19382654012fSReza Sabdar session->ns_data.dd_env = 0; 19392654012fSReza Sabdar session->ns_data.dd_env_len = 0; 19402654012fSReza Sabdar session->ns_data.dd_nlist = 0; 19412654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 19422654012fSReza Sabdar session->ns_data.dd_mover.addr_type = NDMP_ADDR_LOCAL; 19432654012fSReza Sabdar session->ns_data.dd_sock = -1; 19442654012fSReza Sabdar session->ns_data.dd_read_offset = 0; 19452654012fSReza Sabdar session->ns_data.dd_read_length = 0; 19462654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 19472654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 19482654012fSReza Sabdar /* 19492654012fSReza Sabdar * NDMP V3 19502654012fSReza Sabdar */ 19512654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_IDLE; 19522654012fSReza Sabdar session->ns_data.dd_nlist_v3 = 0; 19532654012fSReza Sabdar session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL; 19542654012fSReza Sabdar session->ns_data.dd_listen_sock = -1; 19552654012fSReza Sabdar session->ns_data.dd_bytes_left_to_read = 0LL; 19562654012fSReza Sabdar session->ns_data.dd_position = 0LL; 19572654012fSReza Sabdar session->ns_data.dd_discard_length = 0LL; 19582654012fSReza Sabdar return (0); 19592654012fSReza Sabdar } 19602654012fSReza Sabdar 19612654012fSReza Sabdar 19622654012fSReza Sabdar 19632654012fSReza Sabdar /* 19642654012fSReza Sabdar * ndmpd_data_cleanup 19652654012fSReza Sabdar * 19662654012fSReza Sabdar * Releases resources allocated during a data operation. 19672654012fSReza Sabdar * 19682654012fSReza Sabdar * Parameters: 19692654012fSReza Sabdar * session (input) - session pointer. 19702654012fSReza Sabdar * 19712654012fSReza Sabdar * Returns: 19722654012fSReza Sabdar * void 19732654012fSReza Sabdar */ 19742654012fSReza Sabdar void 19752654012fSReza Sabdar ndmpd_data_cleanup(ndmpd_session_t *session) 19762654012fSReza Sabdar { 19772654012fSReza Sabdar if (session->ns_data.dd_listen_sock != -1) { 19782654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "data.listen_sock: %d", 19792654012fSReza Sabdar session->ns_data.dd_listen_sock); 19802654012fSReza Sabdar (void) ndmpd_remove_file_handler(session, 19812654012fSReza Sabdar session->ns_data.dd_listen_sock); 19822654012fSReza Sabdar (void) close(session->ns_data.dd_listen_sock); 19832654012fSReza Sabdar session->ns_data.dd_listen_sock = -1; 19842654012fSReza Sabdar } 19852654012fSReza Sabdar if (session->ns_data.dd_sock != -1) { 19862654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "data.sock: %d", 19872654012fSReza Sabdar session->ns_data.dd_sock); 19882654012fSReza Sabdar 19892654012fSReza Sabdar /* 19902654012fSReza Sabdar * ndmpcopy: we use the same socket for the mover, 19912654012fSReza Sabdar * so expect to close when mover is done! 19922654012fSReza Sabdar */ 19932654012fSReza Sabdar if (session->ns_data.dd_sock != session->ns_mover.md_sock) 19942654012fSReza Sabdar (void) close(session->ns_data.dd_sock); 19952654012fSReza Sabdar 19962654012fSReza Sabdar session->ns_data.dd_sock = -1; 19972654012fSReza Sabdar } 19982654012fSReza Sabdar 19992654012fSReza Sabdar ndmpd_free_env(session); 20002654012fSReza Sabdar ndmpd_free_nlist(session); 20012654012fSReza Sabdar } 20022654012fSReza Sabdar 20032654012fSReza Sabdar 20042654012fSReza Sabdar /* 20052654012fSReza Sabdar * ndmp_data_get_mover_mode 20062654012fSReza Sabdar * 20072654012fSReza Sabdar * Return the mover mode 20082654012fSReza Sabdar * 20092654012fSReza Sabdar * Parameters: 20102654012fSReza Sabdar * session (input) - session pointer. 20112654012fSReza Sabdar * 20122654012fSReza Sabdar * Returns: 20132654012fSReza Sabdar * remote - remote backup 20142654012fSReza Sabdar * local - local backup 20152654012fSReza Sabdar */ 20162654012fSReza Sabdar char * 20172654012fSReza Sabdar ndmp_data_get_mover_mode(ndmpd_session_t *session) 20182654012fSReza Sabdar { 20192654012fSReza Sabdar char *rv; 20202654012fSReza Sabdar 20212654012fSReza Sabdar switch (session->ns_protocol_version) { 20222654012fSReza Sabdar case NDMPV2: 20232654012fSReza Sabdar rv = ((session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) 20242654012fSReza Sabdar ? "remote" : "local"); 20252654012fSReza Sabdar break; 20262654012fSReza Sabdar case NDMPV3: 20272654012fSReza Sabdar rv = ((session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP) 20282654012fSReza Sabdar ? "remote" : "local"); 20292654012fSReza Sabdar break; 20302654012fSReza Sabdar case NDMPV4: 20312654012fSReza Sabdar rv = ((session->ns_data.dd_data_addr.addr_type == 20322654012fSReza Sabdar NDMP_ADDR_TCP || 20332654012fSReza Sabdar (session->ns_data.dd_data_addr_v4.addr_type == 20342654012fSReza Sabdar NDMP_ADDR_TCP)) ? "remote" : "local"); 20352654012fSReza Sabdar break; 20362654012fSReza Sabdar default: 20378c4f9701SJanice Chang rv = "Unknown"; 20382654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid protocol version %d.", 20392654012fSReza Sabdar session->ns_protocol_version); 20402654012fSReza Sabdar } 20412654012fSReza Sabdar 20422654012fSReza Sabdar return (rv); 20432654012fSReza Sabdar } 20442654012fSReza Sabdar 20452654012fSReza Sabdar /* *** static functions ******************************************** */ 20462654012fSReza Sabdar 20472654012fSReza Sabdar /* 20488c4f9701SJanice Chang * ndmpd_tar_start_backup_v2 20492654012fSReza Sabdar * 20502654012fSReza Sabdar * Request handling code common to version 1 and 20512654012fSReza Sabdar * version 2 data_start_backup request handlers. 20522654012fSReza Sabdar * 20532654012fSReza Sabdar * Parameters: 20542654012fSReza Sabdar * session (input) - session pointer. 20552654012fSReza Sabdar * bu_type (input) - backup type. 20562654012fSReza Sabdar * env_val (input) - environment variable array. 20572654012fSReza Sabdar * env_len (input) - length of env_val. 20582654012fSReza Sabdar * 20592654012fSReza Sabdar * Returns: 20602654012fSReza Sabdar * NDMP_NO_ERR - backup successfully started. 20612654012fSReza Sabdar * otherwise - error code of backup start error. 20622654012fSReza Sabdar */ 20632654012fSReza Sabdar static ndmp_error 20648c4f9701SJanice Chang ndmpd_tar_start_backup_v2(ndmpd_session_t *session, char *bu_type, 20658c4f9701SJanice Chang ndmp_pval *env_val, ulong_t env_len) 20662654012fSReza Sabdar { 20672654012fSReza Sabdar ndmp_data_start_backup_reply reply; 20682654012fSReza Sabdar ndmpd_module_params_t *params; 20692654012fSReza Sabdar ndmp_lbr_params_t *nlp; 20702654012fSReza Sabdar int err; 20712654012fSReza Sabdar 20722654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 20732654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Can't start new backup in current state."); 20742654012fSReza Sabdar return (NDMP_ILLEGAL_STATE_ERR); 20752654012fSReza Sabdar } 20762654012fSReza Sabdar if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 && 20772654012fSReza Sabdar strcmp(bu_type, NDMP_TAR_TYPE) != 0) { 20782654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type); 20792654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump."); 20802654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 20812654012fSReza Sabdar } 20822654012fSReza Sabdar if ((err = ndmpd_save_env(session, env_val, env_len)) != NDMP_NO_ERR) 20832654012fSReza Sabdar return (err); 20842654012fSReza Sabdar 20852654012fSReza Sabdar nlp = ndmp_get_nlp(session); 20862654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 20872654012fSReza Sabdar params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 20882654012fSReza Sabdar if (params == NULL) 20892654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 20902654012fSReza Sabdar 20912654012fSReza Sabdar params->mp_daemon_cookie = (void *)session; 20922654012fSReza Sabdar params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 20932654012fSReza Sabdar params->mp_protocol_version = session->ns_protocol_version; 20942654012fSReza Sabdar params->mp_operation = NDMP_DATA_OP_BACKUP; 20952654012fSReza Sabdar params->mp_get_env_func = ndmpd_api_get_env; 20962654012fSReza Sabdar params->mp_add_env_func = ndmpd_api_add_env; 20972654012fSReza Sabdar params->mp_get_name_func = ndmpd_api_get_name; 20982654012fSReza Sabdar params->mp_dispatch_func = ndmpd_api_dispatch; 20992654012fSReza Sabdar params->mp_done_func = ndmpd_api_done_v2; 21002654012fSReza Sabdar params->mp_log_func = ndmpd_api_log_v2; 21012654012fSReza Sabdar params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 21022654012fSReza Sabdar params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 21032654012fSReza Sabdar params->mp_write_func = ndmpd_api_write_v2; 21042654012fSReza Sabdar params->mp_read_func = 0; 21052654012fSReza Sabdar params->mp_file_recovered_func = 0; 21062654012fSReza Sabdar params->mp_stats = &session->ns_data.dd_module.dm_stats; 21072654012fSReza Sabdar 21082654012fSReza Sabdar session->ns_data.dd_module.dm_module_cookie = 0; 21092654012fSReza Sabdar if (strcmp(bu_type, NDMP_DUMP_TYPE) == 0) { 21102654012fSReza Sabdar NLP_SET(nlp, NLPF_DUMP); 21112654012fSReza Sabdar params->mp_file_history_path_func = 0; 21122654012fSReza Sabdar params->mp_file_history_dir_func = 21132654012fSReza Sabdar ndmpd_api_file_history_dir_v2; 21142654012fSReza Sabdar params->mp_file_history_node_func = 21152654012fSReza Sabdar ndmpd_api_file_history_node_v2; 21162654012fSReza Sabdar } else if (strcmp(bu_type, NDMP_TAR_TYPE) == 0) { 21172654012fSReza Sabdar /* backup type == NDMP_TAR_TYPE */ 21182654012fSReza Sabdar NLP_SET(nlp, NLPF_TAR); 21192654012fSReza Sabdar params->mp_file_history_path_func = 21202654012fSReza Sabdar ndmpd_api_file_history_path_v2; 21212654012fSReza Sabdar params->mp_file_history_dir_func = 0; 21222654012fSReza Sabdar params->mp_file_history_node_func = 0; 21232654012fSReza Sabdar } else { 21242654012fSReza Sabdar NLP_UNSET(nlp, NLPF_DUMP); 21252654012fSReza Sabdar NLP_UNSET(nlp, NLPF_TAR); 21262654012fSReza Sabdar } 21272654012fSReza Sabdar 21282654012fSReza Sabdar session->ns_data.dd_module.dm_start_func = ndmpd_tar_backup_starter; 21292654012fSReza Sabdar session->ns_data.dd_module.dm_abort_func = ndmpd_tar_backup_abort; 21302654012fSReza Sabdar 21312654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 21322654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 21332654012fSReza Sabdar session->ns_data.dd_nlist = 0; 21342654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 21352654012fSReza Sabdar session->ns_data.dd_read_offset = 0; 21362654012fSReza Sabdar session->ns_data.dd_read_length = 0; 21372654012fSReza Sabdar 21382654012fSReza Sabdar if ((err = ndmp_backup_extract_params(session, 21392654012fSReza Sabdar params)) != NDMP_NO_ERR) { 21402654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "err: %d", err); 21412654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 21422654012fSReza Sabdar return (err); 21432654012fSReza Sabdar } 21442654012fSReza Sabdar 21452654012fSReza Sabdar err = ndmpd_mover_connect(session, NDMP_MOVER_MODE_READ); 21462654012fSReza Sabdar if (err != NDMP_NO_ERR) { 21472654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 21482654012fSReza Sabdar "mover connect err: %d", err); 21492654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 21502654012fSReza Sabdar return (err); 21512654012fSReza Sabdar } 21522654012fSReza Sabdar 21532654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 21542654012fSReza Sabdar 21552654012fSReza Sabdar session->ns_data.dd_operation = NDMP_DATA_OP_BACKUP; 21562654012fSReza Sabdar session->ns_data.dd_abort = FALSE; 21572654012fSReza Sabdar 21582654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "starting backup"); 21592654012fSReza Sabdar 21602654012fSReza Sabdar reply.error = NDMP_NO_ERR; 21612654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 21622654012fSReza Sabdar &reply) < 0) { 21632654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Sending data_start_backup reply"); 21642654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 21652654012fSReza Sabdar if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) { 21662654012fSReza Sabdar /* 21672654012fSReza Sabdar * ndmpcopy: we use the same socket for the mover, 21682654012fSReza Sabdar * so expect to close when mover is done! 21692654012fSReza Sabdar */ 21702654012fSReza Sabdar if (session->ns_data.dd_sock != 21712654012fSReza Sabdar session->ns_mover.md_sock) 21722654012fSReza Sabdar (void) close(session->ns_data.dd_sock); 21732654012fSReza Sabdar 21742654012fSReza Sabdar session->ns_data.dd_sock = -1; 21752654012fSReza Sabdar } else 21762654012fSReza Sabdar ndmpd_mover_error(session, 21772654012fSReza Sabdar NDMP_MOVER_HALT_CONNECT_CLOSED); 21782654012fSReza Sabdar return (NDMP_NO_ERR); 21792654012fSReza Sabdar } 21802654012fSReza Sabdar 21812654012fSReza Sabdar /* 21822654012fSReza Sabdar * perform the backup 21832654012fSReza Sabdar * 21842654012fSReza Sabdar * Cannot wait for the thread to exit as we are replying to the 21852654012fSReza Sabdar * client request here. 21862654012fSReza Sabdar */ 21872654012fSReza Sabdar (void) pthread_create(NULL, NULL, 21882654012fSReza Sabdar (funct_t)session->ns_data.dd_module.dm_start_func, 21892654012fSReza Sabdar params); 21902654012fSReza Sabdar 21912654012fSReza Sabdar return (NDMP_NO_ERR); 21922654012fSReza Sabdar } 21932654012fSReza Sabdar 21942654012fSReza Sabdar /* 21958c4f9701SJanice Chang * ndmpd_tar_start_recover_v2 21962654012fSReza Sabdar * 21972654012fSReza Sabdar * The main recover/restore function 21982654012fSReza Sabdar * 21992654012fSReza Sabdar * Parameters: 22002654012fSReza Sabdar * session (input) - session pointer. 22012654012fSReza Sabdar * bu_type (input) - backup type. 22022654012fSReza Sabdar * env_val (input) - environment variable array. 22032654012fSReza Sabdar * env_len (input) - length of env_val. 22048c4f9701SJanice Chang * nlist_val (input) - list of files. 22058c4f9701SJanice Chang * nlist_len (input) - length of nlist_val. 22062654012fSReza Sabdar * 22072654012fSReza Sabdar * Returns: 22082654012fSReza Sabdar * NDMP_NO_ERR - recover successfully started. 22092654012fSReza Sabdar * otherwise - error code of backup start error. 22102654012fSReza Sabdar */ 22112654012fSReza Sabdar static ndmp_error 22128c4f9701SJanice Chang ndmpd_tar_start_recover_v2(ndmpd_session_t *session, char *bu_type, 22138c4f9701SJanice Chang ndmp_pval *env_val, ulong_t env_len, ndmp_name *nlist_val, 22148c4f9701SJanice Chang ulong_t nlist_len) 22152654012fSReza Sabdar { 22162654012fSReza Sabdar ndmp_data_start_recover_reply_v2 reply; 22172654012fSReza Sabdar ndmpd_module_params_t *params; 22182654012fSReza Sabdar ndmp_lbr_params_t *nlp; 22192654012fSReza Sabdar int err; 22202654012fSReza Sabdar 22212654012fSReza Sabdar if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 22222654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Can't start new recover in current state."); 22232654012fSReza Sabdar return (NDMP_ILLEGAL_STATE_ERR); 22242654012fSReza Sabdar } 22252654012fSReza Sabdar 22262654012fSReza Sabdar if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 && 22272654012fSReza Sabdar strcmp(bu_type, NDMP_TAR_TYPE) != 0) { 22282654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type); 22292654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump."); 22302654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 22312654012fSReza Sabdar } 22322654012fSReza Sabdar 22332654012fSReza Sabdar reply.error = ndmpd_save_env(session, env_val, env_len); 22342654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) 22352654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 22362654012fSReza Sabdar 22372654012fSReza Sabdar reply.error = ndmpd_save_nlist_v2(session, nlist_val, nlist_len); 22382654012fSReza Sabdar if (reply.error != NDMP_NO_ERR) 22392654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 22402654012fSReza Sabdar 22412654012fSReza Sabdar nlp = ndmp_get_nlp(session); 22422654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 22432654012fSReza Sabdar params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 22442654012fSReza Sabdar if (params == NULL) 22452654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 22462654012fSReza Sabdar 22472654012fSReza Sabdar /* 22482654012fSReza Sabdar * Setup restore parameters. 22492654012fSReza Sabdar */ 22502654012fSReza Sabdar params->mp_daemon_cookie = (void *)session; 22512654012fSReza Sabdar params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 22522654012fSReza Sabdar params->mp_protocol_version = session->ns_protocol_version; 22532654012fSReza Sabdar params->mp_operation = NDMP_DATA_OP_RECOVER; 22542654012fSReza Sabdar params->mp_get_env_func = ndmpd_api_get_env; 22552654012fSReza Sabdar params->mp_add_env_func = ndmpd_api_add_env; 22562654012fSReza Sabdar params->mp_get_name_func = ndmpd_api_get_name; 22572654012fSReza Sabdar params->mp_dispatch_func = ndmpd_api_dispatch; 22582654012fSReza Sabdar params->mp_done_func = ndmpd_api_done_v2; 22592654012fSReza Sabdar params->mp_log_func = ndmpd_api_log_v2; 22602654012fSReza Sabdar params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 22612654012fSReza Sabdar params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 22622654012fSReza Sabdar params->mp_write_func = 0; 22632654012fSReza Sabdar params->mp_file_history_path_func = 0; 22642654012fSReza Sabdar params->mp_file_history_dir_func = 0; 22652654012fSReza Sabdar params->mp_file_history_node_func = 0; 22662654012fSReza Sabdar params->mp_read_func = ndmpd_api_read_v2; 22672654012fSReza Sabdar params->mp_seek_func = ndmpd_api_seek_v2; 22682654012fSReza Sabdar params->mp_file_recovered_func = ndmpd_api_file_recovered_v2; 22692654012fSReza Sabdar params->mp_stats = &session->ns_data.dd_module.dm_stats; 22702654012fSReza Sabdar 22712654012fSReza Sabdar session->ns_data.dd_module.dm_module_cookie = 0; 22722654012fSReza Sabdar session->ns_data.dd_module.dm_start_func = ndmpd_tar_restore_starter; 22732654012fSReza Sabdar session->ns_data.dd_module.dm_abort_func = ndmpd_tar_restore_abort; 22742654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 22752654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 22762654012fSReza Sabdar session->ns_data.dd_read_offset = 0; 22772654012fSReza Sabdar session->ns_data.dd_read_length = 0; 22782654012fSReza Sabdar 22792654012fSReza Sabdar if ((err = ndmp_restore_extract_params(session, 22802654012fSReza Sabdar params)) != NDMP_NO_ERR) { 22812654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 22822654012fSReza Sabdar return (err); 22832654012fSReza Sabdar } 22842654012fSReza Sabdar 22852654012fSReza Sabdar err = ndmpd_mover_connect(session, NDMP_MOVER_MODE_WRITE); 22862654012fSReza Sabdar if (err != NDMP_NO_ERR) { 22872654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 22882654012fSReza Sabdar return (err); 22892654012fSReza Sabdar } 22902654012fSReza Sabdar 22912654012fSReza Sabdar session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 22922654012fSReza Sabdar session->ns_data.dd_operation = NDMP_DATA_OP_RECOVER; 22932654012fSReza Sabdar session->ns_data.dd_abort = FALSE; 22942654012fSReza Sabdar 22952654012fSReza Sabdar reply.error = NDMP_NO_ERR; 22962654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 22972654012fSReza Sabdar &reply) < 0) { 22982654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Sending data_start_recover reply"); 22992654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 23002654012fSReza Sabdar if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) { 23012654012fSReza Sabdar /* 23022654012fSReza Sabdar * ndmpcopy: we use the same socket for the mover, 23032654012fSReza Sabdar * so expect to close when mover is done! 23042654012fSReza Sabdar */ 23052654012fSReza Sabdar if (session->ns_data.dd_sock != 23062654012fSReza Sabdar session->ns_mover.md_sock) 23072654012fSReza Sabdar (void) close(session->ns_data.dd_sock); 23082654012fSReza Sabdar 23092654012fSReza Sabdar session->ns_data.dd_sock = -1; 23102654012fSReza Sabdar } else { 23112654012fSReza Sabdar ndmpd_mover_error(session, 23122654012fSReza Sabdar NDMP_MOVER_HALT_CONNECT_CLOSED); 23132654012fSReza Sabdar } 23142654012fSReza Sabdar return (NDMP_NO_ERR); 23152654012fSReza Sabdar } 23162654012fSReza Sabdar 23172654012fSReza Sabdar 23182654012fSReza Sabdar /* 23192654012fSReza Sabdar * perform the restore 23202654012fSReza Sabdar * 23218c4f9701SJanice Chang * Cannot wait for the thread to exit as we are replying to the 23222654012fSReza Sabdar * client request here. 23232654012fSReza Sabdar */ 23242654012fSReza Sabdar (void) pthread_create(NULL, NULL, 23252654012fSReza Sabdar (funct_t)session->ns_data.dd_module.dm_start_func, 23262654012fSReza Sabdar params); 23272654012fSReza Sabdar 23282654012fSReza Sabdar return (NDMP_NO_ERR); 23292654012fSReza Sabdar } 23302654012fSReza Sabdar 23312654012fSReza Sabdar /* 23322654012fSReza Sabdar * ndmpd_data_get_info 23332654012fSReza Sabdar * 23342654012fSReza Sabdar * Return the total number of bytes processed 23352654012fSReza Sabdar * 23362654012fSReza Sabdar * Parameters: 23372654012fSReza Sabdar * session (input) - session pointer. 23382654012fSReza Sabdar * 23392654012fSReza Sabdar * Returns: 23402654012fSReza Sabdar * the number of bytes processed 23412654012fSReza Sabdar */ 23422654012fSReza Sabdar static u_longlong_t 23432654012fSReza Sabdar ndmpd_data_get_info(ndmpd_session_t *session) 23442654012fSReza Sabdar { 23452654012fSReza Sabdar ndmp_lbr_params_t *nlp; 23462654012fSReza Sabdar 23472654012fSReza Sabdar nlp = ndmp_get_nlp(session); 23482654012fSReza Sabdar if (nlp == NULL) 23492654012fSReza Sabdar return ((u_longlong_t)0); 23502654012fSReza Sabdar 23512654012fSReza Sabdar if (nlp->nlp_jstat == NULL) 23522654012fSReza Sabdar return (nlp->nlp_bytes_total); 23532654012fSReza Sabdar 23542654012fSReza Sabdar return ((u_longlong_t)nlp->nlp_jstat->js_bytes_total); 23552654012fSReza Sabdar } 2356