ndmpd_comm.c revision 97f7c4750238e3c507904468e4e9f17b15a08e2d
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
97f7c4750238e3c507904468e4e9f17b15a08e2dJan Kryl * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 2007, The Storage Networking Industry Association. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The ndmp connection version can be set through command line. If command line
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is not specified it will be set from the ndmp SMF version property.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The NDMP listening port number
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Restore path mechanism definition
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 means partial path restore and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 1 means full path restore.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Refer to NDMP_FULL_RESTORE_PATH for partial path and full path definition.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Do we support Direct Access Restore?
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_connection_t handler function
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic ndmpd_file_handler_func_t connection_file_handler;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int ndmp_recv_msg(ndmp_connection_t *connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int ndmp_process_messages(ndmp_connection_t *connection,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic ndmp_msg_handler_t *ndmp_get_handler(ndmp_connection_t *connection,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t ndmp_check_auth_required(ndmp_message message);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic ndmp_handler_t *ndmp_get_interface(ndmp_message message);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#endif /* lint */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_create_connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate and initialize a connection structure.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * handler_tbl (input) - message handlers.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NULL - error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection pointer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The returned connection should be destroyed using
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_destroy_connection().
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar connection = ndmp_malloc(sizeof (ndmp_connection_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_init(&connection->conn_lock, 0, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xdrrec_create(&connection->conn_xdrs, 0, 0, (caddr_t)connection,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_destroy_connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Shutdown a connection and release allocated resources.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (Input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_destroy_connection(ndmp_connection_t *connection_handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_close
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Close a connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (Input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * We should close all the tapes that are used by this connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In some cases the ndmp client opens a tape, but does not close the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tape and closes the connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_start_worker
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Initializes and starts a ndmp_worker thread
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rc = pthread_create(NULL, &tattr, ndmpd_worker, (void *)argp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Creates a socket for listening and accepting connections
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * from NDMP clients.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Accepts connections and passes each connection to the connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * port (input) - NDMP server port.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If 0, the port number will be retrieved from
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the network service database. If not found there,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the default NDMP port number (from ndmp.x)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will be used.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * handler (input) - connection handler function.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function normally never returns unless there's error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 : error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function does not return unless encountering an error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * related to the listen socket.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_run(ulong_t port, ndmp_con_handler_func_t con_handler_func)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar unsigned int ipaddr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bind(server_socket, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (; ; ) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((ns = tcp_accept(server_socket, &ipaddr)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((argp = ndmp_malloc(sizeof (ndmpd_worker_arg_t))) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_worker thread
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * argp (input) - structure containing socket and handler function
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - successful connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_worker_arg_t *argp = (ndmpd_worker_arg_t *)ptarg;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ((void *)-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((connection = ndmp_create_connection()) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* initialize auditing session */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_start_session(&connection->conn_ah, NULL, 0) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ((void *)-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((ndmp_connection_t *)connection)->conn_sock = sock;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_process_requests
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Reads the next request message into the stream buffer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Processes messages until the stream buffer is empty.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - 1 or more messages successfully processed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error; connection no longer established.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_process_requests(ndmp_connection_t *connection_handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_process_messages(connection, FALSE) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_send_request
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Send an NDMP request message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * message (input) - message number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * err (input) - error code to place in header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * request_data (input) - message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply (output) - reply message. If 0, reply will be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * discarded.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - successful send.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * otherwise - error from reply header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The reply body is only returned if the error code is NDMP_NO_ERR.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_send_request(ndmp_connection_t *connection_handle, ndmp_message message,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_error err, void *request_data, void **reply)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Lookup info necessary for processing this request. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!(handler = ndmp_get_handler(connection, message))) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: not supported",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar header.sequence = ++(connection->conn_my_sequence);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Sending message 0x%x: encoding request header", message);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err == NDMP_NO_ERR && handler->mh_xdr_request && request_data) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!(*handler->mh_xdr_request)(&connection->conn_xdrs,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Sending message 0x%x: encoding request body",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "handler->mh_xdr_reply == 0");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Process messages until the reply to this request has been
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * processed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (; ; ) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* connection error? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* no reply received? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* reply received? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (r == 1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Received unexpected reply 0x%x",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* error handling reply */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_send_request_lock
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * A wrapper for ndmp_send_request with locks.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * message (input) - message number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * err (input) - error code to place in header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * request_data (input) - message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply (output) - reply message. If 0, reply will be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * discarded.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - successful send.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * otherwise - error from reply header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The reply body is only returned if the error code is NDMP_NO_ERR.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_send_request_lock(ndmp_connection_t *connection_handle,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_message message, ndmp_error err, void *request_data, void **reply)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = ndmp_send_request(connection_handle, message, err, request_data,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_send_response
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Send an NDMP reply message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * err (input) - error code to place in header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply (input) - reply message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - successful send.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The body is only sent if the error code is NDMP_NO_ERR.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_send_response(ndmp_connection_t *connection_handle, ndmp_error err,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar header.sequence = ++(connection->conn_my_sequence);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar header.message = connection->conn_msginfo.mi_hdr.message;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar header.reply_sequence = connection->conn_msginfo.mi_hdr.sequence;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "encoding reply header",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar connection->conn_msginfo.mi_handler->mh_xdr_reply &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!(*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Sending message 0x%x: encoding reply body",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_free_message
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free the memory of NDMP message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_free_message(ndmp_connection_t *connection_handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_handler == NULL ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_hdr.message_type ==
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_handler->mh_xdr_request)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (*connection->conn_msginfo.mi_handler->mh_xdr_request)(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_handler->mh_xdr_reply)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_get_fd
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the connection file descriptor.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * >=0 - file descriptor.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - connection not open.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_get_fd(ndmp_connection_t *connection_handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (((ndmp_connection_t *)connection_handle)->conn_sock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_set_client_data
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function provides a means for the library client to provide
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a pointer to some user data structure that is retrievable by
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * each message handler via ndmp_get_client_data.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * client_data (input) - user data pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_set_client_data(ndmp_connection_t *connection_handle, void *client_data)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((ndmp_connection_t *)connection_handle)->conn_client_data =
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_get_client_data
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function provides a means for the library client to provide
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a pointer to some user data structure that is retrievable by
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * each message handler via ndmp_get_client_data.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * client data pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_get_client_data(ndmp_connection_t *connection_handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (((ndmp_connection_t *)connection_handle)->conn_client_data);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_set_version
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Sets the NDMP protocol version to be used on the connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * version (input) - protocol version.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_set_version(ndmp_connection_t *connection_handle, ushort_t version)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((ndmp_connection_t *)connection_handle)->conn_version = version;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_get_version
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Gets the NDMP protocol version in use on the connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * version (input) - protocol version.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_get_version(ndmp_connection_t *connection_handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (((ndmp_connection_t *)connection_handle)->conn_version);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_set_authorized
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Mark the connection as either having been authorized or not.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handle (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * authorized (input) - TRUE or FALSE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_set_authorized(ndmp_connection_t *connection_handle, boolean_t authorized)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((ndmp_connection_t *)connection_handle)->conn_authorized = authorized;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_main
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP main function called from main().
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar "Could not open log file properly.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Find ndmp port number to be used. If ndmpd is run as command line
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and port number is supplied, use that port number. If port number is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is not supplied, find out if ndmp port property is set. If ndmp
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * port property is set, use that port number otherwise use the defaule
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * port number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((propval = ndmpd_get_prop(NDMP_TCP_PORT)) == NULL ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_run(ndmp_port, connection_handler) == -1)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_handler
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP connection handler.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Waits for, reads, and processes NDMP requests on a connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarconnection_handler(ndmp_connection_t *connection)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The 'protocol_version' must be 1 at first, since the client talks
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to the server in version 1 then they can move to a higher
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * protocol version.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(session.ns_scsi.sd_adapter_name, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(session.ns_tape.td_adapter_name, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Setup defaults here. The init functions can not set defaults
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * since the init functions are called by the stop request handlers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and client set variables need to persist across data operations.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session.ns_mover.md_record_size = MAX_RECORD_SIZE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_set_client_data(connection, (void *)&session);
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar if (ndmp_send_request_lock(connection, NDMP_NOTIFY_CONNECTION_STATUS,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "connection_fd: %d", connection_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Add the handler function for the connection to the DMA.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmpd_add_file_handler(&session, (void *)&session, connection_fd,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMPD_SELECT_MODE_READ, HC_CLIENT, connection_file_handler) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Could not register session handler.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Register the connection in the list of active connections.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_connect_list_add(connection, &conn_id) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not register the session to the server.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmpd_remove_file_handler(&session, connection_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmpd_remove_file_handler(&session, connection_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_open_list_del(session.ns_scsi.sd_adapter_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session.ns_scsi.sd_sid, session.ns_scsi.sd_lun);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "tape.fd: %d", session.ns_tape.td_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_open_list_del(session.ns_tape.td_adapter_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session.ns_tape.td_sid, session.ns_tape.td_lun);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection_file_handler
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_connection_t file handler function.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Called by ndmpd_select when data is available to be read on the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP connection.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * cookie (input) - session pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * fd (input) - connection file descriptor.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * mode (input) - select mode.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarconnection_file_handler(void *cookie, int fd, ulong_t mode)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_process_requests(session->ns_connection) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* ************* private functions *************************************** */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_readit
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Low level read routine called by the xdrrec library.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * buf (input) - location to store received data.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * len (input) - max number of bytes to read.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * >0 - number of bytes received.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_readit(void *connection_handle, caddr_t buf, int len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* ndmp_connection_t has been closed. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_writeit
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Low level write routine called by the xdrrec library.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * buf (input) - location to store received data.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * len (input) - max number of bytes to read.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * >0 - number of bytes sent.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_writeit(void *connection_handle, caddr_t buf, int len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar register int n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar register int cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((n = write(connection->conn_sock, buf, cnt)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_recv_msg
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read the next message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * msg (output) - received message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - Message successfully received.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * error number - Message related error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -1 - Error decoding the message header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Decode the header. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) xdrrec_skiprecord(&connection->conn_xdrs);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Lookup info necessary for processing this message. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((connection->conn_msginfo.mi_handler = ndmp_get_handler(connection,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar connection->conn_msginfo.mi_hdr.message)) == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Message 0x%x not supported",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_hdr.error != NDMP_NO_ERR)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Determine body type */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_hdr.message_type ==
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Processing request 0x%x:connection not authorized",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_handler->mh_sizeof_request >
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar connection->conn_msginfo.mi_handler->mh_xdr_request;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Processing request 0x%x: no xdr function "
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "in handler table",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(connection->conn_msginfo.mi_body, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_handler->mh_sizeof_reply > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar connection->conn_msginfo.mi_handler->mh_xdr_reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Processing reply 0x%x: no xdr function "
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "in handler table",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(connection->conn_msginfo.mi_body, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Decode message arguments if needed */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Processing message 0x%x: error decoding arguments",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_process_messages
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Reads the next message into the stream buffer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Processes messages until the stream buffer is empty.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function processes all data in the stream buffer before returning.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This allows functions like poll() to be used to determine when new
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * messages have arrived. If only some of the messages in the stream buffer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * were processed and then poll was called, poll() could block waiting for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a message that had already been received and read into the stream buffer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function processes both request and reply messages.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Request messages are dispatched using the appropriate function from the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * message handling table.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Only one reply messages may be pending receipt at a time.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * A reply message, if received, is placed in connection->conn_msginfo
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * before returning to the caller.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Errors are reported if a reply is received but not expected or if
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * more than one reply message is received
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply_expected (output) - TRUE - a reply message is expected.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * FALSE - no reply message is expected and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * an error will be reported if a reply
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is received.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * error processing reply message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply seen.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * no reply seen.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP_PROC_REP_ERR - error; connection no longer established.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the peer is generating a large number of requests, a caller
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * looking for a reply will be blocked while the requests are handled.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This is because this function does not return until the stream
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * buffer is empty.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Code needs to be added to allow a return if the stream buffer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is not empty but there is data available on the socket. This will
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * prevent poll() from blocking and prevent a caller looking for a reply
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * from getting blocked by a bunch of requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_process_messages(ndmp_connection_t *connection, boolean_t reply_expected)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *)&reply_msginfo, 0, sizeof (msg_info_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *)&connection->conn_msginfo, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((err = ndmp_recv_msg(connection)) != NDMP_NO_ERR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Error occurred decoding the header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Don't send a reply since we don't know
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the message or if the message was even
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a request message. To be safe, assume
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * that the message was a reply if a reply
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * was expected. Need to do this to prevent
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * hanging ndmp_send_request() waiting for a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply. Don't set reply_read so that the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply will be processed if it is received
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_hdr.message_type
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Unexpected reply message: 0x%x",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_free_message((ndmp_connection_t *)connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_hdr.message_type
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (reply_expected == FALSE || reply_read == TRUE) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Unexpected reply message: 0x%x",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The following is needed to catch an improperly constructed
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * handler table or to deal with an NDMP client that is not
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * conforming to the negotiated protocol version.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (connection->conn_msginfo.mi_handler->mh_func == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "No handler for message 0x%x",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_free_message((ndmp_connection_t *)connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Call the handler function.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The handler will send any necessary reply.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (*connection->conn_msginfo.mi_handler->mh_func) (connection,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_free_message((ndmp_connection_t *)connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (xdrrec_eof(&connection->conn_xdrs) == FALSE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "no more messages in stream buffer");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_get_interface
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return the NDMP interface (e.g. config, scsi, tape) for the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * specific message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * message (input) - message number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NULL - message not found.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pointer to handler info.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_handler_t *ni = &ndmp_msghdl_tab[(message >> 8) % INT_MAXCMD];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Sanity check */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ni->hd_msgs[message & 0xff].hm_message != message)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_get_handler
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return the handler info for the specified NDMP message.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * message (input) - message number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NULL - message not found.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pointer to handler info.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_get_handler(ndmp_connection_t *connection, ndmp_message message)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_handler_t *ni = ndmp_get_interface(message);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar handler = &ni->hd_msgs[message & 0xff].hm_msg_v[ver - 2];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_check_auth_required
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if the connection needs to be authenticated before
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this message is being processed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * message (input) - message number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TRUE - required
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * FALSE - not required
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_handler_t *ni = ndmp_get_interface(message);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar auth_req = ni->hd_msgs[message & 0xff].hm_auth_required;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tcp_accept
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * A wrapper around accept for retrying and getting the IP address
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * listen_sock (input) - the socket for listening
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * inaddr_p (output) - the IP address of peer connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * socket for the accepted connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartcp_accept(int listen_sock, unsigned int *inaddr_p)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i = sizeof (sin);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sock = accept(listen_sock, (struct sockaddr *)&sin, &i);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tcp_get_peer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the peer IP address for a connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * sock (input) - the active socket
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * inaddr_p (output) - the IP address of peer connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * port_p (output) - the port number of peer connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * socket for the accepted connection
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartcp_get_peer(int sock, unsigned int *inaddr_p, int *port_p)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i = sizeof (sin);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rc = getpeername(sock, (struct sockaddr *)&sin, &i);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * gethostaddr
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the IP address string of the current host
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IP address
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NULL: error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar static char s[MAXHOSTNAMELEN];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(&in.s_addr, p, sizeof (in.s_addr));
588541fbf64fffe619698198cef04af1900f1f86Reza Sabdar * get_default_nic_addr
588541fbf64fffe619698198cef04af1900f1f86Reza Sabdar * Get the IP address of the default NIC
588541fbf64fffe619698198cef04af1900f1f86Reza Sabdar nifs = ifaddrlist(&al, AF_INET, LIFC_EXTERNAL_SOURCE, errmsg);
588541fbf64fffe619698198cef04af1900f1f86Reza Sabdar /* pick the first interface's address */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_audit_backup
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generate AUE_ndmp_backup audit record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *path, int dest, char *local_path, int result)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((event = adt_alloc_event(conn->conn_ah, ADT_ndmp_backup)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar event->adt_ndmp_backup.remote_dest = conn->conn_sock;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_FAILURE, result) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_audit_restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generate AUE_ndmp_restore audit record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *path, int dest, char *local_path, int result)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar event->adt_ndmp_restore.local_source = local_path;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar event->adt_ndmp_restore.remote_source = conn->conn_sock;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_FAILURE, result) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_audit_connect
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generate AUE_ndmp_connect audit record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_audit_connect(ndmp_connection_t *conn, int result)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_load_termid(conn->conn_sock, &termid) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_set_user(conn->conn_ah, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ADT_NO_ATTRIB, ADT_NO_ATTRIB, termid, ADT_NEW) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_FAILURE, result) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_audit_disconnect
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generate AUE_ndmp_disconnect audit record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * get_backup_path_v3
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * Get the backup path from the NDMP environment variables.
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * Parameters:
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * params (input) - pointer to the parameters structure.
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * The backup path: if anything is specified
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * NULL: Otherwise
8c4f9701439555b41fbfe7848508f53b52166007Janice Changget_backup_path_v3(ndmpd_module_params_t *params)
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang "Backup path not defined.\n");
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * get_backup_path
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * Find the backup path from the environment variables (v2)
8c4f9701439555b41fbfe7848508f53b52166007Janice Changget_backup_path_v2(ndmpd_module_params_t *params)
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang MOD_LOG(params, "Error: restore path not specified.\n");
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang MOD_LOG(params, "Error: relative backup path not allowed.\n");