1*7917SReza.Sabdar@Sun.COM /* 2*7917SReza.Sabdar@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3*7917SReza.Sabdar@Sun.COM * Use is subject to license terms. 4*7917SReza.Sabdar@Sun.COM */ 5*7917SReza.Sabdar@Sun.COM 6*7917SReza.Sabdar@Sun.COM /* 7*7917SReza.Sabdar@Sun.COM * BSD 3 Clause License 8*7917SReza.Sabdar@Sun.COM * 9*7917SReza.Sabdar@Sun.COM * Copyright (c) 2007, The Storage Networking Industry Association. 10*7917SReza.Sabdar@Sun.COM * 11*7917SReza.Sabdar@Sun.COM * Redistribution and use in source and binary forms, with or without 12*7917SReza.Sabdar@Sun.COM * modification, are permitted provided that the following conditions 13*7917SReza.Sabdar@Sun.COM * are met: 14*7917SReza.Sabdar@Sun.COM * - Redistributions of source code must retain the above copyright 15*7917SReza.Sabdar@Sun.COM * notice, this list of conditions and the following disclaimer. 16*7917SReza.Sabdar@Sun.COM * 17*7917SReza.Sabdar@Sun.COM * - Redistributions in binary form must reproduce the above copyright 18*7917SReza.Sabdar@Sun.COM * notice, this list of conditions and the following disclaimer in 19*7917SReza.Sabdar@Sun.COM * the documentation and/or other materials provided with the 20*7917SReza.Sabdar@Sun.COM * distribution. 21*7917SReza.Sabdar@Sun.COM * 22*7917SReza.Sabdar@Sun.COM * - Neither the name of The Storage Networking Industry Association (SNIA) 23*7917SReza.Sabdar@Sun.COM * nor the names of its contributors may be used to endorse or promote 24*7917SReza.Sabdar@Sun.COM * products derived from this software without specific prior written 25*7917SReza.Sabdar@Sun.COM * permission. 26*7917SReza.Sabdar@Sun.COM * 27*7917SReza.Sabdar@Sun.COM * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28*7917SReza.Sabdar@Sun.COM * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29*7917SReza.Sabdar@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30*7917SReza.Sabdar@Sun.COM * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31*7917SReza.Sabdar@Sun.COM * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32*7917SReza.Sabdar@Sun.COM * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33*7917SReza.Sabdar@Sun.COM * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34*7917SReza.Sabdar@Sun.COM * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35*7917SReza.Sabdar@Sun.COM * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36*7917SReza.Sabdar@Sun.COM * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37*7917SReza.Sabdar@Sun.COM * POSSIBILITY OF SUCH DAMAGE. 38*7917SReza.Sabdar@Sun.COM */ 39*7917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */ 40*7917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */ 41*7917SReza.Sabdar@Sun.COM 42*7917SReza.Sabdar@Sun.COM #include <sys/types.h> 43*7917SReza.Sabdar@Sun.COM #include <sys/param.h> 44*7917SReza.Sabdar@Sun.COM #include <sys/socket.h> 45*7917SReza.Sabdar@Sun.COM #include <netinet/in.h> 46*7917SReza.Sabdar@Sun.COM #include <errno.h> 47*7917SReza.Sabdar@Sun.COM #include <arpa/inet.h> 48*7917SReza.Sabdar@Sun.COM #include <stdlib.h> 49*7917SReza.Sabdar@Sun.COM #include <string.h> 50*7917SReza.Sabdar@Sun.COM #include "ndmpd_common.h" 51*7917SReza.Sabdar@Sun.COM #include "ndmpd.h" 52*7917SReza.Sabdar@Sun.COM 53*7917SReza.Sabdar@Sun.COM 54*7917SReza.Sabdar@Sun.COM static int ndmpd_data_error_send_v4(ndmpd_session_t *session, 55*7917SReza.Sabdar@Sun.COM ndmp_data_halt_reason reason); 56*7917SReza.Sabdar@Sun.COM static int ndmpd_data_error_send(ndmpd_session_t *session, 57*7917SReza.Sabdar@Sun.COM ndmp_data_halt_reason reason); 58*7917SReza.Sabdar@Sun.COM static void data_accept_connection_v3(void *cookie, int fd, ulong_t mode); 59*7917SReza.Sabdar@Sun.COM static int create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, 60*7917SReza.Sabdar@Sun.COM ushort_t *port); 61*7917SReza.Sabdar@Sun.COM static ndmp_error data_connect_sock_v3(ndmpd_session_t *session, ulong_t addr, 62*7917SReza.Sabdar@Sun.COM ushort_t port); 63*7917SReza.Sabdar@Sun.COM static int discard_data_v3(ndmpd_session_t *session, ulong_t length); 64*7917SReza.Sabdar@Sun.COM static void nlp_release_job_stat(ndmpd_session_t *session); 65*7917SReza.Sabdar@Sun.COM static u_longlong_t ndmpd_data_get_info(ndmpd_session_t *session); 66*7917SReza.Sabdar@Sun.COM static ndmp_error start_backup_v3(ndmpd_session_t *session, char *bu_type, 67*7917SReza.Sabdar@Sun.COM ndmp_pval *env_val, ulong_t env_len); 68*7917SReza.Sabdar@Sun.COM static ndmp_error start_backup(ndmpd_session_t *session, char *bu_type, 69*7917SReza.Sabdar@Sun.COM ndmp_pval *env_val, ulong_t env_len); 70*7917SReza.Sabdar@Sun.COM static ndmp_error start_recover(ndmpd_session_t *session, char *bu_type, 71*7917SReza.Sabdar@Sun.COM ndmp_pval *env_val, ulong_t env_len, ndmp_name *nlist_val, 72*7917SReza.Sabdar@Sun.COM ulong_t nlist_len); 73*7917SReza.Sabdar@Sun.COM static ndmp_error start_recover_v3(ndmpd_session_t *session, char *bu_type, 74*7917SReza.Sabdar@Sun.COM ndmp_pval *env_val, ulong_t env_len, ndmp_name_v3 *nlist_val, 75*7917SReza.Sabdar@Sun.COM ulong_t nlist_len); 76*7917SReza.Sabdar@Sun.COM static ndmp_error start_backup(ndmpd_session_t *session, char *bu_type, 77*7917SReza.Sabdar@Sun.COM ndmp_pval *env_val, ulong_t env_len); 78*7917SReza.Sabdar@Sun.COM static ndmp_error start_recover(ndmpd_session_t *session, char *bu_type, 79*7917SReza.Sabdar@Sun.COM ndmp_pval *env_val, ulong_t env_len, ndmp_name *nlist_val, 80*7917SReza.Sabdar@Sun.COM ulong_t nlist_len); 81*7917SReza.Sabdar@Sun.COM static u_longlong_t ndmpd_data_get_info(ndmpd_session_t *session); 82*7917SReza.Sabdar@Sun.COM static void nlp_release_job_stat(ndmpd_session_t *session); 83*7917SReza.Sabdar@Sun.COM 84*7917SReza.Sabdar@Sun.COM 85*7917SReza.Sabdar@Sun.COM /* 86*7917SReza.Sabdar@Sun.COM * ************************************************************************ 87*7917SReza.Sabdar@Sun.COM * NDMP V2 HANDLERS 88*7917SReza.Sabdar@Sun.COM * ************************************************************************ 89*7917SReza.Sabdar@Sun.COM */ 90*7917SReza.Sabdar@Sun.COM 91*7917SReza.Sabdar@Sun.COM /* 92*7917SReza.Sabdar@Sun.COM * ndmpd_data_get_state_v2 93*7917SReza.Sabdar@Sun.COM * 94*7917SReza.Sabdar@Sun.COM * Request handler. Returns current data state. 95*7917SReza.Sabdar@Sun.COM * 96*7917SReza.Sabdar@Sun.COM * Parameters: 97*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 98*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 99*7917SReza.Sabdar@Sun.COM * 100*7917SReza.Sabdar@Sun.COM * Returns: 101*7917SReza.Sabdar@Sun.COM * void 102*7917SReza.Sabdar@Sun.COM */ 103*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 104*7917SReza.Sabdar@Sun.COM void 105*7917SReza.Sabdar@Sun.COM ndmpd_data_get_state_v2(ndmp_connection_t *connection, void *body) 106*7917SReza.Sabdar@Sun.COM { 107*7917SReza.Sabdar@Sun.COM ndmp_data_get_state_reply_v2 reply; 108*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 109*7917SReza.Sabdar@Sun.COM 110*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 111*7917SReza.Sabdar@Sun.COM reply.operation = session->ns_data.dd_operation; 112*7917SReza.Sabdar@Sun.COM reply.state = session->ns_data.dd_state; 113*7917SReza.Sabdar@Sun.COM reply.halt_reason = session->ns_data.dd_halt_reason; 114*7917SReza.Sabdar@Sun.COM 115*7917SReza.Sabdar@Sun.COM reply.est_time_remain = 116*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_time_remaining; 117*7917SReza.Sabdar@Sun.COM reply.est_bytes_remain = 118*7917SReza.Sabdar@Sun.COM long_long_to_quad( 119*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining); 120*7917SReza.Sabdar@Sun.COM 121*7917SReza.Sabdar@Sun.COM reply.bytes_processed = 122*7917SReza.Sabdar@Sun.COM long_long_to_quad(ndmpd_data_get_info(session)); 123*7917SReza.Sabdar@Sun.COM 124*7917SReza.Sabdar@Sun.COM reply.mover = session->ns_data.dd_mover; 125*7917SReza.Sabdar@Sun.COM reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset); 126*7917SReza.Sabdar@Sun.COM reply.read_length = long_long_to_quad(session->ns_data.dd_read_length); 127*7917SReza.Sabdar@Sun.COM 128*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 129*7917SReza.Sabdar@Sun.COM "sending data_get_state reply"); 130*7917SReza.Sabdar@Sun.COM } 131*7917SReza.Sabdar@Sun.COM 132*7917SReza.Sabdar@Sun.COM 133*7917SReza.Sabdar@Sun.COM /* 134*7917SReza.Sabdar@Sun.COM * ndmpd_data_start_backup_v2 135*7917SReza.Sabdar@Sun.COM * 136*7917SReza.Sabdar@Sun.COM * Request handler. Starts a backup. 137*7917SReza.Sabdar@Sun.COM * 138*7917SReza.Sabdar@Sun.COM * Parameters: 139*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 140*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 141*7917SReza.Sabdar@Sun.COM * 142*7917SReza.Sabdar@Sun.COM * Returns: 143*7917SReza.Sabdar@Sun.COM * void 144*7917SReza.Sabdar@Sun.COM */ 145*7917SReza.Sabdar@Sun.COM void 146*7917SReza.Sabdar@Sun.COM ndmpd_data_start_backup_v2(ndmp_connection_t *connection, void *body) 147*7917SReza.Sabdar@Sun.COM { 148*7917SReza.Sabdar@Sun.COM ndmp_data_start_backup_request_v2 *request; 149*7917SReza.Sabdar@Sun.COM ndmp_data_start_backup_reply_v2 reply; 150*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 151*7917SReza.Sabdar@Sun.COM ndmp_error err; 152*7917SReza.Sabdar@Sun.COM 153*7917SReza.Sabdar@Sun.COM request = (ndmp_data_start_backup_request_v2 *)body; 154*7917SReza.Sabdar@Sun.COM 155*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 156*7917SReza.Sabdar@Sun.COM session->ns_data.dd_mover = request->mover; 157*7917SReza.Sabdar@Sun.COM 158*7917SReza.Sabdar@Sun.COM err = start_backup(session, request->bu_type, request->env.env_val, 159*7917SReza.Sabdar@Sun.COM request->env.env_len); 160*7917SReza.Sabdar@Sun.COM 161*7917SReza.Sabdar@Sun.COM /* 162*7917SReza.Sabdar@Sun.COM * start_backup sends the reply if the backup is successfully started. 163*7917SReza.Sabdar@Sun.COM * Otherwise, send the reply containing the error here. 164*7917SReza.Sabdar@Sun.COM */ 165*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 166*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "err: %d", err); 167*7917SReza.Sabdar@Sun.COM reply.error = err; 168*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 169*7917SReza.Sabdar@Sun.COM "sending data_start_backup reply"); 170*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(session); 171*7917SReza.Sabdar@Sun.COM } 172*7917SReza.Sabdar@Sun.COM } 173*7917SReza.Sabdar@Sun.COM 174*7917SReza.Sabdar@Sun.COM 175*7917SReza.Sabdar@Sun.COM /* 176*7917SReza.Sabdar@Sun.COM * ndmpd_data_start_recover_v2 177*7917SReza.Sabdar@Sun.COM * 178*7917SReza.Sabdar@Sun.COM * Request handler. Starts a restore. 179*7917SReza.Sabdar@Sun.COM * 180*7917SReza.Sabdar@Sun.COM * Parameters: 181*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 182*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 183*7917SReza.Sabdar@Sun.COM * 184*7917SReza.Sabdar@Sun.COM * Returns: 185*7917SReza.Sabdar@Sun.COM * void 186*7917SReza.Sabdar@Sun.COM */ 187*7917SReza.Sabdar@Sun.COM void 188*7917SReza.Sabdar@Sun.COM ndmpd_data_start_recover_v2(ndmp_connection_t *connection, void *body) 189*7917SReza.Sabdar@Sun.COM { 190*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_request_v2 *request; 191*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_reply_v2 reply; 192*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 193*7917SReza.Sabdar@Sun.COM ndmp_error err; 194*7917SReza.Sabdar@Sun.COM 195*7917SReza.Sabdar@Sun.COM request = (ndmp_data_start_recover_request_v2 *) body; 196*7917SReza.Sabdar@Sun.COM session->ns_data.dd_mover = request->mover; 197*7917SReza.Sabdar@Sun.COM 198*7917SReza.Sabdar@Sun.COM err = start_recover(session, request->bu_type, request->env.env_val, 199*7917SReza.Sabdar@Sun.COM request->env.env_len, request->nlist.nlist_val, 200*7917SReza.Sabdar@Sun.COM request->nlist.nlist_len); 201*7917SReza.Sabdar@Sun.COM /* 202*7917SReza.Sabdar@Sun.COM * start_recover sends the reply if the recover is successfully started. 203*7917SReza.Sabdar@Sun.COM * Otherwise, send the reply containing the error here. 204*7917SReza.Sabdar@Sun.COM */ 205*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 206*7917SReza.Sabdar@Sun.COM reply.error = err; 207*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 208*7917SReza.Sabdar@Sun.COM "sending ndmp_data_start_recover_request_v2 reply"); 209*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(session); 210*7917SReza.Sabdar@Sun.COM } 211*7917SReza.Sabdar@Sun.COM } 212*7917SReza.Sabdar@Sun.COM 213*7917SReza.Sabdar@Sun.COM 214*7917SReza.Sabdar@Sun.COM /* 215*7917SReza.Sabdar@Sun.COM * ndmpd_data_get_env_v2 216*7917SReza.Sabdar@Sun.COM * 217*7917SReza.Sabdar@Sun.COM * Request handler. Returns the environment variable array sent 218*7917SReza.Sabdar@Sun.COM * with the backup request. This request may only be sent with 219*7917SReza.Sabdar@Sun.COM * a backup operation is in progress. 220*7917SReza.Sabdar@Sun.COM * 221*7917SReza.Sabdar@Sun.COM * Parameters: 222*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 223*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 224*7917SReza.Sabdar@Sun.COM * 225*7917SReza.Sabdar@Sun.COM * Returns: 226*7917SReza.Sabdar@Sun.COM * void 227*7917SReza.Sabdar@Sun.COM */ 228*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 229*7917SReza.Sabdar@Sun.COM void 230*7917SReza.Sabdar@Sun.COM ndmpd_data_get_env_v2(ndmp_connection_t *connection, void *body) 231*7917SReza.Sabdar@Sun.COM { 232*7917SReza.Sabdar@Sun.COM ndmp_data_get_env_reply reply; 233*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 234*7917SReza.Sabdar@Sun.COM 235*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 236*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_operation != NDMP_DATA_OP_BACKUP) { 237*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Backup operation not active."); 238*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 239*7917SReza.Sabdar@Sun.COM reply.env.env_len = 0; 240*7917SReza.Sabdar@Sun.COM } else { 241*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 242*7917SReza.Sabdar@Sun.COM reply.env.env_len = session->ns_data.dd_env_len; 243*7917SReza.Sabdar@Sun.COM reply.env.env_val = session->ns_data.dd_env; 244*7917SReza.Sabdar@Sun.COM } 245*7917SReza.Sabdar@Sun.COM 246*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, "sending data_get_env reply"); 247*7917SReza.Sabdar@Sun.COM } 248*7917SReza.Sabdar@Sun.COM 249*7917SReza.Sabdar@Sun.COM 250*7917SReza.Sabdar@Sun.COM /* 251*7917SReza.Sabdar@Sun.COM * ndmpd_data_stop_v2 252*7917SReza.Sabdar@Sun.COM * 253*7917SReza.Sabdar@Sun.COM * Request handler. Stops the current data operation. 254*7917SReza.Sabdar@Sun.COM * 255*7917SReza.Sabdar@Sun.COM * Parameters: 256*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 257*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 258*7917SReza.Sabdar@Sun.COM * 259*7917SReza.Sabdar@Sun.COM * Returns: 260*7917SReza.Sabdar@Sun.COM * void 261*7917SReza.Sabdar@Sun.COM */ 262*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 263*7917SReza.Sabdar@Sun.COM void 264*7917SReza.Sabdar@Sun.COM ndmpd_data_stop_v2(ndmp_connection_t *connection, void *body) 265*7917SReza.Sabdar@Sun.COM { 266*7917SReza.Sabdar@Sun.COM ndmp_data_stop_reply reply; 267*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 268*7917SReza.Sabdar@Sun.COM 269*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) { 270*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state to process stop request."); 271*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 272*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 273*7917SReza.Sabdar@Sun.COM "sending data_stop reply"); 274*7917SReza.Sabdar@Sun.COM return; 275*7917SReza.Sabdar@Sun.COM } 276*7917SReza.Sabdar@Sun.COM ndmp_waitfor_op(session); 277*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(session); 278*7917SReza.Sabdar@Sun.COM ndmpd_file_history_cleanup(session, FALSE); 279*7917SReza.Sabdar@Sun.COM 280*7917SReza.Sabdar@Sun.COM nlp_release_job_stat(session); 281*7917SReza.Sabdar@Sun.COM 282*7917SReza.Sabdar@Sun.COM /* prepare for another data operation */ 283*7917SReza.Sabdar@Sun.COM (void) ndmpd_data_init(session); 284*7917SReza.Sabdar@Sun.COM ndmpd_file_history_init(session); 285*7917SReza.Sabdar@Sun.COM 286*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 287*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, "sending data_stop reply"); 288*7917SReza.Sabdar@Sun.COM } 289*7917SReza.Sabdar@Sun.COM 290*7917SReza.Sabdar@Sun.COM 291*7917SReza.Sabdar@Sun.COM /* 292*7917SReza.Sabdar@Sun.COM * ndmpd_data_abort_v2 293*7917SReza.Sabdar@Sun.COM * 294*7917SReza.Sabdar@Sun.COM * Request handler. Aborts the current backup/restore. The operation 295*7917SReza.Sabdar@Sun.COM * state is not changed to the halted state until after the operation 296*7917SReza.Sabdar@Sun.COM * has actually been aborted and the notify_halt request has been sent. 297*7917SReza.Sabdar@Sun.COM * 298*7917SReza.Sabdar@Sun.COM * Parameters: 299*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 300*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 301*7917SReza.Sabdar@Sun.COM * 302*7917SReza.Sabdar@Sun.COM * Returns: 303*7917SReza.Sabdar@Sun.COM * void 304*7917SReza.Sabdar@Sun.COM */ 305*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 306*7917SReza.Sabdar@Sun.COM void 307*7917SReza.Sabdar@Sun.COM ndmpd_data_abort_v2(ndmp_connection_t *connection, void *body) 308*7917SReza.Sabdar@Sun.COM { 309*7917SReza.Sabdar@Sun.COM ndmp_data_abort_reply reply; 310*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 311*7917SReza.Sabdar@Sun.COM 312*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE || 313*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state == NDMP_DATA_STATE_HALTED) { 314*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state to process abort request."); 315*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 316*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 317*7917SReza.Sabdar@Sun.COM "sending data_abort reply"); 318*7917SReza.Sabdar@Sun.COM return; 319*7917SReza.Sabdar@Sun.COM } 320*7917SReza.Sabdar@Sun.COM /* 321*7917SReza.Sabdar@Sun.COM * Don't go to HALTED state yet. Need to wait for data operation to 322*7917SReza.Sabdar@Sun.COM * abort. When this happens, ndmpd_done will get called and will 323*7917SReza.Sabdar@Sun.COM * perform the halt processing. 324*7917SReza.Sabdar@Sun.COM */ 325*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = TRUE; 326*7917SReza.Sabdar@Sun.COM (*session->ns_data.dd_module.dm_abort_func)( 327*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_module_cookie); 328*7917SReza.Sabdar@Sun.COM 329*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 330*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, "sending data_abort reply"); 331*7917SReza.Sabdar@Sun.COM } 332*7917SReza.Sabdar@Sun.COM 333*7917SReza.Sabdar@Sun.COM /* 334*7917SReza.Sabdar@Sun.COM * ************************************************************************ 335*7917SReza.Sabdar@Sun.COM * NDMP V3 HANDLERS 336*7917SReza.Sabdar@Sun.COM * ************************************************************************ 337*7917SReza.Sabdar@Sun.COM */ 338*7917SReza.Sabdar@Sun.COM 339*7917SReza.Sabdar@Sun.COM /* 340*7917SReza.Sabdar@Sun.COM * ndmpd_data_get_state_v3 341*7917SReza.Sabdar@Sun.COM * 342*7917SReza.Sabdar@Sun.COM * Request handler. Returns current data state. 343*7917SReza.Sabdar@Sun.COM * 344*7917SReza.Sabdar@Sun.COM * Parameters: 345*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 346*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 347*7917SReza.Sabdar@Sun.COM * 348*7917SReza.Sabdar@Sun.COM * Returns: 349*7917SReza.Sabdar@Sun.COM * void 350*7917SReza.Sabdar@Sun.COM */ 351*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 352*7917SReza.Sabdar@Sun.COM void 353*7917SReza.Sabdar@Sun.COM ndmpd_data_get_state_v3(ndmp_connection_t *connection, void *body) 354*7917SReza.Sabdar@Sun.COM { 355*7917SReza.Sabdar@Sun.COM ndmp_data_get_state_reply_v3 reply; 356*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 357*7917SReza.Sabdar@Sun.COM 358*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 359*7917SReza.Sabdar@Sun.COM 360*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 361*7917SReza.Sabdar@Sun.COM reply.invalid = NDMP_DATA_STATE_EST_BYTES_REMAIN_INVALID 362*7917SReza.Sabdar@Sun.COM | NDMP_DATA_STATE_EST_TIME_REMAIN_INVALID; 363*7917SReza.Sabdar@Sun.COM reply.operation = session->ns_data.dd_operation; 364*7917SReza.Sabdar@Sun.COM reply.state = session->ns_data.dd_state; 365*7917SReza.Sabdar@Sun.COM reply.halt_reason = session->ns_data.dd_halt_reason; 366*7917SReza.Sabdar@Sun.COM 367*7917SReza.Sabdar@Sun.COM if (reply.operation == NDMP_DATA_OP_BACKUP) 368*7917SReza.Sabdar@Sun.COM reply.bytes_processed = 369*7917SReza.Sabdar@Sun.COM long_long_to_quad( 370*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_bytes_processed); 371*7917SReza.Sabdar@Sun.COM else 372*7917SReza.Sabdar@Sun.COM reply.bytes_processed = 373*7917SReza.Sabdar@Sun.COM long_long_to_quad(ndmpd_data_get_info(session)); 374*7917SReza.Sabdar@Sun.COM 375*7917SReza.Sabdar@Sun.COM reply.est_bytes_remain = long_long_to_quad(0LL); 376*7917SReza.Sabdar@Sun.COM reply.est_time_remain = 0; 377*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) 378*7917SReza.Sabdar@Sun.COM ndmp_copy_addr_v3(&reply.data_connection_addr, 379*7917SReza.Sabdar@Sun.COM &session->ns_data.dd_data_addr); 380*7917SReza.Sabdar@Sun.COM reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset); 381*7917SReza.Sabdar@Sun.COM reply.read_length = long_long_to_quad(session->ns_data.dd_read_length); 382*7917SReza.Sabdar@Sun.COM 383*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 384*7917SReza.Sabdar@Sun.COM "sending ndmp_data_get_state_v3 reply"); 385*7917SReza.Sabdar@Sun.COM } 386*7917SReza.Sabdar@Sun.COM 387*7917SReza.Sabdar@Sun.COM 388*7917SReza.Sabdar@Sun.COM /* 389*7917SReza.Sabdar@Sun.COM * ndmpd_data_start_backup_v3 390*7917SReza.Sabdar@Sun.COM * 391*7917SReza.Sabdar@Sun.COM * Request handler. Starts a backup. 392*7917SReza.Sabdar@Sun.COM * 393*7917SReza.Sabdar@Sun.COM * Parameters: 394*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 395*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 396*7917SReza.Sabdar@Sun.COM * 397*7917SReza.Sabdar@Sun.COM * Returns: 398*7917SReza.Sabdar@Sun.COM * void 399*7917SReza.Sabdar@Sun.COM */ 400*7917SReza.Sabdar@Sun.COM void 401*7917SReza.Sabdar@Sun.COM ndmpd_data_start_backup_v3(ndmp_connection_t *connection, void *body) 402*7917SReza.Sabdar@Sun.COM { 403*7917SReza.Sabdar@Sun.COM ndmp_data_start_backup_request_v3 *request; 404*7917SReza.Sabdar@Sun.COM ndmp_data_start_backup_reply_v3 reply; 405*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 406*7917SReza.Sabdar@Sun.COM ndmp_error err; 407*7917SReza.Sabdar@Sun.COM 408*7917SReza.Sabdar@Sun.COM request = (ndmp_data_start_backup_request_v3 *)body; 409*7917SReza.Sabdar@Sun.COM 410*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 411*7917SReza.Sabdar@Sun.COM 412*7917SReza.Sabdar@Sun.COM err = start_backup_v3(session, request->bu_type, request->env.env_val, 413*7917SReza.Sabdar@Sun.COM request->env.env_len); 414*7917SReza.Sabdar@Sun.COM 415*7917SReza.Sabdar@Sun.COM /* 416*7917SReza.Sabdar@Sun.COM * start_backup_v3 sends the reply if the backup is 417*7917SReza.Sabdar@Sun.COM * successfully started. Otherwise, send the reply 418*7917SReza.Sabdar@Sun.COM * containing the error here. 419*7917SReza.Sabdar@Sun.COM */ 420*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 421*7917SReza.Sabdar@Sun.COM reply.error = err; 422*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 423*7917SReza.Sabdar@Sun.COM "sending data_start_backup_v3 reply"); 424*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(session); 425*7917SReza.Sabdar@Sun.COM } 426*7917SReza.Sabdar@Sun.COM } 427*7917SReza.Sabdar@Sun.COM 428*7917SReza.Sabdar@Sun.COM 429*7917SReza.Sabdar@Sun.COM /* 430*7917SReza.Sabdar@Sun.COM * ndmpd_data_start_recover_v3 431*7917SReza.Sabdar@Sun.COM * 432*7917SReza.Sabdar@Sun.COM * Request handler. Starts a restore. 433*7917SReza.Sabdar@Sun.COM * 434*7917SReza.Sabdar@Sun.COM * Parameters: 435*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 436*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 437*7917SReza.Sabdar@Sun.COM * 438*7917SReza.Sabdar@Sun.COM * Returns: 439*7917SReza.Sabdar@Sun.COM * void 440*7917SReza.Sabdar@Sun.COM */ 441*7917SReza.Sabdar@Sun.COM void 442*7917SReza.Sabdar@Sun.COM ndmpd_data_start_recover_v3(ndmp_connection_t *connection, void *body) 443*7917SReza.Sabdar@Sun.COM { 444*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_request_v3 *request; 445*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_reply_v3 reply; 446*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 447*7917SReza.Sabdar@Sun.COM ndmp_error err; 448*7917SReza.Sabdar@Sun.COM 449*7917SReza.Sabdar@Sun.COM request = (ndmp_data_start_recover_request_v3 *)body; 450*7917SReza.Sabdar@Sun.COM 451*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 452*7917SReza.Sabdar@Sun.COM 453*7917SReza.Sabdar@Sun.COM err = start_recover_v3(session, request->bu_type, request->env.env_val, 454*7917SReza.Sabdar@Sun.COM request->env.env_len, request->nlist.nlist_val, 455*7917SReza.Sabdar@Sun.COM request->nlist.nlist_len); 456*7917SReza.Sabdar@Sun.COM 457*7917SReza.Sabdar@Sun.COM /* 458*7917SReza.Sabdar@Sun.COM * start_recover_v3 sends the reply if the recover is 459*7917SReza.Sabdar@Sun.COM * successfully started. Otherwise, send the reply 460*7917SReza.Sabdar@Sun.COM * containing the error here. 461*7917SReza.Sabdar@Sun.COM */ 462*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 463*7917SReza.Sabdar@Sun.COM reply.error = err; 464*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 465*7917SReza.Sabdar@Sun.COM "sending data_start_recover_v3 reply"); 466*7917SReza.Sabdar@Sun.COM ndmpd_data_error(session, NDMP_DATA_HALT_INTERNAL_ERROR); 467*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(session); 468*7917SReza.Sabdar@Sun.COM } 469*7917SReza.Sabdar@Sun.COM } 470*7917SReza.Sabdar@Sun.COM 471*7917SReza.Sabdar@Sun.COM 472*7917SReza.Sabdar@Sun.COM /* 473*7917SReza.Sabdar@Sun.COM * ndmpd_data_abort_v3 474*7917SReza.Sabdar@Sun.COM * 475*7917SReza.Sabdar@Sun.COM * Request handler. Aborts the current backup/restore. The operation 476*7917SReza.Sabdar@Sun.COM * state is not changed to the halted state until after the operation 477*7917SReza.Sabdar@Sun.COM * has actually been aborted and the notify_halt request has been sent. 478*7917SReza.Sabdar@Sun.COM * 479*7917SReza.Sabdar@Sun.COM * Parameters: 480*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 481*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 482*7917SReza.Sabdar@Sun.COM * 483*7917SReza.Sabdar@Sun.COM * Returns: 484*7917SReza.Sabdar@Sun.COM * void 485*7917SReza.Sabdar@Sun.COM */ 486*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 487*7917SReza.Sabdar@Sun.COM void 488*7917SReza.Sabdar@Sun.COM ndmpd_data_abort_v3(ndmp_connection_t *connection, void *body) 489*7917SReza.Sabdar@Sun.COM { 490*7917SReza.Sabdar@Sun.COM ndmp_data_abort_reply reply; 491*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 492*7917SReza.Sabdar@Sun.COM 493*7917SReza.Sabdar@Sun.COM switch (session->ns_data.dd_state) { 494*7917SReza.Sabdar@Sun.COM case NDMP_DATA_STATE_IDLE: 495*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 496*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state to process abort request."); 497*7917SReza.Sabdar@Sun.COM break; 498*7917SReza.Sabdar@Sun.COM 499*7917SReza.Sabdar@Sun.COM case NDMP_DATA_STATE_ACTIVE: 500*7917SReza.Sabdar@Sun.COM /* 501*7917SReza.Sabdar@Sun.COM * Don't go to HALTED state yet. Need to wait for data 502*7917SReza.Sabdar@Sun.COM * operation to abort. When this happens, ndmpd_done_v3 503*7917SReza.Sabdar@Sun.COM * will get called and will perform the halt processing. 504*7917SReza.Sabdar@Sun.COM */ 505*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 506*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = TRUE; 507*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_module.dm_abort_func) 508*7917SReza.Sabdar@Sun.COM (*session->ns_data.dd_module.dm_abort_func)( 509*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_module_cookie); 510*7917SReza.Sabdar@Sun.COM break; 511*7917SReza.Sabdar@Sun.COM 512*7917SReza.Sabdar@Sun.COM case NDMP_DATA_STATE_HALTED: 513*7917SReza.Sabdar@Sun.COM case NDMP_DATA_STATE_LISTEN: 514*7917SReza.Sabdar@Sun.COM case NDMP_DATA_STATE_CONNECTED: 515*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 516*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = TRUE; 517*7917SReza.Sabdar@Sun.COM ndmpd_data_error(session, NDMP_DATA_HALT_ABORTED); 518*7917SReza.Sabdar@Sun.COM break; 519*7917SReza.Sabdar@Sun.COM default: 520*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 521*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Unknown data V3 state %d", 522*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state); 523*7917SReza.Sabdar@Sun.COM } 524*7917SReza.Sabdar@Sun.COM 525*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 526*7917SReza.Sabdar@Sun.COM "sending data_abort_v3 reply"); 527*7917SReza.Sabdar@Sun.COM } 528*7917SReza.Sabdar@Sun.COM 529*7917SReza.Sabdar@Sun.COM 530*7917SReza.Sabdar@Sun.COM /* 531*7917SReza.Sabdar@Sun.COM * ndmpd_data_stop_v3 532*7917SReza.Sabdar@Sun.COM * 533*7917SReza.Sabdar@Sun.COM * Request handler. Stops the current data operation. 534*7917SReza.Sabdar@Sun.COM * 535*7917SReza.Sabdar@Sun.COM * Parameters: 536*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 537*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 538*7917SReza.Sabdar@Sun.COM * 539*7917SReza.Sabdar@Sun.COM * Returns: 540*7917SReza.Sabdar@Sun.COM * void 541*7917SReza.Sabdar@Sun.COM */ 542*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 543*7917SReza.Sabdar@Sun.COM void 544*7917SReza.Sabdar@Sun.COM ndmpd_data_stop_v3(ndmp_connection_t *connection, void *body) 545*7917SReza.Sabdar@Sun.COM { 546*7917SReza.Sabdar@Sun.COM ndmp_data_stop_reply reply; 547*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 548*7917SReza.Sabdar@Sun.COM 549*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) { 550*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state to process stop request."); 551*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 552*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 553*7917SReza.Sabdar@Sun.COM "sending data_stop_v3 reply"); 554*7917SReza.Sabdar@Sun.COM return; 555*7917SReza.Sabdar@Sun.COM } 556*7917SReza.Sabdar@Sun.COM ndmp_waitfor_op(session); 557*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(session); 558*7917SReza.Sabdar@Sun.COM ndmpd_file_history_cleanup(session, FALSE); 559*7917SReza.Sabdar@Sun.COM 560*7917SReza.Sabdar@Sun.COM /* prepare for another data operation */ 561*7917SReza.Sabdar@Sun.COM (void) ndmpd_data_init(session); 562*7917SReza.Sabdar@Sun.COM ndmpd_file_history_init(session); 563*7917SReza.Sabdar@Sun.COM 564*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 565*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 566*7917SReza.Sabdar@Sun.COM "sending data_stop_v3 reply"); 567*7917SReza.Sabdar@Sun.COM } 568*7917SReza.Sabdar@Sun.COM 569*7917SReza.Sabdar@Sun.COM 570*7917SReza.Sabdar@Sun.COM /* 571*7917SReza.Sabdar@Sun.COM * ndmpd_data_listen_v3 572*7917SReza.Sabdar@Sun.COM * 573*7917SReza.Sabdar@Sun.COM * Request handler. Configures the server to listen for a connection 574*7917SReza.Sabdar@Sun.COM * from a remote mover. 575*7917SReza.Sabdar@Sun.COM * 576*7917SReza.Sabdar@Sun.COM * Parameters: 577*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 578*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 579*7917SReza.Sabdar@Sun.COM * 580*7917SReza.Sabdar@Sun.COM * Returns: 581*7917SReza.Sabdar@Sun.COM * void 582*7917SReza.Sabdar@Sun.COM */ 583*7917SReza.Sabdar@Sun.COM void 584*7917SReza.Sabdar@Sun.COM ndmpd_data_listen_v3(ndmp_connection_t *connection, void *body) 585*7917SReza.Sabdar@Sun.COM { 586*7917SReza.Sabdar@Sun.COM ndmp_data_listen_request_v3 *request; 587*7917SReza.Sabdar@Sun.COM ndmp_data_listen_reply_v3 reply; 588*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 589*7917SReza.Sabdar@Sun.COM ulong_t addr; 590*7917SReza.Sabdar@Sun.COM ushort_t port; 591*7917SReza.Sabdar@Sun.COM 592*7917SReza.Sabdar@Sun.COM request = (ndmp_data_listen_request_v3 *)body; 593*7917SReza.Sabdar@Sun.COM 594*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 595*7917SReza.Sabdar@Sun.COM 596*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 597*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 598*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 599*7917SReza.Sabdar@Sun.COM "Invalid internal data state to process listen request."); 600*7917SReza.Sabdar@Sun.COM } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) { 601*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 602*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 603*7917SReza.Sabdar@Sun.COM "Invalid mover state to process listen request."); 604*7917SReza.Sabdar@Sun.COM } else { 605*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 606*7917SReza.Sabdar@Sun.COM } 607*7917SReza.Sabdar@Sun.COM 608*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 609*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 610*7917SReza.Sabdar@Sun.COM "ndmp_data_listen_request_v3 reply"); 611*7917SReza.Sabdar@Sun.COM return; 612*7917SReza.Sabdar@Sun.COM } 613*7917SReza.Sabdar@Sun.COM 614*7917SReza.Sabdar@Sun.COM switch (request->addr_type) { 615*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_LOCAL: 616*7917SReza.Sabdar@Sun.COM reply.data_connection_addr.addr_type = request->addr_type; 617*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL; 618*7917SReza.Sabdar@Sun.COM break; 619*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_TCP: 620*7917SReza.Sabdar@Sun.COM if (create_listen_socket_v3(session, &addr, &port) < 0) { 621*7917SReza.Sabdar@Sun.COM reply.error = NDMP_IO_ERR; 622*7917SReza.Sabdar@Sun.COM break; 623*7917SReza.Sabdar@Sun.COM } 624*7917SReza.Sabdar@Sun.COM 625*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 626*7917SReza.Sabdar@Sun.COM reply.data_connection_addr.addr_type = request->addr_type; 627*7917SReza.Sabdar@Sun.COM reply.data_connection_addr.tcp_ip_v3 = htonl(addr); 628*7917SReza.Sabdar@Sun.COM reply.data_connection_addr.tcp_port_v3 = htons(port); 629*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP; 630*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_ip_v3 = addr; 631*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(port); 632*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "listen_socket: %d", 633*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock); 634*7917SReza.Sabdar@Sun.COM break; 635*7917SReza.Sabdar@Sun.COM 636*7917SReza.Sabdar@Sun.COM default: 637*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid address type: %d", 638*7917SReza.Sabdar@Sun.COM request->addr_type); 639*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_ARGS_ERR; 640*7917SReza.Sabdar@Sun.COM break; 641*7917SReza.Sabdar@Sun.COM } 642*7917SReza.Sabdar@Sun.COM 643*7917SReza.Sabdar@Sun.COM if (reply.error == NDMP_NO_ERR) 644*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_LISTEN; 645*7917SReza.Sabdar@Sun.COM 646*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 647*7917SReza.Sabdar@Sun.COM "ndmp_data_listen_request_v3 reply"); 648*7917SReza.Sabdar@Sun.COM } 649*7917SReza.Sabdar@Sun.COM 650*7917SReza.Sabdar@Sun.COM 651*7917SReza.Sabdar@Sun.COM /* 652*7917SReza.Sabdar@Sun.COM * ndmpd_data_connect_v3 653*7917SReza.Sabdar@Sun.COM * 654*7917SReza.Sabdar@Sun.COM * Request handler. Connects the data server to either a local 655*7917SReza.Sabdar@Sun.COM * or remote mover. 656*7917SReza.Sabdar@Sun.COM * 657*7917SReza.Sabdar@Sun.COM * Parameters: 658*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 659*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 660*7917SReza.Sabdar@Sun.COM * 661*7917SReza.Sabdar@Sun.COM * Returns: 662*7917SReza.Sabdar@Sun.COM * void 663*7917SReza.Sabdar@Sun.COM */ 664*7917SReza.Sabdar@Sun.COM void 665*7917SReza.Sabdar@Sun.COM ndmpd_data_connect_v3(ndmp_connection_t *connection, void *body) 666*7917SReza.Sabdar@Sun.COM { 667*7917SReza.Sabdar@Sun.COM ndmp_data_connect_request_v3 *request; 668*7917SReza.Sabdar@Sun.COM ndmp_data_connect_reply_v3 reply; 669*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 670*7917SReza.Sabdar@Sun.COM 671*7917SReza.Sabdar@Sun.COM request = (ndmp_data_connect_request_v3 *)body; 672*7917SReza.Sabdar@Sun.COM 673*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 674*7917SReza.Sabdar@Sun.COM 675*7917SReza.Sabdar@Sun.COM if (!ndmp_valid_v3addr_type(request->addr.addr_type)) { 676*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_ARGS_ERR; 677*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 678*7917SReza.Sabdar@Sun.COM request->addr.addr_type); 679*7917SReza.Sabdar@Sun.COM } else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 680*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 681*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state to process connect request."); 682*7917SReza.Sabdar@Sun.COM } else { 683*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 684*7917SReza.Sabdar@Sun.COM } 685*7917SReza.Sabdar@Sun.COM 686*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 687*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 688*7917SReza.Sabdar@Sun.COM "sending ndmp_data_connect_v3 reply"); 689*7917SReza.Sabdar@Sun.COM return; 690*7917SReza.Sabdar@Sun.COM } 691*7917SReza.Sabdar@Sun.COM 692*7917SReza.Sabdar@Sun.COM switch (request->addr.addr_type) { 693*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_LOCAL: 694*7917SReza.Sabdar@Sun.COM /* 695*7917SReza.Sabdar@Sun.COM * Verify that the mover is listening for a 696*7917SReza.Sabdar@Sun.COM * local connection 697*7917SReza.Sabdar@Sun.COM */ 698*7917SReza.Sabdar@Sun.COM if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN || 699*7917SReza.Sabdar@Sun.COM session->ns_mover.md_listen_sock != -1) { 700*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 701*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 702*7917SReza.Sabdar@Sun.COM "Mover is not in local listen state."); 703*7917SReza.Sabdar@Sun.COM } else { 704*7917SReza.Sabdar@Sun.COM session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE; 705*7917SReza.Sabdar@Sun.COM } 706*7917SReza.Sabdar@Sun.COM break; 707*7917SReza.Sabdar@Sun.COM 708*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_TCP: 709*7917SReza.Sabdar@Sun.COM reply.error = data_connect_sock_v3(session, 710*7917SReza.Sabdar@Sun.COM request->addr.tcp_ip_v3, request->addr.tcp_port_v3); 711*7917SReza.Sabdar@Sun.COM break; 712*7917SReza.Sabdar@Sun.COM 713*7917SReza.Sabdar@Sun.COM default: 714*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_ARGS_ERR; 715*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 716*7917SReza.Sabdar@Sun.COM request->addr.addr_type); 717*7917SReza.Sabdar@Sun.COM } 718*7917SReza.Sabdar@Sun.COM 719*7917SReza.Sabdar@Sun.COM if (reply.error == NDMP_NO_ERR) 720*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED; 721*7917SReza.Sabdar@Sun.COM 722*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 723*7917SReza.Sabdar@Sun.COM "sending ndmp_data_connect_v3 reply"); 724*7917SReza.Sabdar@Sun.COM } 725*7917SReza.Sabdar@Sun.COM 726*7917SReza.Sabdar@Sun.COM 727*7917SReza.Sabdar@Sun.COM /* 728*7917SReza.Sabdar@Sun.COM * ************************************************************************ 729*7917SReza.Sabdar@Sun.COM * NDMP V4 HANDLERS 730*7917SReza.Sabdar@Sun.COM * ************************************************************************ 731*7917SReza.Sabdar@Sun.COM */ 732*7917SReza.Sabdar@Sun.COM 733*7917SReza.Sabdar@Sun.COM /* 734*7917SReza.Sabdar@Sun.COM * ndmpd_data_get_env_v4 735*7917SReza.Sabdar@Sun.COM * 736*7917SReza.Sabdar@Sun.COM * Request handler. Returns the environment variable array sent 737*7917SReza.Sabdar@Sun.COM * with the backup request. This request may only be sent with 738*7917SReza.Sabdar@Sun.COM * a backup operation is in progress. 739*7917SReza.Sabdar@Sun.COM * 740*7917SReza.Sabdar@Sun.COM * Parameters: 741*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 742*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 743*7917SReza.Sabdar@Sun.COM * 744*7917SReza.Sabdar@Sun.COM * Returns: 745*7917SReza.Sabdar@Sun.COM * void 746*7917SReza.Sabdar@Sun.COM */ 747*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 748*7917SReza.Sabdar@Sun.COM void 749*7917SReza.Sabdar@Sun.COM ndmpd_data_get_env_v4(ndmp_connection_t *connection, void *body) 750*7917SReza.Sabdar@Sun.COM { 751*7917SReza.Sabdar@Sun.COM ndmp_data_get_env_reply reply; 752*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 753*7917SReza.Sabdar@Sun.COM 754*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 755*7917SReza.Sabdar@Sun.COM 756*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_ACTIVE && 757*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state != NDMP_DATA_STATE_HALTED) { 758*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state for the data server."); 759*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 760*7917SReza.Sabdar@Sun.COM reply.env.env_len = 0; 761*7917SReza.Sabdar@Sun.COM } else if (session->ns_data.dd_operation != NDMP_DATA_OP_BACKUP) { 762*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Backup operation not active."); 763*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 764*7917SReza.Sabdar@Sun.COM reply.env.env_len = 0; 765*7917SReza.Sabdar@Sun.COM } else { 766*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 767*7917SReza.Sabdar@Sun.COM reply.env.env_len = session->ns_data.dd_env_len; 768*7917SReza.Sabdar@Sun.COM reply.env.env_val = session->ns_data.dd_env; 769*7917SReza.Sabdar@Sun.COM } 770*7917SReza.Sabdar@Sun.COM 771*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, "sending data_get_env reply"); 772*7917SReza.Sabdar@Sun.COM } 773*7917SReza.Sabdar@Sun.COM 774*7917SReza.Sabdar@Sun.COM /* 775*7917SReza.Sabdar@Sun.COM * ndmpd_data_get_state_v4 776*7917SReza.Sabdar@Sun.COM * 777*7917SReza.Sabdar@Sun.COM * Request handler. Returns current data state. 778*7917SReza.Sabdar@Sun.COM * 779*7917SReza.Sabdar@Sun.COM * Parameters: 780*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 781*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 782*7917SReza.Sabdar@Sun.COM * 783*7917SReza.Sabdar@Sun.COM * Returns: 784*7917SReza.Sabdar@Sun.COM * void 785*7917SReza.Sabdar@Sun.COM */ 786*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 787*7917SReza.Sabdar@Sun.COM void 788*7917SReza.Sabdar@Sun.COM ndmpd_data_get_state_v4(ndmp_connection_t *connection, void *body) 789*7917SReza.Sabdar@Sun.COM { 790*7917SReza.Sabdar@Sun.COM ndmp_data_get_state_reply_v4 reply; 791*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 792*7917SReza.Sabdar@Sun.COM 793*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 794*7917SReza.Sabdar@Sun.COM 795*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 796*7917SReza.Sabdar@Sun.COM reply.unsupported = NDMP_DATA_STATE_EST_BYTES_REMAIN_INVALID 797*7917SReza.Sabdar@Sun.COM | NDMP_DATA_STATE_EST_TIME_REMAIN_INVALID; 798*7917SReza.Sabdar@Sun.COM reply.operation = session->ns_data.dd_operation; 799*7917SReza.Sabdar@Sun.COM reply.state = session->ns_data.dd_state; 800*7917SReza.Sabdar@Sun.COM reply.halt_reason = session->ns_data.dd_halt_reason; 801*7917SReza.Sabdar@Sun.COM 802*7917SReza.Sabdar@Sun.COM if (reply.operation == NDMP_DATA_OP_BACKUP) 803*7917SReza.Sabdar@Sun.COM reply.bytes_processed = long_long_to_quad( 804*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_bytes_processed); 805*7917SReza.Sabdar@Sun.COM else 806*7917SReza.Sabdar@Sun.COM reply.bytes_processed = 807*7917SReza.Sabdar@Sun.COM long_long_to_quad(ndmpd_data_get_info(session)); 808*7917SReza.Sabdar@Sun.COM 809*7917SReza.Sabdar@Sun.COM reply.est_bytes_remain = long_long_to_quad(0LL); 810*7917SReza.Sabdar@Sun.COM reply.est_time_remain = 0; 811*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) 812*7917SReza.Sabdar@Sun.COM ndmp_copy_addr_v4(&reply.data_connection_addr, 813*7917SReza.Sabdar@Sun.COM &session->ns_data.dd_data_addr_v4); 814*7917SReza.Sabdar@Sun.COM 815*7917SReza.Sabdar@Sun.COM reply.read_offset = long_long_to_quad(session->ns_data.dd_read_offset); 816*7917SReza.Sabdar@Sun.COM reply.read_length = long_long_to_quad(session->ns_data.dd_read_length); 817*7917SReza.Sabdar@Sun.COM 818*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 819*7917SReza.Sabdar@Sun.COM "sending ndmp_data_get_state_v4 reply"); 820*7917SReza.Sabdar@Sun.COM free(reply.data_connection_addr.tcp_addr_v4); 821*7917SReza.Sabdar@Sun.COM } 822*7917SReza.Sabdar@Sun.COM 823*7917SReza.Sabdar@Sun.COM 824*7917SReza.Sabdar@Sun.COM /* 825*7917SReza.Sabdar@Sun.COM * ndmpd_data_connect_v4 826*7917SReza.Sabdar@Sun.COM * 827*7917SReza.Sabdar@Sun.COM * Request handler. Connects the data server to either a local 828*7917SReza.Sabdar@Sun.COM * or remote mover. 829*7917SReza.Sabdar@Sun.COM * 830*7917SReza.Sabdar@Sun.COM * Parameters: 831*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 832*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 833*7917SReza.Sabdar@Sun.COM * 834*7917SReza.Sabdar@Sun.COM * Returns: 835*7917SReza.Sabdar@Sun.COM * void 836*7917SReza.Sabdar@Sun.COM */ 837*7917SReza.Sabdar@Sun.COM void 838*7917SReza.Sabdar@Sun.COM ndmpd_data_connect_v4(ndmp_connection_t *connection, void *body) 839*7917SReza.Sabdar@Sun.COM { 840*7917SReza.Sabdar@Sun.COM ndmp_data_connect_request_v4 *request; 841*7917SReza.Sabdar@Sun.COM ndmp_data_connect_reply_v4 reply; 842*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 843*7917SReza.Sabdar@Sun.COM 844*7917SReza.Sabdar@Sun.COM request = (ndmp_data_connect_request_v4 *)body; 845*7917SReza.Sabdar@Sun.COM 846*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 847*7917SReza.Sabdar@Sun.COM 848*7917SReza.Sabdar@Sun.COM if (!ndmp_valid_v3addr_type(request->addr.addr_type)) { 849*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_ARGS_ERR; 850*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 851*7917SReza.Sabdar@Sun.COM request->addr.addr_type); 852*7917SReza.Sabdar@Sun.COM } else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 853*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 854*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid state to process connect request."); 855*7917SReza.Sabdar@Sun.COM } else { 856*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 857*7917SReza.Sabdar@Sun.COM } 858*7917SReza.Sabdar@Sun.COM 859*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 860*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 861*7917SReza.Sabdar@Sun.COM "sending ndmp_data_connect_v4 reply"); 862*7917SReza.Sabdar@Sun.COM return; 863*7917SReza.Sabdar@Sun.COM } 864*7917SReza.Sabdar@Sun.COM 865*7917SReza.Sabdar@Sun.COM switch (request->addr.addr_type) { 866*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_LOCAL: 867*7917SReza.Sabdar@Sun.COM /* 868*7917SReza.Sabdar@Sun.COM * Verify that the mover is listening for a 869*7917SReza.Sabdar@Sun.COM * local connection 870*7917SReza.Sabdar@Sun.COM */ 871*7917SReza.Sabdar@Sun.COM if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN || 872*7917SReza.Sabdar@Sun.COM session->ns_mover.md_listen_sock != -1) { 873*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 874*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 875*7917SReza.Sabdar@Sun.COM "Mover is not in local listen state."); 876*7917SReza.Sabdar@Sun.COM } else { 877*7917SReza.Sabdar@Sun.COM session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE; 878*7917SReza.Sabdar@Sun.COM } 879*7917SReza.Sabdar@Sun.COM break; 880*7917SReza.Sabdar@Sun.COM 881*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_TCP: 882*7917SReza.Sabdar@Sun.COM reply.error = data_connect_sock_v3(session, 883*7917SReza.Sabdar@Sun.COM request->addr.tcp_ip_v4(0), request->addr.tcp_port_v4(0)); 884*7917SReza.Sabdar@Sun.COM break; 885*7917SReza.Sabdar@Sun.COM 886*7917SReza.Sabdar@Sun.COM default: 887*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_ARGS_ERR; 888*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid address type %d", 889*7917SReza.Sabdar@Sun.COM request->addr.addr_type); 890*7917SReza.Sabdar@Sun.COM } 891*7917SReza.Sabdar@Sun.COM 892*7917SReza.Sabdar@Sun.COM if (reply.error == NDMP_NO_ERR) 893*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED; 894*7917SReza.Sabdar@Sun.COM 895*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 896*7917SReza.Sabdar@Sun.COM "sending ndmp_data_connect_v4 reply"); 897*7917SReza.Sabdar@Sun.COM } 898*7917SReza.Sabdar@Sun.COM 899*7917SReza.Sabdar@Sun.COM /* 900*7917SReza.Sabdar@Sun.COM * ndmpd_data_listen_v4 901*7917SReza.Sabdar@Sun.COM * 902*7917SReza.Sabdar@Sun.COM * Request handler. Configures the server to listen for a connection 903*7917SReza.Sabdar@Sun.COM * from a remote mover. 904*7917SReza.Sabdar@Sun.COM * 905*7917SReza.Sabdar@Sun.COM * Parameters: 906*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 907*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 908*7917SReza.Sabdar@Sun.COM * 909*7917SReza.Sabdar@Sun.COM * Returns: 910*7917SReza.Sabdar@Sun.COM * void 911*7917SReza.Sabdar@Sun.COM */ 912*7917SReza.Sabdar@Sun.COM void 913*7917SReza.Sabdar@Sun.COM ndmpd_data_listen_v4(ndmp_connection_t *connection, void *body) 914*7917SReza.Sabdar@Sun.COM { 915*7917SReza.Sabdar@Sun.COM ndmp_data_listen_request_v4 *request; 916*7917SReza.Sabdar@Sun.COM ndmp_data_listen_reply_v4 reply; 917*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = ndmp_get_client_data(connection); 918*7917SReza.Sabdar@Sun.COM ulong_t addr; 919*7917SReza.Sabdar@Sun.COM ushort_t port; 920*7917SReza.Sabdar@Sun.COM 921*7917SReza.Sabdar@Sun.COM request = (ndmp_data_listen_request_v4 *)body; 922*7917SReza.Sabdar@Sun.COM 923*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 924*7917SReza.Sabdar@Sun.COM 925*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 926*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 927*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 928*7917SReza.Sabdar@Sun.COM "Invalid internal data state to process listen request."); 929*7917SReza.Sabdar@Sun.COM } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) { 930*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_STATE_ERR; 931*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 932*7917SReza.Sabdar@Sun.COM "Invalid mover state to process listen request."); 933*7917SReza.Sabdar@Sun.COM } else { 934*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 935*7917SReza.Sabdar@Sun.COM } 936*7917SReza.Sabdar@Sun.COM 937*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 938*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 939*7917SReza.Sabdar@Sun.COM "ndmp_data_listen_request_v4 reply"); 940*7917SReza.Sabdar@Sun.COM return; 941*7917SReza.Sabdar@Sun.COM } 942*7917SReza.Sabdar@Sun.COM 943*7917SReza.Sabdar@Sun.COM switch (request->addr_type) { 944*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_LOCAL: 945*7917SReza.Sabdar@Sun.COM reply.connect_addr.addr_type = request->addr_type; 946*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL; 947*7917SReza.Sabdar@Sun.COM break; 948*7917SReza.Sabdar@Sun.COM case NDMP_ADDR_TCP: 949*7917SReza.Sabdar@Sun.COM if (create_listen_socket_v3(session, &addr, &port) < 0) { 950*7917SReza.Sabdar@Sun.COM reply.error = NDMP_IO_ERR; 951*7917SReza.Sabdar@Sun.COM break; 952*7917SReza.Sabdar@Sun.COM } 953*7917SReza.Sabdar@Sun.COM 954*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 955*7917SReza.Sabdar@Sun.COM reply.connect_addr.addr_type = request->addr_type; 956*7917SReza.Sabdar@Sun.COM reply.connect_addr.tcp_addr_v4 = 957*7917SReza.Sabdar@Sun.COM ndmp_malloc(sizeof (ndmp_tcp_addr_v4)); 958*7917SReza.Sabdar@Sun.COM 959*7917SReza.Sabdar@Sun.COM reply.connect_addr.tcp_ip_v4(0) = htonl(addr); 960*7917SReza.Sabdar@Sun.COM reply.connect_addr.tcp_port_v4(0) = htons(port); 961*7917SReza.Sabdar@Sun.COM reply.connect_addr.tcp_len_v4 = 1; 962*7917SReza.Sabdar@Sun.COM 963*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr_v4.addr_type = NDMP_ADDR_TCP; 964*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr_v4.tcp_addr_v4 = 965*7917SReza.Sabdar@Sun.COM ndmp_malloc(sizeof (ndmp_tcp_addr_v4)); 966*7917SReza.Sabdar@Sun.COM 967*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr_v4.tcp_ip_v4(0) = addr; 968*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr_v4.tcp_port_v4(0) = ntohs(port); 969*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr_v4.tcp_len_v4 = 1; 970*7917SReza.Sabdar@Sun.COM 971*7917SReza.Sabdar@Sun.COM /* Copy that to data_addr for compatibility */ 972*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP; 973*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_ip_v3 = addr; 974*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(port); 975*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "listen_socket: %d", 976*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock); 977*7917SReza.Sabdar@Sun.COM break; 978*7917SReza.Sabdar@Sun.COM 979*7917SReza.Sabdar@Sun.COM default: 980*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid address type: %d", 981*7917SReza.Sabdar@Sun.COM request->addr_type); 982*7917SReza.Sabdar@Sun.COM reply.error = NDMP_ILLEGAL_ARGS_ERR; 983*7917SReza.Sabdar@Sun.COM break; 984*7917SReza.Sabdar@Sun.COM } 985*7917SReza.Sabdar@Sun.COM 986*7917SReza.Sabdar@Sun.COM if (reply.error == NDMP_NO_ERR) 987*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_LISTEN; 988*7917SReza.Sabdar@Sun.COM 989*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 990*7917SReza.Sabdar@Sun.COM "ndmp_data_listen_request_v4 reply"); 991*7917SReza.Sabdar@Sun.COM } 992*7917SReza.Sabdar@Sun.COM 993*7917SReza.Sabdar@Sun.COM 994*7917SReza.Sabdar@Sun.COM /* 995*7917SReza.Sabdar@Sun.COM * ndmpd_data_start_recover_filehist_v4 996*7917SReza.Sabdar@Sun.COM * 997*7917SReza.Sabdar@Sun.COM * Request handler. Recovers the file history (not supported yet) 998*7917SReza.Sabdar@Sun.COM * This command has an optional support in V4. 999*7917SReza.Sabdar@Sun.COM * 1000*7917SReza.Sabdar@Sun.COM * Parameters: 1001*7917SReza.Sabdar@Sun.COM * connection (input) - connection handle. 1002*7917SReza.Sabdar@Sun.COM * body (input) - request message body. 1003*7917SReza.Sabdar@Sun.COM * 1004*7917SReza.Sabdar@Sun.COM * Returns: 1005*7917SReza.Sabdar@Sun.COM * void 1006*7917SReza.Sabdar@Sun.COM */ 1007*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 1008*7917SReza.Sabdar@Sun.COM void 1009*7917SReza.Sabdar@Sun.COM ndmpd_data_start_recover_filehist_v4(ndmp_connection_t *connection, void *body) 1010*7917SReza.Sabdar@Sun.COM { 1011*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_filehist_reply_v4 reply; 1012*7917SReza.Sabdar@Sun.COM 1013*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Request not supported"); 1014*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NOT_SUPPORTED_ERR; 1015*7917SReza.Sabdar@Sun.COM 1016*7917SReza.Sabdar@Sun.COM ndmp_send_reply(connection, &reply, 1017*7917SReza.Sabdar@Sun.COM "sending ndmp_data_start_recover_filehist_reply_v4 reply"); 1018*7917SReza.Sabdar@Sun.COM } 1019*7917SReza.Sabdar@Sun.COM 1020*7917SReza.Sabdar@Sun.COM /* 1021*7917SReza.Sabdar@Sun.COM * ************************************************************************ 1022*7917SReza.Sabdar@Sun.COM * LOCALS 1023*7917SReza.Sabdar@Sun.COM * ************************************************************************ 1024*7917SReza.Sabdar@Sun.COM */ 1025*7917SReza.Sabdar@Sun.COM 1026*7917SReza.Sabdar@Sun.COM /* 1027*7917SReza.Sabdar@Sun.COM * ndmpd_data_error_send 1028*7917SReza.Sabdar@Sun.COM * 1029*7917SReza.Sabdar@Sun.COM * This function sends the notify message to the client. 1030*7917SReza.Sabdar@Sun.COM * 1031*7917SReza.Sabdar@Sun.COM * Parameters: 1032*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1033*7917SReza.Sabdar@Sun.COM * reason (input) - halt reason. 1034*7917SReza.Sabdar@Sun.COM * 1035*7917SReza.Sabdar@Sun.COM * Returns: 1036*7917SReza.Sabdar@Sun.COM * Error code 1037*7917SReza.Sabdar@Sun.COM */ 1038*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 1039*7917SReza.Sabdar@Sun.COM static int 1040*7917SReza.Sabdar@Sun.COM ndmpd_data_error_send(ndmpd_session_t *session, ndmp_data_halt_reason reason) 1041*7917SReza.Sabdar@Sun.COM { 1042*7917SReza.Sabdar@Sun.COM ndmp_notify_data_halted_request req; 1043*7917SReza.Sabdar@Sun.COM 1044*7917SReza.Sabdar@Sun.COM req.reason = session->ns_data.dd_halt_reason; 1045*7917SReza.Sabdar@Sun.COM req.text_reason = ""; 1046*7917SReza.Sabdar@Sun.COM 1047*7917SReza.Sabdar@Sun.COM return (ndmp_send_request(session->ns_connection, 1048*7917SReza.Sabdar@Sun.COM NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, &req, 0)); 1049*7917SReza.Sabdar@Sun.COM } 1050*7917SReza.Sabdar@Sun.COM 1051*7917SReza.Sabdar@Sun.COM 1052*7917SReza.Sabdar@Sun.COM /* 1053*7917SReza.Sabdar@Sun.COM * ndmpd_data_error_send_v4 1054*7917SReza.Sabdar@Sun.COM * 1055*7917SReza.Sabdar@Sun.COM * This function sends the notify message to the client. 1056*7917SReza.Sabdar@Sun.COM * 1057*7917SReza.Sabdar@Sun.COM * Parameters: 1058*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1059*7917SReza.Sabdar@Sun.COM * reason (input) - halt reason. 1060*7917SReza.Sabdar@Sun.COM * 1061*7917SReza.Sabdar@Sun.COM * Returns: 1062*7917SReza.Sabdar@Sun.COM * Error code 1063*7917SReza.Sabdar@Sun.COM */ 1064*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 1065*7917SReza.Sabdar@Sun.COM static int 1066*7917SReza.Sabdar@Sun.COM ndmpd_data_error_send_v4(ndmpd_session_t *session, ndmp_data_halt_reason reason) 1067*7917SReza.Sabdar@Sun.COM { 1068*7917SReza.Sabdar@Sun.COM ndmp_notify_data_halted_request_v4 req; 1069*7917SReza.Sabdar@Sun.COM 1070*7917SReza.Sabdar@Sun.COM req.reason = session->ns_data.dd_halt_reason; 1071*7917SReza.Sabdar@Sun.COM 1072*7917SReza.Sabdar@Sun.COM return ndmp_send_request(session->ns_connection, 1073*7917SReza.Sabdar@Sun.COM NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, &req, 0); 1074*7917SReza.Sabdar@Sun.COM } 1075*7917SReza.Sabdar@Sun.COM 1076*7917SReza.Sabdar@Sun.COM 1077*7917SReza.Sabdar@Sun.COM /* 1078*7917SReza.Sabdar@Sun.COM * ndmpd_data_error 1079*7917SReza.Sabdar@Sun.COM * 1080*7917SReza.Sabdar@Sun.COM * This function is called when a data error has been detected. 1081*7917SReza.Sabdar@Sun.COM * A notify message is sent to the client and the data server is 1082*7917SReza.Sabdar@Sun.COM * placed into the halted state. 1083*7917SReza.Sabdar@Sun.COM * 1084*7917SReza.Sabdar@Sun.COM * Parameters: 1085*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1086*7917SReza.Sabdar@Sun.COM * reason (input) - halt reason. 1087*7917SReza.Sabdar@Sun.COM * 1088*7917SReza.Sabdar@Sun.COM * Returns: 1089*7917SReza.Sabdar@Sun.COM * void 1090*7917SReza.Sabdar@Sun.COM */ 1091*7917SReza.Sabdar@Sun.COM void 1092*7917SReza.Sabdar@Sun.COM ndmpd_data_error(ndmpd_session_t *session, ndmp_data_halt_reason reason) 1093*7917SReza.Sabdar@Sun.COM { 1094*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE || 1095*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state == NDMP_DATA_STATE_HALTED) 1096*7917SReza.Sabdar@Sun.COM return; 1097*7917SReza.Sabdar@Sun.COM 1098*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) { 1099*7917SReza.Sabdar@Sun.COM /* 1100*7917SReza.Sabdar@Sun.COM * Send/discard any buffered file history data. 1101*7917SReza.Sabdar@Sun.COM */ 1102*7917SReza.Sabdar@Sun.COM ndmpd_file_history_cleanup(session, 1103*7917SReza.Sabdar@Sun.COM (reason == NDMP_DATA_HALT_SUCCESSFUL ? TRUE : FALSE)); 1104*7917SReza.Sabdar@Sun.COM 1105*7917SReza.Sabdar@Sun.COM /* 1106*7917SReza.Sabdar@Sun.COM * If mover local and successful backup, write any 1107*7917SReza.Sabdar@Sun.COM * remaining buffered data to tape. 1108*7917SReza.Sabdar@Sun.COM */ 1109*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_data_addr.addr_type 1110*7917SReza.Sabdar@Sun.COM == NDMP_ADDR_LOCAL && reason == NDMP_DATA_HALT_SUCCESSFUL) 1111*7917SReza.Sabdar@Sun.COM (void) ndmpd_local_write_v3(session, 0, 0); 1112*7917SReza.Sabdar@Sun.COM } 1113*7917SReza.Sabdar@Sun.COM 1114*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_HALTED; 1115*7917SReza.Sabdar@Sun.COM session->ns_data.dd_halt_reason = reason; 1116*7917SReza.Sabdar@Sun.COM 1117*7917SReza.Sabdar@Sun.COM if (session->ns_protocol_version == NDMPV4) { 1118*7917SReza.Sabdar@Sun.COM if (ndmpd_data_error_send_v4(session, reason) < 0) 1119*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 1120*7917SReza.Sabdar@Sun.COM "Error sending notify_data_halted request"); 1121*7917SReza.Sabdar@Sun.COM } else { 1122*7917SReza.Sabdar@Sun.COM if (ndmpd_data_error_send(session, reason) < 0) 1123*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 1124*7917SReza.Sabdar@Sun.COM "Error sending notify_data_halted request"); 1125*7917SReza.Sabdar@Sun.COM } 1126*7917SReza.Sabdar@Sun.COM 1127*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP) { 1128*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock != -1) { 1129*7917SReza.Sabdar@Sun.COM (void) ndmpd_remove_file_handler(session, 1130*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock); 1131*7917SReza.Sabdar@Sun.COM /* 1132*7917SReza.Sabdar@Sun.COM * ndmpcopy: we use the same socket for the mover, 1133*7917SReza.Sabdar@Sun.COM * so expect to close when mover is done! 1134*7917SReza.Sabdar@Sun.COM */ 1135*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock != 1136*7917SReza.Sabdar@Sun.COM session->ns_mover.md_sock) 1137*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_sock); 1138*7917SReza.Sabdar@Sun.COM 1139*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = -1; 1140*7917SReza.Sabdar@Sun.COM } 1141*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_listen_sock != -1) { 1142*7917SReza.Sabdar@Sun.COM (void) ndmpd_remove_file_handler(session, 1143*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock); 1144*7917SReza.Sabdar@Sun.COM 1145*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_listen_sock); 1146*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock = -1; 1147*7917SReza.Sabdar@Sun.COM } 1148*7917SReza.Sabdar@Sun.COM } else { 1149*7917SReza.Sabdar@Sun.COM ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED); 1150*7917SReza.Sabdar@Sun.COM } 1151*7917SReza.Sabdar@Sun.COM } 1152*7917SReza.Sabdar@Sun.COM 1153*7917SReza.Sabdar@Sun.COM 1154*7917SReza.Sabdar@Sun.COM /* 1155*7917SReza.Sabdar@Sun.COM * data_accept_connection_v3 1156*7917SReza.Sabdar@Sun.COM * 1157*7917SReza.Sabdar@Sun.COM * Accept a data connection from a remote mover. 1158*7917SReza.Sabdar@Sun.COM * Called by ndmpd_select when a connection is pending on 1159*7917SReza.Sabdar@Sun.COM * the data listen socket. 1160*7917SReza.Sabdar@Sun.COM * 1161*7917SReza.Sabdar@Sun.COM * Parameters: 1162*7917SReza.Sabdar@Sun.COM * cookie (input) - session pointer. 1163*7917SReza.Sabdar@Sun.COM * fd (input) - file descriptor. 1164*7917SReza.Sabdar@Sun.COM * mode (input) - select mode. 1165*7917SReza.Sabdar@Sun.COM * 1166*7917SReza.Sabdar@Sun.COM * Returns: 1167*7917SReza.Sabdar@Sun.COM * void 1168*7917SReza.Sabdar@Sun.COM */ 1169*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 1170*7917SReza.Sabdar@Sun.COM static void 1171*7917SReza.Sabdar@Sun.COM data_accept_connection_v3(void *cookie, int fd, ulong_t mode) 1172*7917SReza.Sabdar@Sun.COM { 1173*7917SReza.Sabdar@Sun.COM ndmpd_session_t *session = (ndmpd_session_t *)cookie; 1174*7917SReza.Sabdar@Sun.COM int from_len; 1175*7917SReza.Sabdar@Sun.COM struct sockaddr_in from; 1176*7917SReza.Sabdar@Sun.COM int flag = 1; 1177*7917SReza.Sabdar@Sun.COM 1178*7917SReza.Sabdar@Sun.COM from_len = sizeof (from); 1179*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = accept(fd, (struct sockaddr *)&from, 1180*7917SReza.Sabdar@Sun.COM &from_len); 1181*7917SReza.Sabdar@Sun.COM 1182*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "sock fd: %d", 1183*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock); 1184*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "sin: port %d addr %s", 1185*7917SReza.Sabdar@Sun.COM ntohs(from.sin_port), 1186*7917SReza.Sabdar@Sun.COM inet_ntoa(IN_ADDR(from.sin_addr.s_addr))); 1187*7917SReza.Sabdar@Sun.COM 1188*7917SReza.Sabdar@Sun.COM (void) ndmpd_remove_file_handler(session, fd); 1189*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_listen_sock); 1190*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock = -1; 1191*7917SReza.Sabdar@Sun.COM 1192*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock < 0) { 1193*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Accept error: %m"); 1194*7917SReza.Sabdar@Sun.COM ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR); 1195*7917SReza.Sabdar@Sun.COM return; 1196*7917SReza.Sabdar@Sun.COM } 1197*7917SReza.Sabdar@Sun.COM 1198*7917SReza.Sabdar@Sun.COM /* 1199*7917SReza.Sabdar@Sun.COM * Save the peer address. 1200*7917SReza.Sabdar@Sun.COM */ 1201*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_ip_v3 = from.sin_addr.s_addr; 1202*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(from.sin_port); 1203*7917SReza.Sabdar@Sun.COM 1204*7917SReza.Sabdar@Sun.COM /* 1205*7917SReza.Sabdar@Sun.COM * Set the parameter of the new socket. 1206*7917SReza.Sabdar@Sun.COM */ 1207*7917SReza.Sabdar@Sun.COM (void) setsockopt(session->ns_data.dd_sock, SOL_SOCKET, SO_KEEPALIVE, 1208*7917SReza.Sabdar@Sun.COM &flag, sizeof (flag)); 1209*7917SReza.Sabdar@Sun.COM ndmp_set_socket_nodelay(session->ns_data.dd_sock); 1210*7917SReza.Sabdar@Sun.COM if (ndmp_sbs > 0) 1211*7917SReza.Sabdar@Sun.COM ndmp_set_socket_snd_buf(session->ns_data.dd_sock, 1212*7917SReza.Sabdar@Sun.COM ndmp_sbs * KILOBYTE); 1213*7917SReza.Sabdar@Sun.COM if (ndmp_rbs > 0) 1214*7917SReza.Sabdar@Sun.COM ndmp_set_socket_rcv_buf(session->ns_data.dd_sock, 1215*7917SReza.Sabdar@Sun.COM ndmp_rbs * KILOBYTE); 1216*7917SReza.Sabdar@Sun.COM 1217*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED; 1218*7917SReza.Sabdar@Sun.COM } 1219*7917SReza.Sabdar@Sun.COM 1220*7917SReza.Sabdar@Sun.COM 1221*7917SReza.Sabdar@Sun.COM /* 1222*7917SReza.Sabdar@Sun.COM * create_listen_socket_v3 1223*7917SReza.Sabdar@Sun.COM * 1224*7917SReza.Sabdar@Sun.COM * Creates the data sockets for listening for a remote mover/data 1225*7917SReza.Sabdar@Sun.COM * incoming connections. 1226*7917SReza.Sabdar@Sun.COM */ 1227*7917SReza.Sabdar@Sun.COM static int 1228*7917SReza.Sabdar@Sun.COM create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, ushort_t *port) 1229*7917SReza.Sabdar@Sun.COM { 1230*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock = ndmp_create_socket(addr, port); 1231*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_listen_sock < 0) 1232*7917SReza.Sabdar@Sun.COM return (-1); 1233*7917SReza.Sabdar@Sun.COM 1234*7917SReza.Sabdar@Sun.COM /* 1235*7917SReza.Sabdar@Sun.COM * Add a file handler for the listen socket. 1236*7917SReza.Sabdar@Sun.COM * ndmpd_select will call data_accept_connection when a 1237*7917SReza.Sabdar@Sun.COM * connection is ready to be accepted. 1238*7917SReza.Sabdar@Sun.COM */ 1239*7917SReza.Sabdar@Sun.COM if (ndmpd_add_file_handler(session, (void*)session, 1240*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock, NDMPD_SELECT_MODE_READ, HC_MOVER, 1241*7917SReza.Sabdar@Sun.COM data_accept_connection_v3) < 0) { 1242*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_listen_sock); 1243*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock = -1; 1244*7917SReza.Sabdar@Sun.COM return (-1); 1245*7917SReza.Sabdar@Sun.COM } 1246*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "addr: %s:%d", 1247*7917SReza.Sabdar@Sun.COM inet_ntoa(IN_ADDR(*addr)), ntohs(*port)); 1248*7917SReza.Sabdar@Sun.COM 1249*7917SReza.Sabdar@Sun.COM return (0); 1250*7917SReza.Sabdar@Sun.COM } 1251*7917SReza.Sabdar@Sun.COM 1252*7917SReza.Sabdar@Sun.COM 1253*7917SReza.Sabdar@Sun.COM /* 1254*7917SReza.Sabdar@Sun.COM * data_connect_sock_v3 1255*7917SReza.Sabdar@Sun.COM * 1256*7917SReza.Sabdar@Sun.COM * Connect the data interface socket to the specified ip/port 1257*7917SReza.Sabdar@Sun.COM * 1258*7917SReza.Sabdar@Sun.COM * Parameters: 1259*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1260*7917SReza.Sabdar@Sun.COM * addr (input) - IP address 1261*7917SReza.Sabdar@Sun.COM * port (input) - port number 1262*7917SReza.Sabdar@Sun.COM * 1263*7917SReza.Sabdar@Sun.COM * Returns: 1264*7917SReza.Sabdar@Sun.COM * NDMP_NO_ERR - backup successfully started. 1265*7917SReza.Sabdar@Sun.COM * otherwise - error code of backup start error. 1266*7917SReza.Sabdar@Sun.COM */ 1267*7917SReza.Sabdar@Sun.COM static ndmp_error 1268*7917SReza.Sabdar@Sun.COM data_connect_sock_v3(ndmpd_session_t *session, ulong_t addr, ushort_t port) 1269*7917SReza.Sabdar@Sun.COM { 1270*7917SReza.Sabdar@Sun.COM int sock; 1271*7917SReza.Sabdar@Sun.COM 1272*7917SReza.Sabdar@Sun.COM sock = ndmp_connect_sock_v3(addr, port); 1273*7917SReza.Sabdar@Sun.COM if (sock < 0) 1274*7917SReza.Sabdar@Sun.COM return (NDMP_CONNECT_ERR); 1275*7917SReza.Sabdar@Sun.COM 1276*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = sock; 1277*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_TCP; 1278*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_ip_v3 = ntohl(addr); 1279*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.tcp_port_v3 = port; 1280*7917SReza.Sabdar@Sun.COM 1281*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 1282*7917SReza.Sabdar@Sun.COM } 1283*7917SReza.Sabdar@Sun.COM 1284*7917SReza.Sabdar@Sun.COM 1285*7917SReza.Sabdar@Sun.COM /* 1286*7917SReza.Sabdar@Sun.COM * start_backup_v3 1287*7917SReza.Sabdar@Sun.COM * 1288*7917SReza.Sabdar@Sun.COM * Start the backup work 1289*7917SReza.Sabdar@Sun.COM * 1290*7917SReza.Sabdar@Sun.COM * Parameters: 1291*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1292*7917SReza.Sabdar@Sun.COM * bu_type (input) - backup type. 1293*7917SReza.Sabdar@Sun.COM * env_val (input) - environment variable array. 1294*7917SReza.Sabdar@Sun.COM * env_len (input) - length of env_val. 1295*7917SReza.Sabdar@Sun.COM * 1296*7917SReza.Sabdar@Sun.COM * Returns: 1297*7917SReza.Sabdar@Sun.COM * NDMP_NO_ERR - backup successfully started. 1298*7917SReza.Sabdar@Sun.COM * otherwise - error code of backup start error. 1299*7917SReza.Sabdar@Sun.COM */ 1300*7917SReza.Sabdar@Sun.COM static ndmp_error 1301*7917SReza.Sabdar@Sun.COM start_backup_v3(ndmpd_session_t *session, char *bu_type, ndmp_pval *env_val, 1302*7917SReza.Sabdar@Sun.COM ulong_t env_len) 1303*7917SReza.Sabdar@Sun.COM { 1304*7917SReza.Sabdar@Sun.COM int err; 1305*7917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 1306*7917SReza.Sabdar@Sun.COM ndmpd_module_params_t *params; 1307*7917SReza.Sabdar@Sun.COM ndmp_data_start_backup_reply_v3 reply; 1308*7917SReza.Sabdar@Sun.COM 1309*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 1310*7917SReza.Sabdar@Sun.COM 1311*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_CONNECTED) { 1312*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 1313*7917SReza.Sabdar@Sun.COM "Can't start new backup in current state."); 1314*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, 1315*7917SReza.Sabdar@Sun.COM "Connection to the mover is not established."); 1316*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_STATE_ERR); 1317*7917SReza.Sabdar@Sun.COM } 1318*7917SReza.Sabdar@Sun.COM 1319*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL) { 1320*7917SReza.Sabdar@Sun.COM if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) { 1321*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Write protected device."); 1322*7917SReza.Sabdar@Sun.COM return (NDMP_WRITE_PROTECT_ERR); 1323*7917SReza.Sabdar@Sun.COM } 1324*7917SReza.Sabdar@Sun.COM } 1325*7917SReza.Sabdar@Sun.COM 1326*7917SReza.Sabdar@Sun.COM if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 && 1327*7917SReza.Sabdar@Sun.COM strcmp(bu_type, NDMP_TAR_TYPE) != 0) { 1328*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type); 1329*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump."); 1330*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 1331*7917SReza.Sabdar@Sun.COM } 1332*7917SReza.Sabdar@Sun.COM 1333*7917SReza.Sabdar@Sun.COM err = ndmpd_save_env(session, env_val, env_len); 1334*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) 1335*7917SReza.Sabdar@Sun.COM return (err); 1336*7917SReza.Sabdar@Sun.COM 1337*7917SReza.Sabdar@Sun.COM nlp = ndmp_get_nlp(session); 1338*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1339*7917SReza.Sabdar@Sun.COM params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 1340*7917SReza.Sabdar@Sun.COM if (!params) 1341*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 1342*7917SReza.Sabdar@Sun.COM 1343*7917SReza.Sabdar@Sun.COM params->mp_daemon_cookie = (void *)session; 1344*7917SReza.Sabdar@Sun.COM params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 1345*7917SReza.Sabdar@Sun.COM params->mp_protocol_version = session->ns_protocol_version; 1346*7917SReza.Sabdar@Sun.COM params->mp_operation = NDMP_DATA_OP_BACKUP; 1347*7917SReza.Sabdar@Sun.COM params->mp_get_env_func = ndmpd_api_get_env; 1348*7917SReza.Sabdar@Sun.COM params->mp_add_env_func = ndmpd_api_add_env; 1349*7917SReza.Sabdar@Sun.COM params->mp_set_env_func = ndmpd_api_set_env; 1350*7917SReza.Sabdar@Sun.COM params->mp_get_name_func = 0; 1351*7917SReza.Sabdar@Sun.COM params->mp_dispatch_func = ndmpd_api_dispatch; 1352*7917SReza.Sabdar@Sun.COM params->mp_done_func = ndmpd_api_done_v3; 1353*7917SReza.Sabdar@Sun.COM if (session->ns_protocol_version == NDMPV4) 1354*7917SReza.Sabdar@Sun.COM params->mp_log_func_v3 = ndmpd_api_log_v4; 1355*7917SReza.Sabdar@Sun.COM else 1356*7917SReza.Sabdar@Sun.COM params->mp_log_func_v3 = ndmpd_api_log_v3; 1357*7917SReza.Sabdar@Sun.COM 1358*7917SReza.Sabdar@Sun.COM params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 1359*7917SReza.Sabdar@Sun.COM params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 1360*7917SReza.Sabdar@Sun.COM params->mp_write_func = ndmpd_api_write_v3; 1361*7917SReza.Sabdar@Sun.COM params->mp_read_func = 0; 1362*7917SReza.Sabdar@Sun.COM params->mp_file_recovered_func = 0; 1363*7917SReza.Sabdar@Sun.COM params->mp_stats = &session->ns_data.dd_module.dm_stats; 1364*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_module_cookie = 0; 1365*7917SReza.Sabdar@Sun.COM 1366*7917SReza.Sabdar@Sun.COM if (strcmp(bu_type, NDMP_DUMP_TYPE) == 0) { 1367*7917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_DUMP); 1368*7917SReza.Sabdar@Sun.COM params->mp_file_history_path_func = 0; 1369*7917SReza.Sabdar@Sun.COM params->mp_file_history_dir_func = 1370*7917SReza.Sabdar@Sun.COM ndmpd_api_file_history_dir_v3; 1371*7917SReza.Sabdar@Sun.COM params->mp_file_history_node_func = 1372*7917SReza.Sabdar@Sun.COM ndmpd_api_file_history_node_v3; 1373*7917SReza.Sabdar@Sun.COM } else if (strcmp(bu_type, NDMP_TAR_TYPE) == 0) { 1374*7917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_TAR); 1375*7917SReza.Sabdar@Sun.COM params->mp_file_history_path_func = 1376*7917SReza.Sabdar@Sun.COM ndmpd_api_file_history_file_v3; 1377*7917SReza.Sabdar@Sun.COM params->mp_file_history_dir_func = 0; 1378*7917SReza.Sabdar@Sun.COM params->mp_file_history_node_func = 0; 1379*7917SReza.Sabdar@Sun.COM } else { 1380*7917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_DUMP); 1381*7917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_TAR); 1382*7917SReza.Sabdar@Sun.COM } 1383*7917SReza.Sabdar@Sun.COM 1384*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_start_func = ndmpd_tar_backup_starter_v3; 1385*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_abort_func = ndmpd_tar_backup_abort_v3; 1386*7917SReza.Sabdar@Sun.COM 1387*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 1388*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 1389*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist_v3 = 0; 1390*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist_len = 0; 1391*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read = 0; 1392*7917SReza.Sabdar@Sun.COM session->ns_data.dd_position = 0; 1393*7917SReza.Sabdar@Sun.COM session->ns_data.dd_discard_length = 0; 1394*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 0; 1395*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = 0; 1396*7917SReza.Sabdar@Sun.COM 1397*7917SReza.Sabdar@Sun.COM reply.error = ndmp_backup_get_params_v3(session, params); 1398*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 1399*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "err: %d", err); 1400*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1401*7917SReza.Sabdar@Sun.COM return (reply.error); 1402*7917SReza.Sabdar@Sun.COM } 1403*7917SReza.Sabdar@Sun.COM 1404*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 1405*7917SReza.Sabdar@Sun.COM if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 1406*7917SReza.Sabdar@Sun.COM &reply) < 0) { 1407*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Sending data_start_backup_v3 reply"); 1408*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 1409*7917SReza.Sabdar@Sun.COM } 1410*7917SReza.Sabdar@Sun.COM 1411*7917SReza.Sabdar@Sun.COM NS_INC(nbk); 1412*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 1413*7917SReza.Sabdar@Sun.COM session->ns_data.dd_operation = NDMP_DATA_OP_BACKUP; 1414*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = FALSE; 1415*7917SReza.Sabdar@Sun.COM 1416*7917SReza.Sabdar@Sun.COM /* 1417*7917SReza.Sabdar@Sun.COM * perform the backup 1418*7917SReza.Sabdar@Sun.COM * 1419*7917SReza.Sabdar@Sun.COM * Cannot wait for the thread to exit as we are replying the 1420*7917SReza.Sabdar@Sun.COM * client request here. 1421*7917SReza.Sabdar@Sun.COM */ 1422*7917SReza.Sabdar@Sun.COM err = pthread_create(NULL, NULL, 1423*7917SReza.Sabdar@Sun.COM (funct_t)session->ns_data.dd_module.dm_start_func, 1424*7917SReza.Sabdar@Sun.COM params); 1425*7917SReza.Sabdar@Sun.COM if (err != 0) { 1426*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Can't start backup session."); 1427*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 1428*7917SReza.Sabdar@Sun.COM } 1429*7917SReza.Sabdar@Sun.COM 1430*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 1431*7917SReza.Sabdar@Sun.COM } 1432*7917SReza.Sabdar@Sun.COM 1433*7917SReza.Sabdar@Sun.COM 1434*7917SReza.Sabdar@Sun.COM /* 1435*7917SReza.Sabdar@Sun.COM * start_recover_v3 1436*7917SReza.Sabdar@Sun.COM * 1437*7917SReza.Sabdar@Sun.COM * Start the restore work 1438*7917SReza.Sabdar@Sun.COM * 1439*7917SReza.Sabdar@Sun.COM * Parameters: 1440*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1441*7917SReza.Sabdar@Sun.COM * bu_type (input) - backup type. 1442*7917SReza.Sabdar@Sun.COM * env_val (input) - environment variable array. 1443*7917SReza.Sabdar@Sun.COM * env_len (input) - length of env_val. 1444*7917SReza.Sabdar@Sun.COM * 1445*7917SReza.Sabdar@Sun.COM * Returns: 1446*7917SReza.Sabdar@Sun.COM * NDMP_NO_ERR - recover successfully started. 1447*7917SReza.Sabdar@Sun.COM * otherwise - error code of recover start error. 1448*7917SReza.Sabdar@Sun.COM */ 1449*7917SReza.Sabdar@Sun.COM static ndmp_error 1450*7917SReza.Sabdar@Sun.COM start_recover_v3(ndmpd_session_t *session, char *bu_type, ndmp_pval *env_val, 1451*7917SReza.Sabdar@Sun.COM ulong_t env_len, ndmp_name_v3 *nlist_val, ulong_t nlist_len) 1452*7917SReza.Sabdar@Sun.COM { 1453*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_reply_v3 reply; 1454*7917SReza.Sabdar@Sun.COM ndmpd_module_params_t *params; 1455*7917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 1456*7917SReza.Sabdar@Sun.COM int err; 1457*7917SReza.Sabdar@Sun.COM 1458*7917SReza.Sabdar@Sun.COM (void) memset((void*)&reply, 0, sizeof (reply)); 1459*7917SReza.Sabdar@Sun.COM 1460*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_CONNECTED) { 1461*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Can't start new recover in current state."); 1462*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_STATE_ERR); 1463*7917SReza.Sabdar@Sun.COM } 1464*7917SReza.Sabdar@Sun.COM if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 && 1465*7917SReza.Sabdar@Sun.COM strcmp(bu_type, NDMP_TAR_TYPE) != 0) { 1466*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type); 1467*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump."); 1468*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 1469*7917SReza.Sabdar@Sun.COM } 1470*7917SReza.Sabdar@Sun.COM 1471*7917SReza.Sabdar@Sun.COM nlp = ndmp_get_nlp(session); 1472*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1473*7917SReza.Sabdar@Sun.COM params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 1474*7917SReza.Sabdar@Sun.COM if (!params) { 1475*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 1476*7917SReza.Sabdar@Sun.COM } 1477*7917SReza.Sabdar@Sun.COM 1478*7917SReza.Sabdar@Sun.COM reply.error = ndmpd_save_env(session, env_val, env_len); 1479*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 1480*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1481*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 1482*7917SReza.Sabdar@Sun.COM } 1483*7917SReza.Sabdar@Sun.COM 1484*7917SReza.Sabdar@Sun.COM reply.error = ndmpd_save_nlist_v3(session, nlist_val, nlist_len); 1485*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) { 1486*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1487*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 1488*7917SReza.Sabdar@Sun.COM } 1489*7917SReza.Sabdar@Sun.COM 1490*7917SReza.Sabdar@Sun.COM /* 1491*7917SReza.Sabdar@Sun.COM * Setup restore parameters. 1492*7917SReza.Sabdar@Sun.COM */ 1493*7917SReza.Sabdar@Sun.COM params->mp_daemon_cookie = (void *)session; 1494*7917SReza.Sabdar@Sun.COM params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 1495*7917SReza.Sabdar@Sun.COM params->mp_protocol_version = session->ns_protocol_version; 1496*7917SReza.Sabdar@Sun.COM params->mp_operation = NDMP_DATA_OP_RECOVER; 1497*7917SReza.Sabdar@Sun.COM params->mp_get_env_func = ndmpd_api_get_env; 1498*7917SReza.Sabdar@Sun.COM params->mp_add_env_func = ndmpd_api_add_env; 1499*7917SReza.Sabdar@Sun.COM params->mp_set_env_func = ndmpd_api_set_env; 1500*7917SReza.Sabdar@Sun.COM params->mp_get_name_func = ndmpd_api_get_name_v3; 1501*7917SReza.Sabdar@Sun.COM params->mp_dispatch_func = ndmpd_api_dispatch; 1502*7917SReza.Sabdar@Sun.COM params->mp_done_func = ndmpd_api_done_v3; 1503*7917SReza.Sabdar@Sun.COM if (session->ns_protocol_version == NDMPV4) { 1504*7917SReza.Sabdar@Sun.COM params->mp_log_func_v3 = ndmpd_api_log_v4; 1505*7917SReza.Sabdar@Sun.COM params->mp_file_recovered_func = ndmpd_api_file_recovered_v4; 1506*7917SReza.Sabdar@Sun.COM } else { 1507*7917SReza.Sabdar@Sun.COM params->mp_log_func_v3 = ndmpd_api_log_v3; 1508*7917SReza.Sabdar@Sun.COM params->mp_file_recovered_func = ndmpd_api_file_recovered_v3; 1509*7917SReza.Sabdar@Sun.COM } 1510*7917SReza.Sabdar@Sun.COM 1511*7917SReza.Sabdar@Sun.COM params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 1512*7917SReza.Sabdar@Sun.COM params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 1513*7917SReza.Sabdar@Sun.COM params->mp_write_func = 0; 1514*7917SReza.Sabdar@Sun.COM params->mp_file_history_path_func = 0; 1515*7917SReza.Sabdar@Sun.COM params->mp_file_history_dir_func = 0; 1516*7917SReza.Sabdar@Sun.COM params->mp_file_history_node_func = 0; 1517*7917SReza.Sabdar@Sun.COM params->mp_read_func = ndmpd_api_read_v3; 1518*7917SReza.Sabdar@Sun.COM params->mp_seek_func = ndmpd_api_seek_v3; 1519*7917SReza.Sabdar@Sun.COM params->mp_stats = &session->ns_data.dd_module.dm_stats; 1520*7917SReza.Sabdar@Sun.COM 1521*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_module_cookie = 0; 1522*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_start_func = ndmpd_tar_restore_starter_v3; 1523*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_abort_func = ndmpd_tar_restore_abort_v3; 1524*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 1525*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 1526*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read = 0; 1527*7917SReza.Sabdar@Sun.COM session->ns_data.dd_position = 0; 1528*7917SReza.Sabdar@Sun.COM session->ns_data.dd_discard_length = 0; 1529*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 0; 1530*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = 0; 1531*7917SReza.Sabdar@Sun.COM 1532*7917SReza.Sabdar@Sun.COM err = ndmp_restore_get_params_v3(session, params); 1533*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 1534*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1535*7917SReza.Sabdar@Sun.COM return (err); 1536*7917SReza.Sabdar@Sun.COM } 1537*7917SReza.Sabdar@Sun.COM 1538*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 1539*7917SReza.Sabdar@Sun.COM if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 1540*7917SReza.Sabdar@Sun.COM &reply) < 0) { 1541*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1542*7917SReza.Sabdar@Sun.COM ndmpd_free_nlist_v3(session); 1543*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 1544*7917SReza.Sabdar@Sun.COM "Error sending ndmp_data_start_recover_reply"); 1545*7917SReza.Sabdar@Sun.COM ndmpd_data_error(session, NDMP_DATA_HALT_CONNECT_ERROR); 1546*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 1547*7917SReza.Sabdar@Sun.COM } 1548*7917SReza.Sabdar@Sun.COM 1549*7917SReza.Sabdar@Sun.COM NS_INC(nrs); 1550*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 1551*7917SReza.Sabdar@Sun.COM session->ns_data.dd_operation = NDMP_DATA_OP_RECOVER; 1552*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = FALSE; 1553*7917SReza.Sabdar@Sun.COM 1554*7917SReza.Sabdar@Sun.COM /* 1555*7917SReza.Sabdar@Sun.COM * perform the restore 1556*7917SReza.Sabdar@Sun.COM * 1557*7917SReza.Sabdar@Sun.COM * Cannot wait for the thread to exit as we are replying to the 1558*7917SReza.Sabdar@Sun.COM * client request here. 1559*7917SReza.Sabdar@Sun.COM */ 1560*7917SReza.Sabdar@Sun.COM err = pthread_create(NULL, NULL, 1561*7917SReza.Sabdar@Sun.COM (funct_t)session->ns_data.dd_module.dm_start_func, 1562*7917SReza.Sabdar@Sun.COM params); 1563*7917SReza.Sabdar@Sun.COM 1564*7917SReza.Sabdar@Sun.COM if (err != 0) { 1565*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Can't start recover session."); 1566*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 1567*7917SReza.Sabdar@Sun.COM } 1568*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 1569*7917SReza.Sabdar@Sun.COM } 1570*7917SReza.Sabdar@Sun.COM 1571*7917SReza.Sabdar@Sun.COM 1572*7917SReza.Sabdar@Sun.COM /* 1573*7917SReza.Sabdar@Sun.COM * discard_data_v3 1574*7917SReza.Sabdar@Sun.COM * 1575*7917SReza.Sabdar@Sun.COM * Read and discard data from the data connection. 1576*7917SReza.Sabdar@Sun.COM * Called when a module has called ndmpd_seek() prior to 1577*7917SReza.Sabdar@Sun.COM * reading all of the data from the previous seek. 1578*7917SReza.Sabdar@Sun.COM * 1579*7917SReza.Sabdar@Sun.COM * Parameters: 1580*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1581*7917SReza.Sabdar@Sun.COM * 1582*7917SReza.Sabdar@Sun.COM * Returns: 1583*7917SReza.Sabdar@Sun.COM * number of bytes read and discarded. 1584*7917SReza.Sabdar@Sun.COM * -1 - error. 1585*7917SReza.Sabdar@Sun.COM */ 1586*7917SReza.Sabdar@Sun.COM static int 1587*7917SReza.Sabdar@Sun.COM discard_data_v3(ndmpd_session_t *session, ulong_t length) 1588*7917SReza.Sabdar@Sun.COM { 1589*7917SReza.Sabdar@Sun.COM static char buf[MAX_RECORD_SIZE]; 1590*7917SReza.Sabdar@Sun.COM int n, toread; 1591*7917SReza.Sabdar@Sun.COM 1592*7917SReza.Sabdar@Sun.COM toread = (length < MAX_RECORD_SIZE) ? length : 1593*7917SReza.Sabdar@Sun.COM MAX_RECORD_SIZE; 1594*7917SReza.Sabdar@Sun.COM 1595*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "discard data, length = %u", length); 1596*7917SReza.Sabdar@Sun.COM 1597*7917SReza.Sabdar@Sun.COM /* Read and discard the data. */ 1598*7917SReza.Sabdar@Sun.COM n = read(session->ns_data.dd_sock, buf, toread); 1599*7917SReza.Sabdar@Sun.COM if (n < 0) { 1600*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Socket read error: %m."); 1601*7917SReza.Sabdar@Sun.COM n = -1; 1602*7917SReza.Sabdar@Sun.COM } 1603*7917SReza.Sabdar@Sun.COM 1604*7917SReza.Sabdar@Sun.COM return (n); 1605*7917SReza.Sabdar@Sun.COM } 1606*7917SReza.Sabdar@Sun.COM 1607*7917SReza.Sabdar@Sun.COM 1608*7917SReza.Sabdar@Sun.COM /* 1609*7917SReza.Sabdar@Sun.COM * ndmpd_remote_read_v3 1610*7917SReza.Sabdar@Sun.COM * 1611*7917SReza.Sabdar@Sun.COM * Reads data from the remote mover. 1612*7917SReza.Sabdar@Sun.COM * 1613*7917SReza.Sabdar@Sun.COM * Parameters: 1614*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1615*7917SReza.Sabdar@Sun.COM * data (input) - data to be written. 1616*7917SReza.Sabdar@Sun.COM * length (input) - data length. 1617*7917SReza.Sabdar@Sun.COM * 1618*7917SReza.Sabdar@Sun.COM * Returns: 1619*7917SReza.Sabdar@Sun.COM * 0 - data successfully read. 1620*7917SReza.Sabdar@Sun.COM * -1 - error. 1621*7917SReza.Sabdar@Sun.COM */ 1622*7917SReza.Sabdar@Sun.COM int 1623*7917SReza.Sabdar@Sun.COM ndmpd_remote_read_v3(ndmpd_session_t *session, char *data, ulong_t length) 1624*7917SReza.Sabdar@Sun.COM { 1625*7917SReza.Sabdar@Sun.COM ulong_t count; 1626*7917SReza.Sabdar@Sun.COM ulong_t len; 1627*7917SReza.Sabdar@Sun.COM ssize_t n; 1628*7917SReza.Sabdar@Sun.COM ndmp_notify_data_read_request request; 1629*7917SReza.Sabdar@Sun.COM tlm_job_stats_t *jstat; 1630*7917SReza.Sabdar@Sun.COM longlong_t fsize; 1631*7917SReza.Sabdar@Sun.COM 1632*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "ns_data.dd_xx: [%llu, %llu, %llu, %llu, %llu]", 1633*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read, 1634*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset, 1635*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length, 1636*7917SReza.Sabdar@Sun.COM session->ns_data.dd_position, 1637*7917SReza.Sabdar@Sun.COM session->ns_data.dd_discard_length); 1638*7917SReza.Sabdar@Sun.COM 1639*7917SReza.Sabdar@Sun.COM count = 0; 1640*7917SReza.Sabdar@Sun.COM while (count < length) { 1641*7917SReza.Sabdar@Sun.COM len = length - count; 1642*7917SReza.Sabdar@Sun.COM 1643*7917SReza.Sabdar@Sun.COM /* 1644*7917SReza.Sabdar@Sun.COM * If the end of the seek window has been reached then 1645*7917SReza.Sabdar@Sun.COM * send an ndmp_read request to the client. 1646*7917SReza.Sabdar@Sun.COM * The NDMP client will then send a mover_data_read request to 1647*7917SReza.Sabdar@Sun.COM * the remote mover and the mover will send more data. 1648*7917SReza.Sabdar@Sun.COM * This condition can occur if the module attempts to read past 1649*7917SReza.Sabdar@Sun.COM * a seek window set via a prior call to ndmpd_seek() or 1650*7917SReza.Sabdar@Sun.COM * the module has not issued a seek. If no seek was issued then 1651*7917SReza.Sabdar@Sun.COM * pretend that a seek was issued to read the entire tape. 1652*7917SReza.Sabdar@Sun.COM */ 1653*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_bytes_left_to_read == 0) { 1654*7917SReza.Sabdar@Sun.COM /* ndmpd_seek() never called? */ 1655*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_read_length == 0) { 1656*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read = ~0LL; 1657*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 0LL; 1658*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = ~0LL; 1659*7917SReza.Sabdar@Sun.COM } else { 1660*7917SReza.Sabdar@Sun.COM /* 1661*7917SReza.Sabdar@Sun.COM * While restoring a file, restoreFile() 1662*7917SReza.Sabdar@Sun.COM * records the number of bytes still need to 1663*7917SReza.Sabdar@Sun.COM * be restored. We use this as a guidance 1664*7917SReza.Sabdar@Sun.COM * when asking for data from the tape. 1665*7917SReza.Sabdar@Sun.COM */ 1666*7917SReza.Sabdar@Sun.COM jstat = session->ns_ndmp_lbr_params->nlp_jstat; 1667*7917SReza.Sabdar@Sun.COM fsize = jstat->js_bytes_in_file; 1668*7917SReza.Sabdar@Sun.COM 1669*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "bytes_left [%llu / %u]", 1670*7917SReza.Sabdar@Sun.COM fsize, len); 1671*7917SReza.Sabdar@Sun.COM 1672*7917SReza.Sabdar@Sun.COM /* 1673*7917SReza.Sabdar@Sun.COM * Fall back to the old way if fsize if too 1674*7917SReza.Sabdar@Sun.COM * small. 1675*7917SReza.Sabdar@Sun.COM */ 1676*7917SReza.Sabdar@Sun.COM if (fsize < len) 1677*7917SReza.Sabdar@Sun.COM fsize = len; 1678*7917SReza.Sabdar@Sun.COM 1679*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read = fsize; 1680*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 1681*7917SReza.Sabdar@Sun.COM session->ns_data.dd_position; 1682*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = fsize; 1683*7917SReza.Sabdar@Sun.COM } 1684*7917SReza.Sabdar@Sun.COM 1685*7917SReza.Sabdar@Sun.COM request.offset = 1686*7917SReza.Sabdar@Sun.COM long_long_to_quad(session->ns_data.dd_read_offset); 1687*7917SReza.Sabdar@Sun.COM request.length = 1688*7917SReza.Sabdar@Sun.COM long_long_to_quad(session->ns_data.dd_read_length); 1689*7917SReza.Sabdar@Sun.COM 1690*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "to NOTIFY_DATA_READ [%llu, %llu]", 1691*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset, 1692*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length); 1693*7917SReza.Sabdar@Sun.COM 1694*7917SReza.Sabdar@Sun.COM if (ndmp_send_request(session->ns_connection, 1695*7917SReza.Sabdar@Sun.COM NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR, 1696*7917SReza.Sabdar@Sun.COM &request, 0) < 0) { 1697*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 1698*7917SReza.Sabdar@Sun.COM "Sending notify_data_read request"); 1699*7917SReza.Sabdar@Sun.COM return (-1); 1700*7917SReza.Sabdar@Sun.COM } 1701*7917SReza.Sabdar@Sun.COM } 1702*7917SReza.Sabdar@Sun.COM 1703*7917SReza.Sabdar@Sun.COM /* 1704*7917SReza.Sabdar@Sun.COM * If the module called ndmpd_seek() prior to reading all of the 1705*7917SReza.Sabdar@Sun.COM * data that the remote mover was requested to send, then the 1706*7917SReza.Sabdar@Sun.COM * excess data from the seek has to be discarded. 1707*7917SReza.Sabdar@Sun.COM */ 1708*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_discard_length != 0) { 1709*7917SReza.Sabdar@Sun.COM n = discard_data_v3(session, 1710*7917SReza.Sabdar@Sun.COM (ulong_t)session->ns_data.dd_discard_length); 1711*7917SReza.Sabdar@Sun.COM if (n < 0) 1712*7917SReza.Sabdar@Sun.COM return (-1); 1713*7917SReza.Sabdar@Sun.COM 1714*7917SReza.Sabdar@Sun.COM session->ns_data.dd_discard_length -= n; 1715*7917SReza.Sabdar@Sun.COM continue; 1716*7917SReza.Sabdar@Sun.COM } 1717*7917SReza.Sabdar@Sun.COM 1718*7917SReza.Sabdar@Sun.COM /* 1719*7917SReza.Sabdar@Sun.COM * Don't attempt to read more data than the remote is sending. 1720*7917SReza.Sabdar@Sun.COM */ 1721*7917SReza.Sabdar@Sun.COM if (len > session->ns_data.dd_bytes_left_to_read) 1722*7917SReza.Sabdar@Sun.COM len = session->ns_data.dd_bytes_left_to_read; 1723*7917SReza.Sabdar@Sun.COM 1724*7917SReza.Sabdar@Sun.COM if ((n = read(session->ns_data.dd_sock, &data[count], 1725*7917SReza.Sabdar@Sun.COM len)) < 0) { 1726*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Socket read error: %m."); 1727*7917SReza.Sabdar@Sun.COM return (-1); 1728*7917SReza.Sabdar@Sun.COM } 1729*7917SReza.Sabdar@Sun.COM 1730*7917SReza.Sabdar@Sun.COM /* read returns 0 if the connection was closed */ 1731*7917SReza.Sabdar@Sun.COM if (n == 0) { 1732*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "n 0 errno %d", 1733*7917SReza.Sabdar@Sun.COM errno); 1734*7917SReza.Sabdar@Sun.COM return (-1); 1735*7917SReza.Sabdar@Sun.COM } 1736*7917SReza.Sabdar@Sun.COM 1737*7917SReza.Sabdar@Sun.COM count += n; 1738*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read -= n; 1739*7917SReza.Sabdar@Sun.COM session->ns_data.dd_position += n; 1740*7917SReza.Sabdar@Sun.COM } 1741*7917SReza.Sabdar@Sun.COM 1742*7917SReza.Sabdar@Sun.COM return (0); 1743*7917SReza.Sabdar@Sun.COM } 1744*7917SReza.Sabdar@Sun.COM 1745*7917SReza.Sabdar@Sun.COM 1746*7917SReza.Sabdar@Sun.COM /* 1747*7917SReza.Sabdar@Sun.COM * nlp_release_job_stat 1748*7917SReza.Sabdar@Sun.COM * 1749*7917SReza.Sabdar@Sun.COM * Unreference the job statistics 1750*7917SReza.Sabdar@Sun.COM * 1751*7917SReza.Sabdar@Sun.COM * Parameters: 1752*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1753*7917SReza.Sabdar@Sun.COM * 1754*7917SReza.Sabdar@Sun.COM * Returns: 1755*7917SReza.Sabdar@Sun.COM * void 1756*7917SReza.Sabdar@Sun.COM */ 1757*7917SReza.Sabdar@Sun.COM static void 1758*7917SReza.Sabdar@Sun.COM nlp_release_job_stat(ndmpd_session_t *session) 1759*7917SReza.Sabdar@Sun.COM { 1760*7917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 1761*7917SReza.Sabdar@Sun.COM 1762*7917SReza.Sabdar@Sun.COM if ((nlp = ndmp_get_nlp(session)) == NULL) { 1763*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1764*7917SReza.Sabdar@Sun.COM return; 1765*7917SReza.Sabdar@Sun.COM } 1766*7917SReza.Sabdar@Sun.COM if (nlp->nlp_jstat != NULL) { 1767*7917SReza.Sabdar@Sun.COM nlp->nlp_bytes_total = 1768*7917SReza.Sabdar@Sun.COM (u_longlong_t)nlp->nlp_jstat->js_bytes_total; 1769*7917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(nlp->nlp_jstat->js_job_name); 1770*7917SReza.Sabdar@Sun.COM nlp->nlp_jstat = NULL; 1771*7917SReza.Sabdar@Sun.COM } else 1772*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "JSTAT == NULL"); 1773*7917SReza.Sabdar@Sun.COM } 1774*7917SReza.Sabdar@Sun.COM 1775*7917SReza.Sabdar@Sun.COM 1776*7917SReza.Sabdar@Sun.COM /* *** ndmpd global internal functions *********************************** */ 1777*7917SReza.Sabdar@Sun.COM 1778*7917SReza.Sabdar@Sun.COM /* 1779*7917SReza.Sabdar@Sun.COM * ndmpd_data_init 1780*7917SReza.Sabdar@Sun.COM * 1781*7917SReza.Sabdar@Sun.COM * Initializes data specific session variables. 1782*7917SReza.Sabdar@Sun.COM * 1783*7917SReza.Sabdar@Sun.COM * Parameters: 1784*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1785*7917SReza.Sabdar@Sun.COM * 1786*7917SReza.Sabdar@Sun.COM * Returns: 1787*7917SReza.Sabdar@Sun.COM * void 1788*7917SReza.Sabdar@Sun.COM */ 1789*7917SReza.Sabdar@Sun.COM int 1790*7917SReza.Sabdar@Sun.COM ndmpd_data_init(ndmpd_session_t *session) 1791*7917SReza.Sabdar@Sun.COM { 1792*7917SReza.Sabdar@Sun.COM session->ns_data.dd_operation = NDMP_DATA_OP_NOACTION; 1793*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_IDLE; 1794*7917SReza.Sabdar@Sun.COM session->ns_data.dd_halt_reason = NDMP_DATA_HALT_NA; 1795*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = FALSE; 1796*7917SReza.Sabdar@Sun.COM session->ns_data.dd_env = 0; 1797*7917SReza.Sabdar@Sun.COM session->ns_data.dd_env_len = 0; 1798*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist = 0; 1799*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist_len = 0; 1800*7917SReza.Sabdar@Sun.COM session->ns_data.dd_mover.addr_type = NDMP_ADDR_LOCAL; 1801*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = -1; 1802*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 0; 1803*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = 0; 1804*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 1805*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 1806*7917SReza.Sabdar@Sun.COM /* 1807*7917SReza.Sabdar@Sun.COM * NDMP V3 1808*7917SReza.Sabdar@Sun.COM */ 1809*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_IDLE; 1810*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist_v3 = 0; 1811*7917SReza.Sabdar@Sun.COM session->ns_data.dd_data_addr.addr_type = NDMP_ADDR_LOCAL; 1812*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock = -1; 1813*7917SReza.Sabdar@Sun.COM session->ns_data.dd_bytes_left_to_read = 0LL; 1814*7917SReza.Sabdar@Sun.COM session->ns_data.dd_position = 0LL; 1815*7917SReza.Sabdar@Sun.COM session->ns_data.dd_discard_length = 0LL; 1816*7917SReza.Sabdar@Sun.COM return (0); 1817*7917SReza.Sabdar@Sun.COM } 1818*7917SReza.Sabdar@Sun.COM 1819*7917SReza.Sabdar@Sun.COM 1820*7917SReza.Sabdar@Sun.COM 1821*7917SReza.Sabdar@Sun.COM /* 1822*7917SReza.Sabdar@Sun.COM * ndmpd_data_cleanup 1823*7917SReza.Sabdar@Sun.COM * 1824*7917SReza.Sabdar@Sun.COM * Releases resources allocated during a data operation. 1825*7917SReza.Sabdar@Sun.COM * 1826*7917SReza.Sabdar@Sun.COM * Parameters: 1827*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1828*7917SReza.Sabdar@Sun.COM * 1829*7917SReza.Sabdar@Sun.COM * Returns: 1830*7917SReza.Sabdar@Sun.COM * void 1831*7917SReza.Sabdar@Sun.COM */ 1832*7917SReza.Sabdar@Sun.COM void 1833*7917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(ndmpd_session_t *session) 1834*7917SReza.Sabdar@Sun.COM { 1835*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_listen_sock != -1) { 1836*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "data.listen_sock: %d", 1837*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock); 1838*7917SReza.Sabdar@Sun.COM (void) ndmpd_remove_file_handler(session, 1839*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock); 1840*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_listen_sock); 1841*7917SReza.Sabdar@Sun.COM session->ns_data.dd_listen_sock = -1; 1842*7917SReza.Sabdar@Sun.COM } 1843*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock != -1) { 1844*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "data.sock: %d", 1845*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock); 1846*7917SReza.Sabdar@Sun.COM 1847*7917SReza.Sabdar@Sun.COM /* 1848*7917SReza.Sabdar@Sun.COM * ndmpcopy: we use the same socket for the mover, 1849*7917SReza.Sabdar@Sun.COM * so expect to close when mover is done! 1850*7917SReza.Sabdar@Sun.COM */ 1851*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock != session->ns_mover.md_sock) 1852*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_sock); 1853*7917SReza.Sabdar@Sun.COM 1854*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = -1; 1855*7917SReza.Sabdar@Sun.COM } 1856*7917SReza.Sabdar@Sun.COM 1857*7917SReza.Sabdar@Sun.COM ndmpd_free_env(session); 1858*7917SReza.Sabdar@Sun.COM ndmpd_free_nlist(session); 1859*7917SReza.Sabdar@Sun.COM } 1860*7917SReza.Sabdar@Sun.COM 1861*7917SReza.Sabdar@Sun.COM 1862*7917SReza.Sabdar@Sun.COM /* 1863*7917SReza.Sabdar@Sun.COM * ndmp_data_get_mover_mode 1864*7917SReza.Sabdar@Sun.COM * 1865*7917SReza.Sabdar@Sun.COM * Return the mover mode 1866*7917SReza.Sabdar@Sun.COM * 1867*7917SReza.Sabdar@Sun.COM * Parameters: 1868*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1869*7917SReza.Sabdar@Sun.COM * 1870*7917SReza.Sabdar@Sun.COM * Returns: 1871*7917SReza.Sabdar@Sun.COM * remote - remote backup 1872*7917SReza.Sabdar@Sun.COM * local - local backup 1873*7917SReza.Sabdar@Sun.COM */ 1874*7917SReza.Sabdar@Sun.COM char * 1875*7917SReza.Sabdar@Sun.COM ndmp_data_get_mover_mode(ndmpd_session_t *session) 1876*7917SReza.Sabdar@Sun.COM { 1877*7917SReza.Sabdar@Sun.COM char *rv; 1878*7917SReza.Sabdar@Sun.COM 1879*7917SReza.Sabdar@Sun.COM switch (session->ns_protocol_version) { 1880*7917SReza.Sabdar@Sun.COM case NDMPV2: 1881*7917SReza.Sabdar@Sun.COM rv = ((session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) 1882*7917SReza.Sabdar@Sun.COM ? "remote" : "local"); 1883*7917SReza.Sabdar@Sun.COM break; 1884*7917SReza.Sabdar@Sun.COM case NDMPV3: 1885*7917SReza.Sabdar@Sun.COM rv = ((session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP) 1886*7917SReza.Sabdar@Sun.COM ? "remote" : "local"); 1887*7917SReza.Sabdar@Sun.COM break; 1888*7917SReza.Sabdar@Sun.COM case NDMPV4: 1889*7917SReza.Sabdar@Sun.COM rv = ((session->ns_data.dd_data_addr.addr_type == 1890*7917SReza.Sabdar@Sun.COM NDMP_ADDR_TCP || 1891*7917SReza.Sabdar@Sun.COM (session->ns_data.dd_data_addr_v4.addr_type == 1892*7917SReza.Sabdar@Sun.COM NDMP_ADDR_TCP)) ? "remote" : "local"); 1893*7917SReza.Sabdar@Sun.COM break; 1894*7917SReza.Sabdar@Sun.COM default: 1895*7917SReza.Sabdar@Sun.COM rv = "Uknonwn"; 1896*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid protocol version %d.", 1897*7917SReza.Sabdar@Sun.COM session->ns_protocol_version); 1898*7917SReza.Sabdar@Sun.COM } 1899*7917SReza.Sabdar@Sun.COM 1900*7917SReza.Sabdar@Sun.COM return (rv); 1901*7917SReza.Sabdar@Sun.COM } 1902*7917SReza.Sabdar@Sun.COM 1903*7917SReza.Sabdar@Sun.COM /* *** static functions ******************************************** */ 1904*7917SReza.Sabdar@Sun.COM 1905*7917SReza.Sabdar@Sun.COM /* 1906*7917SReza.Sabdar@Sun.COM * start_backup 1907*7917SReza.Sabdar@Sun.COM * 1908*7917SReza.Sabdar@Sun.COM * Request handling code common to version 1 and 1909*7917SReza.Sabdar@Sun.COM * version 2 data_start_backup request handlers. 1910*7917SReza.Sabdar@Sun.COM * 1911*7917SReza.Sabdar@Sun.COM * Parameters: 1912*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 1913*7917SReza.Sabdar@Sun.COM * bu_type (input) - backup type. 1914*7917SReza.Sabdar@Sun.COM * env_val (input) - environment variable array. 1915*7917SReza.Sabdar@Sun.COM * env_len (input) - length of env_val. 1916*7917SReza.Sabdar@Sun.COM * 1917*7917SReza.Sabdar@Sun.COM * Returns: 1918*7917SReza.Sabdar@Sun.COM * NDMP_NO_ERR - backup successfully started. 1919*7917SReza.Sabdar@Sun.COM * otherwise - error code of backup start error. 1920*7917SReza.Sabdar@Sun.COM */ 1921*7917SReza.Sabdar@Sun.COM static ndmp_error 1922*7917SReza.Sabdar@Sun.COM start_backup(ndmpd_session_t *session, char *bu_type, ndmp_pval *env_val, 1923*7917SReza.Sabdar@Sun.COM ulong_t env_len) 1924*7917SReza.Sabdar@Sun.COM { 1925*7917SReza.Sabdar@Sun.COM ndmp_data_start_backup_reply reply; 1926*7917SReza.Sabdar@Sun.COM ndmpd_module_params_t *params; 1927*7917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 1928*7917SReza.Sabdar@Sun.COM int err; 1929*7917SReza.Sabdar@Sun.COM 1930*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 1931*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Can't start new backup in current state."); 1932*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_STATE_ERR); 1933*7917SReza.Sabdar@Sun.COM } 1934*7917SReza.Sabdar@Sun.COM if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 && 1935*7917SReza.Sabdar@Sun.COM strcmp(bu_type, NDMP_TAR_TYPE) != 0) { 1936*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type); 1937*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump."); 1938*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 1939*7917SReza.Sabdar@Sun.COM } 1940*7917SReza.Sabdar@Sun.COM if ((err = ndmpd_save_env(session, env_val, env_len)) != NDMP_NO_ERR) 1941*7917SReza.Sabdar@Sun.COM return (err); 1942*7917SReza.Sabdar@Sun.COM 1943*7917SReza.Sabdar@Sun.COM nlp = ndmp_get_nlp(session); 1944*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 1945*7917SReza.Sabdar@Sun.COM params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 1946*7917SReza.Sabdar@Sun.COM if (params == NULL) 1947*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 1948*7917SReza.Sabdar@Sun.COM 1949*7917SReza.Sabdar@Sun.COM params->mp_daemon_cookie = (void *)session; 1950*7917SReza.Sabdar@Sun.COM params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 1951*7917SReza.Sabdar@Sun.COM params->mp_protocol_version = session->ns_protocol_version; 1952*7917SReza.Sabdar@Sun.COM params->mp_operation = NDMP_DATA_OP_BACKUP; 1953*7917SReza.Sabdar@Sun.COM params->mp_get_env_func = ndmpd_api_get_env; 1954*7917SReza.Sabdar@Sun.COM params->mp_add_env_func = ndmpd_api_add_env; 1955*7917SReza.Sabdar@Sun.COM params->mp_get_name_func = ndmpd_api_get_name; 1956*7917SReza.Sabdar@Sun.COM params->mp_dispatch_func = ndmpd_api_dispatch; 1957*7917SReza.Sabdar@Sun.COM params->mp_done_func = ndmpd_api_done_v2; 1958*7917SReza.Sabdar@Sun.COM params->mp_log_func = ndmpd_api_log_v2; 1959*7917SReza.Sabdar@Sun.COM params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 1960*7917SReza.Sabdar@Sun.COM params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 1961*7917SReza.Sabdar@Sun.COM params->mp_write_func = ndmpd_api_write_v2; 1962*7917SReza.Sabdar@Sun.COM params->mp_read_func = 0; 1963*7917SReza.Sabdar@Sun.COM params->mp_file_recovered_func = 0; 1964*7917SReza.Sabdar@Sun.COM params->mp_stats = &session->ns_data.dd_module.dm_stats; 1965*7917SReza.Sabdar@Sun.COM 1966*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_module_cookie = 0; 1967*7917SReza.Sabdar@Sun.COM if (strcmp(bu_type, NDMP_DUMP_TYPE) == 0) { 1968*7917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_DUMP); 1969*7917SReza.Sabdar@Sun.COM params->mp_file_history_path_func = 0; 1970*7917SReza.Sabdar@Sun.COM params->mp_file_history_dir_func = 1971*7917SReza.Sabdar@Sun.COM ndmpd_api_file_history_dir_v2; 1972*7917SReza.Sabdar@Sun.COM params->mp_file_history_node_func = 1973*7917SReza.Sabdar@Sun.COM ndmpd_api_file_history_node_v2; 1974*7917SReza.Sabdar@Sun.COM } else if (strcmp(bu_type, NDMP_TAR_TYPE) == 0) { 1975*7917SReza.Sabdar@Sun.COM /* backup type == NDMP_TAR_TYPE */ 1976*7917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_TAR); 1977*7917SReza.Sabdar@Sun.COM params->mp_file_history_path_func = 1978*7917SReza.Sabdar@Sun.COM ndmpd_api_file_history_path_v2; 1979*7917SReza.Sabdar@Sun.COM params->mp_file_history_dir_func = 0; 1980*7917SReza.Sabdar@Sun.COM params->mp_file_history_node_func = 0; 1981*7917SReza.Sabdar@Sun.COM } else { 1982*7917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_DUMP); 1983*7917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_TAR); 1984*7917SReza.Sabdar@Sun.COM } 1985*7917SReza.Sabdar@Sun.COM 1986*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_start_func = ndmpd_tar_backup_starter; 1987*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_abort_func = ndmpd_tar_backup_abort; 1988*7917SReza.Sabdar@Sun.COM 1989*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 1990*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 1991*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist = 0; 1992*7917SReza.Sabdar@Sun.COM session->ns_data.dd_nlist_len = 0; 1993*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 0; 1994*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = 0; 1995*7917SReza.Sabdar@Sun.COM 1996*7917SReza.Sabdar@Sun.COM if ((err = ndmp_backup_extract_params(session, 1997*7917SReza.Sabdar@Sun.COM params)) != NDMP_NO_ERR) { 1998*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "err: %d", err); 1999*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2000*7917SReza.Sabdar@Sun.COM return (err); 2001*7917SReza.Sabdar@Sun.COM } 2002*7917SReza.Sabdar@Sun.COM 2003*7917SReza.Sabdar@Sun.COM err = ndmpd_mover_connect(session, NDMP_MOVER_MODE_READ); 2004*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 2005*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 2006*7917SReza.Sabdar@Sun.COM "mover connect err: %d", err); 2007*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2008*7917SReza.Sabdar@Sun.COM return (err); 2009*7917SReza.Sabdar@Sun.COM } 2010*7917SReza.Sabdar@Sun.COM 2011*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 2012*7917SReza.Sabdar@Sun.COM 2013*7917SReza.Sabdar@Sun.COM session->ns_data.dd_operation = NDMP_DATA_OP_BACKUP; 2014*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = FALSE; 2015*7917SReza.Sabdar@Sun.COM 2016*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "starting backup"); 2017*7917SReza.Sabdar@Sun.COM 2018*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 2019*7917SReza.Sabdar@Sun.COM if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 2020*7917SReza.Sabdar@Sun.COM &reply) < 0) { 2021*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Sending data_start_backup reply"); 2022*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2023*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) { 2024*7917SReza.Sabdar@Sun.COM /* 2025*7917SReza.Sabdar@Sun.COM * ndmpcopy: we use the same socket for the mover, 2026*7917SReza.Sabdar@Sun.COM * so expect to close when mover is done! 2027*7917SReza.Sabdar@Sun.COM */ 2028*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock != 2029*7917SReza.Sabdar@Sun.COM session->ns_mover.md_sock) 2030*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_sock); 2031*7917SReza.Sabdar@Sun.COM 2032*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = -1; 2033*7917SReza.Sabdar@Sun.COM } else 2034*7917SReza.Sabdar@Sun.COM ndmpd_mover_error(session, 2035*7917SReza.Sabdar@Sun.COM NDMP_MOVER_HALT_CONNECT_CLOSED); 2036*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 2037*7917SReza.Sabdar@Sun.COM } 2038*7917SReza.Sabdar@Sun.COM 2039*7917SReza.Sabdar@Sun.COM /* 2040*7917SReza.Sabdar@Sun.COM * perform the backup 2041*7917SReza.Sabdar@Sun.COM * 2042*7917SReza.Sabdar@Sun.COM * Cannot wait for the thread to exit as we are replying to the 2043*7917SReza.Sabdar@Sun.COM * client request here. 2044*7917SReza.Sabdar@Sun.COM */ 2045*7917SReza.Sabdar@Sun.COM (void) pthread_create(NULL, NULL, 2046*7917SReza.Sabdar@Sun.COM (funct_t)session->ns_data.dd_module.dm_start_func, 2047*7917SReza.Sabdar@Sun.COM params); 2048*7917SReza.Sabdar@Sun.COM 2049*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 2050*7917SReza.Sabdar@Sun.COM } 2051*7917SReza.Sabdar@Sun.COM 2052*7917SReza.Sabdar@Sun.COM 2053*7917SReza.Sabdar@Sun.COM /* 2054*7917SReza.Sabdar@Sun.COM * start_recover 2055*7917SReza.Sabdar@Sun.COM * 2056*7917SReza.Sabdar@Sun.COM * The main recover/restore function 2057*7917SReza.Sabdar@Sun.COM * 2058*7917SReza.Sabdar@Sun.COM * Parameters: 2059*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 2060*7917SReza.Sabdar@Sun.COM * bu_type (input) - backup type. 2061*7917SReza.Sabdar@Sun.COM * env_val (input) - environment variable array. 2062*7917SReza.Sabdar@Sun.COM * env_len (input) - length of env_val. 2063*7917SReza.Sabdar@Sun.COM * nlist_val (input) - list of files 2064*7917SReza.Sabdar@Sun.COM * nlist_len (input) - length of nlist_val 2065*7917SReza.Sabdar@Sun.COM * 2066*7917SReza.Sabdar@Sun.COM * Returns: 2067*7917SReza.Sabdar@Sun.COM * NDMP_NO_ERR - recover successfully started. 2068*7917SReza.Sabdar@Sun.COM * otherwise - error code of backup start error. 2069*7917SReza.Sabdar@Sun.COM */ 2070*7917SReza.Sabdar@Sun.COM static ndmp_error 2071*7917SReza.Sabdar@Sun.COM start_recover(ndmpd_session_t *session, char *bu_type, ndmp_pval *env_val, 2072*7917SReza.Sabdar@Sun.COM ulong_t env_len, ndmp_name *nlist_val, ulong_t nlist_len) 2073*7917SReza.Sabdar@Sun.COM { 2074*7917SReza.Sabdar@Sun.COM ndmp_data_start_recover_reply_v2 reply; 2075*7917SReza.Sabdar@Sun.COM ndmpd_module_params_t *params; 2076*7917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 2077*7917SReza.Sabdar@Sun.COM int err; 2078*7917SReza.Sabdar@Sun.COM 2079*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) { 2080*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Can't start new recover in current state."); 2081*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_STATE_ERR); 2082*7917SReza.Sabdar@Sun.COM } 2083*7917SReza.Sabdar@Sun.COM 2084*7917SReza.Sabdar@Sun.COM if (strcmp(bu_type, NDMP_DUMP_TYPE) != 0 && 2085*7917SReza.Sabdar@Sun.COM strcmp(bu_type, NDMP_TAR_TYPE) != 0) { 2086*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Invalid backup type: %s.", bu_type); 2087*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Supported backup types are tar and dump."); 2088*7917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 2089*7917SReza.Sabdar@Sun.COM } 2090*7917SReza.Sabdar@Sun.COM 2091*7917SReza.Sabdar@Sun.COM reply.error = ndmpd_save_env(session, env_val, env_len); 2092*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) 2093*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 2094*7917SReza.Sabdar@Sun.COM 2095*7917SReza.Sabdar@Sun.COM reply.error = ndmpd_save_nlist_v2(session, nlist_val, nlist_len); 2096*7917SReza.Sabdar@Sun.COM if (reply.error != NDMP_NO_ERR) 2097*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 2098*7917SReza.Sabdar@Sun.COM 2099*7917SReza.Sabdar@Sun.COM nlp = ndmp_get_nlp(session); 2100*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2101*7917SReza.Sabdar@Sun.COM params = nlp->nlp_params = ndmp_malloc(sizeof (ndmpd_module_params_t)); 2102*7917SReza.Sabdar@Sun.COM if (params == NULL) 2103*7917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 2104*7917SReza.Sabdar@Sun.COM 2105*7917SReza.Sabdar@Sun.COM /* 2106*7917SReza.Sabdar@Sun.COM * Setup restore parameters. 2107*7917SReza.Sabdar@Sun.COM */ 2108*7917SReza.Sabdar@Sun.COM params->mp_daemon_cookie = (void *)session; 2109*7917SReza.Sabdar@Sun.COM params->mp_module_cookie = &session->ns_data.dd_module.dm_module_cookie; 2110*7917SReza.Sabdar@Sun.COM params->mp_protocol_version = session->ns_protocol_version; 2111*7917SReza.Sabdar@Sun.COM params->mp_operation = NDMP_DATA_OP_RECOVER; 2112*7917SReza.Sabdar@Sun.COM params->mp_get_env_func = ndmpd_api_get_env; 2113*7917SReza.Sabdar@Sun.COM params->mp_add_env_func = ndmpd_api_add_env; 2114*7917SReza.Sabdar@Sun.COM params->mp_get_name_func = ndmpd_api_get_name; 2115*7917SReza.Sabdar@Sun.COM params->mp_dispatch_func = ndmpd_api_dispatch; 2116*7917SReza.Sabdar@Sun.COM params->mp_done_func = ndmpd_api_done_v2; 2117*7917SReza.Sabdar@Sun.COM params->mp_log_func = ndmpd_api_log_v2; 2118*7917SReza.Sabdar@Sun.COM params->mp_add_file_handler_func = ndmpd_api_add_file_handler; 2119*7917SReza.Sabdar@Sun.COM params->mp_remove_file_handler_func = ndmpd_api_remove_file_handler; 2120*7917SReza.Sabdar@Sun.COM params->mp_write_func = 0; 2121*7917SReza.Sabdar@Sun.COM params->mp_file_history_path_func = 0; 2122*7917SReza.Sabdar@Sun.COM params->mp_file_history_dir_func = 0; 2123*7917SReza.Sabdar@Sun.COM params->mp_file_history_node_func = 0; 2124*7917SReza.Sabdar@Sun.COM params->mp_read_func = ndmpd_api_read_v2; 2125*7917SReza.Sabdar@Sun.COM params->mp_seek_func = ndmpd_api_seek_v2; 2126*7917SReza.Sabdar@Sun.COM params->mp_file_recovered_func = ndmpd_api_file_recovered_v2; 2127*7917SReza.Sabdar@Sun.COM params->mp_stats = &session->ns_data.dd_module.dm_stats; 2128*7917SReza.Sabdar@Sun.COM 2129*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_module_cookie = 0; 2130*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_start_func = ndmpd_tar_restore_starter; 2131*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_abort_func = ndmpd_tar_restore_abort; 2132*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_bytes_remaining = 0; 2133*7917SReza.Sabdar@Sun.COM session->ns_data.dd_module.dm_stats.ms_est_time_remaining = 0; 2134*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_offset = 0; 2135*7917SReza.Sabdar@Sun.COM session->ns_data.dd_read_length = 0; 2136*7917SReza.Sabdar@Sun.COM 2137*7917SReza.Sabdar@Sun.COM if ((err = ndmp_restore_extract_params(session, 2138*7917SReza.Sabdar@Sun.COM params)) != NDMP_NO_ERR) { 2139*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2140*7917SReza.Sabdar@Sun.COM return (err); 2141*7917SReza.Sabdar@Sun.COM } 2142*7917SReza.Sabdar@Sun.COM 2143*7917SReza.Sabdar@Sun.COM err = ndmpd_mover_connect(session, NDMP_MOVER_MODE_WRITE); 2144*7917SReza.Sabdar@Sun.COM if (err != NDMP_NO_ERR) { 2145*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2146*7917SReza.Sabdar@Sun.COM return (err); 2147*7917SReza.Sabdar@Sun.COM } 2148*7917SReza.Sabdar@Sun.COM 2149*7917SReza.Sabdar@Sun.COM session->ns_data.dd_state = NDMP_DATA_STATE_ACTIVE; 2150*7917SReza.Sabdar@Sun.COM session->ns_data.dd_operation = NDMP_DATA_OP_RECOVER; 2151*7917SReza.Sabdar@Sun.COM session->ns_data.dd_abort = FALSE; 2152*7917SReza.Sabdar@Sun.COM 2153*7917SReza.Sabdar@Sun.COM reply.error = NDMP_NO_ERR; 2154*7917SReza.Sabdar@Sun.COM if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 2155*7917SReza.Sabdar@Sun.COM &reply) < 0) { 2156*7917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Sending data_start_recover reply"); 2157*7917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 2158*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) { 2159*7917SReza.Sabdar@Sun.COM /* 2160*7917SReza.Sabdar@Sun.COM * ndmpcopy: we use the same socket for the mover, 2161*7917SReza.Sabdar@Sun.COM * so expect to close when mover is done! 2162*7917SReza.Sabdar@Sun.COM */ 2163*7917SReza.Sabdar@Sun.COM if (session->ns_data.dd_sock != 2164*7917SReza.Sabdar@Sun.COM session->ns_mover.md_sock) 2165*7917SReza.Sabdar@Sun.COM (void) close(session->ns_data.dd_sock); 2166*7917SReza.Sabdar@Sun.COM 2167*7917SReza.Sabdar@Sun.COM session->ns_data.dd_sock = -1; 2168*7917SReza.Sabdar@Sun.COM } else { 2169*7917SReza.Sabdar@Sun.COM ndmpd_mover_error(session, 2170*7917SReza.Sabdar@Sun.COM NDMP_MOVER_HALT_CONNECT_CLOSED); 2171*7917SReza.Sabdar@Sun.COM } 2172*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 2173*7917SReza.Sabdar@Sun.COM } 2174*7917SReza.Sabdar@Sun.COM 2175*7917SReza.Sabdar@Sun.COM 2176*7917SReza.Sabdar@Sun.COM /* 2177*7917SReza.Sabdar@Sun.COM * perform the restore 2178*7917SReza.Sabdar@Sun.COM * 2179*7917SReza.Sabdar@Sun.COM * Cannot wait for the thread to exit as we are replying the 2180*7917SReza.Sabdar@Sun.COM * client request here. 2181*7917SReza.Sabdar@Sun.COM */ 2182*7917SReza.Sabdar@Sun.COM (void) pthread_create(NULL, NULL, 2183*7917SReza.Sabdar@Sun.COM (funct_t)session->ns_data.dd_module.dm_start_func, 2184*7917SReza.Sabdar@Sun.COM params); 2185*7917SReza.Sabdar@Sun.COM 2186*7917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 2187*7917SReza.Sabdar@Sun.COM } 2188*7917SReza.Sabdar@Sun.COM 2189*7917SReza.Sabdar@Sun.COM 2190*7917SReza.Sabdar@Sun.COM /* 2191*7917SReza.Sabdar@Sun.COM * ndmpd_data_get_info 2192*7917SReza.Sabdar@Sun.COM * 2193*7917SReza.Sabdar@Sun.COM * Return the total number of bytes processed 2194*7917SReza.Sabdar@Sun.COM * 2195*7917SReza.Sabdar@Sun.COM * Parameters: 2196*7917SReza.Sabdar@Sun.COM * session (input) - session pointer. 2197*7917SReza.Sabdar@Sun.COM * 2198*7917SReza.Sabdar@Sun.COM * Returns: 2199*7917SReza.Sabdar@Sun.COM * the number of bytes processed 2200*7917SReza.Sabdar@Sun.COM */ 2201*7917SReza.Sabdar@Sun.COM static u_longlong_t 2202*7917SReza.Sabdar@Sun.COM ndmpd_data_get_info(ndmpd_session_t *session) 2203*7917SReza.Sabdar@Sun.COM { 2204*7917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 2205*7917SReza.Sabdar@Sun.COM 2206*7917SReza.Sabdar@Sun.COM nlp = ndmp_get_nlp(session); 2207*7917SReza.Sabdar@Sun.COM if (nlp == NULL) 2208*7917SReza.Sabdar@Sun.COM return ((u_longlong_t)0); 2209*7917SReza.Sabdar@Sun.COM 2210*7917SReza.Sabdar@Sun.COM if (nlp->nlp_jstat == NULL) 2211*7917SReza.Sabdar@Sun.COM return (nlp->nlp_bytes_total); 2212*7917SReza.Sabdar@Sun.COM 2213*7917SReza.Sabdar@Sun.COM return ((u_longlong_t)nlp->nlp_jstat->js_bytes_total); 2214*7917SReza.Sabdar@Sun.COM } 2215