17917SReza.Sabdar@Sun.COM /*
212186SJanice.Chang@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
37917SReza.Sabdar@Sun.COM */
47917SReza.Sabdar@Sun.COM
57917SReza.Sabdar@Sun.COM /*
67917SReza.Sabdar@Sun.COM * BSD 3 Clause License
77917SReza.Sabdar@Sun.COM *
87917SReza.Sabdar@Sun.COM * Copyright (c) 2007, The Storage Networking Industry Association.
97917SReza.Sabdar@Sun.COM *
107917SReza.Sabdar@Sun.COM * Redistribution and use in source and binary forms, with or without
117917SReza.Sabdar@Sun.COM * modification, are permitted provided that the following conditions
127917SReza.Sabdar@Sun.COM * are met:
137917SReza.Sabdar@Sun.COM * - Redistributions of source code must retain the above copyright
147917SReza.Sabdar@Sun.COM * notice, this list of conditions and the following disclaimer.
157917SReza.Sabdar@Sun.COM *
167917SReza.Sabdar@Sun.COM * - Redistributions in binary form must reproduce the above copyright
177917SReza.Sabdar@Sun.COM * notice, this list of conditions and the following disclaimer in
187917SReza.Sabdar@Sun.COM * the documentation and/or other materials provided with the
197917SReza.Sabdar@Sun.COM * distribution.
207917SReza.Sabdar@Sun.COM *
217917SReza.Sabdar@Sun.COM * - Neither the name of The Storage Networking Industry Association (SNIA)
227917SReza.Sabdar@Sun.COM * nor the names of its contributors may be used to endorse or promote
237917SReza.Sabdar@Sun.COM * products derived from this software without specific prior written
247917SReza.Sabdar@Sun.COM * permission.
257917SReza.Sabdar@Sun.COM *
267917SReza.Sabdar@Sun.COM * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
277917SReza.Sabdar@Sun.COM * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287917SReza.Sabdar@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297917SReza.Sabdar@Sun.COM * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
307917SReza.Sabdar@Sun.COM * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
317917SReza.Sabdar@Sun.COM * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
327917SReza.Sabdar@Sun.COM * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
337917SReza.Sabdar@Sun.COM * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
347917SReza.Sabdar@Sun.COM * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
357917SReza.Sabdar@Sun.COM * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
367917SReza.Sabdar@Sun.COM * POSSIBILITY OF SUCH DAMAGE.
377917SReza.Sabdar@Sun.COM */
387917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
397917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
407917SReza.Sabdar@Sun.COM
417917SReza.Sabdar@Sun.COM #include <sys/types.h>
427917SReza.Sabdar@Sun.COM #include <sys/socket.h>
437917SReza.Sabdar@Sun.COM #include <sys/time.h>
447917SReza.Sabdar@Sun.COM #include <sys/uio.h>
457917SReza.Sabdar@Sun.COM #include <unistd.h>
467917SReza.Sabdar@Sun.COM #include <string.h>
477917SReza.Sabdar@Sun.COM #include <stdlib.h>
487917SReza.Sabdar@Sun.COM #include <errno.h>
497917SReza.Sabdar@Sun.COM #include <netdb.h>
507917SReza.Sabdar@Sun.COM #include <netinet/in.h>
517917SReza.Sabdar@Sun.COM #include <arpa/inet.h>
52*13023SReza.Sabdar@Sun.COM #include <libinetutil.h>
537917SReza.Sabdar@Sun.COM #include "ndmpd.h"
547917SReza.Sabdar@Sun.COM #include "ndmpd_common.h"
557917SReza.Sabdar@Sun.COM
567917SReza.Sabdar@Sun.COM #define NDMP_PROC_ERR -1
577917SReza.Sabdar@Sun.COM #define NDMP_PROC_MSG 1
587917SReza.Sabdar@Sun.COM #define NDMP_PROC_REP 0
597917SReza.Sabdar@Sun.COM #define NDMP_PROC_REP_ERR 2
607917SReza.Sabdar@Sun.COM
617917SReza.Sabdar@Sun.COM /*
627917SReza.Sabdar@Sun.COM * The ndmp connection version can be set through command line. If command line
637917SReza.Sabdar@Sun.COM * is not specified it will be set from the ndmp SMF version property.
647917SReza.Sabdar@Sun.COM */
657917SReza.Sabdar@Sun.COM int ndmp_ver = 0;
667917SReza.Sabdar@Sun.COM
677917SReza.Sabdar@Sun.COM /*
687917SReza.Sabdar@Sun.COM * The NDMP listening port number
697917SReza.Sabdar@Sun.COM */
707917SReza.Sabdar@Sun.COM int ndmp_port = 0;
717917SReza.Sabdar@Sun.COM
727917SReza.Sabdar@Sun.COM /*
737917SReza.Sabdar@Sun.COM * Restore path mechanism definition
747917SReza.Sabdar@Sun.COM * 0 means partial path restore and
757917SReza.Sabdar@Sun.COM * 1 means full path restore.
767917SReza.Sabdar@Sun.COM * Refer to NDMP_FULL_RESTORE_PATH for partial path and full path definition.
777917SReza.Sabdar@Sun.COM */
787917SReza.Sabdar@Sun.COM int ndmp_full_restore_path = 1;
797917SReza.Sabdar@Sun.COM
807917SReza.Sabdar@Sun.COM /*
817917SReza.Sabdar@Sun.COM * Do we support Direct Access Restore?
827917SReza.Sabdar@Sun.COM */
837917SReza.Sabdar@Sun.COM int ndmp_dar_support = 0;
847917SReza.Sabdar@Sun.COM
857917SReza.Sabdar@Sun.COM /*
867917SReza.Sabdar@Sun.COM * ndmp_connection_t handler function
877917SReza.Sabdar@Sun.COM */
887917SReza.Sabdar@Sun.COM static ndmpd_file_handler_func_t connection_file_handler;
897917SReza.Sabdar@Sun.COM
907917SReza.Sabdar@Sun.COM extern ndmp_handler_t ndmp_msghdl_tab[];
917917SReza.Sabdar@Sun.COM
927917SReza.Sabdar@Sun.COM static int ndmp_readit(void *connection_handle,
937917SReza.Sabdar@Sun.COM caddr_t buf,
947917SReza.Sabdar@Sun.COM int len);
957917SReza.Sabdar@Sun.COM static int ndmp_writeit(void *connection_handle,
967917SReza.Sabdar@Sun.COM caddr_t buf,
977917SReza.Sabdar@Sun.COM int len);
987917SReza.Sabdar@Sun.COM static int ndmp_recv_msg(ndmp_connection_t *connection);
997917SReza.Sabdar@Sun.COM static int ndmp_process_messages(ndmp_connection_t *connection,
1007917SReza.Sabdar@Sun.COM boolean_t reply_expected);
1017917SReza.Sabdar@Sun.COM static ndmp_msg_handler_t *ndmp_get_handler(ndmp_connection_t *connection,
1027917SReza.Sabdar@Sun.COM ndmp_message message);
1037917SReza.Sabdar@Sun.COM static boolean_t ndmp_check_auth_required(ndmp_message message);
1047917SReza.Sabdar@Sun.COM static ndmp_handler_t *ndmp_get_interface(ndmp_message message);
1057917SReza.Sabdar@Sun.COM void *ndmpd_worker(void *ptarg);
1067917SReza.Sabdar@Sun.COM
1077917SReza.Sabdar@Sun.COM #ifdef lint
1087917SReza.Sabdar@Sun.COM bool_t
xdr_ndmp_header(XDR * xdrs,ndmp_header * objp)1097917SReza.Sabdar@Sun.COM xdr_ndmp_header(XDR *xdrs, ndmp_header *objp)
1107917SReza.Sabdar@Sun.COM {
1117917SReza.Sabdar@Sun.COM xdrs = xdrs;
1127917SReza.Sabdar@Sun.COM objp = objp;
1137917SReza.Sabdar@Sun.COM return (0);
1147917SReza.Sabdar@Sun.COM }
1157917SReza.Sabdar@Sun.COM #endif /* lint */
1167917SReza.Sabdar@Sun.COM
1177917SReza.Sabdar@Sun.COM /*
1187917SReza.Sabdar@Sun.COM * ndmp_create_connection
1197917SReza.Sabdar@Sun.COM *
1207917SReza.Sabdar@Sun.COM * Allocate and initialize a connection structure.
1217917SReza.Sabdar@Sun.COM *
1227917SReza.Sabdar@Sun.COM * Parameters:
1237917SReza.Sabdar@Sun.COM * handler_tbl (input) - message handlers.
1247917SReza.Sabdar@Sun.COM *
1257917SReza.Sabdar@Sun.COM * Returns:
1267917SReza.Sabdar@Sun.COM * NULL - error
1277917SReza.Sabdar@Sun.COM * connection pointer
1287917SReza.Sabdar@Sun.COM *
1297917SReza.Sabdar@Sun.COM * Notes:
1307917SReza.Sabdar@Sun.COM * The returned connection should be destroyed using
1317917SReza.Sabdar@Sun.COM * ndmp_destroy_connection().
1327917SReza.Sabdar@Sun.COM */
1337917SReza.Sabdar@Sun.COM ndmp_connection_t *
ndmp_create_connection(void)1347917SReza.Sabdar@Sun.COM ndmp_create_connection(void)
1357917SReza.Sabdar@Sun.COM {
1367917SReza.Sabdar@Sun.COM ndmp_connection_t *connection;
1377917SReza.Sabdar@Sun.COM
1387917SReza.Sabdar@Sun.COM connection = ndmp_malloc(sizeof (ndmp_connection_t));
1397917SReza.Sabdar@Sun.COM if (connection == NULL)
1407917SReza.Sabdar@Sun.COM return (NULL);
1417917SReza.Sabdar@Sun.COM
1427917SReza.Sabdar@Sun.COM connection->conn_sock = -1;
1437917SReza.Sabdar@Sun.COM connection->conn_my_sequence = 0;
1447917SReza.Sabdar@Sun.COM connection->conn_authorized = FALSE;
1457917SReza.Sabdar@Sun.COM connection->conn_eof = FALSE;
1467917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body = 0;
1477917SReza.Sabdar@Sun.COM connection->conn_version = ndmp_ver;
1487917SReza.Sabdar@Sun.COM connection->conn_client_data = 0;
1497917SReza.Sabdar@Sun.COM (void) mutex_init(&connection->conn_lock, 0, NULL);
1507917SReza.Sabdar@Sun.COM connection->conn_xdrs.x_ops = 0;
1517917SReza.Sabdar@Sun.COM
1527917SReza.Sabdar@Sun.COM xdrrec_create(&connection->conn_xdrs, 0, 0, (caddr_t)connection,
1537917SReza.Sabdar@Sun.COM ndmp_readit, ndmp_writeit);
1547917SReza.Sabdar@Sun.COM
1557917SReza.Sabdar@Sun.COM if (connection->conn_xdrs.x_ops == 0) {
1567917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "xdrrec_create failed");
1577917SReza.Sabdar@Sun.COM (void) mutex_destroy(&connection->conn_lock);
1587917SReza.Sabdar@Sun.COM (void) close(connection->conn_sock);
1597917SReza.Sabdar@Sun.COM free(connection);
1607917SReza.Sabdar@Sun.COM return (0);
1617917SReza.Sabdar@Sun.COM }
1627917SReza.Sabdar@Sun.COM return ((ndmp_connection_t *)connection);
1637917SReza.Sabdar@Sun.COM }
1647917SReza.Sabdar@Sun.COM
1657917SReza.Sabdar@Sun.COM /*
1667917SReza.Sabdar@Sun.COM * ndmp_destroy_connection
1677917SReza.Sabdar@Sun.COM *
1687917SReza.Sabdar@Sun.COM * Shutdown a connection and release allocated resources.
1697917SReza.Sabdar@Sun.COM *
1707917SReza.Sabdar@Sun.COM * Parameters:
1717917SReza.Sabdar@Sun.COM * connection_handle (Input) - connection handle.
1727917SReza.Sabdar@Sun.COM *
1737917SReza.Sabdar@Sun.COM * Returns:
1747917SReza.Sabdar@Sun.COM * void
1757917SReza.Sabdar@Sun.COM */
1767917SReza.Sabdar@Sun.COM void
ndmp_destroy_connection(ndmp_connection_t * connection_handle)1777917SReza.Sabdar@Sun.COM ndmp_destroy_connection(ndmp_connection_t *connection_handle)
1787917SReza.Sabdar@Sun.COM {
1797917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
1807917SReza.Sabdar@Sun.COM
1817917SReza.Sabdar@Sun.COM if (connection->conn_sock >= 0) {
1827917SReza.Sabdar@Sun.COM (void) mutex_destroy(&connection->conn_lock);
1837917SReza.Sabdar@Sun.COM (void) close(connection->conn_sock);
1847917SReza.Sabdar@Sun.COM connection->conn_sock = -1;
1857917SReza.Sabdar@Sun.COM }
1867917SReza.Sabdar@Sun.COM xdr_destroy(&connection->conn_xdrs);
1877917SReza.Sabdar@Sun.COM free(connection);
1887917SReza.Sabdar@Sun.COM }
1897917SReza.Sabdar@Sun.COM
1907917SReza.Sabdar@Sun.COM
1917917SReza.Sabdar@Sun.COM /*
1927917SReza.Sabdar@Sun.COM * ndmp_close
1937917SReza.Sabdar@Sun.COM *
1947917SReza.Sabdar@Sun.COM * Close a connection.
1957917SReza.Sabdar@Sun.COM *
1967917SReza.Sabdar@Sun.COM * Parameters:
1977917SReza.Sabdar@Sun.COM * connection_handle (Input) - connection handle.
1987917SReza.Sabdar@Sun.COM *
1997917SReza.Sabdar@Sun.COM * Returns:
2007917SReza.Sabdar@Sun.COM * void
2017917SReza.Sabdar@Sun.COM */
2027917SReza.Sabdar@Sun.COM void
ndmp_close(ndmp_connection_t * connection_handle)2037917SReza.Sabdar@Sun.COM ndmp_close(ndmp_connection_t *connection_handle)
2047917SReza.Sabdar@Sun.COM {
2057917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
2067917SReza.Sabdar@Sun.COM
2077917SReza.Sabdar@Sun.COM ndmpd_audit_disconnect(connection);
2087917SReza.Sabdar@Sun.COM if (connection->conn_sock >= 0) {
2097917SReza.Sabdar@Sun.COM (void) mutex_destroy(&connection->conn_lock);
2107917SReza.Sabdar@Sun.COM (void) close(connection->conn_sock);
2117917SReza.Sabdar@Sun.COM connection->conn_sock = -1;
2127917SReza.Sabdar@Sun.COM }
2137917SReza.Sabdar@Sun.COM connection->conn_eof = TRUE;
2147917SReza.Sabdar@Sun.COM
2157917SReza.Sabdar@Sun.COM /*
2167917SReza.Sabdar@Sun.COM * We should close all the tapes that are used by this connection.
2177917SReza.Sabdar@Sun.COM * In some cases the ndmp client opens a tape, but does not close the
2187917SReza.Sabdar@Sun.COM * tape and closes the connection.
2197917SReza.Sabdar@Sun.COM */
2207917SReza.Sabdar@Sun.COM ndmp_open_list_release(connection_handle);
2217917SReza.Sabdar@Sun.COM }
2227917SReza.Sabdar@Sun.COM
2237917SReza.Sabdar@Sun.COM /*
2247917SReza.Sabdar@Sun.COM * ndmp_start_worker
2257917SReza.Sabdar@Sun.COM *
2267917SReza.Sabdar@Sun.COM * Initializes and starts a ndmp_worker thread
2277917SReza.Sabdar@Sun.COM */
2287917SReza.Sabdar@Sun.COM int
ndmp_start_worker(ndmpd_worker_arg_t * argp)2297917SReza.Sabdar@Sun.COM ndmp_start_worker(ndmpd_worker_arg_t *argp)
2307917SReza.Sabdar@Sun.COM {
2317917SReza.Sabdar@Sun.COM pthread_attr_t tattr;
2327917SReza.Sabdar@Sun.COM int rc;
2337917SReza.Sabdar@Sun.COM
2347917SReza.Sabdar@Sun.COM (void) pthread_attr_init(&tattr);
2357917SReza.Sabdar@Sun.COM (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
2367917SReza.Sabdar@Sun.COM rc = pthread_create(NULL, &tattr, ndmpd_worker, (void *)argp);
2377917SReza.Sabdar@Sun.COM (void) pthread_attr_destroy(&tattr);
2387917SReza.Sabdar@Sun.COM return (rc);
2397917SReza.Sabdar@Sun.COM }
2407917SReza.Sabdar@Sun.COM
2417917SReza.Sabdar@Sun.COM /*
2427917SReza.Sabdar@Sun.COM * ndmp_run
2437917SReza.Sabdar@Sun.COM *
2447917SReza.Sabdar@Sun.COM * Creates a socket for listening and accepting connections
2457917SReza.Sabdar@Sun.COM * from NDMP clients.
2467917SReza.Sabdar@Sun.COM * Accepts connections and passes each connection to the connection
2477917SReza.Sabdar@Sun.COM * handler.
2487917SReza.Sabdar@Sun.COM *
2497917SReza.Sabdar@Sun.COM * Parameters:
2507917SReza.Sabdar@Sun.COM * port (input) - NDMP server port.
2517917SReza.Sabdar@Sun.COM * If 0, the port number will be retrieved from
2527917SReza.Sabdar@Sun.COM * the network service database. If not found there,
2537917SReza.Sabdar@Sun.COM * the default NDMP port number (from ndmp.x)
2547917SReza.Sabdar@Sun.COM * will be used.
2557917SReza.Sabdar@Sun.COM * handler (input) - connection handler function.
2567917SReza.Sabdar@Sun.COM *
2577917SReza.Sabdar@Sun.COM * Returns:
2587917SReza.Sabdar@Sun.COM * This function normally never returns unless there's error.
2597917SReza.Sabdar@Sun.COM * -1 : error
2607917SReza.Sabdar@Sun.COM *
2617917SReza.Sabdar@Sun.COM * Notes:
2627917SReza.Sabdar@Sun.COM * This function does not return unless encountering an error
2637917SReza.Sabdar@Sun.COM * related to the listen socket.
2647917SReza.Sabdar@Sun.COM */
2657917SReza.Sabdar@Sun.COM int
ndmp_run(ulong_t port,ndmp_con_handler_func_t con_handler_func)2667917SReza.Sabdar@Sun.COM ndmp_run(ulong_t port, ndmp_con_handler_func_t con_handler_func)
2677917SReza.Sabdar@Sun.COM {
2687917SReza.Sabdar@Sun.COM int ns;
2697917SReza.Sabdar@Sun.COM int on, tmp;
2707917SReza.Sabdar@Sun.COM int server_socket;
2717917SReza.Sabdar@Sun.COM unsigned int ipaddr;
2727917SReza.Sabdar@Sun.COM struct sockaddr_in sin;
2737917SReza.Sabdar@Sun.COM int flag = 1;
2747917SReza.Sabdar@Sun.COM ndmpd_worker_arg_t *argp;
2757917SReza.Sabdar@Sun.COM
2767917SReza.Sabdar@Sun.COM sin.sin_family = AF_INET;
2777917SReza.Sabdar@Sun.COM sin.sin_addr.s_addr = INADDR_ANY;
2787917SReza.Sabdar@Sun.COM sin.sin_port = htons(port);
2797917SReza.Sabdar@Sun.COM
2807917SReza.Sabdar@Sun.COM if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2817917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Socket error: %m");
2827917SReza.Sabdar@Sun.COM return (-1);
2837917SReza.Sabdar@Sun.COM }
2847917SReza.Sabdar@Sun.COM
2857917SReza.Sabdar@Sun.COM on = 1;
2867917SReza.Sabdar@Sun.COM (void) setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,
2877917SReza.Sabdar@Sun.COM (char *)&on, sizeof (on));
2887917SReza.Sabdar@Sun.COM
2897917SReza.Sabdar@Sun.COM
2907917SReza.Sabdar@Sun.COM if (bind(server_socket, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
2917917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "bind error: %m");
2927917SReza.Sabdar@Sun.COM (void) close(server_socket);
2937917SReza.Sabdar@Sun.COM return (-1);
2947917SReza.Sabdar@Sun.COM }
2957917SReza.Sabdar@Sun.COM if (listen(server_socket, 5) < 0) {
2967917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "listen error: %m");
2977917SReza.Sabdar@Sun.COM (void) close(server_socket);
2987917SReza.Sabdar@Sun.COM return (-1);
2997917SReza.Sabdar@Sun.COM }
3007917SReza.Sabdar@Sun.COM
3017917SReza.Sabdar@Sun.COM for (; ; ) {
3027917SReza.Sabdar@Sun.COM if ((ns = tcp_accept(server_socket, &ipaddr)) < 0) {
3037917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "tcp_accept error: %m");
3047917SReza.Sabdar@Sun.COM continue;
3057917SReza.Sabdar@Sun.COM }
3067917SReza.Sabdar@Sun.COM
3077917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "connection fd: %d", ns);
3087917SReza.Sabdar@Sun.COM
3097917SReza.Sabdar@Sun.COM /*
3107917SReza.Sabdar@Sun.COM * 'css' and 'crs' in the following env variables stand for:
3117917SReza.Sabdar@Sun.COM * 'connection send size' and 'connection receive size'.
3127917SReza.Sabdar@Sun.COM */
3137917SReza.Sabdar@Sun.COM tmp = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CSS,
3147917SReza.Sabdar@Sun.COM "65"));
3157917SReza.Sabdar@Sun.COM if (tmp <= 0)
3167917SReza.Sabdar@Sun.COM tmp = 65;
3177917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "css: %d_KB", tmp);
3187917SReza.Sabdar@Sun.COM ndmp_set_socket_snd_buf(ns, tmp * KILOBYTE);
3197917SReza.Sabdar@Sun.COM
3207917SReza.Sabdar@Sun.COM tmp = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CRS,
3217917SReza.Sabdar@Sun.COM "80"));
3227917SReza.Sabdar@Sun.COM if (tmp <= 0)
3237917SReza.Sabdar@Sun.COM tmp = 80;
3247917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "crs: %d_KB", tmp);
3257917SReza.Sabdar@Sun.COM ndmp_set_socket_rcv_buf(ns, tmp * KILOBYTE);
3267917SReza.Sabdar@Sun.COM
3277917SReza.Sabdar@Sun.COM ndmp_set_socket_nodelay(ns);
3287917SReza.Sabdar@Sun.COM (void) setsockopt(ns, SOL_SOCKET, SO_KEEPALIVE, &flag,
3297917SReza.Sabdar@Sun.COM sizeof (flag));
3307917SReza.Sabdar@Sun.COM
3317917SReza.Sabdar@Sun.COM if ((argp = ndmp_malloc(sizeof (ndmpd_worker_arg_t))) != NULL) {
3327917SReza.Sabdar@Sun.COM argp->nw_sock = ns;
3337917SReza.Sabdar@Sun.COM argp->nw_ipaddr = ipaddr;
3347917SReza.Sabdar@Sun.COM argp->nw_con_handler_func = con_handler_func;
3357917SReza.Sabdar@Sun.COM (void) ndmp_start_worker(argp);
3367917SReza.Sabdar@Sun.COM }
3377917SReza.Sabdar@Sun.COM }
3387917SReza.Sabdar@Sun.COM }
3397917SReza.Sabdar@Sun.COM
3407917SReza.Sabdar@Sun.COM /*
3417917SReza.Sabdar@Sun.COM * ndmpd_worker thread
3427917SReza.Sabdar@Sun.COM *
3437917SReza.Sabdar@Sun.COM * Parameters:
3447917SReza.Sabdar@Sun.COM * argp (input) - structure containing socket and handler function
3457917SReza.Sabdar@Sun.COM *
3467917SReza.Sabdar@Sun.COM * Returns:
3477917SReza.Sabdar@Sun.COM * 0 - successful connection.
3487917SReza.Sabdar@Sun.COM * -1 - error.
3497917SReza.Sabdar@Sun.COM */
3507917SReza.Sabdar@Sun.COM void *
ndmpd_worker(void * ptarg)3517917SReza.Sabdar@Sun.COM ndmpd_worker(void *ptarg)
3527917SReza.Sabdar@Sun.COM {
3537917SReza.Sabdar@Sun.COM int sock;
3547917SReza.Sabdar@Sun.COM ndmp_connection_t *connection;
3557917SReza.Sabdar@Sun.COM ndmpd_worker_arg_t *argp = (ndmpd_worker_arg_t *)ptarg;
3567917SReza.Sabdar@Sun.COM
3577917SReza.Sabdar@Sun.COM if (!argp)
3587917SReza.Sabdar@Sun.COM return ((void *)-1);
3597917SReza.Sabdar@Sun.COM
3607917SReza.Sabdar@Sun.COM NS_INC(trun);
3617917SReza.Sabdar@Sun.COM sock = argp->nw_sock;
3627917SReza.Sabdar@Sun.COM
3637917SReza.Sabdar@Sun.COM if ((connection = ndmp_create_connection()) == NULL) {
3647917SReza.Sabdar@Sun.COM (void) close(sock);
3657917SReza.Sabdar@Sun.COM free(argp);
3667917SReza.Sabdar@Sun.COM exit(1);
3677917SReza.Sabdar@Sun.COM }
3687917SReza.Sabdar@Sun.COM
3697917SReza.Sabdar@Sun.COM /* initialize auditing session */
3707917SReza.Sabdar@Sun.COM if (adt_start_session(&connection->conn_ah, NULL, 0) != 0) {
3717917SReza.Sabdar@Sun.COM free(argp);
3727917SReza.Sabdar@Sun.COM return ((void *)-1);
3737917SReza.Sabdar@Sun.COM }
3747917SReza.Sabdar@Sun.COM
3757917SReza.Sabdar@Sun.COM ((ndmp_connection_t *)connection)->conn_sock = sock;
3767917SReza.Sabdar@Sun.COM (*argp->nw_con_handler_func)(connection);
3777917SReza.Sabdar@Sun.COM (void) adt_end_session(connection->conn_ah);
3787917SReza.Sabdar@Sun.COM ndmp_destroy_connection(connection);
3797917SReza.Sabdar@Sun.COM NS_DEC(trun);
3807917SReza.Sabdar@Sun.COM
3817917SReza.Sabdar@Sun.COM free(argp);
3827917SReza.Sabdar@Sun.COM return (NULL);
3837917SReza.Sabdar@Sun.COM }
3847917SReza.Sabdar@Sun.COM
3857917SReza.Sabdar@Sun.COM /*
3867917SReza.Sabdar@Sun.COM * ndmp_process_requests
3877917SReza.Sabdar@Sun.COM *
3887917SReza.Sabdar@Sun.COM * Reads the next request message into the stream buffer.
3897917SReza.Sabdar@Sun.COM * Processes messages until the stream buffer is empty.
3907917SReza.Sabdar@Sun.COM *
3917917SReza.Sabdar@Sun.COM * Parameters:
3927917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle.
3937917SReza.Sabdar@Sun.COM *
3947917SReza.Sabdar@Sun.COM * Returns:
3957917SReza.Sabdar@Sun.COM * 0 - 1 or more messages successfully processed.
3967917SReza.Sabdar@Sun.COM * -1 - error; connection no longer established.
3977917SReza.Sabdar@Sun.COM */
3987917SReza.Sabdar@Sun.COM int
ndmp_process_requests(ndmp_connection_t * connection_handle)3997917SReza.Sabdar@Sun.COM ndmp_process_requests(ndmp_connection_t *connection_handle)
4007917SReza.Sabdar@Sun.COM {
4017917SReza.Sabdar@Sun.COM int rv;
4027917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
4037917SReza.Sabdar@Sun.COM
4047917SReza.Sabdar@Sun.COM (void) mutex_lock(&connection->conn_lock);
4057917SReza.Sabdar@Sun.COM rv = 0;
4067917SReza.Sabdar@Sun.COM if (ndmp_process_messages(connection, FALSE) < 0)
4077917SReza.Sabdar@Sun.COM rv = -1;
4087917SReza.Sabdar@Sun.COM
4097917SReza.Sabdar@Sun.COM (void) mutex_unlock(&connection->conn_lock);
4107917SReza.Sabdar@Sun.COM return (rv);
4117917SReza.Sabdar@Sun.COM }
4127917SReza.Sabdar@Sun.COM
4137917SReza.Sabdar@Sun.COM
4147917SReza.Sabdar@Sun.COM /*
4157917SReza.Sabdar@Sun.COM * ndmp_send_request
4167917SReza.Sabdar@Sun.COM *
4177917SReza.Sabdar@Sun.COM * Send an NDMP request message.
4187917SReza.Sabdar@Sun.COM *
4197917SReza.Sabdar@Sun.COM * Parameters:
4207917SReza.Sabdar@Sun.COM * connection_handle (input) - connection pointer.
4217917SReza.Sabdar@Sun.COM * message (input) - message number.
4227917SReza.Sabdar@Sun.COM * err (input) - error code to place in header.
4237917SReza.Sabdar@Sun.COM * request_data (input) - message body.
4247917SReza.Sabdar@Sun.COM * reply (output) - reply message. If 0, reply will be
4257917SReza.Sabdar@Sun.COM * discarded.
4267917SReza.Sabdar@Sun.COM *
4277917SReza.Sabdar@Sun.COM * Returns:
4287917SReza.Sabdar@Sun.COM * 0 - successful send.
4297917SReza.Sabdar@Sun.COM * -1 - error.
4307917SReza.Sabdar@Sun.COM * otherwise - error from reply header.
4317917SReza.Sabdar@Sun.COM *
4327917SReza.Sabdar@Sun.COM * Notes:
4337917SReza.Sabdar@Sun.COM * - The reply body is only returned if the error code is NDMP_NO_ERR.
4347917SReza.Sabdar@Sun.COM */
4357917SReza.Sabdar@Sun.COM int
ndmp_send_request(ndmp_connection_t * connection_handle,ndmp_message message,ndmp_error err,void * request_data,void ** reply)4367917SReza.Sabdar@Sun.COM ndmp_send_request(ndmp_connection_t *connection_handle, ndmp_message message,
4377917SReza.Sabdar@Sun.COM ndmp_error err, void *request_data, void **reply)
4387917SReza.Sabdar@Sun.COM {
4397917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
4407917SReza.Sabdar@Sun.COM ndmp_header header;
4417917SReza.Sabdar@Sun.COM ndmp_msg_handler_t *handler;
4427917SReza.Sabdar@Sun.COM int r;
4437917SReza.Sabdar@Sun.COM struct timeval time;
4447917SReza.Sabdar@Sun.COM
4457917SReza.Sabdar@Sun.COM /* Lookup info necessary for processing this request. */
4467917SReza.Sabdar@Sun.COM if (!(handler = ndmp_get_handler(connection, message))) {
4477917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: not supported",
4487917SReza.Sabdar@Sun.COM message);
4497917SReza.Sabdar@Sun.COM return (-1);
4507917SReza.Sabdar@Sun.COM }
4517917SReza.Sabdar@Sun.COM (void) gettimeofday(&time, 0);
4527917SReza.Sabdar@Sun.COM
4537917SReza.Sabdar@Sun.COM header.sequence = ++(connection->conn_my_sequence);
4547917SReza.Sabdar@Sun.COM header.time_stamp = time.tv_sec;
4557917SReza.Sabdar@Sun.COM header.message_type = NDMP_MESSAGE_REQUEST;
4567917SReza.Sabdar@Sun.COM header.message = message;
4577917SReza.Sabdar@Sun.COM header.reply_sequence = 0;
4587917SReza.Sabdar@Sun.COM header.error = err;
4597917SReza.Sabdar@Sun.COM
4607917SReza.Sabdar@Sun.COM connection->conn_xdrs.x_op = XDR_ENCODE;
4617917SReza.Sabdar@Sun.COM if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
4627917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
4637917SReza.Sabdar@Sun.COM "Sending message 0x%x: encoding request header", message);
4647917SReza.Sabdar@Sun.COM (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
4657917SReza.Sabdar@Sun.COM return (-1);
4667917SReza.Sabdar@Sun.COM }
4677917SReza.Sabdar@Sun.COM if (err == NDMP_NO_ERR && handler->mh_xdr_request && request_data) {
4687917SReza.Sabdar@Sun.COM if (!(*handler->mh_xdr_request)(&connection->conn_xdrs,
4697917SReza.Sabdar@Sun.COM request_data)) {
4707917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
4717917SReza.Sabdar@Sun.COM "Sending message 0x%x: encoding request body",
4727917SReza.Sabdar@Sun.COM message);
4737917SReza.Sabdar@Sun.COM (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
4747917SReza.Sabdar@Sun.COM return (-1);
4757917SReza.Sabdar@Sun.COM }
4767917SReza.Sabdar@Sun.COM }
4777917SReza.Sabdar@Sun.COM (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
4787917SReza.Sabdar@Sun.COM
4797917SReza.Sabdar@Sun.COM if (handler->mh_xdr_reply == 0) {
4807917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "handler->mh_xdr_reply == 0");
4817917SReza.Sabdar@Sun.COM return (0);
4827917SReza.Sabdar@Sun.COM }
4837917SReza.Sabdar@Sun.COM
4847917SReza.Sabdar@Sun.COM /*
4857917SReza.Sabdar@Sun.COM * Process messages until the reply to this request has been
4867917SReza.Sabdar@Sun.COM * processed.
4877917SReza.Sabdar@Sun.COM */
4887917SReza.Sabdar@Sun.COM for (; ; ) {
4897917SReza.Sabdar@Sun.COM r = ndmp_process_messages(connection, TRUE);
4907917SReza.Sabdar@Sun.COM
4917917SReza.Sabdar@Sun.COM /* connection error? */
4927917SReza.Sabdar@Sun.COM if (r < 0)
4937917SReza.Sabdar@Sun.COM return (-1);
4947917SReza.Sabdar@Sun.COM
4957917SReza.Sabdar@Sun.COM /* no reply received? */
4967917SReza.Sabdar@Sun.COM if (r == 0)
4977917SReza.Sabdar@Sun.COM continue;
4987917SReza.Sabdar@Sun.COM
4997917SReza.Sabdar@Sun.COM /* reply received? */
5007917SReza.Sabdar@Sun.COM if (r == 1) {
5017917SReza.Sabdar@Sun.COM if (message !=
5027917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message) {
5037917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
5047917SReza.Sabdar@Sun.COM "Received unexpected reply 0x%x",
5057917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
5067917SReza.Sabdar@Sun.COM ndmp_free_message(connection_handle);
5077917SReza.Sabdar@Sun.COM return (-1);
5087917SReza.Sabdar@Sun.COM }
5097917SReza.Sabdar@Sun.COM if (reply != NULL)
5107917SReza.Sabdar@Sun.COM *reply = connection->conn_msginfo.mi_body;
5117917SReza.Sabdar@Sun.COM else
5127917SReza.Sabdar@Sun.COM ndmp_free_message(connection_handle);
5137917SReza.Sabdar@Sun.COM
5147917SReza.Sabdar@Sun.COM return (connection->conn_msginfo.mi_hdr.error);
5157917SReza.Sabdar@Sun.COM }
5167917SReza.Sabdar@Sun.COM /* error handling reply */
5177917SReza.Sabdar@Sun.COM
5187917SReza.Sabdar@Sun.COM return (-1);
5197917SReza.Sabdar@Sun.COM }
5207917SReza.Sabdar@Sun.COM }
5217917SReza.Sabdar@Sun.COM
5227917SReza.Sabdar@Sun.COM
5237917SReza.Sabdar@Sun.COM /*
5247917SReza.Sabdar@Sun.COM * ndmp_send_request_lock
5257917SReza.Sabdar@Sun.COM *
5267917SReza.Sabdar@Sun.COM * A wrapper for ndmp_send_request with locks.
5277917SReza.Sabdar@Sun.COM *
5287917SReza.Sabdar@Sun.COM * Parameters:
5297917SReza.Sabdar@Sun.COM * connection_handle (input) - connection pointer.
5307917SReza.Sabdar@Sun.COM * message (input) - message number.
5317917SReza.Sabdar@Sun.COM * err (input) - error code to place in header.
5327917SReza.Sabdar@Sun.COM * request_data (input) - message body.
5337917SReza.Sabdar@Sun.COM * reply (output) - reply message. If 0, reply will be
5347917SReza.Sabdar@Sun.COM * discarded.
5357917SReza.Sabdar@Sun.COM *
5367917SReza.Sabdar@Sun.COM * Returns:
5377917SReza.Sabdar@Sun.COM * 0 - successful send.
5387917SReza.Sabdar@Sun.COM * -1 - error.
5397917SReza.Sabdar@Sun.COM * otherwise - error from reply header.
5407917SReza.Sabdar@Sun.COM *
5417917SReza.Sabdar@Sun.COM * Notes:
5427917SReza.Sabdar@Sun.COM * - The reply body is only returned if the error code is NDMP_NO_ERR.
5437917SReza.Sabdar@Sun.COM */
5447917SReza.Sabdar@Sun.COM int
ndmp_send_request_lock(ndmp_connection_t * connection_handle,ndmp_message message,ndmp_error err,void * request_data,void ** reply)5457917SReza.Sabdar@Sun.COM ndmp_send_request_lock(ndmp_connection_t *connection_handle,
5467917SReza.Sabdar@Sun.COM ndmp_message message, ndmp_error err, void *request_data, void **reply)
5477917SReza.Sabdar@Sun.COM {
5487917SReza.Sabdar@Sun.COM int rv;
5497917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
5507917SReza.Sabdar@Sun.COM
5517917SReza.Sabdar@Sun.COM (void) mutex_lock(&connection->conn_lock);
5527917SReza.Sabdar@Sun.COM
5537917SReza.Sabdar@Sun.COM rv = ndmp_send_request(connection_handle, message, err, request_data,
5547917SReza.Sabdar@Sun.COM reply);
5557917SReza.Sabdar@Sun.COM (void) mutex_unlock(&connection->conn_lock);
5567917SReza.Sabdar@Sun.COM return (rv);
5577917SReza.Sabdar@Sun.COM }
5587917SReza.Sabdar@Sun.COM
5597917SReza.Sabdar@Sun.COM
5607917SReza.Sabdar@Sun.COM /*
5617917SReza.Sabdar@Sun.COM * ndmp_send_response
5627917SReza.Sabdar@Sun.COM *
5637917SReza.Sabdar@Sun.COM * Send an NDMP reply message.
5647917SReza.Sabdar@Sun.COM *
5657917SReza.Sabdar@Sun.COM * Parameters:
5667917SReza.Sabdar@Sun.COM * connection_handle (input) - connection pointer.
5677917SReza.Sabdar@Sun.COM * err (input) - error code to place in header.
5687917SReza.Sabdar@Sun.COM * reply (input) - reply message body.
5697917SReza.Sabdar@Sun.COM *
5707917SReza.Sabdar@Sun.COM * Returns:
5717917SReza.Sabdar@Sun.COM * 0 - successful send.
5727917SReza.Sabdar@Sun.COM * -1 - error.
5737917SReza.Sabdar@Sun.COM *
5747917SReza.Sabdar@Sun.COM * Notes:
5757917SReza.Sabdar@Sun.COM * - The body is only sent if the error code is NDMP_NO_ERR.
5767917SReza.Sabdar@Sun.COM */
5777917SReza.Sabdar@Sun.COM int
ndmp_send_response(ndmp_connection_t * connection_handle,ndmp_error err,void * reply)5787917SReza.Sabdar@Sun.COM ndmp_send_response(ndmp_connection_t *connection_handle, ndmp_error err,
5797917SReza.Sabdar@Sun.COM void *reply)
5807917SReza.Sabdar@Sun.COM {
5817917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
5827917SReza.Sabdar@Sun.COM ndmp_header header;
5837917SReza.Sabdar@Sun.COM struct timeval time;
5847917SReza.Sabdar@Sun.COM
5857917SReza.Sabdar@Sun.COM (void) gettimeofday(&time, 0);
5867917SReza.Sabdar@Sun.COM
5877917SReza.Sabdar@Sun.COM header.sequence = ++(connection->conn_my_sequence);
5887917SReza.Sabdar@Sun.COM header.time_stamp = time.tv_sec;
5897917SReza.Sabdar@Sun.COM header.message_type = NDMP_MESSAGE_REPLY;
5907917SReza.Sabdar@Sun.COM header.message = connection->conn_msginfo.mi_hdr.message;
5917917SReza.Sabdar@Sun.COM header.reply_sequence = connection->conn_msginfo.mi_hdr.sequence;
5927917SReza.Sabdar@Sun.COM header.error = err;
5937917SReza.Sabdar@Sun.COM
5947917SReza.Sabdar@Sun.COM connection->conn_xdrs.x_op = XDR_ENCODE;
5957917SReza.Sabdar@Sun.COM if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
5967917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: "
5977917SReza.Sabdar@Sun.COM "encoding reply header",
5987917SReza.Sabdar@Sun.COM header.message);
5997917SReza.Sabdar@Sun.COM (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
6007917SReza.Sabdar@Sun.COM return (-1);
6017917SReza.Sabdar@Sun.COM }
6027917SReza.Sabdar@Sun.COM if (err == NDMP_NO_ERR &&
6037917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->mh_xdr_reply &&
6047917SReza.Sabdar@Sun.COM reply) {
6057917SReza.Sabdar@Sun.COM if (!(*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
6067917SReza.Sabdar@Sun.COM &connection->conn_xdrs, reply)) {
6077917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
6087917SReza.Sabdar@Sun.COM "Sending message 0x%x: encoding reply body",
6097917SReza.Sabdar@Sun.COM header.message);
6107917SReza.Sabdar@Sun.COM (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
6117917SReza.Sabdar@Sun.COM return (-1);
6127917SReza.Sabdar@Sun.COM }
6137917SReza.Sabdar@Sun.COM }
6147917SReza.Sabdar@Sun.COM (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
6157917SReza.Sabdar@Sun.COM return (0);
6167917SReza.Sabdar@Sun.COM }
6177917SReza.Sabdar@Sun.COM
6187917SReza.Sabdar@Sun.COM /*
6197917SReza.Sabdar@Sun.COM * ndmp_free_message
6207917SReza.Sabdar@Sun.COM *
6217917SReza.Sabdar@Sun.COM * Free the memory of NDMP message body.
6227917SReza.Sabdar@Sun.COM *
6237917SReza.Sabdar@Sun.COM * Parameters:
6247917SReza.Sabdar@Sun.COM * connection_handle (input) - connection pointer.
6257917SReza.Sabdar@Sun.COM *
6267917SReza.Sabdar@Sun.COM * Returns:
6277917SReza.Sabdar@Sun.COM * void
6287917SReza.Sabdar@Sun.COM *
6297917SReza.Sabdar@Sun.COM */
6307917SReza.Sabdar@Sun.COM void
ndmp_free_message(ndmp_connection_t * connection_handle)6317917SReza.Sabdar@Sun.COM ndmp_free_message(ndmp_connection_t *connection_handle)
6327917SReza.Sabdar@Sun.COM {
6337917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
6347917SReza.Sabdar@Sun.COM
6357917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_handler == NULL ||
6367917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body == NULL)
6377917SReza.Sabdar@Sun.COM return;
6387917SReza.Sabdar@Sun.COM
6397917SReza.Sabdar@Sun.COM connection->conn_xdrs.x_op = XDR_FREE;
6407917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_hdr.message_type ==
6417917SReza.Sabdar@Sun.COM NDMP_MESSAGE_REQUEST) {
6427917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_handler->mh_xdr_request)
6437917SReza.Sabdar@Sun.COM (*connection->conn_msginfo.mi_handler->mh_xdr_request)(
6447917SReza.Sabdar@Sun.COM &connection->conn_xdrs,
6457917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body);
6467917SReza.Sabdar@Sun.COM } else {
6477917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_handler->mh_xdr_reply)
6487917SReza.Sabdar@Sun.COM (*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
6497917SReza.Sabdar@Sun.COM &connection->conn_xdrs,
6507917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body);
6517917SReza.Sabdar@Sun.COM }
6527917SReza.Sabdar@Sun.COM
6537917SReza.Sabdar@Sun.COM (void) free(connection->conn_msginfo.mi_body);
6547917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body = 0;
6557917SReza.Sabdar@Sun.COM }
6567917SReza.Sabdar@Sun.COM
6577917SReza.Sabdar@Sun.COM /*
6587917SReza.Sabdar@Sun.COM * ndmp_get_fd
6597917SReza.Sabdar@Sun.COM *
6607917SReza.Sabdar@Sun.COM * Returns the connection file descriptor.
6617917SReza.Sabdar@Sun.COM *
6627917SReza.Sabdar@Sun.COM * Parameters:
6637917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle
6647917SReza.Sabdar@Sun.COM *
6657917SReza.Sabdar@Sun.COM * Returns:
6667917SReza.Sabdar@Sun.COM * >=0 - file descriptor.
6677917SReza.Sabdar@Sun.COM * -1 - connection not open.
6687917SReza.Sabdar@Sun.COM */
6697917SReza.Sabdar@Sun.COM int
ndmp_get_fd(ndmp_connection_t * connection_handle)6707917SReza.Sabdar@Sun.COM ndmp_get_fd(ndmp_connection_t *connection_handle)
6717917SReza.Sabdar@Sun.COM {
6727917SReza.Sabdar@Sun.COM return (((ndmp_connection_t *)connection_handle)->conn_sock);
6737917SReza.Sabdar@Sun.COM }
6747917SReza.Sabdar@Sun.COM
6757917SReza.Sabdar@Sun.COM
6767917SReza.Sabdar@Sun.COM /*
6777917SReza.Sabdar@Sun.COM * ndmp_set_client_data
6787917SReza.Sabdar@Sun.COM *
6797917SReza.Sabdar@Sun.COM * This function provides a means for the library client to provide
6807917SReza.Sabdar@Sun.COM * a pointer to some user data structure that is retrievable by
6817917SReza.Sabdar@Sun.COM * each message handler via ndmp_get_client_data.
6827917SReza.Sabdar@Sun.COM *
6837917SReza.Sabdar@Sun.COM * Parameters:
6847917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle.
6857917SReza.Sabdar@Sun.COM * client_data (input) - user data pointer.
6867917SReza.Sabdar@Sun.COM *
6877917SReza.Sabdar@Sun.COM * Returns:
6887917SReza.Sabdar@Sun.COM * void
6897917SReza.Sabdar@Sun.COM */
6907917SReza.Sabdar@Sun.COM void
ndmp_set_client_data(ndmp_connection_t * connection_handle,void * client_data)6917917SReza.Sabdar@Sun.COM ndmp_set_client_data(ndmp_connection_t *connection_handle, void *client_data)
6927917SReza.Sabdar@Sun.COM {
6937917SReza.Sabdar@Sun.COM ((ndmp_connection_t *)connection_handle)->conn_client_data =
6947917SReza.Sabdar@Sun.COM client_data;
6957917SReza.Sabdar@Sun.COM }
6967917SReza.Sabdar@Sun.COM
6977917SReza.Sabdar@Sun.COM
6987917SReza.Sabdar@Sun.COM /*
6997917SReza.Sabdar@Sun.COM * ndmp_get_client_data
7007917SReza.Sabdar@Sun.COM *
7017917SReza.Sabdar@Sun.COM * This function provides a means for the library client to provide
7027917SReza.Sabdar@Sun.COM * a pointer to some user data structure that is retrievable by
7037917SReza.Sabdar@Sun.COM * each message handler via ndmp_get_client_data.
7047917SReza.Sabdar@Sun.COM *
7057917SReza.Sabdar@Sun.COM * Parameters:
7067917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle.
7077917SReza.Sabdar@Sun.COM *
7087917SReza.Sabdar@Sun.COM * Returns:
7097917SReza.Sabdar@Sun.COM * client data pointer.
7107917SReza.Sabdar@Sun.COM */
7117917SReza.Sabdar@Sun.COM void *
ndmp_get_client_data(ndmp_connection_t * connection_handle)7127917SReza.Sabdar@Sun.COM ndmp_get_client_data(ndmp_connection_t *connection_handle)
7137917SReza.Sabdar@Sun.COM {
7147917SReza.Sabdar@Sun.COM return (((ndmp_connection_t *)connection_handle)->conn_client_data);
7157917SReza.Sabdar@Sun.COM }
7167917SReza.Sabdar@Sun.COM
7177917SReza.Sabdar@Sun.COM
7187917SReza.Sabdar@Sun.COM /*
7197917SReza.Sabdar@Sun.COM * ndmp_set_version
7207917SReza.Sabdar@Sun.COM *
7217917SReza.Sabdar@Sun.COM * Sets the NDMP protocol version to be used on the connection.
7227917SReza.Sabdar@Sun.COM *
7237917SReza.Sabdar@Sun.COM * Parameters:
7247917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle.
7257917SReza.Sabdar@Sun.COM * version (input) - protocol version.
7267917SReza.Sabdar@Sun.COM *
7277917SReza.Sabdar@Sun.COM * Returns:
7287917SReza.Sabdar@Sun.COM * void
7297917SReza.Sabdar@Sun.COM */
7307917SReza.Sabdar@Sun.COM void
ndmp_set_version(ndmp_connection_t * connection_handle,ushort_t version)7317917SReza.Sabdar@Sun.COM ndmp_set_version(ndmp_connection_t *connection_handle, ushort_t version)
7327917SReza.Sabdar@Sun.COM {
7337917SReza.Sabdar@Sun.COM ((ndmp_connection_t *)connection_handle)->conn_version = version;
7347917SReza.Sabdar@Sun.COM }
7357917SReza.Sabdar@Sun.COM
7367917SReza.Sabdar@Sun.COM
7377917SReza.Sabdar@Sun.COM /*
7387917SReza.Sabdar@Sun.COM * ndmp_get_version
7397917SReza.Sabdar@Sun.COM *
7407917SReza.Sabdar@Sun.COM * Gets the NDMP protocol version in use on the connection.
7417917SReza.Sabdar@Sun.COM *
7427917SReza.Sabdar@Sun.COM * Parameters:
7437917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle.
7447917SReza.Sabdar@Sun.COM * version (input) - protocol version.
7457917SReza.Sabdar@Sun.COM *
7467917SReza.Sabdar@Sun.COM * Returns:
7477917SReza.Sabdar@Sun.COM * void
7487917SReza.Sabdar@Sun.COM */
7497917SReza.Sabdar@Sun.COM ushort_t
ndmp_get_version(ndmp_connection_t * connection_handle)7507917SReza.Sabdar@Sun.COM ndmp_get_version(ndmp_connection_t *connection_handle)
7517917SReza.Sabdar@Sun.COM {
7527917SReza.Sabdar@Sun.COM return (((ndmp_connection_t *)connection_handle)->conn_version);
7537917SReza.Sabdar@Sun.COM }
7547917SReza.Sabdar@Sun.COM
7557917SReza.Sabdar@Sun.COM
7567917SReza.Sabdar@Sun.COM /*
7577917SReza.Sabdar@Sun.COM * ndmp_set_authorized
7587917SReza.Sabdar@Sun.COM *
7597917SReza.Sabdar@Sun.COM * Mark the connection as either having been authorized or not.
7607917SReza.Sabdar@Sun.COM *
7617917SReza.Sabdar@Sun.COM * Parameters:
7627917SReza.Sabdar@Sun.COM * connection_handle (input) - connection handle.
7637917SReza.Sabdar@Sun.COM * authorized (input) - TRUE or FALSE.
7647917SReza.Sabdar@Sun.COM *
7657917SReza.Sabdar@Sun.COM * Returns:
7667917SReza.Sabdar@Sun.COM * void
7677917SReza.Sabdar@Sun.COM */
7687917SReza.Sabdar@Sun.COM void
ndmp_set_authorized(ndmp_connection_t * connection_handle,boolean_t authorized)7697917SReza.Sabdar@Sun.COM ndmp_set_authorized(ndmp_connection_t *connection_handle, boolean_t authorized)
7707917SReza.Sabdar@Sun.COM {
7717917SReza.Sabdar@Sun.COM ((ndmp_connection_t *)connection_handle)->conn_authorized = authorized;
7727917SReza.Sabdar@Sun.COM }
7737917SReza.Sabdar@Sun.COM
7747917SReza.Sabdar@Sun.COM
7757917SReza.Sabdar@Sun.COM /*
7767917SReza.Sabdar@Sun.COM * ndmpd_main
7777917SReza.Sabdar@Sun.COM *
7787917SReza.Sabdar@Sun.COM * NDMP main function called from main().
7797917SReza.Sabdar@Sun.COM *
7807917SReza.Sabdar@Sun.COM * Parameters:
7817917SReza.Sabdar@Sun.COM * void
7827917SReza.Sabdar@Sun.COM *
7837917SReza.Sabdar@Sun.COM * Returns:
7847917SReza.Sabdar@Sun.COM * void
7857917SReza.Sabdar@Sun.COM */
7867917SReza.Sabdar@Sun.COM void
ndmpd_main(void)7877917SReza.Sabdar@Sun.COM ndmpd_main(void)
7887917SReza.Sabdar@Sun.COM {
7897917SReza.Sabdar@Sun.COM char *propval;
7907917SReza.Sabdar@Sun.COM
7917917SReza.Sabdar@Sun.COM ndmp_load_params();
7928800SReza.Sabdar@Sun.COM if (ndmp_log_open_file() != 0) {
7938800SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR,
7948800SReza.Sabdar@Sun.COM "Could not open log file properly.");
7958800SReza.Sabdar@Sun.COM }
7968800SReza.Sabdar@Sun.COM
7977917SReza.Sabdar@Sun.COM /*
7987917SReza.Sabdar@Sun.COM * Find ndmp port number to be used. If ndmpd is run as command line
7997917SReza.Sabdar@Sun.COM * and port number is supplied, use that port number. If port number is
8007917SReza.Sabdar@Sun.COM * is not supplied, find out if ndmp port property is set. If ndmp
8017917SReza.Sabdar@Sun.COM * port property is set, use that port number otherwise use the defaule
8027917SReza.Sabdar@Sun.COM * port number.
8037917SReza.Sabdar@Sun.COM */
8047917SReza.Sabdar@Sun.COM if (ndmp_port == 0) {
8057917SReza.Sabdar@Sun.COM if ((propval = ndmpd_get_prop(NDMP_TCP_PORT)) == NULL ||
8067917SReza.Sabdar@Sun.COM *propval == 0)
8077917SReza.Sabdar@Sun.COM ndmp_port = NDMPPORT;
8087917SReza.Sabdar@Sun.COM else
8097917SReza.Sabdar@Sun.COM ndmp_port = strtol(propval, 0, 0);
8107917SReza.Sabdar@Sun.COM }
8117917SReza.Sabdar@Sun.COM
8127917SReza.Sabdar@Sun.COM if (ndmp_run(ndmp_port, connection_handler) == -1)
8137917SReza.Sabdar@Sun.COM perror("ndmp_run ERROR");
8147917SReza.Sabdar@Sun.COM
8157917SReza.Sabdar@Sun.COM ndmp_log_close_file();
8167917SReza.Sabdar@Sun.COM }
8177917SReza.Sabdar@Sun.COM
8187917SReza.Sabdar@Sun.COM /*
8197917SReza.Sabdar@Sun.COM * connection_handler
8207917SReza.Sabdar@Sun.COM *
8217917SReza.Sabdar@Sun.COM * NDMP connection handler.
8227917SReza.Sabdar@Sun.COM * Waits for, reads, and processes NDMP requests on a connection.
8237917SReza.Sabdar@Sun.COM *
8247917SReza.Sabdar@Sun.COM * Parameters:
8257917SReza.Sabdar@Sun.COM * connection (input) - connection handle.
8267917SReza.Sabdar@Sun.COM *
8277917SReza.Sabdar@Sun.COM * Return:
8287917SReza.Sabdar@Sun.COM * void
8297917SReza.Sabdar@Sun.COM */
8307917SReza.Sabdar@Sun.COM void
connection_handler(ndmp_connection_t * connection)8317917SReza.Sabdar@Sun.COM connection_handler(ndmp_connection_t *connection)
8327917SReza.Sabdar@Sun.COM {
8337917SReza.Sabdar@Sun.COM static int conn_id = 1;
8347917SReza.Sabdar@Sun.COM ndmpd_session_t session;
8357917SReza.Sabdar@Sun.COM ndmp_notify_connected_request req;
8367917SReza.Sabdar@Sun.COM int connection_fd;
8377917SReza.Sabdar@Sun.COM
8387917SReza.Sabdar@Sun.COM (void) memset(&session, 0, sizeof (session));
8397917SReza.Sabdar@Sun.COM session.ns_connection = connection;
8407917SReza.Sabdar@Sun.COM session.ns_eof = FALSE;
8417917SReza.Sabdar@Sun.COM /*
8427917SReza.Sabdar@Sun.COM * The 'protocol_version' must be 1 at first, since the client talks
8437917SReza.Sabdar@Sun.COM * to the server in version 1 then they can move to a higher
8447917SReza.Sabdar@Sun.COM * protocol version.
8457917SReza.Sabdar@Sun.COM */
8467917SReza.Sabdar@Sun.COM session.ns_protocol_version = ndmp_ver;
8477917SReza.Sabdar@Sun.COM
8487917SReza.Sabdar@Sun.COM session.ns_scsi.sd_is_open = -1;
8497917SReza.Sabdar@Sun.COM session.ns_scsi.sd_devid = -1;
8507917SReza.Sabdar@Sun.COM
8517917SReza.Sabdar@Sun.COM session.ns_scsi.sd_sid = 0;
8527917SReza.Sabdar@Sun.COM session.ns_scsi.sd_lun = 0;
8537917SReza.Sabdar@Sun.COM session.ns_scsi.sd_valid_target_set = 0;
8547917SReza.Sabdar@Sun.COM (void) memset(session.ns_scsi.sd_adapter_name, 0,
8557917SReza.Sabdar@Sun.COM sizeof (session.ns_scsi.sd_adapter_name));
8567917SReza.Sabdar@Sun.COM
8577917SReza.Sabdar@Sun.COM session.ns_tape.td_fd = -1;
8587917SReza.Sabdar@Sun.COM session.ns_tape.td_sid = 0;
8597917SReza.Sabdar@Sun.COM session.ns_tape.td_lun = 0;
8607917SReza.Sabdar@Sun.COM (void) memset(session.ns_tape.td_adapter_name, 0,
8617917SReza.Sabdar@Sun.COM sizeof (session.ns_tape.td_adapter_name));
8627917SReza.Sabdar@Sun.COM session.ns_tape.td_pos = 0;
8637917SReza.Sabdar@Sun.COM session.ns_tape.td_record_count = 0;
8647917SReza.Sabdar@Sun.COM session.ns_file_handler_list = 0;
8657917SReza.Sabdar@Sun.COM
8667917SReza.Sabdar@Sun.COM (void) ndmpd_data_init(&session);
8677917SReza.Sabdar@Sun.COM ndmpd_file_history_init(&session);
8687917SReza.Sabdar@Sun.COM if (ndmpd_mover_init(&session) < 0)
8697917SReza.Sabdar@Sun.COM return;
8707917SReza.Sabdar@Sun.COM
8717917SReza.Sabdar@Sun.COM if (ndmp_lbr_init(&session) < 0)
8727917SReza.Sabdar@Sun.COM return;
8737917SReza.Sabdar@Sun.COM
8747917SReza.Sabdar@Sun.COM /*
8757917SReza.Sabdar@Sun.COM * Setup defaults here. The init functions can not set defaults
8767917SReza.Sabdar@Sun.COM * since the init functions are called by the stop request handlers
8777917SReza.Sabdar@Sun.COM * and client set variables need to persist across data operations.
8787917SReza.Sabdar@Sun.COM */
8797917SReza.Sabdar@Sun.COM session.ns_mover.md_record_size = MAX_RECORD_SIZE;
8807917SReza.Sabdar@Sun.COM
8817917SReza.Sabdar@Sun.COM ndmp_set_client_data(connection, (void *)&session);
8827917SReza.Sabdar@Sun.COM
8837917SReza.Sabdar@Sun.COM req.reason = NDMP_CONNECTED;
8847917SReza.Sabdar@Sun.COM req.protocol_version = ndmp_ver;
8857917SReza.Sabdar@Sun.COM req.text_reason = "";
8867917SReza.Sabdar@Sun.COM
8878193SReza.Sabdar@Sun.COM if (ndmp_send_request_lock(connection, NDMP_NOTIFY_CONNECTION_STATUS,
8887917SReza.Sabdar@Sun.COM NDMP_NO_ERR, (void *)&req, 0) < 0) {
8897917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Connection terminated");
8907917SReza.Sabdar@Sun.COM return;
8917917SReza.Sabdar@Sun.COM }
8927917SReza.Sabdar@Sun.COM connection_fd = ndmp_get_fd(connection);
8937917SReza.Sabdar@Sun.COM
8947917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "connection_fd: %d", connection_fd);
8957917SReza.Sabdar@Sun.COM
8967917SReza.Sabdar@Sun.COM /*
8977917SReza.Sabdar@Sun.COM * Add the handler function for the connection to the DMA.
8987917SReza.Sabdar@Sun.COM */
8997917SReza.Sabdar@Sun.COM if (ndmpd_add_file_handler(&session, (void *)&session, connection_fd,
9007917SReza.Sabdar@Sun.COM NDMPD_SELECT_MODE_READ, HC_CLIENT, connection_file_handler) != 0) {
9017917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Could not register session handler.");
9027917SReza.Sabdar@Sun.COM return;
9037917SReza.Sabdar@Sun.COM }
9047917SReza.Sabdar@Sun.COM
9057917SReza.Sabdar@Sun.COM /*
9067917SReza.Sabdar@Sun.COM * Register the connection in the list of active connections.
9077917SReza.Sabdar@Sun.COM */
9087917SReza.Sabdar@Sun.COM if (ndmp_connect_list_add(connection, &conn_id) != 0) {
9097917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR,
9107917SReza.Sabdar@Sun.COM "Could not register the session to the server.");
9117917SReza.Sabdar@Sun.COM (void) ndmpd_remove_file_handler(&session, connection_fd);
9127917SReza.Sabdar@Sun.COM return;
9137917SReza.Sabdar@Sun.COM }
9147917SReza.Sabdar@Sun.COM
9157917SReza.Sabdar@Sun.COM session.hardlink_q = hardlink_q_init();
9167917SReza.Sabdar@Sun.COM
9177917SReza.Sabdar@Sun.COM while (session.ns_eof == FALSE)
9187917SReza.Sabdar@Sun.COM (void) ndmpd_select(&session, TRUE, HC_ALL);
9197917SReza.Sabdar@Sun.COM
9207917SReza.Sabdar@Sun.COM hardlink_q_cleanup(session.hardlink_q);
9217917SReza.Sabdar@Sun.COM
9227917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Connection terminated");
9237917SReza.Sabdar@Sun.COM
9247917SReza.Sabdar@Sun.COM (void) ndmpd_remove_file_handler(&session, connection_fd);
9257917SReza.Sabdar@Sun.COM
9267917SReza.Sabdar@Sun.COM if (session.ns_scsi.sd_is_open != -1) {
9277917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "scsi.is_open: %d",
9287917SReza.Sabdar@Sun.COM session.ns_scsi.sd_is_open);
9297917SReza.Sabdar@Sun.COM (void) ndmp_open_list_del(session.ns_scsi.sd_adapter_name,
9307917SReza.Sabdar@Sun.COM session.ns_scsi.sd_sid, session.ns_scsi.sd_lun);
9317917SReza.Sabdar@Sun.COM }
9327917SReza.Sabdar@Sun.COM if (session.ns_tape.td_fd != -1) {
9337917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "tape.fd: %d", session.ns_tape.td_fd);
9347917SReza.Sabdar@Sun.COM (void) close(session.ns_tape.td_fd);
9357917SReza.Sabdar@Sun.COM (void) ndmp_open_list_del(session.ns_tape.td_adapter_name,
9367917SReza.Sabdar@Sun.COM session.ns_tape.td_sid, session.ns_tape.td_lun);
9377917SReza.Sabdar@Sun.COM }
9387917SReza.Sabdar@Sun.COM ndmpd_mover_shut_down(&session);
9397917SReza.Sabdar@Sun.COM ndmp_lbr_cleanup(&session);
9407917SReza.Sabdar@Sun.COM ndmpd_data_cleanup(&session);
9417917SReza.Sabdar@Sun.COM ndmpd_file_history_cleanup(&session, FALSE);
9427917SReza.Sabdar@Sun.COM ndmpd_mover_cleanup(&session);
9437917SReza.Sabdar@Sun.COM
9447917SReza.Sabdar@Sun.COM (void) ndmp_connect_list_del(connection);
9457917SReza.Sabdar@Sun.COM }
9467917SReza.Sabdar@Sun.COM
9477917SReza.Sabdar@Sun.COM
9487917SReza.Sabdar@Sun.COM /*
9497917SReza.Sabdar@Sun.COM * connection_file_handler
9507917SReza.Sabdar@Sun.COM *
9517917SReza.Sabdar@Sun.COM * ndmp_connection_t file handler function.
9527917SReza.Sabdar@Sun.COM * Called by ndmpd_select when data is available to be read on the
9537917SReza.Sabdar@Sun.COM * NDMP connection.
9547917SReza.Sabdar@Sun.COM *
9557917SReza.Sabdar@Sun.COM * Parameters:
9567917SReza.Sabdar@Sun.COM * cookie (input) - session pointer.
9577917SReza.Sabdar@Sun.COM * fd (input) - connection file descriptor.
9587917SReza.Sabdar@Sun.COM * mode (input) - select mode.
9597917SReza.Sabdar@Sun.COM *
9607917SReza.Sabdar@Sun.COM * Returns:
9617917SReza.Sabdar@Sun.COM * void.
9627917SReza.Sabdar@Sun.COM */
9637917SReza.Sabdar@Sun.COM /*ARGSUSED*/
9647917SReza.Sabdar@Sun.COM static void
connection_file_handler(void * cookie,int fd,ulong_t mode)9657917SReza.Sabdar@Sun.COM connection_file_handler(void *cookie, int fd, ulong_t mode)
9667917SReza.Sabdar@Sun.COM {
9677917SReza.Sabdar@Sun.COM ndmpd_session_t *session = (ndmpd_session_t *)cookie;
9687917SReza.Sabdar@Sun.COM
9697917SReza.Sabdar@Sun.COM if (ndmp_process_requests(session->ns_connection) < 0)
9707917SReza.Sabdar@Sun.COM session->ns_eof = TRUE;
9717917SReza.Sabdar@Sun.COM }
9727917SReza.Sabdar@Sun.COM
9737917SReza.Sabdar@Sun.COM
9747917SReza.Sabdar@Sun.COM /* ************* private functions *************************************** */
9757917SReza.Sabdar@Sun.COM
9767917SReza.Sabdar@Sun.COM /*
9777917SReza.Sabdar@Sun.COM * ndmp_readit
9787917SReza.Sabdar@Sun.COM *
9797917SReza.Sabdar@Sun.COM * Low level read routine called by the xdrrec library.
9807917SReza.Sabdar@Sun.COM *
9817917SReza.Sabdar@Sun.COM * Parameters:
9827917SReza.Sabdar@Sun.COM * connection (input) - connection pointer.
9837917SReza.Sabdar@Sun.COM * buf (input) - location to store received data.
9847917SReza.Sabdar@Sun.COM * len (input) - max number of bytes to read.
9857917SReza.Sabdar@Sun.COM *
9867917SReza.Sabdar@Sun.COM * Returns:
9877917SReza.Sabdar@Sun.COM * >0 - number of bytes received.
9887917SReza.Sabdar@Sun.COM * -1 - error.
9897917SReza.Sabdar@Sun.COM */
9907917SReza.Sabdar@Sun.COM static int
ndmp_readit(void * connection_handle,caddr_t buf,int len)9917917SReza.Sabdar@Sun.COM ndmp_readit(void *connection_handle, caddr_t buf, int len)
9927917SReza.Sabdar@Sun.COM {
9937917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
9947917SReza.Sabdar@Sun.COM
9957917SReza.Sabdar@Sun.COM len = read(connection->conn_sock, buf, len);
9967917SReza.Sabdar@Sun.COM if (len <= 0) {
9977917SReza.Sabdar@Sun.COM /* ndmp_connection_t has been closed. */
9987917SReza.Sabdar@Sun.COM connection->conn_eof = TRUE;
9997917SReza.Sabdar@Sun.COM return (-1);
10007917SReza.Sabdar@Sun.COM }
10017917SReza.Sabdar@Sun.COM return (len);
10027917SReza.Sabdar@Sun.COM }
10037917SReza.Sabdar@Sun.COM
10047917SReza.Sabdar@Sun.COM /*
10057917SReza.Sabdar@Sun.COM * ndmp_writeit
10067917SReza.Sabdar@Sun.COM *
10077917SReza.Sabdar@Sun.COM * Low level write routine called by the xdrrec library.
10087917SReza.Sabdar@Sun.COM *
10097917SReza.Sabdar@Sun.COM * Parameters:
10107917SReza.Sabdar@Sun.COM * connection (input) - connection pointer.
10117917SReza.Sabdar@Sun.COM * buf (input) - location to store received data.
10127917SReza.Sabdar@Sun.COM * len (input) - max number of bytes to read.
10137917SReza.Sabdar@Sun.COM *
10147917SReza.Sabdar@Sun.COM * Returns:
10157917SReza.Sabdar@Sun.COM * >0 - number of bytes sent.
10167917SReza.Sabdar@Sun.COM * -1 - error.
10177917SReza.Sabdar@Sun.COM */
10187917SReza.Sabdar@Sun.COM static int
ndmp_writeit(void * connection_handle,caddr_t buf,int len)10197917SReza.Sabdar@Sun.COM ndmp_writeit(void *connection_handle, caddr_t buf, int len)
10207917SReza.Sabdar@Sun.COM {
10217917SReza.Sabdar@Sun.COM ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
10227917SReza.Sabdar@Sun.COM register int n;
10237917SReza.Sabdar@Sun.COM register int cnt;
10247917SReza.Sabdar@Sun.COM
10257917SReza.Sabdar@Sun.COM for (cnt = len; cnt > 0; cnt -= n, buf += n) {
10267917SReza.Sabdar@Sun.COM if ((n = write(connection->conn_sock, buf, cnt)) < 0) {
10277917SReza.Sabdar@Sun.COM connection->conn_eof = TRUE;
10287917SReza.Sabdar@Sun.COM return (-1);
10297917SReza.Sabdar@Sun.COM }
10307917SReza.Sabdar@Sun.COM }
10317917SReza.Sabdar@Sun.COM
10327917SReza.Sabdar@Sun.COM return (len);
10337917SReza.Sabdar@Sun.COM }
10347917SReza.Sabdar@Sun.COM
10357917SReza.Sabdar@Sun.COM
10367917SReza.Sabdar@Sun.COM /*
10377917SReza.Sabdar@Sun.COM * ndmp_recv_msg
10387917SReza.Sabdar@Sun.COM *
10397917SReza.Sabdar@Sun.COM * Read the next message.
10407917SReza.Sabdar@Sun.COM *
10417917SReza.Sabdar@Sun.COM * Parameters:
10427917SReza.Sabdar@Sun.COM * connection (input) - connection pointer.
10437917SReza.Sabdar@Sun.COM * msg (output) - received message.
10447917SReza.Sabdar@Sun.COM *
10457917SReza.Sabdar@Sun.COM * Returns:
10467917SReza.Sabdar@Sun.COM * 0 - Message successfully received.
10477917SReza.Sabdar@Sun.COM * error number - Message related error.
10487917SReza.Sabdar@Sun.COM * -1 - Error decoding the message header.
10497917SReza.Sabdar@Sun.COM */
10507917SReza.Sabdar@Sun.COM static int
ndmp_recv_msg(ndmp_connection_t * connection)10517917SReza.Sabdar@Sun.COM ndmp_recv_msg(ndmp_connection_t *connection)
10527917SReza.Sabdar@Sun.COM {
10537917SReza.Sabdar@Sun.COM bool_t(*xdr_func) (XDR *, ...) = NULL;
10547917SReza.Sabdar@Sun.COM
10557917SReza.Sabdar@Sun.COM /* Decode the header. */
10567917SReza.Sabdar@Sun.COM connection->conn_xdrs.x_op = XDR_DECODE;
10577917SReza.Sabdar@Sun.COM (void) xdrrec_skiprecord(&connection->conn_xdrs);
10587917SReza.Sabdar@Sun.COM if (!xdr_ndmp_header(&connection->conn_xdrs,
10597917SReza.Sabdar@Sun.COM &connection->conn_msginfo.mi_hdr))
10607917SReza.Sabdar@Sun.COM return (-1);
10617917SReza.Sabdar@Sun.COM
10627917SReza.Sabdar@Sun.COM /* Lookup info necessary for processing this message. */
10637917SReza.Sabdar@Sun.COM if ((connection->conn_msginfo.mi_handler = ndmp_get_handler(connection,
10647917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message)) == 0) {
10657917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Message 0x%x not supported",
10667917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
10677917SReza.Sabdar@Sun.COM return (NDMP_NOT_SUPPORTED_ERR);
10687917SReza.Sabdar@Sun.COM }
10697917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body = 0;
10707917SReza.Sabdar@Sun.COM
10717917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_hdr.error != NDMP_NO_ERR)
10727917SReza.Sabdar@Sun.COM return (0);
10737917SReza.Sabdar@Sun.COM
10747917SReza.Sabdar@Sun.COM /* Determine body type */
10757917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_hdr.message_type ==
10767917SReza.Sabdar@Sun.COM NDMP_MESSAGE_REQUEST) {
10777917SReza.Sabdar@Sun.COM if (ndmp_check_auth_required(
10787917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message) &&
10797917SReza.Sabdar@Sun.COM !connection->conn_authorized) {
10807917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
10817917SReza.Sabdar@Sun.COM "Processing request 0x%x:connection not authorized",
10827917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
10837917SReza.Sabdar@Sun.COM return (NDMP_NOT_AUTHORIZED_ERR);
10847917SReza.Sabdar@Sun.COM }
10857917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_handler->mh_sizeof_request >
10867917SReza.Sabdar@Sun.COM 0) {
10877917SReza.Sabdar@Sun.COM xdr_func =
10887917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->mh_xdr_request;
10897917SReza.Sabdar@Sun.COM if (xdr_func == NULL) {
10907917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
10917917SReza.Sabdar@Sun.COM "Processing request 0x%x: no xdr function "
10927917SReza.Sabdar@Sun.COM "in handler table",
10937917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
10947917SReza.Sabdar@Sun.COM return (NDMP_NOT_SUPPORTED_ERR);
10957917SReza.Sabdar@Sun.COM }
10967917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body = ndmp_malloc(
10977917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->
10987917SReza.Sabdar@Sun.COM mh_sizeof_request);
10997917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_body == NULL)
11007917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR);
11017917SReza.Sabdar@Sun.COM
11027917SReza.Sabdar@Sun.COM (void) memset(connection->conn_msginfo.mi_body, 0,
11037917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->
11047917SReza.Sabdar@Sun.COM mh_sizeof_request);
11057917SReza.Sabdar@Sun.COM }
11067917SReza.Sabdar@Sun.COM } else {
11077917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_handler->mh_sizeof_reply > 0) {
11087917SReza.Sabdar@Sun.COM xdr_func =
11097917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->mh_xdr_reply;
11107917SReza.Sabdar@Sun.COM if (xdr_func == NULL) {
11117917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
11127917SReza.Sabdar@Sun.COM "Processing reply 0x%x: no xdr function "
11137917SReza.Sabdar@Sun.COM "in handler table",
11147917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
11157917SReza.Sabdar@Sun.COM return (NDMP_NOT_SUPPORTED_ERR);
11167917SReza.Sabdar@Sun.COM }
11177917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body = ndmp_malloc(
11187917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->
11197917SReza.Sabdar@Sun.COM mh_sizeof_reply);
11207917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_body == NULL)
11217917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR);
11227917SReza.Sabdar@Sun.COM
11237917SReza.Sabdar@Sun.COM (void) memset(connection->conn_msginfo.mi_body, 0,
11247917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_handler->
11257917SReza.Sabdar@Sun.COM mh_sizeof_reply);
11267917SReza.Sabdar@Sun.COM }
11277917SReza.Sabdar@Sun.COM }
11287917SReza.Sabdar@Sun.COM
11297917SReza.Sabdar@Sun.COM /* Decode message arguments if needed */
11307917SReza.Sabdar@Sun.COM if (xdr_func) {
11317917SReza.Sabdar@Sun.COM if (!(*xdr_func)(&connection->conn_xdrs,
11327917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body)) {
11337917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
11347917SReza.Sabdar@Sun.COM "Processing message 0x%x: error decoding arguments",
11357917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
11367917SReza.Sabdar@Sun.COM free(connection->conn_msginfo.mi_body);
11377917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body = 0;
11387917SReza.Sabdar@Sun.COM return (NDMP_XDR_DECODE_ERR);
11397917SReza.Sabdar@Sun.COM }
11407917SReza.Sabdar@Sun.COM }
11417917SReza.Sabdar@Sun.COM return (0);
11427917SReza.Sabdar@Sun.COM }
11437917SReza.Sabdar@Sun.COM
11447917SReza.Sabdar@Sun.COM /*
11457917SReza.Sabdar@Sun.COM * ndmp_process_messages
11467917SReza.Sabdar@Sun.COM *
11477917SReza.Sabdar@Sun.COM * Reads the next message into the stream buffer.
11487917SReza.Sabdar@Sun.COM * Processes messages until the stream buffer is empty.
11497917SReza.Sabdar@Sun.COM *
11507917SReza.Sabdar@Sun.COM * This function processes all data in the stream buffer before returning.
11517917SReza.Sabdar@Sun.COM * This allows functions like poll() to be used to determine when new
11527917SReza.Sabdar@Sun.COM * messages have arrived. If only some of the messages in the stream buffer
11537917SReza.Sabdar@Sun.COM * were processed and then poll was called, poll() could block waiting for
11547917SReza.Sabdar@Sun.COM * a message that had already been received and read into the stream buffer.
11557917SReza.Sabdar@Sun.COM *
11567917SReza.Sabdar@Sun.COM * This function processes both request and reply messages.
11577917SReza.Sabdar@Sun.COM * Request messages are dispatched using the appropriate function from the
11587917SReza.Sabdar@Sun.COM * message handling table.
11597917SReza.Sabdar@Sun.COM * Only one reply messages may be pending receipt at a time.
11607917SReza.Sabdar@Sun.COM * A reply message, if received, is placed in connection->conn_msginfo
11617917SReza.Sabdar@Sun.COM * before returning to the caller.
11627917SReza.Sabdar@Sun.COM * Errors are reported if a reply is received but not expected or if
11637917SReza.Sabdar@Sun.COM * more than one reply message is received
11647917SReza.Sabdar@Sun.COM *
11657917SReza.Sabdar@Sun.COM * Parameters:
11667917SReza.Sabdar@Sun.COM * connection (input) - connection pointer.
11677917SReza.Sabdar@Sun.COM * reply_expected (output) - TRUE - a reply message is expected.
11687917SReza.Sabdar@Sun.COM * FALSE - no reply message is expected and
11697917SReza.Sabdar@Sun.COM * an error will be reported if a reply
11707917SReza.Sabdar@Sun.COM * is received.
11717917SReza.Sabdar@Sun.COM *
11727917SReza.Sabdar@Sun.COM * Returns:
11737917SReza.Sabdar@Sun.COM * NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
11747917SReza.Sabdar@Sun.COM * error processing reply message.
11757917SReza.Sabdar@Sun.COM * NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
11767917SReza.Sabdar@Sun.COM * reply seen.
11777917SReza.Sabdar@Sun.COM * NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
11787917SReza.Sabdar@Sun.COM * no reply seen.
11797917SReza.Sabdar@Sun.COM * NDMP_PROC_REP_ERR - error; connection no longer established.
11807917SReza.Sabdar@Sun.COM *
11817917SReza.Sabdar@Sun.COM * Notes:
11827917SReza.Sabdar@Sun.COM * If the peer is generating a large number of requests, a caller
11837917SReza.Sabdar@Sun.COM * looking for a reply will be blocked while the requests are handled.
11847917SReza.Sabdar@Sun.COM * This is because this function does not return until the stream
11857917SReza.Sabdar@Sun.COM * buffer is empty.
11867917SReza.Sabdar@Sun.COM * Code needs to be added to allow a return if the stream buffer
11877917SReza.Sabdar@Sun.COM * is not empty but there is data available on the socket. This will
11887917SReza.Sabdar@Sun.COM * prevent poll() from blocking and prevent a caller looking for a reply
11897917SReza.Sabdar@Sun.COM * from getting blocked by a bunch of requests.
11907917SReza.Sabdar@Sun.COM */
11917917SReza.Sabdar@Sun.COM static int
ndmp_process_messages(ndmp_connection_t * connection,boolean_t reply_expected)11927917SReza.Sabdar@Sun.COM ndmp_process_messages(ndmp_connection_t *connection, boolean_t reply_expected)
11937917SReza.Sabdar@Sun.COM {
11947917SReza.Sabdar@Sun.COM msg_info_t reply_msginfo;
11957917SReza.Sabdar@Sun.COM boolean_t reply_read = FALSE;
11967917SReza.Sabdar@Sun.COM boolean_t reply_error = FALSE;
11977917SReza.Sabdar@Sun.COM int err;
11987917SReza.Sabdar@Sun.COM
11997917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "reply_expected: %s",
12007917SReza.Sabdar@Sun.COM reply_expected == TRUE ? "TRUE" : "FALSE");
12017917SReza.Sabdar@Sun.COM
12027917SReza.Sabdar@Sun.COM (void) memset((void *)&reply_msginfo, 0, sizeof (msg_info_t));
12037917SReza.Sabdar@Sun.COM
12047917SReza.Sabdar@Sun.COM do {
12057917SReza.Sabdar@Sun.COM (void) memset((void *)&connection->conn_msginfo, 0,
12067917SReza.Sabdar@Sun.COM sizeof (msg_info_t));
12077917SReza.Sabdar@Sun.COM
12087917SReza.Sabdar@Sun.COM if ((err = ndmp_recv_msg(connection)) != NDMP_NO_ERR) {
12097917SReza.Sabdar@Sun.COM if (connection->conn_eof) {
12107917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "detected eof");
12117917SReza.Sabdar@Sun.COM return (NDMP_PROC_ERR);
12127917SReza.Sabdar@Sun.COM }
12137917SReza.Sabdar@Sun.COM if (err < 1) {
12147917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "error decoding header");
12157917SReza.Sabdar@Sun.COM
12167917SReza.Sabdar@Sun.COM /*
12177917SReza.Sabdar@Sun.COM * Error occurred decoding the header.
12187917SReza.Sabdar@Sun.COM * Don't send a reply since we don't know
12197917SReza.Sabdar@Sun.COM * the message or if the message was even
12207917SReza.Sabdar@Sun.COM * a request message. To be safe, assume
12217917SReza.Sabdar@Sun.COM * that the message was a reply if a reply
12227917SReza.Sabdar@Sun.COM * was expected. Need to do this to prevent
12237917SReza.Sabdar@Sun.COM * hanging ndmp_send_request() waiting for a
12247917SReza.Sabdar@Sun.COM * reply. Don't set reply_read so that the
12257917SReza.Sabdar@Sun.COM * reply will be processed if it is received
12267917SReza.Sabdar@Sun.COM * later.
12277917SReza.Sabdar@Sun.COM */
12287917SReza.Sabdar@Sun.COM if (reply_read == FALSE)
12297917SReza.Sabdar@Sun.COM reply_error = TRUE;
12307917SReza.Sabdar@Sun.COM
12317917SReza.Sabdar@Sun.COM continue;
12327917SReza.Sabdar@Sun.COM }
12337917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_hdr.message_type
12347917SReza.Sabdar@Sun.COM != NDMP_MESSAGE_REQUEST) {
12357917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "received reply: 0x%x",
12367917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
12377917SReza.Sabdar@Sun.COM
12387917SReza.Sabdar@Sun.COM if (reply_expected == FALSE ||
12397917SReza.Sabdar@Sun.COM reply_read == TRUE)
12407917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
12417917SReza.Sabdar@Sun.COM "Unexpected reply message: 0x%x",
12427917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.
12437917SReza.Sabdar@Sun.COM message);
12447917SReza.Sabdar@Sun.COM
12457917SReza.Sabdar@Sun.COM ndmp_free_message((ndmp_connection_t *)
12467917SReza.Sabdar@Sun.COM connection);
12477917SReza.Sabdar@Sun.COM
12487917SReza.Sabdar@Sun.COM if (reply_read == FALSE) {
12497917SReza.Sabdar@Sun.COM reply_read = TRUE;
12507917SReza.Sabdar@Sun.COM reply_error = TRUE;
12517917SReza.Sabdar@Sun.COM }
12527917SReza.Sabdar@Sun.COM continue;
12537917SReza.Sabdar@Sun.COM }
12547917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "received request: 0x%x",
12557917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
12567917SReza.Sabdar@Sun.COM
12577917SReza.Sabdar@Sun.COM (void) ndmp_send_response((ndmp_connection_t *)
12587917SReza.Sabdar@Sun.COM connection, err, NULL);
12597917SReza.Sabdar@Sun.COM ndmp_free_message((ndmp_connection_t *)connection);
12607917SReza.Sabdar@Sun.COM continue;
12617917SReza.Sabdar@Sun.COM }
12627917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_hdr.message_type
12637917SReza.Sabdar@Sun.COM != NDMP_MESSAGE_REQUEST) {
12647917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "received reply: 0x%x",
12657917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
12667917SReza.Sabdar@Sun.COM
12677917SReza.Sabdar@Sun.COM if (reply_expected == FALSE || reply_read == TRUE) {
12687917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG,
12697917SReza.Sabdar@Sun.COM "Unexpected reply message: 0x%x",
12707917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
12717917SReza.Sabdar@Sun.COM ndmp_free_message((ndmp_connection_t *)
12727917SReza.Sabdar@Sun.COM connection);
12737917SReza.Sabdar@Sun.COM continue;
12747917SReza.Sabdar@Sun.COM }
12757917SReza.Sabdar@Sun.COM reply_read = TRUE;
12767917SReza.Sabdar@Sun.COM reply_msginfo = connection->conn_msginfo;
12777917SReza.Sabdar@Sun.COM continue;
12787917SReza.Sabdar@Sun.COM }
12797917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "received request: 0x%x",
12807917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
12817917SReza.Sabdar@Sun.COM
12827917SReza.Sabdar@Sun.COM /*
12837917SReza.Sabdar@Sun.COM * The following is needed to catch an improperly constructed
12847917SReza.Sabdar@Sun.COM * handler table or to deal with an NDMP client that is not
12857917SReza.Sabdar@Sun.COM * conforming to the negotiated protocol version.
12867917SReza.Sabdar@Sun.COM */
12877917SReza.Sabdar@Sun.COM if (connection->conn_msginfo.mi_handler->mh_func == NULL) {
12887917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "No handler for message 0x%x",
12897917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_hdr.message);
12907917SReza.Sabdar@Sun.COM
12917917SReza.Sabdar@Sun.COM (void) ndmp_send_response((ndmp_connection_t *)
12927917SReza.Sabdar@Sun.COM connection, NDMP_NOT_SUPPORTED_ERR, NULL);
12937917SReza.Sabdar@Sun.COM ndmp_free_message((ndmp_connection_t *)connection);
12947917SReza.Sabdar@Sun.COM continue;
12957917SReza.Sabdar@Sun.COM }
12967917SReza.Sabdar@Sun.COM /*
12977917SReza.Sabdar@Sun.COM * Call the handler function.
12987917SReza.Sabdar@Sun.COM * The handler will send any necessary reply.
12997917SReza.Sabdar@Sun.COM */
13007917SReza.Sabdar@Sun.COM (*connection->conn_msginfo.mi_handler->mh_func) (connection,
13017917SReza.Sabdar@Sun.COM connection->conn_msginfo.mi_body);
13027917SReza.Sabdar@Sun.COM
13037917SReza.Sabdar@Sun.COM ndmp_free_message((ndmp_connection_t *)connection);
13047917SReza.Sabdar@Sun.COM
13057917SReza.Sabdar@Sun.COM } while (xdrrec_eof(&connection->conn_xdrs) == FALSE &&
13067917SReza.Sabdar@Sun.COM connection->conn_eof == FALSE);
13077917SReza.Sabdar@Sun.COM
13087917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "no more messages in stream buffer");
13097917SReza.Sabdar@Sun.COM
13107917SReza.Sabdar@Sun.COM if (connection->conn_eof == TRUE) {
13117917SReza.Sabdar@Sun.COM if (reply_msginfo.mi_body)
13127917SReza.Sabdar@Sun.COM free(reply_msginfo.mi_body);
13137917SReza.Sabdar@Sun.COM return (NDMP_PROC_ERR);
13147917SReza.Sabdar@Sun.COM }
13157917SReza.Sabdar@Sun.COM if (reply_error) {
13167917SReza.Sabdar@Sun.COM if (reply_msginfo.mi_body)
13177917SReza.Sabdar@Sun.COM free(reply_msginfo.mi_body);
13187917SReza.Sabdar@Sun.COM return (NDMP_PROC_REP_ERR);
13197917SReza.Sabdar@Sun.COM }
13207917SReza.Sabdar@Sun.COM if (reply_read) {
13217917SReza.Sabdar@Sun.COM connection->conn_msginfo = reply_msginfo;
13227917SReza.Sabdar@Sun.COM return (NDMP_PROC_MSG);
13237917SReza.Sabdar@Sun.COM }
13247917SReza.Sabdar@Sun.COM return (NDMP_PROC_REP);
13257917SReza.Sabdar@Sun.COM }
13267917SReza.Sabdar@Sun.COM
13277917SReza.Sabdar@Sun.COM
13287917SReza.Sabdar@Sun.COM /*
13297917SReza.Sabdar@Sun.COM * ndmp_get_interface
13307917SReza.Sabdar@Sun.COM *
13317917SReza.Sabdar@Sun.COM * Return the NDMP interface (e.g. config, scsi, tape) for the
13327917SReza.Sabdar@Sun.COM * specific message.
13337917SReza.Sabdar@Sun.COM *
13347917SReza.Sabdar@Sun.COM * Parameters:
13357917SReza.Sabdar@Sun.COM * message (input) - message number.
13367917SReza.Sabdar@Sun.COM *
13377917SReza.Sabdar@Sun.COM * Returns:
13387917SReza.Sabdar@Sun.COM * NULL - message not found.
13397917SReza.Sabdar@Sun.COM * pointer to handler info.
13407917SReza.Sabdar@Sun.COM */
13417917SReza.Sabdar@Sun.COM static ndmp_handler_t *
ndmp_get_interface(ndmp_message message)13427917SReza.Sabdar@Sun.COM ndmp_get_interface(ndmp_message message)
13437917SReza.Sabdar@Sun.COM {
13447917SReza.Sabdar@Sun.COM ndmp_handler_t *ni = &ndmp_msghdl_tab[(message >> 8) % INT_MAXCMD];
13457917SReza.Sabdar@Sun.COM
13467917SReza.Sabdar@Sun.COM if ((message & 0xff) >= ni->hd_cnt)
13477917SReza.Sabdar@Sun.COM return (NULL);
13487917SReza.Sabdar@Sun.COM
13497917SReza.Sabdar@Sun.COM /* Sanity check */
13507917SReza.Sabdar@Sun.COM if (ni->hd_msgs[message & 0xff].hm_message != message)
13517917SReza.Sabdar@Sun.COM return (NULL);
13527917SReza.Sabdar@Sun.COM
13537917SReza.Sabdar@Sun.COM return (ni);
13547917SReza.Sabdar@Sun.COM }
13557917SReza.Sabdar@Sun.COM
13567917SReza.Sabdar@Sun.COM /*
13577917SReza.Sabdar@Sun.COM * ndmp_get_handler
13587917SReza.Sabdar@Sun.COM *
13597917SReza.Sabdar@Sun.COM * Return the handler info for the specified NDMP message.
13607917SReza.Sabdar@Sun.COM *
13617917SReza.Sabdar@Sun.COM * Parameters:
13627917SReza.Sabdar@Sun.COM * connection (input) - connection pointer.
13637917SReza.Sabdar@Sun.COM * message (input) - message number.
13647917SReza.Sabdar@Sun.COM *
13657917SReza.Sabdar@Sun.COM * Returns:
13667917SReza.Sabdar@Sun.COM * NULL - message not found.
13677917SReza.Sabdar@Sun.COM * pointer to handler info.
13687917SReza.Sabdar@Sun.COM */
13697917SReza.Sabdar@Sun.COM static ndmp_msg_handler_t *
ndmp_get_handler(ndmp_connection_t * connection,ndmp_message message)13707917SReza.Sabdar@Sun.COM ndmp_get_handler(ndmp_connection_t *connection, ndmp_message message)
13717917SReza.Sabdar@Sun.COM {
13727917SReza.Sabdar@Sun.COM ndmp_msg_handler_t *handler = NULL;
13737917SReza.Sabdar@Sun.COM
13747917SReza.Sabdar@Sun.COM ndmp_handler_t *ni = ndmp_get_interface(message);
13757917SReza.Sabdar@Sun.COM int ver = connection->conn_version;
13767917SReza.Sabdar@Sun.COM
13777917SReza.Sabdar@Sun.COM if (ni)
13787917SReza.Sabdar@Sun.COM handler = &ni->hd_msgs[message & 0xff].hm_msg_v[ver - 2];
13797917SReza.Sabdar@Sun.COM
13807917SReza.Sabdar@Sun.COM return (handler);
13817917SReza.Sabdar@Sun.COM }
13827917SReza.Sabdar@Sun.COM
13837917SReza.Sabdar@Sun.COM /*
13847917SReza.Sabdar@Sun.COM * ndmp_check_auth_required
13857917SReza.Sabdar@Sun.COM *
13867917SReza.Sabdar@Sun.COM * Check if the connection needs to be authenticated before
13877917SReza.Sabdar@Sun.COM * this message is being processed.
13887917SReza.Sabdar@Sun.COM *
13897917SReza.Sabdar@Sun.COM * Parameters:
13907917SReza.Sabdar@Sun.COM * message (input) - message number.
13917917SReza.Sabdar@Sun.COM *
13927917SReza.Sabdar@Sun.COM * Returns:
13937917SReza.Sabdar@Sun.COM * TRUE - required
13947917SReza.Sabdar@Sun.COM * FALSE - not required
13957917SReza.Sabdar@Sun.COM */
13967917SReza.Sabdar@Sun.COM static boolean_t
ndmp_check_auth_required(ndmp_message message)13977917SReza.Sabdar@Sun.COM ndmp_check_auth_required(ndmp_message message)
13987917SReza.Sabdar@Sun.COM {
13997917SReza.Sabdar@Sun.COM boolean_t auth_req = FALSE;
14007917SReza.Sabdar@Sun.COM ndmp_handler_t *ni = ndmp_get_interface(message);
14017917SReza.Sabdar@Sun.COM
14027917SReza.Sabdar@Sun.COM if (ni)
14037917SReza.Sabdar@Sun.COM auth_req = ni->hd_msgs[message & 0xff].hm_auth_required;
14047917SReza.Sabdar@Sun.COM
14057917SReza.Sabdar@Sun.COM return (auth_req);
14067917SReza.Sabdar@Sun.COM }
14077917SReza.Sabdar@Sun.COM
14087917SReza.Sabdar@Sun.COM /*
14097917SReza.Sabdar@Sun.COM * tcp_accept
14107917SReza.Sabdar@Sun.COM *
14117917SReza.Sabdar@Sun.COM * A wrapper around accept for retrying and getting the IP address
14127917SReza.Sabdar@Sun.COM *
14137917SReza.Sabdar@Sun.COM * Parameters:
14147917SReza.Sabdar@Sun.COM * listen_sock (input) - the socket for listening
14157917SReza.Sabdar@Sun.COM * inaddr_p (output) - the IP address of peer connection
14167917SReza.Sabdar@Sun.COM *
14177917SReza.Sabdar@Sun.COM * Returns:
14187917SReza.Sabdar@Sun.COM * socket for the accepted connection
14197917SReza.Sabdar@Sun.COM * -1: error
14207917SReza.Sabdar@Sun.COM */
14217917SReza.Sabdar@Sun.COM int
tcp_accept(int listen_sock,unsigned int * inaddr_p)14227917SReza.Sabdar@Sun.COM tcp_accept(int listen_sock, unsigned int *inaddr_p)
14237917SReza.Sabdar@Sun.COM {
14247917SReza.Sabdar@Sun.COM struct sockaddr_in sin;
14257917SReza.Sabdar@Sun.COM int sock, i;
14267917SReza.Sabdar@Sun.COM int try;
14277917SReza.Sabdar@Sun.COM
14287917SReza.Sabdar@Sun.COM for (try = 0; try < 3; try++) {
14297917SReza.Sabdar@Sun.COM i = sizeof (sin);
14307917SReza.Sabdar@Sun.COM sock = accept(listen_sock, (struct sockaddr *)&sin, &i);
14317917SReza.Sabdar@Sun.COM if (sock < 0) {
14327917SReza.Sabdar@Sun.COM continue;
14337917SReza.Sabdar@Sun.COM }
14347917SReza.Sabdar@Sun.COM *inaddr_p = sin.sin_addr.s_addr;
14357917SReza.Sabdar@Sun.COM return (sock);
14367917SReza.Sabdar@Sun.COM }
14377917SReza.Sabdar@Sun.COM return (-1);
14387917SReza.Sabdar@Sun.COM }
14397917SReza.Sabdar@Sun.COM
14407917SReza.Sabdar@Sun.COM
14417917SReza.Sabdar@Sun.COM /*
14427917SReza.Sabdar@Sun.COM * tcp_get_peer
14437917SReza.Sabdar@Sun.COM *
14447917SReza.Sabdar@Sun.COM * Get the peer IP address for a connection
14457917SReza.Sabdar@Sun.COM *
14467917SReza.Sabdar@Sun.COM * Parameters:
14477917SReza.Sabdar@Sun.COM * sock (input) - the active socket
14487917SReza.Sabdar@Sun.COM * inaddr_p (output) - the IP address of peer connection
14497917SReza.Sabdar@Sun.COM * port_p (output) - the port number of peer connection
14507917SReza.Sabdar@Sun.COM *
14517917SReza.Sabdar@Sun.COM * Returns:
14527917SReza.Sabdar@Sun.COM * socket for the accepted connection
14537917SReza.Sabdar@Sun.COM * -1: error
14547917SReza.Sabdar@Sun.COM */
14557917SReza.Sabdar@Sun.COM int
tcp_get_peer(int sock,unsigned int * inaddr_p,int * port_p)14567917SReza.Sabdar@Sun.COM tcp_get_peer(int sock, unsigned int *inaddr_p, int *port_p)
14577917SReza.Sabdar@Sun.COM {
14587917SReza.Sabdar@Sun.COM struct sockaddr_in sin;
14597917SReza.Sabdar@Sun.COM int i, rc;
14607917SReza.Sabdar@Sun.COM
14617917SReza.Sabdar@Sun.COM i = sizeof (sin);
14627917SReza.Sabdar@Sun.COM rc = getpeername(sock, (struct sockaddr *)&sin, &i);
14637917SReza.Sabdar@Sun.COM if (rc != 0)
14647917SReza.Sabdar@Sun.COM return (-1);
14657917SReza.Sabdar@Sun.COM
14667917SReza.Sabdar@Sun.COM if (inaddr_p)
14677917SReza.Sabdar@Sun.COM *inaddr_p = sin.sin_addr.s_addr;
14687917SReza.Sabdar@Sun.COM
14697917SReza.Sabdar@Sun.COM if (port_p)
14707917SReza.Sabdar@Sun.COM *port_p = ntohs(sin.sin_port);
14717917SReza.Sabdar@Sun.COM
14727917SReza.Sabdar@Sun.COM return (sock);
14737917SReza.Sabdar@Sun.COM
14747917SReza.Sabdar@Sun.COM }
14757917SReza.Sabdar@Sun.COM
14767917SReza.Sabdar@Sun.COM /*
14777917SReza.Sabdar@Sun.COM * gethostaddr
14787917SReza.Sabdar@Sun.COM *
14797917SReza.Sabdar@Sun.COM * Get the IP address string of the current host
14807917SReza.Sabdar@Sun.COM *
14817917SReza.Sabdar@Sun.COM * Parameters:
14827917SReza.Sabdar@Sun.COM * void
14837917SReza.Sabdar@Sun.COM *
14847917SReza.Sabdar@Sun.COM * Returns:
14857917SReza.Sabdar@Sun.COM * IP address
14867917SReza.Sabdar@Sun.COM * NULL: error
14877917SReza.Sabdar@Sun.COM */
14887917SReza.Sabdar@Sun.COM char *
gethostaddr(void)14897917SReza.Sabdar@Sun.COM gethostaddr(void)
14907917SReza.Sabdar@Sun.COM {
14917917SReza.Sabdar@Sun.COM static char s[MAXHOSTNAMELEN];
14927917SReza.Sabdar@Sun.COM struct hostent *h;
14937917SReza.Sabdar@Sun.COM struct in_addr in;
14947917SReza.Sabdar@Sun.COM char *p;
14957917SReza.Sabdar@Sun.COM
14967917SReza.Sabdar@Sun.COM if (gethostname(s, sizeof (s)) == -1)
14977917SReza.Sabdar@Sun.COM return (NULL);
14987917SReza.Sabdar@Sun.COM
14997917SReza.Sabdar@Sun.COM if ((h = gethostbyname(s)) == NULL)
15007917SReza.Sabdar@Sun.COM return (NULL);
15017917SReza.Sabdar@Sun.COM
15027917SReza.Sabdar@Sun.COM p = h->h_addr_list[0];
15037917SReza.Sabdar@Sun.COM (void) memcpy(&in.s_addr, p, sizeof (in.s_addr));
15047917SReza.Sabdar@Sun.COM return (inet_ntoa(in));
15057917SReza.Sabdar@Sun.COM }
15067917SReza.Sabdar@Sun.COM
1507*13023SReza.Sabdar@Sun.COM
1508*13023SReza.Sabdar@Sun.COM /*
1509*13023SReza.Sabdar@Sun.COM * get_default_nic_addr
1510*13023SReza.Sabdar@Sun.COM *
1511*13023SReza.Sabdar@Sun.COM * Get the IP address of the default NIC
1512*13023SReza.Sabdar@Sun.COM */
1513*13023SReza.Sabdar@Sun.COM char *
get_default_nic_addr(void)1514*13023SReza.Sabdar@Sun.COM get_default_nic_addr(void)
1515*13023SReza.Sabdar@Sun.COM {
1516*13023SReza.Sabdar@Sun.COM struct ifaddrlist *al = NULL;
1517*13023SReza.Sabdar@Sun.COM char errmsg[ERRBUFSIZE];
1518*13023SReza.Sabdar@Sun.COM struct in_addr addr;
1519*13023SReza.Sabdar@Sun.COM int nifs;
1520*13023SReza.Sabdar@Sun.COM
1521*13023SReza.Sabdar@Sun.COM nifs = ifaddrlist(&al, AF_INET, LIFC_EXTERNAL_SOURCE, errmsg);
1522*13023SReza.Sabdar@Sun.COM if (nifs <= 0)
1523*13023SReza.Sabdar@Sun.COM return (NULL);
1524*13023SReza.Sabdar@Sun.COM
1525*13023SReza.Sabdar@Sun.COM /* pick the first interface's address */
1526*13023SReza.Sabdar@Sun.COM addr = al[0].addr.addr;
1527*13023SReza.Sabdar@Sun.COM free(al);
1528*13023SReza.Sabdar@Sun.COM
1529*13023SReza.Sabdar@Sun.COM return (inet_ntoa(IN_ADDR(addr.s_addr)));
1530*13023SReza.Sabdar@Sun.COM }
1531*13023SReza.Sabdar@Sun.COM
1532*13023SReza.Sabdar@Sun.COM
15337917SReza.Sabdar@Sun.COM /*
15347917SReza.Sabdar@Sun.COM * ndmpd_audit_backup
15357917SReza.Sabdar@Sun.COM *
15367917SReza.Sabdar@Sun.COM * Generate AUE_ndmp_backup audit record
15377917SReza.Sabdar@Sun.COM */
15387917SReza.Sabdar@Sun.COM /*ARGSUSED*/
15397917SReza.Sabdar@Sun.COM void
ndmpd_audit_backup(ndmp_connection_t * conn,char * path,int dest,char * local_path,int result)15407917SReza.Sabdar@Sun.COM ndmpd_audit_backup(ndmp_connection_t *conn,
15417917SReza.Sabdar@Sun.COM char *path, int dest, char *local_path, int result)
15427917SReza.Sabdar@Sun.COM {
15437917SReza.Sabdar@Sun.COM adt_event_data_t *event;
15447917SReza.Sabdar@Sun.COM
15457917SReza.Sabdar@Sun.COM if ((event = adt_alloc_event(conn->conn_ah, ADT_ndmp_backup)) == NULL) {
15467917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
15477917SReza.Sabdar@Sun.COM return;
15487917SReza.Sabdar@Sun.COM }
15497917SReza.Sabdar@Sun.COM event->adt_ndmp_backup.source = path;
15507917SReza.Sabdar@Sun.COM
15517917SReza.Sabdar@Sun.COM if (dest == NDMP_ADDR_LOCAL) {
15527917SReza.Sabdar@Sun.COM event->adt_ndmp_backup.local_dest = local_path;
15537917SReza.Sabdar@Sun.COM } else {
15547917SReza.Sabdar@Sun.COM event->adt_ndmp_backup.remote_dest = conn->conn_sock;
15557917SReza.Sabdar@Sun.COM }
15567917SReza.Sabdar@Sun.COM
15577917SReza.Sabdar@Sun.COM if (result == 0) {
15587917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
15597917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
15607917SReza.Sabdar@Sun.COM } else {
15617917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_FAILURE, result) != 0)
15627917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
15637917SReza.Sabdar@Sun.COM }
15647917SReza.Sabdar@Sun.COM
15657917SReza.Sabdar@Sun.COM adt_free_event(event);
15667917SReza.Sabdar@Sun.COM }
15677917SReza.Sabdar@Sun.COM
15687917SReza.Sabdar@Sun.COM
15697917SReza.Sabdar@Sun.COM /*
15707917SReza.Sabdar@Sun.COM * ndmpd_audit_restore
15717917SReza.Sabdar@Sun.COM *
15727917SReza.Sabdar@Sun.COM * Generate AUE_ndmp_restore audit record
15737917SReza.Sabdar@Sun.COM */
15747917SReza.Sabdar@Sun.COM /*ARGSUSED*/
15757917SReza.Sabdar@Sun.COM void
ndmpd_audit_restore(ndmp_connection_t * conn,char * path,int dest,char * local_path,int result)15767917SReza.Sabdar@Sun.COM ndmpd_audit_restore(ndmp_connection_t *conn,
15777917SReza.Sabdar@Sun.COM char *path, int dest, char *local_path, int result)
15787917SReza.Sabdar@Sun.COM {
15797917SReza.Sabdar@Sun.COM adt_event_data_t *event;
15807917SReza.Sabdar@Sun.COM
15817917SReza.Sabdar@Sun.COM if ((event = adt_alloc_event(conn->conn_ah,
15827917SReza.Sabdar@Sun.COM ADT_ndmp_restore)) == NULL) {
15837917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
15847917SReza.Sabdar@Sun.COM return;
15857917SReza.Sabdar@Sun.COM }
15867917SReza.Sabdar@Sun.COM event->adt_ndmp_restore.destination = path;
15877917SReza.Sabdar@Sun.COM
15887917SReza.Sabdar@Sun.COM if (dest == NDMP_ADDR_LOCAL) {
15897917SReza.Sabdar@Sun.COM event->adt_ndmp_restore.local_source = local_path;
15907917SReza.Sabdar@Sun.COM } else {
15917917SReza.Sabdar@Sun.COM event->adt_ndmp_restore.remote_source = conn->conn_sock;
15927917SReza.Sabdar@Sun.COM }
15937917SReza.Sabdar@Sun.COM
15947917SReza.Sabdar@Sun.COM if (result == 0) {
15957917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
15967917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
15977917SReza.Sabdar@Sun.COM } else {
15987917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_FAILURE, result) != 0)
15997917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16007917SReza.Sabdar@Sun.COM }
16017917SReza.Sabdar@Sun.COM
16027917SReza.Sabdar@Sun.COM adt_free_event(event);
16037917SReza.Sabdar@Sun.COM }
16047917SReza.Sabdar@Sun.COM
16057917SReza.Sabdar@Sun.COM
16067917SReza.Sabdar@Sun.COM /*
16077917SReza.Sabdar@Sun.COM * ndmpd_audit_connect
16087917SReza.Sabdar@Sun.COM *
16097917SReza.Sabdar@Sun.COM * Generate AUE_ndmp_connect audit record
16107917SReza.Sabdar@Sun.COM */
16117917SReza.Sabdar@Sun.COM /*ARGSUSED*/
16127917SReza.Sabdar@Sun.COM void
ndmpd_audit_connect(ndmp_connection_t * conn,int result)16137917SReza.Sabdar@Sun.COM ndmpd_audit_connect(ndmp_connection_t *conn, int result)
16147917SReza.Sabdar@Sun.COM {
16157917SReza.Sabdar@Sun.COM adt_event_data_t *event;
16167917SReza.Sabdar@Sun.COM adt_termid_t *termid;
16177917SReza.Sabdar@Sun.COM
16187917SReza.Sabdar@Sun.COM if (adt_load_termid(conn->conn_sock, &termid) != 0) {
16197917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16207917SReza.Sabdar@Sun.COM return;
16217917SReza.Sabdar@Sun.COM }
16227917SReza.Sabdar@Sun.COM
16237917SReza.Sabdar@Sun.COM if (adt_set_user(conn->conn_ah, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
16247917SReza.Sabdar@Sun.COM ADT_NO_ATTRIB, ADT_NO_ATTRIB, termid, ADT_NEW) != 0) {
16257917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16267917SReza.Sabdar@Sun.COM free(termid);
16277917SReza.Sabdar@Sun.COM return;
16287917SReza.Sabdar@Sun.COM }
16297917SReza.Sabdar@Sun.COM free(termid);
16307917SReza.Sabdar@Sun.COM
16317917SReza.Sabdar@Sun.COM if ((event = adt_alloc_event(conn->conn_ah,
16327917SReza.Sabdar@Sun.COM ADT_ndmp_connect)) == NULL) {
16337917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16347917SReza.Sabdar@Sun.COM return;
16357917SReza.Sabdar@Sun.COM }
16367917SReza.Sabdar@Sun.COM
16377917SReza.Sabdar@Sun.COM if (result == 0) {
16387917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
16397917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16407917SReza.Sabdar@Sun.COM } else {
16417917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_FAILURE, result) != 0)
16427917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16437917SReza.Sabdar@Sun.COM }
16447917SReza.Sabdar@Sun.COM
16457917SReza.Sabdar@Sun.COM adt_free_event(event);
16467917SReza.Sabdar@Sun.COM }
16477917SReza.Sabdar@Sun.COM
16487917SReza.Sabdar@Sun.COM
16497917SReza.Sabdar@Sun.COM /*
16507917SReza.Sabdar@Sun.COM * ndmpd_audit_disconnect
16517917SReza.Sabdar@Sun.COM *
16527917SReza.Sabdar@Sun.COM * Generate AUE_ndmp_disconnect audit record
16537917SReza.Sabdar@Sun.COM */
16547917SReza.Sabdar@Sun.COM /*ARGSUSED*/
16557917SReza.Sabdar@Sun.COM void
ndmpd_audit_disconnect(ndmp_connection_t * conn)16567917SReza.Sabdar@Sun.COM ndmpd_audit_disconnect(ndmp_connection_t *conn)
16577917SReza.Sabdar@Sun.COM {
16587917SReza.Sabdar@Sun.COM adt_event_data_t *event;
16597917SReza.Sabdar@Sun.COM
16607917SReza.Sabdar@Sun.COM if ((event = adt_alloc_event(conn->conn_ah,
16617917SReza.Sabdar@Sun.COM ADT_ndmp_disconnect)) == NULL) {
16627917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16637917SReza.Sabdar@Sun.COM return;
16647917SReza.Sabdar@Sun.COM }
16657917SReza.Sabdar@Sun.COM if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
16667917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Audit failure: %m.");
16677917SReza.Sabdar@Sun.COM
16687917SReza.Sabdar@Sun.COM adt_free_event(event);
16697917SReza.Sabdar@Sun.COM }
16707917SReza.Sabdar@Sun.COM
16717917SReza.Sabdar@Sun.COM void *
ndmp_malloc(size_t size)16727917SReza.Sabdar@Sun.COM ndmp_malloc(size_t size)
16737917SReza.Sabdar@Sun.COM {
16747917SReza.Sabdar@Sun.COM void *data;
16757917SReza.Sabdar@Sun.COM
16767917SReza.Sabdar@Sun.COM if ((data = calloc(1, size)) == NULL) {
16777917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Out of memory.");
16787917SReza.Sabdar@Sun.COM }
16797917SReza.Sabdar@Sun.COM
16807917SReza.Sabdar@Sun.COM return (data);
16817917SReza.Sabdar@Sun.COM }
168212186SJanice.Chang@Sun.COM
168312186SJanice.Chang@Sun.COM /*
168412186SJanice.Chang@Sun.COM * get_backup_path_v3
168512186SJanice.Chang@Sun.COM *
168612186SJanice.Chang@Sun.COM * Get the backup path from the NDMP environment variables.
168712186SJanice.Chang@Sun.COM *
168812186SJanice.Chang@Sun.COM * Parameters:
168912186SJanice.Chang@Sun.COM * params (input) - pointer to the parameters structure.
169012186SJanice.Chang@Sun.COM *
169112186SJanice.Chang@Sun.COM * Returns:
169212186SJanice.Chang@Sun.COM * The backup path: if anything is specified
169312186SJanice.Chang@Sun.COM * NULL: Otherwise
169412186SJanice.Chang@Sun.COM */
169512186SJanice.Chang@Sun.COM char *
get_backup_path_v3(ndmpd_module_params_t * params)169612186SJanice.Chang@Sun.COM get_backup_path_v3(ndmpd_module_params_t *params)
169712186SJanice.Chang@Sun.COM {
169812186SJanice.Chang@Sun.COM char *bkpath;
169912186SJanice.Chang@Sun.COM
170012186SJanice.Chang@Sun.COM bkpath = MOD_GETENV(params, "PREFIX");
170112186SJanice.Chang@Sun.COM if (!bkpath)
170212186SJanice.Chang@Sun.COM bkpath = MOD_GETENV(params, "FILESYSTEM");
170312186SJanice.Chang@Sun.COM
170412186SJanice.Chang@Sun.COM
170512186SJanice.Chang@Sun.COM if (!bkpath) {
170612186SJanice.Chang@Sun.COM MOD_LOGV3(params, NDMP_LOG_ERROR,
170712186SJanice.Chang@Sun.COM "Backup path not defined.\n");
170812186SJanice.Chang@Sun.COM } else {
170912186SJanice.Chang@Sun.COM NDMP_LOG(LOG_DEBUG, "bkpath: \"%s\"", bkpath);
171012186SJanice.Chang@Sun.COM }
171112186SJanice.Chang@Sun.COM
171212186SJanice.Chang@Sun.COM return (bkpath);
171312186SJanice.Chang@Sun.COM }
171412186SJanice.Chang@Sun.COM
171512186SJanice.Chang@Sun.COM /*
171612186SJanice.Chang@Sun.COM * get_backup_path
171712186SJanice.Chang@Sun.COM *
171812186SJanice.Chang@Sun.COM * Find the backup path from the environment variables (v2)
171912186SJanice.Chang@Sun.COM */
172012186SJanice.Chang@Sun.COM char *
get_backup_path_v2(ndmpd_module_params_t * params)172112186SJanice.Chang@Sun.COM get_backup_path_v2(ndmpd_module_params_t *params)
172212186SJanice.Chang@Sun.COM {
172312186SJanice.Chang@Sun.COM char *bkpath;
172412186SJanice.Chang@Sun.COM
172512186SJanice.Chang@Sun.COM bkpath = MOD_GETENV(params, "PREFIX");
172612186SJanice.Chang@Sun.COM if (bkpath == NULL)
172712186SJanice.Chang@Sun.COM bkpath = MOD_GETENV(params, "FILESYSTEM");
172812186SJanice.Chang@Sun.COM
172912186SJanice.Chang@Sun.COM if (bkpath == NULL) {
173012186SJanice.Chang@Sun.COM MOD_LOG(params, "Error: restore path not specified.\n");
173112186SJanice.Chang@Sun.COM return (NULL);
173212186SJanice.Chang@Sun.COM }
173312186SJanice.Chang@Sun.COM
173412186SJanice.Chang@Sun.COM if (*bkpath != '/') {
173512186SJanice.Chang@Sun.COM MOD_LOG(params, "Error: relative backup path not allowed.\n");
173612186SJanice.Chang@Sun.COM return (NULL);
173712186SJanice.Chang@Sun.COM }
173812186SJanice.Chang@Sun.COM
173912186SJanice.Chang@Sun.COM return (bkpath);
174012186SJanice.Chang@Sun.COM }
1741