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