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