12654012fSReza Sabdar /* 2*8c4f9701SJanice Chang * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 32654012fSReza Sabdar */ 42654012fSReza Sabdar 52654012fSReza Sabdar /* 62654012fSReza Sabdar * BSD 3 Clause License 72654012fSReza Sabdar * 82654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 92654012fSReza Sabdar * 102654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 112654012fSReza Sabdar * modification, are permitted provided that the following conditions 122654012fSReza Sabdar * are met: 132654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 142654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 152654012fSReza Sabdar * 162654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 172654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 182654012fSReza Sabdar * the documentation and/or other materials provided with the 192654012fSReza Sabdar * distribution. 202654012fSReza Sabdar * 212654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 222654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 232654012fSReza Sabdar * products derived from this software without specific prior written 242654012fSReza Sabdar * permission. 252654012fSReza Sabdar * 262654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 272654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 282654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 292654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 302654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 312654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 322654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 332654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 342654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 352654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 362654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 372654012fSReza Sabdar */ 382654012fSReza Sabdar /* Copyright (c) 2007, The Storage Networking Industry Association. */ 392654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */ 402654012fSReza Sabdar 412654012fSReza Sabdar #include <sys/types.h> 422654012fSReza Sabdar #include <sys/socket.h> 432654012fSReza Sabdar #include <assert.h> 442654012fSReza Sabdar #include <ctype.h> 452654012fSReza Sabdar #include <errno.h> 462654012fSReza Sabdar #include <stdio.h> 472654012fSReza Sabdar #include <stdlib.h> 482654012fSReza Sabdar #include <unistd.h> 492654012fSReza Sabdar #include <strings.h> 502654012fSReza Sabdar #include <time.h> 512654012fSReza Sabdar #include "ndmpd.h" 522654012fSReza Sabdar #include <bitmap.h> 532654012fSReza Sabdar #include <sys/queue.h> 542654012fSReza Sabdar #include <sys/socket.h> 552654012fSReza Sabdar #include <netinet/in.h> 562654012fSReza Sabdar #include <netinet/tcp.h> 572654012fSReza Sabdar #include <arpa/inet.h> 582654012fSReza Sabdar #include <sys/socketvar.h> 592654012fSReza Sabdar #include <net/if.h> 602654012fSReza Sabdar #include <netdb.h> 612654012fSReza Sabdar #include <sys/filio.h> 622654012fSReza Sabdar #include <sys/mtio.h> 632654012fSReza Sabdar #include <sys/scsi/impl/uscsi.h> 642654012fSReza Sabdar #include <sys/scsi/scsi.h> 652654012fSReza Sabdar #include "tlm.h" 662654012fSReza Sabdar 672654012fSReza Sabdar /* 682654012fSReza Sabdar * Mutex to protect Nlp 692654012fSReza Sabdar */ 702654012fSReza Sabdar mutex_t nlp_mtx; 712654012fSReza Sabdar 722654012fSReza Sabdar /* 732654012fSReza Sabdar * Patchable socket buffer sizes in kilobytes. 742654012fSReza Sabdar * ssb: send buffer size. 752654012fSReza Sabdar * rsb: receive buffer size. 762654012fSReza Sabdar */ 772654012fSReza Sabdar int ndmp_sbs = 60; 782654012fSReza Sabdar int ndmp_rbs = 60; 792654012fSReza Sabdar 802654012fSReza Sabdar 812654012fSReza Sabdar /* 822654012fSReza Sabdar * Force to backup all the intermediate directories leading to an object 832654012fSReza Sabdar * to be backed up in 'dump' format backup. 842654012fSReza Sabdar */ 852654012fSReza Sabdar boolean_t ndmp_dump_path_node = FALSE; 862654012fSReza Sabdar 872654012fSReza Sabdar 882654012fSReza Sabdar /* 892654012fSReza Sabdar * Force to backup all the intermediate directories leading to an object 902654012fSReza Sabdar * to be backed up in 'tar' format backup. 912654012fSReza Sabdar */ 922654012fSReza Sabdar boolean_t ndmp_tar_path_node = FALSE; 932654012fSReza Sabdar 942654012fSReza Sabdar 952654012fSReza Sabdar /* 962654012fSReza Sabdar * Should the 'st_ctime' be ignored during incremental level backup? 972654012fSReza Sabdar */ 982654012fSReza Sabdar boolean_t ndmp_ignore_ctime = FALSE; 992654012fSReza Sabdar 1002654012fSReza Sabdar /* 1012654012fSReza Sabdar * Should the 'st_lmtime' be included during incremental level backup? 1022654012fSReza Sabdar */ 1032654012fSReza Sabdar boolean_t ndmp_include_lmtime = FALSE; 1042654012fSReza Sabdar 1052654012fSReza Sabdar /* 1062654012fSReza Sabdar * Force to send the file history node entries along with the file history 1072654012fSReza Sabdar * dir entries for all directories containing the changed files to the client 1082654012fSReza Sabdar * for incremental backup. 1092654012fSReza Sabdar * 1102654012fSReza Sabdar * Note: This variable is added to support Bakbone Software's Netvault DMA 1112654012fSReza Sabdar * which expects to get the FH ADD NODES for all upper directories which 1122654012fSReza Sabdar * contain the changed files in incremental backup along with the FH ADD DIRS. 1132654012fSReza Sabdar */ 1142654012fSReza Sabdar boolean_t ndmp_fhinode = FALSE; 1152654012fSReza Sabdar 1162654012fSReza Sabdar /* 1172654012fSReza Sabdar * Maximum permitted sequence number in the token-based backup. The 1182654012fSReza Sabdar * value of this variable can be changed by the administrator and is 1192654012fSReza Sabdar * saved in the NDMP configuration file. 1202654012fSReza Sabdar */ 1212654012fSReza Sabdar static int ndmp_max_tok_seq = NDMP_MAX_TOKSEQ; 1222654012fSReza Sabdar 1232654012fSReza Sabdar /* 1242654012fSReza Sabdar * Force backup directories in incremental backups. If the 1252654012fSReza Sabdar * directory is not modified itself, it's not backed up by 1262654012fSReza Sabdar * default. 1272654012fSReza Sabdar */ 1282654012fSReza Sabdar int ndmp_force_bk_dirs = 0; 1292654012fSReza Sabdar 1302654012fSReza Sabdar /* 1312654012fSReza Sabdar * Keeps track of the open SCSI (including tape and robot) devices. 1322654012fSReza Sabdar * When a SCSI device is opened its name must be added to this list and 1332654012fSReza Sabdar * when it's closed its name must be removed from this list. The main 1342654012fSReza Sabdar * purpose of this list is the robot device. If the robot devices are not 1352654012fSReza Sabdar * attached in SASD layer, Local Backup won't see them. If they are 1362654012fSReza Sabdar * attached and we open the robot devices, then wrong commands are sent 1372654012fSReza Sabdar * to robot by SASD since it assumes that the robot is a tape (sequential 1382654012fSReza Sabdar * access) device. 1392654012fSReza Sabdar */ 1402654012fSReza Sabdar struct open_list { 1412654012fSReza Sabdar LIST_ENTRY(open_list) ol_q; 1422654012fSReza Sabdar int ol_nref; 1432654012fSReza Sabdar char *ol_devnm; 1442654012fSReza Sabdar int ol_sid; 1452654012fSReza Sabdar int ol_lun; 1462654012fSReza Sabdar int ol_fd; 1472654012fSReza Sabdar ndmp_connection_t *cl_conn; 1482654012fSReza Sabdar }; 1492654012fSReza Sabdar LIST_HEAD(ol_head, open_list); 1502654012fSReza Sabdar 1512654012fSReza Sabdar 1522654012fSReza Sabdar /* 1532654012fSReza Sabdar * Head of the opened SCSI devices list. 1542654012fSReza Sabdar */ 1552654012fSReza Sabdar static struct ol_head ol_head; 1562654012fSReza Sabdar 1572654012fSReza Sabdar mutex_t ol_mutex = DEFAULTMUTEX; 1582654012fSReza Sabdar 1592654012fSReza Sabdar 1602654012fSReza Sabdar /* 1612654012fSReza Sabdar * List of things to be exluded from backup. 1622654012fSReza Sabdar */ 1632654012fSReza Sabdar static char *exls[] = { 1642654012fSReza Sabdar EXCL_PROC, 1652654012fSReza Sabdar EXCL_TMP, 1662654012fSReza Sabdar NULL, /* reserved for a copy of the "backup.directory" */ 1672654012fSReza Sabdar NULL 1682654012fSReza Sabdar }; 1692654012fSReza Sabdar 1702654012fSReza Sabdar 1712654012fSReza Sabdar /* 1722654012fSReza Sabdar * The counter for creating unique names with "ndmp.%d" format. 1732654012fSReza Sabdar */ 1742654012fSReza Sabdar #define NDMP_RCF_BASENAME "ndmp." 1752654012fSReza Sabdar static int ndmp_job_cnt = 0; 1762654012fSReza Sabdar 1772654012fSReza Sabdar static int scsi_test_unit_ready(int dev_id); 1782654012fSReza Sabdar 1792654012fSReza Sabdar /* 1802654012fSReza Sabdar * ndmpd_add_file_handler 1812654012fSReza Sabdar * 1822654012fSReza Sabdar * Adds a file handler to the file handler list. 1832654012fSReza Sabdar * The file handler list is used by ndmpd_api_dispatch. 1842654012fSReza Sabdar * 1852654012fSReza Sabdar * Parameters: 1862654012fSReza Sabdar * session (input) - session pointer. 1872654012fSReza Sabdar * cookie (input) - opaque data to be passed to file hander when called. 1882654012fSReza Sabdar * fd (input) - file descriptor. 1892654012fSReza Sabdar * mode (input) - bitmask of the following: 1902654012fSReza Sabdar * 1 = watch file for ready for reading 1912654012fSReza Sabdar * 2 = watch file for ready for writing 1922654012fSReza Sabdar * 4 = watch file for exception 1932654012fSReza Sabdar * class (input) - handler class. (HC_CLIENT, HC_MOVER, HC_MODULE) 1942654012fSReza Sabdar * func (input) - function to call when the file meets one of the 1952654012fSReza Sabdar * conditions specified by mode. 1962654012fSReza Sabdar * 1972654012fSReza Sabdar * Returns: 1982654012fSReza Sabdar * 0 - success. 1992654012fSReza Sabdar * -1 - error. 2002654012fSReza Sabdar */ 2012654012fSReza Sabdar int 2022654012fSReza Sabdar ndmpd_add_file_handler(ndmpd_session_t *session, void *cookie, int fd, 2032654012fSReza Sabdar ulong_t mode, ulong_t class, ndmpd_file_handler_func_t *func) 2042654012fSReza Sabdar { 2052654012fSReza Sabdar ndmpd_file_handler_t *new; 2062654012fSReza Sabdar 2072654012fSReza Sabdar new = ndmp_malloc(sizeof (ndmpd_file_handler_t)); 2082654012fSReza Sabdar if (new == 0) 2092654012fSReza Sabdar return (-1); 2102654012fSReza Sabdar 2112654012fSReza Sabdar new->fh_cookie = cookie; 2122654012fSReza Sabdar new->fh_fd = fd; 2132654012fSReza Sabdar new->fh_mode = mode; 2142654012fSReza Sabdar new->fh_class = class; 2152654012fSReza Sabdar new->fh_func = func; 2162654012fSReza Sabdar new->fh_next = session->ns_file_handler_list; 2172654012fSReza Sabdar session->ns_file_handler_list = new; 2182654012fSReza Sabdar return (0); 2192654012fSReza Sabdar } 2202654012fSReza Sabdar 2212654012fSReza Sabdar 2222654012fSReza Sabdar /* 2232654012fSReza Sabdar * ndmpd_remove_file_handler 2242654012fSReza Sabdar * 2252654012fSReza Sabdar * Removes a file handler from the file handler list. 2262654012fSReza Sabdar * 2272654012fSReza Sabdar * Parameters: 2282654012fSReza Sabdar * session (input) - session pointer. 2292654012fSReza Sabdar * fd (input) - file descriptor. 2302654012fSReza Sabdar * 2312654012fSReza Sabdar * Returns: 2322654012fSReza Sabdar * 0 - success. 2332654012fSReza Sabdar * -1 - error. 2342654012fSReza Sabdar */ 2352654012fSReza Sabdar int 2362654012fSReza Sabdar ndmpd_remove_file_handler(ndmpd_session_t *session, int fd) 2372654012fSReza Sabdar { 2382654012fSReza Sabdar ndmpd_file_handler_t **last; 2392654012fSReza Sabdar ndmpd_file_handler_t *handler; 2402654012fSReza Sabdar 2412654012fSReza Sabdar last = &session->ns_file_handler_list; 2422654012fSReza Sabdar while (*last != 0) { 2432654012fSReza Sabdar handler = *last; 2442654012fSReza Sabdar 2452654012fSReza Sabdar if (handler->fh_fd == fd) { 2462654012fSReza Sabdar *last = handler->fh_next; 2472654012fSReza Sabdar (void) free(handler); 2482654012fSReza Sabdar return (1); 2492654012fSReza Sabdar } 2502654012fSReza Sabdar last = &handler->fh_next; 2512654012fSReza Sabdar } 2522654012fSReza Sabdar 2532654012fSReza Sabdar return (0); 2542654012fSReza Sabdar } 2552654012fSReza Sabdar 2562654012fSReza Sabdar 2572654012fSReza Sabdar /* 2582654012fSReza Sabdar * ndmp_connection_closed 2592654012fSReza Sabdar * 2602654012fSReza Sabdar * If the connection closed or not. 2612654012fSReza Sabdar * 2622654012fSReza Sabdar * Parameters: 2632654012fSReza Sabdar * fd (input) : file descriptor 2642654012fSReza Sabdar * 2652654012fSReza Sabdar * Returns: 2662654012fSReza Sabdar * 0 - connection is still valid 2672654012fSReza Sabdar * 1 - connection is not valid anymore 2682654012fSReza Sabdar * -1 - Internal kernel error 2692654012fSReza Sabdar */ 2702654012fSReza Sabdar int 2712654012fSReza Sabdar ndmp_connection_closed(int fd) 2722654012fSReza Sabdar { 2732654012fSReza Sabdar fd_set fds; 2742654012fSReza Sabdar int closed, ret; 2752654012fSReza Sabdar struct timeval timeout; 2762654012fSReza Sabdar 2772654012fSReza Sabdar if (fd < 0) /* We are not using the mover */ 2782654012fSReza Sabdar return (-1); 2792654012fSReza Sabdar 2802654012fSReza Sabdar timeout.tv_sec = 0; 2812654012fSReza Sabdar timeout.tv_usec = 1000; 2822654012fSReza Sabdar 2832654012fSReza Sabdar FD_ZERO(&fds); 2842654012fSReza Sabdar FD_SET(fd, &fds); 2852654012fSReza Sabdar ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); 2862654012fSReza Sabdar 2872654012fSReza Sabdar closed = (ret == -1 && errno == EBADF); 2882654012fSReza Sabdar 2892654012fSReza Sabdar return (closed); 2902654012fSReza Sabdar } 2912654012fSReza Sabdar 2922654012fSReza Sabdar /* 2932654012fSReza Sabdar * ndmp_check_mover_state 2942654012fSReza Sabdar * 2952654012fSReza Sabdar * Checks the mover connection status and sends an appropriate 2962654012fSReza Sabdar * NDMP message to client based on that. 2972654012fSReza Sabdar * 2982654012fSReza Sabdar * Parameters: 2992654012fSReza Sabdar * ndmpd_session_t *session (input) : session pointer 3002654012fSReza Sabdar * 3012654012fSReza Sabdar * Returns: 3022654012fSReza Sabdar * void. 3032654012fSReza Sabdar */ 3042654012fSReza Sabdar void 3052654012fSReza Sabdar ndmp_check_mover_state(ndmpd_session_t *session) 3062654012fSReza Sabdar { 3072654012fSReza Sabdar int moverfd; 3082654012fSReza Sabdar /* 3092654012fSReza Sabdar * NDMPV3 Spec (Three-way restore): 3102654012fSReza Sabdar * Once all of the files have been recovered, NDMP DATA Server closes 3112654012fSReza Sabdar * the connection to the mover on the NDMP TAPE Server. THEN 3122654012fSReza Sabdar * The NDMP client should receive an NDMP_NOTIFY_MOVER_HALTED message 3132654012fSReza Sabdar * with an NDMP_MOVER_CONNECT_CLOSED reason from the NDMP TAPE Server 3142654012fSReza Sabdar */ 3152654012fSReza Sabdar moverfd = session->ns_mover.md_sock; 3162654012fSReza Sabdar /* If connection is closed by the peer */ 3172654012fSReza Sabdar if (moverfd >= 0 && 3182654012fSReza Sabdar session->ns_mover.md_mode == NDMP_MOVER_MODE_WRITE) { 3192654012fSReza Sabdar int closed, reason; 3202654012fSReza Sabdar 3212654012fSReza Sabdar closed = ndmp_connection_closed(moverfd); 3222654012fSReza Sabdar if (closed) { 3232654012fSReza Sabdar /* Connection closed or internal error */ 3242654012fSReza Sabdar if (closed > 0) { 3252654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 3262654012fSReza Sabdar "ndmp mover: connection closed by peer"); 3272654012fSReza Sabdar reason = NDMP_MOVER_HALT_CONNECT_CLOSED; 3282654012fSReza Sabdar } else { 3292654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 3302654012fSReza Sabdar "ndmp mover: Internal error"); 3312654012fSReza Sabdar reason = NDMP_MOVER_HALT_INTERNAL_ERROR; 3322654012fSReza Sabdar } 3332654012fSReza Sabdar ndmpd_mover_error(session, reason); 3342654012fSReza Sabdar 3352654012fSReza Sabdar } 3362654012fSReza Sabdar } 3372654012fSReza Sabdar } 3382654012fSReza Sabdar 3392654012fSReza Sabdar 3402654012fSReza Sabdar /* 3412654012fSReza Sabdar * ndmpd_select 3422654012fSReza Sabdar * 3432654012fSReza Sabdar * Calls select on the the set of file descriptors from the 3442654012fSReza Sabdar * file handler list masked by the fd_class argument. 3452654012fSReza Sabdar * Calls the file handler function for each 3462654012fSReza Sabdar * file descriptor that is ready for I/O. 3472654012fSReza Sabdar * 3482654012fSReza Sabdar * Parameters: 3492654012fSReza Sabdar * session (input) - session pointer. 3502654012fSReza Sabdar * block (input) - if TRUE, ndmpd_select waits until at least one 3512654012fSReza Sabdar * file descriptor is ready for I/O. Otherwise, 3522654012fSReza Sabdar * it returns immediately if no file descriptors are 3532654012fSReza Sabdar * ready for I/O. 3542654012fSReza Sabdar * class_mask (input) - bit mask of handler classes to be examined. 3552654012fSReza Sabdar * Provides for excluding some of the handlers from 3562654012fSReza Sabdar * being called. 3572654012fSReza Sabdar * 3582654012fSReza Sabdar * Returns: 3592654012fSReza Sabdar * -1 - error. 3602654012fSReza Sabdar * 0 - no handlers were called. 3612654012fSReza Sabdar * 1 - at least one handler was called. 3622654012fSReza Sabdar */ 3632654012fSReza Sabdar int 3642654012fSReza Sabdar ndmpd_select(ndmpd_session_t *session, boolean_t block, ulong_t class_mask) 3652654012fSReza Sabdar { 3662654012fSReza Sabdar fd_set rfds; 3672654012fSReza Sabdar fd_set wfds; 3682654012fSReza Sabdar fd_set efds; 3692654012fSReza Sabdar int n; 3702654012fSReza Sabdar ndmpd_file_handler_t *handler; 3712654012fSReza Sabdar struct timeval timeout; 3722654012fSReza Sabdar 3732654012fSReza Sabdar nlp_event_rv_set(session, 0); 3742654012fSReza Sabdar 3752654012fSReza Sabdar if (session->ns_file_handler_list == 0) 3762654012fSReza Sabdar return (0); 3772654012fSReza Sabdar 3782654012fSReza Sabdar 3792654012fSReza Sabdar /* 3802654012fSReza Sabdar * If select should be blocked, then we poll every ten seconds. 3812654012fSReza Sabdar * The reason is in case of three-way restore we should be able 3822654012fSReza Sabdar * to detect if the other end closed the connection or not. 3832654012fSReza Sabdar * NDMP client(DMA) does not send any information about the connection 3842654012fSReza Sabdar * that was closed in the other end. 3852654012fSReza Sabdar */ 3862654012fSReza Sabdar 3872654012fSReza Sabdar if (block == TRUE) 3882654012fSReza Sabdar timeout.tv_sec = 10; 3892654012fSReza Sabdar else 3902654012fSReza Sabdar timeout.tv_sec = 0; 3912654012fSReza Sabdar timeout.tv_usec = 0; 3922654012fSReza Sabdar 3932654012fSReza Sabdar do { 3942654012fSReza Sabdar /* Create the fd_sets for select. */ 3952654012fSReza Sabdar FD_ZERO(&rfds); 3962654012fSReza Sabdar FD_ZERO(&wfds); 3972654012fSReza Sabdar FD_ZERO(&efds); 3982654012fSReza Sabdar 3992654012fSReza Sabdar for (handler = session->ns_file_handler_list; handler != 0; 4002654012fSReza Sabdar handler = handler->fh_next) { 4012654012fSReza Sabdar if ((handler->fh_class & class_mask) == 0) 4022654012fSReza Sabdar continue; 4032654012fSReza Sabdar 4042654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_READ) 4052654012fSReza Sabdar FD_SET(handler->fh_fd, &rfds); 4062654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) 4072654012fSReza Sabdar FD_SET(handler->fh_fd, &wfds); 4082654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) 4092654012fSReza Sabdar FD_SET(handler->fh_fd, &efds); 4102654012fSReza Sabdar } 4112654012fSReza Sabdar ndmp_check_mover_state(session); 4122654012fSReza Sabdar n = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout); 4132654012fSReza Sabdar } while (n == 0 && block == TRUE); 4142654012fSReza Sabdar 4152654012fSReza Sabdar if (n < 0) { 4162654012fSReza Sabdar int connection_fd = ndmp_get_fd(session->ns_connection); 4172654012fSReza Sabdar 4182654012fSReza Sabdar if (errno == EINTR) 4192654012fSReza Sabdar return (0); 4202654012fSReza Sabdar 4212654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Select error: %m"); 4222654012fSReza Sabdar 4232654012fSReza Sabdar for (handler = session->ns_file_handler_list; handler != 0; 4242654012fSReza Sabdar handler = handler->fh_next) { 4252654012fSReza Sabdar if ((handler->fh_class & class_mask) == 0) 4262654012fSReza Sabdar continue; 4272654012fSReza Sabdar 4282654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_READ) { 4292654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &rfds) && 4302654012fSReza Sabdar connection_fd == handler->fh_fd) 4312654012fSReza Sabdar session->ns_eof = TRUE; 4322654012fSReza Sabdar } 4332654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) { 4342654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &wfds) && 4352654012fSReza Sabdar connection_fd == handler->fh_fd) 4362654012fSReza Sabdar session->ns_eof = TRUE; 4372654012fSReza Sabdar } 4382654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) { 4392654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &efds) && 4402654012fSReza Sabdar connection_fd == handler->fh_fd) 4412654012fSReza Sabdar session->ns_eof = TRUE; 4422654012fSReza Sabdar } 4432654012fSReza Sabdar } 4442654012fSReza Sabdar 4452654012fSReza Sabdar nlp_event_rv_set(session, -1); 4462654012fSReza Sabdar return (-1); 4472654012fSReza Sabdar } 4482654012fSReza Sabdar if (n == 0) 4492654012fSReza Sabdar return (0); 4502654012fSReza Sabdar 4512654012fSReza Sabdar handler = session->ns_file_handler_list; 4522654012fSReza Sabdar while (handler != 0) { 4532654012fSReza Sabdar ulong_t mode = 0; 4542654012fSReza Sabdar 4552654012fSReza Sabdar if ((handler->fh_class & class_mask) == 0) { 4562654012fSReza Sabdar handler = handler->fh_next; 4572654012fSReza Sabdar continue; 4582654012fSReza Sabdar } 4592654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_READ) { 4602654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &rfds)) { 4612654012fSReza Sabdar mode |= NDMPD_SELECT_MODE_READ; 4622654012fSReza Sabdar FD_CLR(handler->fh_fd, &rfds); 4632654012fSReza Sabdar } 4642654012fSReza Sabdar } 4652654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) { 4662654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &wfds)) { 4672654012fSReza Sabdar mode |= NDMPD_SELECT_MODE_WRITE; 4682654012fSReza Sabdar FD_CLR(handler->fh_fd, &wfds); 4692654012fSReza Sabdar } 4702654012fSReza Sabdar } 4712654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) { 4722654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &efds)) { 4732654012fSReza Sabdar mode |= NDMPD_SELECT_MODE_EXCEPTION; 4742654012fSReza Sabdar FD_CLR(handler->fh_fd, &efds); 4752654012fSReza Sabdar } 4762654012fSReza Sabdar } 4772654012fSReza Sabdar if (mode) { 4782654012fSReza Sabdar (*handler->fh_func) (handler->fh_cookie, 4792654012fSReza Sabdar handler->fh_fd, mode); 4802654012fSReza Sabdar 4812654012fSReza Sabdar /* 4822654012fSReza Sabdar * K.L. The list can be modified during the execution 4832654012fSReza Sabdar * of handler->fh_func. Therefore, handler will start 4842654012fSReza Sabdar * from the beginning of the handler list after 4852654012fSReza Sabdar * each execution. 4862654012fSReza Sabdar */ 4872654012fSReza Sabdar handler = session->ns_file_handler_list; 4882654012fSReza Sabdar 4892654012fSReza Sabdar /* 4902654012fSReza Sabdar * Release the thread which is waiting for a request 4912654012fSReza Sabdar * to be proccessed. 4922654012fSReza Sabdar */ 4932654012fSReza Sabdar nlp_event_nw(session); 4942654012fSReza Sabdar } else 4952654012fSReza Sabdar handler = handler->fh_next; 4962654012fSReza Sabdar 4972654012fSReza Sabdar } 4982654012fSReza Sabdar 4992654012fSReza Sabdar nlp_event_rv_set(session, 1); 5002654012fSReza Sabdar return (1); 5012654012fSReza Sabdar } 5022654012fSReza Sabdar 5032654012fSReza Sabdar 5042654012fSReza Sabdar /* 5052654012fSReza Sabdar * ndmpd_save_env 5062654012fSReza Sabdar * 5072654012fSReza Sabdar * Saves a copy of the environment variable list from the data_start_backup 5082654012fSReza Sabdar * request or data_start_recover request. 5092654012fSReza Sabdar * 5102654012fSReza Sabdar * Parameters: 5112654012fSReza Sabdar * session (input) - session pointer. 5122654012fSReza Sabdar * env (input) - environment variable list to be saved. 5132654012fSReza Sabdar * envlen (input) - length of variable array. 5142654012fSReza Sabdar * 5152654012fSReza Sabdar * Returns: 5162654012fSReza Sabdar * error code. 5172654012fSReza Sabdar */ 5182654012fSReza Sabdar ndmp_error 5192654012fSReza Sabdar ndmpd_save_env(ndmpd_session_t *session, ndmp_pval *env, ulong_t envlen) 5202654012fSReza Sabdar { 5212654012fSReza Sabdar ulong_t i; 5222654012fSReza Sabdar char *namebuf; 5232654012fSReza Sabdar char *valbuf; 5242654012fSReza Sabdar 5252654012fSReza Sabdar session->ns_data.dd_env_len = 0; 5262654012fSReza Sabdar 5272654012fSReza Sabdar if (envlen == 0) 5282654012fSReza Sabdar return (NDMP_NO_ERR); 5292654012fSReza Sabdar 5302654012fSReza Sabdar session->ns_data.dd_env = ndmp_malloc(sizeof (ndmp_pval) * envlen); 5312654012fSReza Sabdar if (session->ns_data.dd_env == 0) 5322654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 5332654012fSReza Sabdar 5342654012fSReza Sabdar for (i = 0; i < envlen; i++) { 5352654012fSReza Sabdar namebuf = strdup(env[i].name); 5362654012fSReza Sabdar if (namebuf == 0) 5372654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 5382654012fSReza Sabdar 5392654012fSReza Sabdar valbuf = strdup(env[i].value); 5402654012fSReza Sabdar if (valbuf == 0) { 5412654012fSReza Sabdar free(namebuf); 5422654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 5432654012fSReza Sabdar } 5442654012fSReza Sabdar 5452654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "env(%s): \"%s\"", 5462654012fSReza Sabdar namebuf, valbuf); 5472654012fSReza Sabdar 5482654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 5492654012fSReza Sabdar session->ns_data.dd_env[i].name = namebuf; 5502654012fSReza Sabdar session->ns_data.dd_env[i].value = valbuf; 5512654012fSReza Sabdar session->ns_data.dd_env_len++; 5522654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 5532654012fSReza Sabdar } 5542654012fSReza Sabdar 5552654012fSReza Sabdar return (NDMP_NO_ERR); 5562654012fSReza Sabdar } 5572654012fSReza Sabdar 5582654012fSReza Sabdar 5592654012fSReza Sabdar /* 5602654012fSReza Sabdar * ndmpd_free_env 5612654012fSReza Sabdar * 5622654012fSReza Sabdar * Free the previously saved environment variable array. 5632654012fSReza Sabdar * 5642654012fSReza Sabdar * Parameters: 5652654012fSReza Sabdar * session - NDMP session pointer. 5662654012fSReza Sabdar * 5672654012fSReza Sabdar * Returns: 5682654012fSReza Sabdar * void. 5692654012fSReza Sabdar */ 5702654012fSReza Sabdar void 5712654012fSReza Sabdar ndmpd_free_env(ndmpd_session_t *session) 5722654012fSReza Sabdar { 5732654012fSReza Sabdar ulong_t i; 5742654012fSReza Sabdar int count = session->ns_data.dd_env_len; 5752654012fSReza Sabdar 5762654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 5772654012fSReza Sabdar session->ns_data.dd_env_len = 0; 5782654012fSReza Sabdar for (i = 0; i < count; i++) { 5792654012fSReza Sabdar free(session->ns_data.dd_env[i].name); 5802654012fSReza Sabdar free(session->ns_data.dd_env[i].value); 5812654012fSReza Sabdar } 5822654012fSReza Sabdar 5832654012fSReza Sabdar free((char *)session->ns_data.dd_env); 5842654012fSReza Sabdar session->ns_data.dd_env = 0; 5852654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 5862654012fSReza Sabdar } 5872654012fSReza Sabdar 5882654012fSReza Sabdar 5892654012fSReza Sabdar /* 5902654012fSReza Sabdar * ndmpd_save_nlist_v2 5912654012fSReza Sabdar * 5922654012fSReza Sabdar * Save a copy of list of file names to be restored. 5932654012fSReza Sabdar * 5942654012fSReza Sabdar * Parameters: 5952654012fSReza Sabdar * nlist (input) - name list from data_start_recover request. 5962654012fSReza Sabdar * nlistlen (input) - length of name list. 5972654012fSReza Sabdar * 5982654012fSReza Sabdar * Returns: 5992654012fSReza Sabdar * array of file name pointers. 6002654012fSReza Sabdar * 6012654012fSReza Sabdar * Notes: 6022654012fSReza Sabdar * free_nlist should be called to free the returned list. 6032654012fSReza Sabdar * A null pointer indicates the end of the list. 6042654012fSReza Sabdar */ 6052654012fSReza Sabdar ndmp_error 6062654012fSReza Sabdar ndmpd_save_nlist_v2(ndmpd_session_t *session, ndmp_name *nlist, 6072654012fSReza Sabdar ulong_t nlistlen) 6082654012fSReza Sabdar { 6092654012fSReza Sabdar ulong_t i; 6102654012fSReza Sabdar char *namebuf; 6112654012fSReza Sabdar char *destbuf; 6122654012fSReza Sabdar 6132654012fSReza Sabdar if (nlistlen == 0) 6142654012fSReza Sabdar return (NDMP_NO_ERR); 6152654012fSReza Sabdar 6162654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 6172654012fSReza Sabdar session->ns_data.dd_nlist = ndmp_malloc(sizeof (ndmp_name)*nlistlen); 6182654012fSReza Sabdar if (session->ns_data.dd_nlist == 0) 6192654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 6202654012fSReza Sabdar 6212654012fSReza Sabdar for (i = 0; i < nlistlen; i++) { 6222654012fSReza Sabdar namebuf = ndmp_malloc(strlen(nlist[i].name) + 1); 6232654012fSReza Sabdar if (namebuf == 0) 6242654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 6252654012fSReza Sabdar 6262654012fSReza Sabdar destbuf = ndmp_malloc(strlen(nlist[i].dest) + 1); 6272654012fSReza Sabdar if (destbuf == 0) { 6282654012fSReza Sabdar free(namebuf); 6292654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 6302654012fSReza Sabdar } 6312654012fSReza Sabdar (void) strlcpy(namebuf, nlist[i].name, 6322654012fSReza Sabdar strlen(nlist[i].name) + 1); 6332654012fSReza Sabdar (void) strlcpy(destbuf, nlist[i].dest, 6342654012fSReza Sabdar strlen(nlist[i].dest) + 1); 6352654012fSReza Sabdar 6362654012fSReza Sabdar session->ns_data.dd_nlist[i].name = namebuf; 6372654012fSReza Sabdar session->ns_data.dd_nlist[i].dest = destbuf; 6382654012fSReza Sabdar session->ns_data.dd_nlist[i].ssid = nlist[i].ssid; 6392654012fSReza Sabdar session->ns_data.dd_nlist[i].fh_info = nlist[i].fh_info; 6402654012fSReza Sabdar session->ns_data.dd_nlist_len++; 6412654012fSReza Sabdar } 6422654012fSReza Sabdar 6432654012fSReza Sabdar return (NDMP_NO_ERR); 6442654012fSReza Sabdar } 6452654012fSReza Sabdar 6462654012fSReza Sabdar 6472654012fSReza Sabdar /* 6482654012fSReza Sabdar * ndmpd_free_nlist_v2 6492654012fSReza Sabdar * 6502654012fSReza Sabdar * Free a list created by ndmpd_save_nlist_v2. 6512654012fSReza Sabdar * 6522654012fSReza Sabdar * Parameters: 6532654012fSReza Sabdar * session (input) - session pointer. 6542654012fSReza Sabdar * 6552654012fSReza Sabdar * Returns: 6562654012fSReza Sabdar * void 6572654012fSReza Sabdar */ 6582654012fSReza Sabdar void 6592654012fSReza Sabdar ndmpd_free_nlist_v2(ndmpd_session_t *session) 6602654012fSReza Sabdar { 6612654012fSReza Sabdar ulong_t i; 6622654012fSReza Sabdar 6632654012fSReza Sabdar for (i = 0; i < session->ns_data.dd_nlist_len; i++) { 6642654012fSReza Sabdar free(session->ns_data.dd_nlist[i].name); 6652654012fSReza Sabdar free(session->ns_data.dd_nlist[i].dest); 6662654012fSReza Sabdar } 6672654012fSReza Sabdar 6682654012fSReza Sabdar if (session->ns_data.dd_nlist != NULL) 6692654012fSReza Sabdar free((char *)session->ns_data.dd_nlist); 6702654012fSReza Sabdar session->ns_data.dd_nlist = 0; 6712654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 6722654012fSReza Sabdar } 6732654012fSReza Sabdar 6742654012fSReza Sabdar 6752654012fSReza Sabdar /* 6762654012fSReza Sabdar * ndmpd_free_nlist_v3 6772654012fSReza Sabdar * 6782654012fSReza Sabdar * Free a list created by ndmpd_save_nlist_v3. 6792654012fSReza Sabdar * 6802654012fSReza Sabdar * Parameters: 6812654012fSReza Sabdar * session (input) - session pointer. 6822654012fSReza Sabdar * 6832654012fSReza Sabdar * Returns: 6842654012fSReza Sabdar * void 6852654012fSReza Sabdar */ 6862654012fSReza Sabdar void 6872654012fSReza Sabdar ndmpd_free_nlist_v3(ndmpd_session_t *session) 6882654012fSReza Sabdar { 6892654012fSReza Sabdar ulong_t i; 6902654012fSReza Sabdar mem_ndmp_name_v3_t *tp; /* destination entry */ 6912654012fSReza Sabdar 6922654012fSReza Sabdar tp = session->ns_data.dd_nlist_v3; 6932654012fSReza Sabdar for (i = 0; i < session->ns_data.dd_nlist_len; tp++, i++) { 6942654012fSReza Sabdar NDMP_FREE(tp->nm3_opath); 6952654012fSReza Sabdar NDMP_FREE(tp->nm3_dpath); 6962654012fSReza Sabdar NDMP_FREE(tp->nm3_newnm); 6972654012fSReza Sabdar } 6982654012fSReza Sabdar 6992654012fSReza Sabdar NDMP_FREE(session->ns_data.dd_nlist_v3); 7002654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 7012654012fSReza Sabdar } 7022654012fSReza Sabdar 7032654012fSReza Sabdar 7042654012fSReza Sabdar /* 7052654012fSReza Sabdar * ndmpd_save_nlist_v3 7062654012fSReza Sabdar * 7072654012fSReza Sabdar * Save a copy of list of file names to be restored. 7082654012fSReza Sabdar * 7092654012fSReza Sabdar * Parameters: 7102654012fSReza Sabdar * nlist (input) - name list from data_start_recover request. 7112654012fSReza Sabdar * nlistlen (input) - length of name list. 7122654012fSReza Sabdar * 7132654012fSReza Sabdar * Returns: 7142654012fSReza Sabdar * array of file name pointers. 7152654012fSReza Sabdar * 7162654012fSReza Sabdar * Notes: 7172654012fSReza Sabdar * free_nlist should be called to free the returned list. 7182654012fSReza Sabdar * A null pointer indicates the end of the list. 7192654012fSReza Sabdar */ 7202654012fSReza Sabdar ndmp_error 7212654012fSReza Sabdar ndmpd_save_nlist_v3(ndmpd_session_t *session, ndmp_name_v3 *nlist, 7222654012fSReza Sabdar ulong_t nlistlen) 7232654012fSReza Sabdar { 7242654012fSReza Sabdar ulong_t i; 7252654012fSReza Sabdar ndmp_error rv; 7262654012fSReza Sabdar ndmp_name_v3 *sp; /* source entry */ 7272654012fSReza Sabdar mem_ndmp_name_v3_t *tp; /* destination entry */ 7282654012fSReza Sabdar 7292654012fSReza Sabdar if (nlistlen == 0) 7302654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 7312654012fSReza Sabdar 7322654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 7332654012fSReza Sabdar tp = session->ns_data.dd_nlist_v3 = 7342654012fSReza Sabdar ndmp_malloc(sizeof (mem_ndmp_name_v3_t) * nlistlen); 7352654012fSReza Sabdar if (session->ns_data.dd_nlist_v3 == 0) 7362654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 7372654012fSReza Sabdar 7382654012fSReza Sabdar rv = NDMP_NO_ERR; 7392654012fSReza Sabdar sp = nlist; 7402654012fSReza Sabdar for (i = 0; i < nlistlen; tp++, sp++, i++) { 7412654012fSReza Sabdar tp->nm3_opath = strdup(sp->original_path); 7422654012fSReza Sabdar if (!tp->nm3_opath) { 7432654012fSReza Sabdar rv = NDMP_NO_MEM_ERR; 7442654012fSReza Sabdar break; 7452654012fSReza Sabdar } 7462654012fSReza Sabdar if (!*sp->destination_dir) { 7472654012fSReza Sabdar tp->nm3_dpath = NULL; 7482654012fSReza Sabdar /* In V4 destination dir cannot be NULL */ 7492654012fSReza Sabdar if (session->ns_protocol_version == NDMPV4) { 7502654012fSReza Sabdar rv = NDMP_ILLEGAL_ARGS_ERR; 7512654012fSReza Sabdar break; 7522654012fSReza Sabdar } 7532654012fSReza Sabdar } else if (!(tp->nm3_dpath = strdup(sp->destination_dir))) { 7542654012fSReza Sabdar rv = NDMP_NO_MEM_ERR; 7552654012fSReza Sabdar break; 7562654012fSReza Sabdar } 7572654012fSReza Sabdar if (!*sp->new_name) 7582654012fSReza Sabdar tp->nm3_newnm = NULL; 7592654012fSReza Sabdar else if (!(tp->nm3_newnm = strdup(sp->new_name))) { 7602654012fSReza Sabdar rv = NDMP_NO_MEM_ERR; 7612654012fSReza Sabdar break; 7622654012fSReza Sabdar } 7632654012fSReza Sabdar 7642654012fSReza Sabdar tp->nm3_node = quad_to_long_long(sp->node); 7652654012fSReza Sabdar tp->nm3_fh_info = quad_to_long_long(sp->fh_info); 7662654012fSReza Sabdar tp->nm3_err = NDMP_NO_ERR; 7672654012fSReza Sabdar session->ns_data.dd_nlist_len++; 7682654012fSReza Sabdar 7692654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "orig \"%s\"", tp->nm3_opath); 7702654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dest \"%s\"", NDMP_SVAL(tp->nm3_dpath)); 7712654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "name \"%s\"", NDMP_SVAL(tp->nm3_newnm)); 7722654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "node %lld", tp->nm3_node); 7732654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "fh_info %lld", tp->nm3_fh_info); 7742654012fSReza Sabdar } 7752654012fSReza Sabdar 7762654012fSReza Sabdar if (rv != NDMP_NO_ERR) 7772654012fSReza Sabdar ndmpd_free_nlist_v3(session); 7782654012fSReza Sabdar 7792654012fSReza Sabdar return (rv); 7802654012fSReza Sabdar } 7812654012fSReza Sabdar 7822654012fSReza Sabdar 7832654012fSReza Sabdar /* 7842654012fSReza Sabdar * ndmpd_free_nlist 7852654012fSReza Sabdar * 7862654012fSReza Sabdar * Free the recovery list based on the version 7872654012fSReza Sabdar * 7882654012fSReza Sabdar * Parameters: 7892654012fSReza Sabdar * session (input) - session pointer. 7902654012fSReza Sabdar * 7912654012fSReza Sabdar * Returns: 7922654012fSReza Sabdar * void 7932654012fSReza Sabdar */ 7942654012fSReza Sabdar void 7952654012fSReza Sabdar ndmpd_free_nlist(ndmpd_session_t *session) 7962654012fSReza Sabdar { 7972654012fSReza Sabdar switch (session->ns_protocol_version) { 7982654012fSReza Sabdar case 1: 7992654012fSReza Sabdar case 2: 8002654012fSReza Sabdar ndmpd_free_nlist_v2(session); 8012654012fSReza Sabdar break; 8022654012fSReza Sabdar case 3: 8032654012fSReza Sabdar case 4: 8042654012fSReza Sabdar ndmpd_free_nlist_v3(session); 8052654012fSReza Sabdar break; 8062654012fSReza Sabdar 8072654012fSReza Sabdar default: 8082654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown version %d", 8092654012fSReza Sabdar session->ns_protocol_version); 8102654012fSReza Sabdar } 8112654012fSReza Sabdar } 8122654012fSReza Sabdar 8132654012fSReza Sabdar 8142654012fSReza Sabdar /* 8152654012fSReza Sabdar * fh_cmpv3 8162654012fSReza Sabdar * 8172654012fSReza Sabdar * Comparison function used in sorting the Nlist based on their 8182654012fSReza Sabdar * file history info (offset of the entry on the tape) 8192654012fSReza Sabdar * 8202654012fSReza Sabdar * Parameters: 8212654012fSReza Sabdar * p (input) - pointer to P 8222654012fSReza Sabdar * q (input) - pointer to Q 8232654012fSReza Sabdar * 8242654012fSReza Sabdar * Returns: 8252654012fSReza Sabdar * -1: P < Q 8262654012fSReza Sabdar * 0: P = Q 8272654012fSReza Sabdar * 1: P > Q 8282654012fSReza Sabdar */ 8292654012fSReza Sabdar static int 8302654012fSReza Sabdar fh_cmpv3(const void *p, 8312654012fSReza Sabdar const void *q) 8322654012fSReza Sabdar { 8332654012fSReza Sabdar #define FH_INFOV3(p) (((mem_ndmp_name_v3_t *)p)->nm3_fh_info) 8342654012fSReza Sabdar 8352654012fSReza Sabdar if (FH_INFOV3(p) < FH_INFOV3(q)) 8362654012fSReza Sabdar return (-1); 8372654012fSReza Sabdar else if (FH_INFOV3(p) == FH_INFOV3(q)) 8382654012fSReza Sabdar return (0); 8392654012fSReza Sabdar else 8402654012fSReza Sabdar return (1); 8412654012fSReza Sabdar 8422654012fSReza Sabdar #undef FH_INFOV3 8432654012fSReza Sabdar } 8442654012fSReza Sabdar 8452654012fSReza Sabdar 8462654012fSReza Sabdar /* 8472654012fSReza Sabdar * ndmp_sort_nlist_v3 8482654012fSReza Sabdar * 8492654012fSReza Sabdar * Sort the recovery list based on their offset on the tape 8502654012fSReza Sabdar * 8512654012fSReza Sabdar * Parameters: 8522654012fSReza Sabdar * session (input) - session pointer. 8532654012fSReza Sabdar * 8542654012fSReza Sabdar * Returns: 8552654012fSReza Sabdar * void 8562654012fSReza Sabdar */ 8572654012fSReza Sabdar void 8582654012fSReza Sabdar ndmp_sort_nlist_v3(ndmpd_session_t *session) 8592654012fSReza Sabdar { 8602654012fSReza Sabdar if (!session || session->ns_data.dd_nlist_len == 0 || 8612654012fSReza Sabdar !session->ns_data.dd_nlist_v3) 8622654012fSReza Sabdar return; 8632654012fSReza Sabdar 8642654012fSReza Sabdar (void) qsort(session->ns_data.dd_nlist_v3, 8652654012fSReza Sabdar session->ns_data.dd_nlist_len, 8662654012fSReza Sabdar sizeof (mem_ndmp_name_v3_t), fh_cmpv3); 8672654012fSReza Sabdar } 8682654012fSReza Sabdar 8692654012fSReza Sabdar 8702654012fSReza Sabdar /* 8712654012fSReza Sabdar * ndmp_send_reply 8722654012fSReza Sabdar * 8732654012fSReza Sabdar * Send the reply, check for error and print the msg if any error 8742654012fSReza Sabdar * occured when sending the reply. 8752654012fSReza Sabdar * 8762654012fSReza Sabdar * Parameters: 8772654012fSReza Sabdar * connection (input) - connection pointer. 8782654012fSReza Sabdar * 8792654012fSReza Sabdar * Return: 8802654012fSReza Sabdar * void 8812654012fSReza Sabdar */ 8822654012fSReza Sabdar void 8832654012fSReza Sabdar ndmp_send_reply(ndmp_connection_t *connection, void *reply, char *msg) 8842654012fSReza Sabdar { 8852654012fSReza Sabdar if (ndmp_send_response(connection, NDMP_NO_ERR, reply) < 0) 8862654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s", msg); 8872654012fSReza Sabdar } 8882654012fSReza Sabdar 8892654012fSReza Sabdar 8902654012fSReza Sabdar /* 8912654012fSReza Sabdar * ndmp_mtioctl 8922654012fSReza Sabdar * 8932654012fSReza Sabdar * Performs numerous filemark operations. 8942654012fSReza Sabdar * 8952654012fSReza Sabdar * Parameters: 8962654012fSReza Sabdar * fd - file descriptor of the device 8972654012fSReza Sabdar * cmd - filemark or record command 8982654012fSReza Sabdar * count - the number of operations to be performed 8992654012fSReza Sabdar */ 9002654012fSReza Sabdar int 9012654012fSReza Sabdar ndmp_mtioctl(int fd, int cmd, int count) 9022654012fSReza Sabdar { 9032654012fSReza Sabdar struct mtop mp; 9042654012fSReza Sabdar 9052654012fSReza Sabdar mp.mt_op = cmd; 9062654012fSReza Sabdar mp.mt_count = count; 9072654012fSReza Sabdar if (ioctl(fd, MTIOCTOP, &mp) < 0) { 9082654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Failed to send command to tape: %m."); 9092654012fSReza Sabdar return (-1); 9102654012fSReza Sabdar } 9112654012fSReza Sabdar 9122654012fSReza Sabdar return (0); 9132654012fSReza Sabdar } 9142654012fSReza Sabdar 9152654012fSReza Sabdar 9162654012fSReza Sabdar /* 9172654012fSReza Sabdar * quad_to_long_long 9182654012fSReza Sabdar * 9192654012fSReza Sabdar * Convert type quad to longlong_t 9202654012fSReza Sabdar */ 9212654012fSReza Sabdar u_longlong_t 9222654012fSReza Sabdar quad_to_long_long(ndmp_u_quad q) 9232654012fSReza Sabdar { 9242654012fSReza Sabdar u_longlong_t ull; 9252654012fSReza Sabdar 9262654012fSReza Sabdar ull = ((u_longlong_t)q.high << 32) + q.low; 9272654012fSReza Sabdar return (ull); 9282654012fSReza Sabdar } 9292654012fSReza Sabdar 9302654012fSReza Sabdar 9312654012fSReza Sabdar /* 9322654012fSReza Sabdar * long_long_to_quad 9332654012fSReza Sabdar * 9342654012fSReza Sabdar * Convert long long to quad type 9352654012fSReza Sabdar */ 9362654012fSReza Sabdar ndmp_u_quad 9372654012fSReza Sabdar long_long_to_quad(u_longlong_t ull) 9382654012fSReza Sabdar { 9392654012fSReza Sabdar ndmp_u_quad q; 9402654012fSReza Sabdar 9412654012fSReza Sabdar q.high = (ulong_t)(ull >> 32); 9422654012fSReza Sabdar q.low = (ulong_t)ull; 9432654012fSReza Sabdar return (q); 9442654012fSReza Sabdar } 9452654012fSReza Sabdar 9462654012fSReza Sabdar 9472654012fSReza Sabdar /* 9482654012fSReza Sabdar * ndmp_set_socket_nodelay 9492654012fSReza Sabdar * 9502654012fSReza Sabdar * Set the TCP socket option to nodelay mode 9512654012fSReza Sabdar */ 9522654012fSReza Sabdar void 9532654012fSReza Sabdar ndmp_set_socket_nodelay(int sock) 9542654012fSReza Sabdar { 9552654012fSReza Sabdar int flag = 1; 9562654012fSReza Sabdar 9572654012fSReza Sabdar (void) setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof (flag)); 9582654012fSReza Sabdar } 9592654012fSReza Sabdar 9602654012fSReza Sabdar 9612654012fSReza Sabdar /* 9622654012fSReza Sabdar * ndmp_set_socket_snd_buf 9632654012fSReza Sabdar * 9642654012fSReza Sabdar * Set the socket send buffer size 9652654012fSReza Sabdar */ 9662654012fSReza Sabdar void 9672654012fSReza Sabdar ndmp_set_socket_snd_buf(int sock, int size) 9682654012fSReza Sabdar { 9692654012fSReza Sabdar if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 9702654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "SO_SNDBUF failed errno=%d", errno); 9712654012fSReza Sabdar } 9722654012fSReza Sabdar 9732654012fSReza Sabdar 9742654012fSReza Sabdar /* 9752654012fSReza Sabdar * ndmp_set_socket_rcv_buf 9762654012fSReza Sabdar * 9772654012fSReza Sabdar * Set the socket receive buffer size 9782654012fSReza Sabdar */ 9792654012fSReza Sabdar void 9802654012fSReza Sabdar ndmp_set_socket_rcv_buf(int sock, int size) 9812654012fSReza Sabdar { 9822654012fSReza Sabdar if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) 9832654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "SO_RCVBUF failed errno=%d", errno); 9842654012fSReza Sabdar } 9852654012fSReza Sabdar 9862654012fSReza Sabdar /* 9872654012fSReza Sabdar * ndmp_get_max_tok_seq 9882654012fSReza Sabdar * 9892654012fSReza Sabdar * Get the maximum permitted token sequence for token-based 9902654012fSReza Sabdar * backups. 9912654012fSReza Sabdar * 9922654012fSReza Sabdar * Parameters: 9932654012fSReza Sabdar * void 9942654012fSReza Sabdar * 9952654012fSReza Sabdar * Returns: 9962654012fSReza Sabdar * ndmp_max_tok_seq 9972654012fSReza Sabdar */ 9982654012fSReza Sabdar int 9992654012fSReza Sabdar ndmp_get_max_tok_seq(void) 10002654012fSReza Sabdar { 10012654012fSReza Sabdar return (ndmp_max_tok_seq); 10022654012fSReza Sabdar } 10032654012fSReza Sabdar 10042654012fSReza Sabdar /* 10052654012fSReza Sabdar * ndmp_buffer_get_size 10062654012fSReza Sabdar * 10072654012fSReza Sabdar * Return the NDMP transfer buffer size 10082654012fSReza Sabdar * 10092654012fSReza Sabdar * Parameters: 10102654012fSReza Sabdar * session (input) - session pointer. 10112654012fSReza Sabdar * 10122654012fSReza Sabdar * Returns: 10132654012fSReza Sabdar * buffer size 10142654012fSReza Sabdar */ 10152654012fSReza Sabdar long 10162654012fSReza Sabdar ndmp_buffer_get_size(ndmpd_session_t *session) 10172654012fSReza Sabdar { 10182654012fSReza Sabdar long xfer_size; 10192654012fSReza Sabdar 10202654012fSReza Sabdar if (session == NULL) 10212654012fSReza Sabdar return (0); 10222654012fSReza Sabdar 10232654012fSReza Sabdar if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) { 10242654012fSReza Sabdar xfer_size = atoi(ndmpd_get_prop_default(NDMP_MOVER_RECSIZE, 10252654012fSReza Sabdar "60")); 10262654012fSReza Sabdar if (xfer_size > 0) 10272654012fSReza Sabdar xfer_size *= KILOBYTE; 10282654012fSReza Sabdar else 10292654012fSReza Sabdar xfer_size = REMOTE_RECORD_SIZE; 10302654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Remote operation: %d", xfer_size); 10312654012fSReza Sabdar } else { 10322654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 10332654012fSReza Sabdar "Local operation: %lu", session->ns_mover.md_record_size); 10342654012fSReza Sabdar if ((xfer_size = session->ns_mover.md_record_size) == 0) 10352654012fSReza Sabdar xfer_size = MAX_RECORD_SIZE; 10362654012fSReza Sabdar } 10372654012fSReza Sabdar 10382654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "xfer_size: %d", xfer_size); 10392654012fSReza Sabdar return (xfer_size); 10402654012fSReza Sabdar } 10412654012fSReza Sabdar 10422654012fSReza Sabdar 10432654012fSReza Sabdar /* 10442654012fSReza Sabdar * ndmp_lbr_init 10452654012fSReza Sabdar * 10462654012fSReza Sabdar * Initialize the LBR/NDMP backup parameters 10472654012fSReza Sabdar * 10482654012fSReza Sabdar * Parameters: 10492654012fSReza Sabdar * session (input) - session pointer. 10502654012fSReza Sabdar * 10512654012fSReza Sabdar * Returns: 10522654012fSReza Sabdar * 0: on success 10532654012fSReza Sabdar * -1: otherwise 10542654012fSReza Sabdar */ 10552654012fSReza Sabdar int 10562654012fSReza Sabdar ndmp_lbr_init(ndmpd_session_t *session) 10572654012fSReza Sabdar { 10582654012fSReza Sabdar if (session->ns_ndmp_lbr_params != NULL) { 10592654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_lbr_params already allocated."); 10602654012fSReza Sabdar return (0); 10612654012fSReza Sabdar } 10622654012fSReza Sabdar 10632654012fSReza Sabdar session->ns_ndmp_lbr_params = ndmp_malloc(sizeof (ndmp_lbr_params_t)); 10642654012fSReza Sabdar if (session->ns_ndmp_lbr_params == NULL) 10652654012fSReza Sabdar return (-1); 10662654012fSReza Sabdar 10672654012fSReza Sabdar session->ns_ndmp_lbr_params->nlp_bkmap = -1; 10682654012fSReza Sabdar session->ns_ndmp_lbr_params->nlp_session = session; 10692654012fSReza Sabdar (void) cond_init(&session->ns_ndmp_lbr_params->nlp_cv, 0, NULL); 10702654012fSReza Sabdar (void) mutex_init(&session->ns_lock, 0, NULL); 10712654012fSReza Sabdar session->ns_nref = 0; 10722654012fSReza Sabdar return (0); 10732654012fSReza Sabdar } 10742654012fSReza Sabdar 10752654012fSReza Sabdar 10762654012fSReza Sabdar /* 10772654012fSReza Sabdar * ndmp_lbr_cleanup 10782654012fSReza Sabdar * 10792654012fSReza Sabdar * Deallocate and cleanup all NDMP/LBR parameters 10802654012fSReza Sabdar * 10812654012fSReza Sabdar * Parameters: 10822654012fSReza Sabdar * session (input) - session pointer. 10832654012fSReza Sabdar * 10842654012fSReza Sabdar * Returns: 10852654012fSReza Sabdar * 0: on success 10862654012fSReza Sabdar * -1: otherwise 10872654012fSReza Sabdar */ 10882654012fSReza Sabdar void 10892654012fSReza Sabdar ndmp_lbr_cleanup(ndmpd_session_t *session) 10902654012fSReza Sabdar { 10912654012fSReza Sabdar /* 10922654012fSReza Sabdar * If in 3-way restore, the connection close is detected after 10932654012fSReza Sabdar * check in tape_read(), the reader thread of mover may wait forever 10942654012fSReza Sabdar * for the tape to be changed. Force the reader thread to exit. 10952654012fSReza Sabdar */ 10962654012fSReza Sabdar nlp_event_rv_set(session, -2); 10972654012fSReza Sabdar nlp_event_nw(session); 10982654012fSReza Sabdar 10992654012fSReza Sabdar ndmpd_abort_marking_v2(session); 11002654012fSReza Sabdar ndmp_stop_buffer_worker(session); 11012654012fSReza Sabdar ndmp_waitfor_op(session); 11022654012fSReza Sabdar ndmp_free_reader_writer_ipc(session); 11032654012fSReza Sabdar if (session->ns_ndmp_lbr_params) { 11042654012fSReza Sabdar if (session->ns_ndmp_lbr_params->nlp_bkmap != -1) 11052654012fSReza Sabdar (void) dbm_free(session->ns_ndmp_lbr_params->nlp_bkmap); 11062654012fSReza Sabdar tlm_release_list(session->ns_ndmp_lbr_params->nlp_exl); 11072654012fSReza Sabdar tlm_release_list(session->ns_ndmp_lbr_params->nlp_inc); 11082654012fSReza Sabdar (void) cond_destroy(&session->ns_ndmp_lbr_params->nlp_cv); 11092654012fSReza Sabdar } 11102654012fSReza Sabdar 11112654012fSReza Sabdar NDMP_FREE(session->ns_ndmp_lbr_params); 11122654012fSReza Sabdar } 11132654012fSReza Sabdar 11142654012fSReza Sabdar 11152654012fSReza Sabdar /* 11162654012fSReza Sabdar * nlp_ref_nw 11172654012fSReza Sabdar * 11182654012fSReza Sabdar * Increase the references to the NDMP/LBR parameter to prevent 11192654012fSReza Sabdar * unwanted release 11202654012fSReza Sabdar * 11212654012fSReza Sabdar * Parameters: 11222654012fSReza Sabdar * session (input) - session pointer. 11232654012fSReza Sabdar * 11242654012fSReza Sabdar * Returns: 11252654012fSReza Sabdar * void 11262654012fSReza Sabdar */ 11272654012fSReza Sabdar void 11282654012fSReza Sabdar nlp_ref_nw(ndmpd_session_t *session) 11292654012fSReza Sabdar { 11302654012fSReza Sabdar ndmp_lbr_params_t *nlp; 11312654012fSReza Sabdar 11322654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 11332654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 11342654012fSReza Sabdar nlp->nlp_nw++; 11352654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 11362654012fSReza Sabdar } else 11372654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 11382654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 11392654012fSReza Sabdar } 11402654012fSReza Sabdar 11412654012fSReza Sabdar 11422654012fSReza Sabdar /* 11432654012fSReza Sabdar * nlp_unref_nw 11442654012fSReza Sabdar * 11452654012fSReza Sabdar * Decrease the references to the NDMP/LBR parameter before 11462654012fSReza Sabdar * release 11472654012fSReza Sabdar * 11482654012fSReza Sabdar * Parameters: 11492654012fSReza Sabdar * session (input) - session pointer. 11502654012fSReza Sabdar * 11512654012fSReza Sabdar * Returns: 11522654012fSReza Sabdar * void 11532654012fSReza Sabdar */ 11542654012fSReza Sabdar void 11552654012fSReza Sabdar nlp_unref_nw(ndmpd_session_t *session) 11562654012fSReza Sabdar { 11572654012fSReza Sabdar ndmp_lbr_params_t *nlp; 11582654012fSReza Sabdar 11592654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 11602654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 11612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 11622654012fSReza Sabdar if (nlp->nlp_nw > 0) 11632654012fSReza Sabdar nlp->nlp_nw--; 11642654012fSReza Sabdar } else 11652654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 11662654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 11672654012fSReza Sabdar } 11682654012fSReza Sabdar 11692654012fSReza Sabdar 11702654012fSReza Sabdar /* 11712654012fSReza Sabdar * nlp_wait_nw 11722654012fSReza Sabdar * 11732654012fSReza Sabdar * Wait for a NDMP/LBR parameter to get available 11742654012fSReza Sabdar * 11752654012fSReza Sabdar * Parameters: 11762654012fSReza Sabdar * session (input) - session pointer. 11772654012fSReza Sabdar * 11782654012fSReza Sabdar * Returns: 11792654012fSReza Sabdar * void 11802654012fSReza Sabdar */ 11812654012fSReza Sabdar void 11822654012fSReza Sabdar nlp_wait_nw(ndmpd_session_t *session) 11832654012fSReza Sabdar { 11842654012fSReza Sabdar ndmp_lbr_params_t *nlp; 11852654012fSReza Sabdar 11862654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 11872654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 11882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 11892654012fSReza Sabdar if (nlp->nlp_nw > 0) { 11902654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Waiting"); 11912654012fSReza Sabdar while ((nlp->nlp_flag & NLP_READY) == 0) 11922654012fSReza Sabdar (void) cond_wait(&nlp->nlp_cv, &nlp_mtx); 11932654012fSReza Sabdar } 11942654012fSReza Sabdar } else 11952654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 11962654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 11972654012fSReza Sabdar } 11982654012fSReza Sabdar 11992654012fSReza Sabdar 12002654012fSReza Sabdar /* 12012654012fSReza Sabdar * nlp_event_nw 12022654012fSReza Sabdar * 12032654012fSReza Sabdar * Signal that a NDMP/LBR parameter is available to wake up the 12042654012fSReza Sabdar * threads waiting on that 12052654012fSReza Sabdar * 12062654012fSReza Sabdar * Parameters: 12072654012fSReza Sabdar * session (input) - session pointer. 12082654012fSReza Sabdar * 12092654012fSReza Sabdar * Returns: 12102654012fSReza Sabdar * void 12112654012fSReza Sabdar */ 12122654012fSReza Sabdar void 12132654012fSReza Sabdar nlp_event_nw(ndmpd_session_t *session) 12142654012fSReza Sabdar { 12152654012fSReza Sabdar ndmp_lbr_params_t *nlp; 12162654012fSReza Sabdar 12172654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 12182654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 12192654012fSReza Sabdar if (nlp->nlp_nw > 0) { 12202654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 12212654012fSReza Sabdar nlp->nlp_flag |= NLP_READY; 12222654012fSReza Sabdar (void) cond_signal(&nlp->nlp_cv); 12232654012fSReza Sabdar } 12242654012fSReza Sabdar } else 12252654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 12262654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 12272654012fSReza Sabdar } 12282654012fSReza Sabdar 12292654012fSReza Sabdar 12302654012fSReza Sabdar /* 12312654012fSReza Sabdar * nlp_event_rv_get 12322654012fSReza Sabdar * 12332654012fSReza Sabdar * Get the return value for each NLP 12342654012fSReza Sabdar * 12352654012fSReza Sabdar * Parameters: 12362654012fSReza Sabdar * session (input) - session pointer. 12372654012fSReza Sabdar * 12382654012fSReza Sabdar * Returns: 12392654012fSReza Sabdar * return value 12402654012fSReza Sabdar */ 12412654012fSReza Sabdar int 12422654012fSReza Sabdar nlp_event_rv_get(ndmpd_session_t *session) 12432654012fSReza Sabdar { 12442654012fSReza Sabdar ndmp_lbr_params_t *nlp; 12452654012fSReza Sabdar 12462654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 12472654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 12482654012fSReza Sabdar return (0); 12492654012fSReza Sabdar } 12502654012fSReza Sabdar 12512654012fSReza Sabdar return (nlp->nlp_rv); 12522654012fSReza Sabdar } 12532654012fSReza Sabdar 12542654012fSReza Sabdar 12552654012fSReza Sabdar /* 12562654012fSReza Sabdar * nlp_event_rv_set 12572654012fSReza Sabdar * 12582654012fSReza Sabdar * Set the return value for an NLP 12592654012fSReza Sabdar * 12602654012fSReza Sabdar * Parameters: 12612654012fSReza Sabdar * session (input) - session pointer. 12622654012fSReza Sabdar * rv (input) - return value 12632654012fSReza Sabdar * 12642654012fSReza Sabdar * Returns: 12652654012fSReza Sabdar * void 12662654012fSReza Sabdar */ 12672654012fSReza Sabdar void 12682654012fSReza Sabdar nlp_event_rv_set(ndmpd_session_t *session, 12692654012fSReza Sabdar int rv) 12702654012fSReza Sabdar { 12712654012fSReza Sabdar ndmp_lbr_params_t *nlp; 12722654012fSReza Sabdar 12732654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 12742654012fSReza Sabdar if (rv != 0) 12752654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "rv: %d", rv); 12762654012fSReza Sabdar 12772654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) 12782654012fSReza Sabdar nlp->nlp_rv = rv; 12792654012fSReza Sabdar else 12802654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 12812654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 12822654012fSReza Sabdar } 12832654012fSReza Sabdar 12842654012fSReza Sabdar /* 12852654012fSReza Sabdar * is_buffer_erroneous 12862654012fSReza Sabdar * 12872654012fSReza Sabdar * Run a sanity check on the buffer 12882654012fSReza Sabdar * 12892654012fSReza Sabdar * returns: 12902654012fSReza Sabdar * TRUE: if the buffer seems to have error 12912654012fSReza Sabdar * FALSE: if the buffer is full and has valid data. 12922654012fSReza Sabdar */ 12932654012fSReza Sabdar boolean_t 12942654012fSReza Sabdar is_buffer_erroneous(tlm_buffer_t *buf) 12952654012fSReza Sabdar { 12962654012fSReza Sabdar boolean_t rv; 12972654012fSReza Sabdar 12982654012fSReza Sabdar rv = (buf == NULL || buf->tb_eot || buf->tb_eof || 12992654012fSReza Sabdar buf->tb_errno != 0); 13002654012fSReza Sabdar if (rv) { 13012654012fSReza Sabdar if (buf == NULL) { 13022654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "buf == NULL"); 13032654012fSReza Sabdar } else { 13042654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "eot: %u, eof: %u, errno: %d", 13052654012fSReza Sabdar buf->tb_eot, buf->tb_eof, buf->tb_errno); 13062654012fSReza Sabdar } 13072654012fSReza Sabdar } 13082654012fSReza Sabdar 13092654012fSReza Sabdar return (rv); 13102654012fSReza Sabdar } 13112654012fSReza Sabdar 13122654012fSReza Sabdar /* 13132654012fSReza Sabdar * ndmp_execute_cdb 13142654012fSReza Sabdar * 13152654012fSReza Sabdar * Main SCSI CDB execution program, this is used by message handler 13162654012fSReza Sabdar * for the NDMP tape/SCSI execute CDB requests. This function uses 13172654012fSReza Sabdar * USCSI interface to run the CDB command and sets all the CDB parameters 13182654012fSReza Sabdar * in the SCSI query before calling the USCSI ioctl. The result of the 13192654012fSReza Sabdar * CDB is returned in two places: 13202654012fSReza Sabdar * cmd.uscsi_status The status of CDB execution 13212654012fSReza Sabdar * cmd.uscsi_rqstatus The status of sense requests 13222654012fSReza Sabdar * reply.error The general errno (ioctl) 13232654012fSReza Sabdar * 13242654012fSReza Sabdar * Parameters: 13252654012fSReza Sabdar * session (input) - session pointer 13262654012fSReza Sabdar * adapter_name (input) - name of SCSI adapter 13272654012fSReza Sabdar * sid (input) - SCSI target ID 13282654012fSReza Sabdar * lun (input) - LUN number 13292654012fSReza Sabdar * request (input) - NDMP client CDB request 13302654012fSReza Sabdar * 13312654012fSReza Sabdar * Returns: 13322654012fSReza Sabdar * void 13332654012fSReza Sabdar */ 13342654012fSReza Sabdar /*ARGSUSED*/ 13352654012fSReza Sabdar void 13362654012fSReza Sabdar ndmp_execute_cdb(ndmpd_session_t *session, char *adapter_name, int sid, int lun, 13372654012fSReza Sabdar ndmp_execute_cdb_request *request) 13382654012fSReza Sabdar { 13392654012fSReza Sabdar ndmp_execute_cdb_reply reply; 13402654012fSReza Sabdar struct uscsi_cmd cmd; 13412654012fSReza Sabdar int fd; 13422654012fSReza Sabdar struct open_list *olp; 13432654012fSReza Sabdar char rq_buf[255]; 13442654012fSReza Sabdar 13452654012fSReza Sabdar (void) memset((void *)&cmd, 0, sizeof (cmd)); 13462654012fSReza Sabdar (void) memset((void *)&reply, 0, sizeof (reply)); 13472654012fSReza Sabdar (void) memset((void *)rq_buf, 0, sizeof (rq_buf)); 13482654012fSReza Sabdar 13492654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) { 1350b6b15642SReza Sabdar cmd.uscsi_flags = USCSI_READ | USCSI_RQENABLE; 13512654012fSReza Sabdar if ((cmd.uscsi_bufaddr = 13522654012fSReza Sabdar ndmp_malloc(request->datain_len)) == 0) { 13532654012fSReza Sabdar reply.error = NDMP_NO_MEM_ERR; 13542654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, 13552654012fSReza Sabdar NDMP_NO_ERR, (void *)&reply) < 0) 13562654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "error sending" 13572654012fSReza Sabdar " scsi_execute_cdb reply."); 13582654012fSReza Sabdar return; 13592654012fSReza Sabdar } 13602654012fSReza Sabdar 13612654012fSReza Sabdar cmd.uscsi_buflen = request->datain_len; 13622654012fSReza Sabdar cmd.uscsi_rqlen = sizeof (rq_buf); 13632654012fSReza Sabdar cmd.uscsi_rqbuf = rq_buf; 13642654012fSReza Sabdar } else if (request->flags == NDMP_SCSI_DATA_OUT) { 1365b6b15642SReza Sabdar cmd.uscsi_flags = USCSI_WRITE; 13662654012fSReza Sabdar cmd.uscsi_bufaddr = request->dataout.dataout_val; 13672654012fSReza Sabdar cmd.uscsi_buflen = request->dataout.dataout_len; 13682654012fSReza Sabdar } else { 136986c48bbfSReza Sabdar cmd.uscsi_flags = USCSI_RQENABLE; 13702654012fSReza Sabdar cmd.uscsi_bufaddr = 0; 13712654012fSReza Sabdar cmd.uscsi_buflen = 0; 13722654012fSReza Sabdar cmd.uscsi_rqlen = sizeof (rq_buf); 13732654012fSReza Sabdar cmd.uscsi_rqbuf = rq_buf; 13742654012fSReza Sabdar } 13752654012fSReza Sabdar 13762654012fSReza Sabdar cmd.uscsi_timeout = (request->timeout < 1000) ? 13772654012fSReza Sabdar 1 : (request->timeout / 1000); 13782654012fSReza Sabdar 13792654012fSReza Sabdar cmd.uscsi_cdb = (caddr_t)request->cdb.cdb_val; 13802654012fSReza Sabdar cmd.uscsi_cdblen = request->cdb.cdb_len; 13812654012fSReza Sabdar 13822654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd: 0x%x, len: %d, flags: %d, datain_len: %d", 13832654012fSReza Sabdar request->cdb.cdb_val[0] & 0xff, request->cdb.cdb_len, 13842654012fSReza Sabdar request->flags, request->datain_len); 13852654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dataout_len: %d, timeout: %d", 13862654012fSReza Sabdar request->dataout.dataout_len, request->timeout); 13872654012fSReza Sabdar 13882654012fSReza Sabdar if (request->cdb.cdb_len > 12) { 13892654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 13902654012fSReza Sabdar ndmp_send_reply(session->ns_connection, (void *) &reply, 13912654012fSReza Sabdar "sending execute_cdb reply"); 13922654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) 13932654012fSReza Sabdar free(cmd.uscsi_bufaddr); 13942654012fSReza Sabdar return; 13952654012fSReza Sabdar } 13962654012fSReza Sabdar 13972654012fSReza Sabdar reply.error = NDMP_NO_ERR; 13982654012fSReza Sabdar 13992654012fSReza Sabdar if ((olp = ndmp_open_list_find(adapter_name, sid, lun)) != NULL) { 14002654012fSReza Sabdar fd = olp->ol_fd; 14012654012fSReza Sabdar } else { 14022654012fSReza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR; 14032654012fSReza Sabdar ndmp_send_reply(session->ns_connection, (void *) &reply, 14042654012fSReza Sabdar "sending execute_cdb reply"); 14052654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) 14062654012fSReza Sabdar free(cmd.uscsi_bufaddr); 14072654012fSReza Sabdar return; 14082654012fSReza Sabdar } 14092654012fSReza Sabdar 14102654012fSReza Sabdar if (ioctl(fd, USCSICMD, &cmd) < 0) { 1411674cb4b0SReza Sabdar if (errno != EIO && errno != 0) 1412674cb4b0SReza Sabdar NDMP_LOG(LOG_ERR, 1413674cb4b0SReza Sabdar "Failed to send command to device: %m"); 14142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(USCSICMD) error: %m"); 14157a088f03SReza Sabdar if (cmd.uscsi_status == 0) 14162654012fSReza Sabdar reply.error = NDMP_IO_ERR; 14172654012fSReza Sabdar } 14182654012fSReza Sabdar 14192654012fSReza Sabdar reply.status = cmd.uscsi_status; 14202654012fSReza Sabdar 14212654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) { 14222654012fSReza Sabdar reply.datain.datain_len = cmd.uscsi_buflen; 14232654012fSReza Sabdar reply.datain.datain_val = cmd.uscsi_bufaddr; 14242654012fSReza Sabdar } else { 14252654012fSReza Sabdar reply.dataout_len = request->dataout.dataout_len; 14262654012fSReza Sabdar } 14272654012fSReza Sabdar 14282654012fSReza Sabdar reply.ext_sense.ext_sense_len = cmd.uscsi_rqlen - cmd.uscsi_rqresid; 14292654012fSReza Sabdar reply.ext_sense.ext_sense_val = rq_buf; 14302654012fSReza Sabdar 14312654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 14322654012fSReza Sabdar (void *)&reply) < 0) 14332654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Error sending scsi_execute_cdb reply."); 14342654012fSReza Sabdar 14352654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) 14362654012fSReza Sabdar free(cmd.uscsi_bufaddr); 14372654012fSReza Sabdar } 14382654012fSReza Sabdar 14392654012fSReza Sabdar 14402654012fSReza Sabdar /* 14412654012fSReza Sabdar * ndmp_stop_local_reader 14422654012fSReza Sabdar * 14432654012fSReza Sabdar * Stops a mover reader thread (for local backup only) 14442654012fSReza Sabdar * 14452654012fSReza Sabdar * Parameters: 14462654012fSReza Sabdar * session (input) - session pointer 14472654012fSReza Sabdar * cmds (input) - reader/writer command struct 14482654012fSReza Sabdar * 14492654012fSReza Sabdar * Returns: 14502654012fSReza Sabdar * void 14512654012fSReza Sabdar */ 14522654012fSReza Sabdar void 14532654012fSReza Sabdar ndmp_stop_local_reader(ndmpd_session_t *session, tlm_commands_t *cmds) 14542654012fSReza Sabdar { 14552654012fSReza Sabdar if (session != NULL) { 14562654012fSReza Sabdar if (session->ns_data.dd_sock == -1) { 14572654012fSReza Sabdar /* 14582654012fSReza Sabdar * 2-way restore. 14592654012fSReza Sabdar */ 14602654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "2-way restore"); 14612654012fSReza Sabdar if (cmds != NULL && cmds->tcs_reader_count > 0) { 14622654012fSReza Sabdar nlp_event_rv_set(session, -2); 14632654012fSReza Sabdar nlp_event_nw(session); 14642654012fSReza Sabdar } 14652654012fSReza Sabdar } 14662654012fSReza Sabdar } 14672654012fSReza Sabdar } 14682654012fSReza Sabdar 14692654012fSReza Sabdar 14702654012fSReza Sabdar /* 14712654012fSReza Sabdar * Stops a mover reader thread (for remote backup only) 14722654012fSReza Sabdar * 14732654012fSReza Sabdar * Parameters: 14742654012fSReza Sabdar * session (input) - session pointer 14752654012fSReza Sabdar * cmds (input) - reader/writer command struct 14762654012fSReza Sabdar * 14772654012fSReza Sabdar * Returns: 14782654012fSReza Sabdar * void 14792654012fSReza Sabdar */ 14802654012fSReza Sabdar void 14812654012fSReza Sabdar ndmp_stop_remote_reader(ndmpd_session_t *session) 14822654012fSReza Sabdar { 14832654012fSReza Sabdar if (session != NULL) { 14842654012fSReza Sabdar if (session->ns_data.dd_sock >= 0) { 14852654012fSReza Sabdar /* 14862654012fSReza Sabdar * 3-way restore. 14872654012fSReza Sabdar */ 14882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 14892654012fSReza Sabdar "data.sock: %d", session->ns_data.dd_sock); 14902654012fSReza Sabdar (void) close(session->ns_data.dd_sock); 14912654012fSReza Sabdar session->ns_data.dd_sock = -1; 14922654012fSReza Sabdar } 14932654012fSReza Sabdar } 14942654012fSReza Sabdar } 14952654012fSReza Sabdar 14962654012fSReza Sabdar 14972654012fSReza Sabdar /* 14982654012fSReza Sabdar * ndmp_wait_for_reader 14992654012fSReza Sabdar * 15002654012fSReza Sabdar * Wait for a reader until get done (busy wait) 15012654012fSReza Sabdar */ 15022654012fSReza Sabdar void 15032654012fSReza Sabdar ndmp_wait_for_reader(tlm_commands_t *cmds) 15042654012fSReza Sabdar { 15052654012fSReza Sabdar if (cmds == NULL) { 15062654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 15072654012fSReza Sabdar } else { 15082654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15092654012fSReza Sabdar "reader_count: %d", cmds->tcs_reader_count); 15102654012fSReza Sabdar 15112654012fSReza Sabdar while (cmds->tcs_reader_count > 0) 15122654012fSReza Sabdar (void) sleep(1); 15132654012fSReza Sabdar } 15142654012fSReza Sabdar } 15152654012fSReza Sabdar 15162654012fSReza Sabdar 15172654012fSReza Sabdar /* 15182654012fSReza Sabdar * ndmp_open_list_find 15192654012fSReza Sabdar * 15202654012fSReza Sabdar * Find a specific device in the open list 15212654012fSReza Sabdar * 15222654012fSReza Sabdar * Parameters: 15232654012fSReza Sabdar * dev (input) - device name 15242654012fSReza Sabdar * sid (input) - SCSI target ID 15252654012fSReza Sabdar * lun (input) - LUN number 15262654012fSReza Sabdar * 15272654012fSReza Sabdar * Returns: 15282654012fSReza Sabdar * pointer to the open list entry 15292654012fSReza Sabdar */ 15302654012fSReza Sabdar struct open_list * 15312654012fSReza Sabdar ndmp_open_list_find(char *dev, int sid, int lun) 15322654012fSReza Sabdar { 15332654012fSReza Sabdar struct ol_head *olhp; 15342654012fSReza Sabdar struct open_list *olp; 15352654012fSReza Sabdar 15362654012fSReza Sabdar if (dev == NULL || *dev == '\0') { 15372654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 15382654012fSReza Sabdar return (NULL); 15392654012fSReza Sabdar } 15402654012fSReza Sabdar 15412654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 15422654012fSReza Sabdar olhp = &ol_head; 15432654012fSReza Sabdar for (olp = LIST_FIRST(olhp); olp != NULL; olp = LIST_NEXT(olp, ol_q)) 15442654012fSReza Sabdar if (strcmp(olp->ol_devnm, dev) == 0 && olp->ol_sid == sid && 15452654012fSReza Sabdar olp->ol_lun == lun) { 15462654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 15472654012fSReza Sabdar return (olp); 15482654012fSReza Sabdar } 15492654012fSReza Sabdar 15502654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 15512654012fSReza Sabdar return (NULL); 15522654012fSReza Sabdar } 15532654012fSReza Sabdar 15542654012fSReza Sabdar 15552654012fSReza Sabdar /* 15562654012fSReza Sabdar * ndmp_open_list_add 15572654012fSReza Sabdar * 15582654012fSReza Sabdar * Add a specific device to the open list 15592654012fSReza Sabdar * 15602654012fSReza Sabdar * Parameters: 15612654012fSReza Sabdar * conn (input) - connection pointer 15622654012fSReza Sabdar * dev (input) - device name 15632654012fSReza Sabdar * sid (input) - SCSI target ID 15642654012fSReza Sabdar * lun (input) - LUN number 15652654012fSReza Sabdar * fd (input) - the device file descriptor 15662654012fSReza Sabdar * 15672654012fSReza Sabdar * Returns: 15682654012fSReza Sabdar * errno 15692654012fSReza Sabdar */ 15702654012fSReza Sabdar int 15712654012fSReza Sabdar ndmp_open_list_add(ndmp_connection_t *conn, char *dev, int sid, int lun, int fd) 15722654012fSReza Sabdar { 15732654012fSReza Sabdar int err; 15742654012fSReza Sabdar struct ol_head *olhp; 15752654012fSReza Sabdar struct open_list *olp; 15762654012fSReza Sabdar 15772654012fSReza Sabdar if (dev == NULL || *dev == '\0') { 15782654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 15792654012fSReza Sabdar return (EINVAL); 15802654012fSReza Sabdar } 15812654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15822654012fSReza Sabdar "conn: 0x%08x, dev: %s, sid: %d, lun: %d", conn, dev, sid, lun); 15832654012fSReza Sabdar 15842654012fSReza Sabdar err = 0; 15852654012fSReza Sabdar olhp = &ol_head; 15862654012fSReza Sabdar 15872654012fSReza Sabdar if ((olp = ndmp_open_list_find(dev, sid, lun)) != NULL) { 15882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "already in list"); 15892654012fSReza Sabdar /* 15902654012fSReza Sabdar * The adapter handle can be opened many times by the clients. 15912654012fSReza Sabdar * Only when the target is set, we must check and reject the 15922654012fSReza Sabdar * open request if the device is already being used by another 15932654012fSReza Sabdar * session. 15942654012fSReza Sabdar */ 15952654012fSReza Sabdar if (sid == -1) 15962654012fSReza Sabdar olp->ol_nref++; 15972654012fSReza Sabdar else 15982654012fSReza Sabdar err = EBUSY; 15992654012fSReza Sabdar } else if ((olp = ndmp_malloc(sizeof (struct open_list))) == NULL) { 16002654012fSReza Sabdar err = ENOMEM; 16012654012fSReza Sabdar } else if ((olp->ol_devnm = strdup(dev)) == NULL) { 16022654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Out of memory."); 16032654012fSReza Sabdar free(olp); 16042654012fSReza Sabdar err = ENOMEM; 16052654012fSReza Sabdar } else { 16062654012fSReza Sabdar olp->cl_conn = conn; 16072654012fSReza Sabdar olp->ol_nref = 1; 16082654012fSReza Sabdar olp->ol_sid = sid; 16092654012fSReza Sabdar olp->ol_lun = lun; 16102654012fSReza Sabdar if (fd > 0) 16112654012fSReza Sabdar olp->ol_fd = fd; 16122654012fSReza Sabdar else 16132654012fSReza Sabdar olp->ol_fd = -1; 16142654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 16152654012fSReza Sabdar LIST_INSERT_HEAD(olhp, olp, ol_q); 16162654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 16172654012fSReza Sabdar } 16182654012fSReza Sabdar 16192654012fSReza Sabdar return (err); 16202654012fSReza Sabdar } 16212654012fSReza Sabdar 16222654012fSReza Sabdar 16232654012fSReza Sabdar /* 16242654012fSReza Sabdar * ndmp_open_list_del 16252654012fSReza Sabdar * 16262654012fSReza Sabdar * Delete a specific device from the open list 16272654012fSReza Sabdar * 16282654012fSReza Sabdar * Parameters: 16292654012fSReza Sabdar * dev (input) - device name 16302654012fSReza Sabdar * sid (input) - SCSI target ID 16312654012fSReza Sabdar * lun (input) - LUN number 16322654012fSReza Sabdar * 16332654012fSReza Sabdar * Returns: 16342654012fSReza Sabdar * errno 16352654012fSReza Sabdar */ 16362654012fSReza Sabdar int 16372654012fSReza Sabdar ndmp_open_list_del(char *dev, int sid, int lun) 16382654012fSReza Sabdar { 16392654012fSReza Sabdar struct open_list *olp; 16402654012fSReza Sabdar 16412654012fSReza Sabdar if (dev == NULL || *dev == '\0') { 16422654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 16432654012fSReza Sabdar return (EINVAL); 16442654012fSReza Sabdar } 16452654012fSReza Sabdar if ((olp = ndmp_open_list_find(dev, sid, lun)) == NULL) { 16462654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s not found", dev); 16472654012fSReza Sabdar return (ENOENT); 16482654012fSReza Sabdar } 16492654012fSReza Sabdar 16502654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 16512654012fSReza Sabdar if (--olp->ol_nref <= 0) { 16522654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 16532654012fSReza Sabdar "Removed dev: %s, sid: %d, lun: %d", dev, sid, lun); 16542654012fSReza Sabdar LIST_REMOVE(olp, ol_q); 16552654012fSReza Sabdar free(olp->ol_devnm); 16562654012fSReza Sabdar free(olp); 16572654012fSReza Sabdar } 16582654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 16592654012fSReza Sabdar 16602654012fSReza Sabdar return (0); 16612654012fSReza Sabdar } 16622654012fSReza Sabdar 16632654012fSReza Sabdar 16642654012fSReza Sabdar /* 16652654012fSReza Sabdar * ndmp_open_list_release 16662654012fSReza Sabdar * 16672654012fSReza Sabdar * Close all the resources belonging to this connection. 16682654012fSReza Sabdar * 16692654012fSReza Sabdar * Parameters: 16702654012fSReza Sabdar * ndmp_connection_t *conn : connection identifier 16712654012fSReza Sabdar * 16722654012fSReza Sabdar * Returns: 16732654012fSReza Sabdar * void 16742654012fSReza Sabdar */ 16752654012fSReza Sabdar void 16762654012fSReza Sabdar ndmp_open_list_release(ndmp_connection_t *conn) 16772654012fSReza Sabdar { 16782654012fSReza Sabdar struct ol_head *olhp = &ol_head; 16792654012fSReza Sabdar struct open_list *olp; 16802654012fSReza Sabdar struct open_list *next; 16812654012fSReza Sabdar 16822654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 16832654012fSReza Sabdar olp = LIST_FIRST(olhp); 16842654012fSReza Sabdar while (olp != NULL) { 16852654012fSReza Sabdar next = LIST_NEXT(olp, ol_q); 16862654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "olp->conn 0x%08x", olp->cl_conn); 16872654012fSReza Sabdar if (olp->cl_conn == conn) { 16882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 16892654012fSReza Sabdar "Removed dev: %s, sid: %d, lun: %d", 16902654012fSReza Sabdar olp->ol_devnm, olp->ol_sid, olp->ol_lun); 16912654012fSReza Sabdar LIST_REMOVE(olp, ol_q); 16922654012fSReza Sabdar if (olp->ol_fd > 0) 16932654012fSReza Sabdar (void) close(olp->ol_fd); 16942654012fSReza Sabdar free(olp->ol_devnm); 16952654012fSReza Sabdar free(olp); 16962654012fSReza Sabdar } 16972654012fSReza Sabdar olp = next; 16982654012fSReza Sabdar } 16992654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 17002654012fSReza Sabdar } 17012654012fSReza Sabdar 17022654012fSReza Sabdar 17032654012fSReza Sabdar /* 17042654012fSReza Sabdar * ndmp_stop_buffer_worker 17052654012fSReza Sabdar * 17062654012fSReza Sabdar * Stop all reader and writer threads for a specific buffer. 17072654012fSReza Sabdar * 17082654012fSReza Sabdar * Parameters: 17092654012fSReza Sabdar * session (input) - session pointer 17102654012fSReza Sabdar * 17112654012fSReza Sabdar * Returns: 17122654012fSReza Sabdar * void 17132654012fSReza Sabdar */ 17142654012fSReza Sabdar void 17152654012fSReza Sabdar ndmp_stop_buffer_worker(ndmpd_session_t *session) 17162654012fSReza Sabdar { 17172654012fSReza Sabdar ndmp_lbr_params_t *nlp; 17182654012fSReza Sabdar tlm_commands_t *cmds; 17192654012fSReza Sabdar 17202654012fSReza Sabdar session->ns_tape.td_pos = 0; 17212654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 17222654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 17232654012fSReza Sabdar } else { 17242654012fSReza Sabdar cmds = &nlp->nlp_cmds; 17252654012fSReza Sabdar if (cmds->tcs_command == NULL) { 17262654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL"); 17272654012fSReza Sabdar } else { 17282654012fSReza Sabdar cmds->tcs_reader = cmds->tcs_writer = TLM_ABORT; 17292654012fSReza Sabdar cmds->tcs_command->tc_reader = TLM_ABORT; 17302654012fSReza Sabdar cmds->tcs_command->tc_writer = TLM_ABORT; 17312654012fSReza Sabdar while (cmds->tcs_reader_count > 0 || 17322654012fSReza Sabdar cmds->tcs_writer_count > 0) { 17332654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 17342654012fSReza Sabdar "trying to stop buffer worker"); 17352654012fSReza Sabdar (void) sleep(1); 17362654012fSReza Sabdar } 17372654012fSReza Sabdar } 17382654012fSReza Sabdar } 17392654012fSReza Sabdar } 17402654012fSReza Sabdar 17412654012fSReza Sabdar 17422654012fSReza Sabdar /* 17432654012fSReza Sabdar * ndmp_stop_reader_thread 17442654012fSReza Sabdar * 17452654012fSReza Sabdar * Stop only the reader threads of a specific buffer 17462654012fSReza Sabdar * 17472654012fSReza Sabdar * Parameters: 17482654012fSReza Sabdar * session (input) - session pointer 17492654012fSReza Sabdar * 17502654012fSReza Sabdar * Returns: 17512654012fSReza Sabdar * void 17522654012fSReza Sabdar */ 17532654012fSReza Sabdar void 17542654012fSReza Sabdar ndmp_stop_reader_thread(ndmpd_session_t *session) 17552654012fSReza Sabdar { 17562654012fSReza Sabdar ndmp_lbr_params_t *nlp; 17572654012fSReza Sabdar tlm_commands_t *cmds; 17582654012fSReza Sabdar 17592654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 17602654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 17612654012fSReza Sabdar } else { 17622654012fSReza Sabdar cmds = &nlp->nlp_cmds; 17632654012fSReza Sabdar if (cmds->tcs_command == NULL) { 17642654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL"); 17652654012fSReza Sabdar } else { 17662654012fSReza Sabdar cmds->tcs_reader = TLM_ABORT; 17672654012fSReza Sabdar cmds->tcs_command->tc_reader = TLM_ABORT; 17682654012fSReza Sabdar while (cmds->tcs_reader_count > 0) { 17692654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 17702654012fSReza Sabdar "trying to stop reader thread"); 17712654012fSReza Sabdar (void) sleep(1); 17722654012fSReza Sabdar } 17732654012fSReza Sabdar } 17742654012fSReza Sabdar } 17752654012fSReza Sabdar } 17762654012fSReza Sabdar 17772654012fSReza Sabdar 17782654012fSReza Sabdar /* 17792654012fSReza Sabdar * ndmp_stop_reader_thread 17802654012fSReza Sabdar * 17812654012fSReza Sabdar * Stop only the writer threads of a specific buffer 17822654012fSReza Sabdar * 17832654012fSReza Sabdar * Parameters: 17842654012fSReza Sabdar * session (input) - session pointer 17852654012fSReza Sabdar * 17862654012fSReza Sabdar * Returns: 17872654012fSReza Sabdar * void 17882654012fSReza Sabdar */ 17892654012fSReza Sabdar void 17902654012fSReza Sabdar ndmp_stop_writer_thread(ndmpd_session_t *session) 17912654012fSReza Sabdar { 17922654012fSReza Sabdar ndmp_lbr_params_t *nlp; 17932654012fSReza Sabdar tlm_commands_t *cmds; 17942654012fSReza Sabdar 17952654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 17962654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 17972654012fSReza Sabdar } else { 17982654012fSReza Sabdar cmds = &nlp->nlp_cmds; 17992654012fSReza Sabdar if (cmds->tcs_command == NULL) { 18002654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL"); 18012654012fSReza Sabdar } else { 18022654012fSReza Sabdar cmds->tcs_writer = TLM_ABORT; 18032654012fSReza Sabdar cmds->tcs_command->tc_writer = TLM_ABORT; 18042654012fSReza Sabdar while (cmds->tcs_writer_count > 0) { 18052654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 18062654012fSReza Sabdar "trying to stop writer thread"); 18072654012fSReza Sabdar (void) sleep(1); 18082654012fSReza Sabdar } 18092654012fSReza Sabdar } 18102654012fSReza Sabdar } 18112654012fSReza Sabdar } 18122654012fSReza Sabdar 18132654012fSReza Sabdar 18142654012fSReza Sabdar /* 18152654012fSReza Sabdar * ndmp_free_reader_writer_ipc 18162654012fSReza Sabdar * 18172654012fSReza Sabdar * Free and release the reader/writer buffers and the IPC structure 18182654012fSReza Sabdar * for reader and writer threads. 18192654012fSReza Sabdar * 18202654012fSReza Sabdar * Parameters: 18212654012fSReza Sabdar * session (input) - session pointer 18222654012fSReza Sabdar * 18232654012fSReza Sabdar * Returns: 18242654012fSReza Sabdar * void 18252654012fSReza Sabdar */ 18262654012fSReza Sabdar void 18272654012fSReza Sabdar ndmp_free_reader_writer_ipc(ndmpd_session_t *session) 18282654012fSReza Sabdar { 18292654012fSReza Sabdar ndmp_lbr_params_t *nlp; 18302654012fSReza Sabdar tlm_commands_t *cmds; 18312654012fSReza Sabdar 18322654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 18332654012fSReza Sabdar cmds = &nlp->nlp_cmds; 18342654012fSReza Sabdar if (cmds->tcs_command != NULL) { 18352654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command->tc_ref: %d", 18362654012fSReza Sabdar cmds->tcs_command->tc_ref); 18372654012fSReza Sabdar tlm_release_reader_writer_ipc(cmds->tcs_command); 18382654012fSReza Sabdar } 18392654012fSReza Sabdar } 18402654012fSReza Sabdar } 18412654012fSReza Sabdar 18422654012fSReza Sabdar 18432654012fSReza Sabdar /* 18442654012fSReza Sabdar * ndmp_waitfor_op 18452654012fSReza Sabdar * 18462654012fSReza Sabdar * Wait for a session reference count to drop to zero 18472654012fSReza Sabdar * 18482654012fSReza Sabdar * Parameters: 18492654012fSReza Sabdar * session (input) - session pointer 18502654012fSReza Sabdar * 18512654012fSReza Sabdar * Returns: 18522654012fSReza Sabdar * void 18532654012fSReza Sabdar */ 18542654012fSReza Sabdar void 18552654012fSReza Sabdar ndmp_waitfor_op(ndmpd_session_t *session) 18562654012fSReza Sabdar { 18572654012fSReza Sabdar if (session != NULL) { 18582654012fSReza Sabdar while (session->ns_nref > 0) { 18592654012fSReza Sabdar (void) sleep(1); 18602654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 18612654012fSReza Sabdar "waiting for session nref: %d", session->ns_nref); 18622654012fSReza Sabdar } 18632654012fSReza Sabdar } 18642654012fSReza Sabdar } 18652654012fSReza Sabdar 18662654012fSReza Sabdar 18672654012fSReza Sabdar /* 18682654012fSReza Sabdar * ndmp_session_ref 18692654012fSReza Sabdar * 18702654012fSReza Sabdar * Increment the reference count of the session 18712654012fSReza Sabdar * 18722654012fSReza Sabdar * Parameters: 18732654012fSReza Sabdar * session (input) - session pointer 18742654012fSReza Sabdar * 18752654012fSReza Sabdar * Returns: 18762654012fSReza Sabdar * void 18772654012fSReza Sabdar */ 18782654012fSReza Sabdar void 18792654012fSReza Sabdar ndmp_session_ref(ndmpd_session_t *session) 18802654012fSReza Sabdar { 18812654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 18822654012fSReza Sabdar session->ns_nref++; 18832654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 18842654012fSReza Sabdar } 18852654012fSReza Sabdar 18862654012fSReza Sabdar 18872654012fSReza Sabdar /* 18882654012fSReza Sabdar * ndmp_session_unref 18892654012fSReza Sabdar * 18902654012fSReza Sabdar * Decrement the reference count of the session 18912654012fSReza Sabdar * 18922654012fSReza Sabdar * Parameters: 18932654012fSReza Sabdar * session (input) - session pointer 18942654012fSReza Sabdar * 18952654012fSReza Sabdar * Returns: 18962654012fSReza Sabdar * void 18972654012fSReza Sabdar */ 18982654012fSReza Sabdar void 18992654012fSReza Sabdar ndmp_session_unref(ndmpd_session_t *session) 19002654012fSReza Sabdar { 19012654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 19022654012fSReza Sabdar session->ns_nref--; 19032654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 19042654012fSReza Sabdar } 19052654012fSReza Sabdar 19062654012fSReza Sabdar 19072654012fSReza Sabdar /* 19082654012fSReza Sabdar * ndmp_addr2str_v3 19092654012fSReza Sabdar * 19102654012fSReza Sabdar * Convert the address type to a string 19112654012fSReza Sabdar * 19122654012fSReza Sabdar * Parameters: 19132654012fSReza Sabdar * type (input) - address type 19142654012fSReza Sabdar * 19152654012fSReza Sabdar * Returns: 19162654012fSReza Sabdar * type in string 19172654012fSReza Sabdar */ 19182654012fSReza Sabdar char * 19192654012fSReza Sabdar ndmp_addr2str_v3(ndmp_addr_type type) 19202654012fSReza Sabdar { 19212654012fSReza Sabdar char *rv; 19222654012fSReza Sabdar 19232654012fSReza Sabdar switch (type) { 19242654012fSReza Sabdar case NDMP_ADDR_LOCAL: 19252654012fSReza Sabdar rv = "Local"; 19262654012fSReza Sabdar break; 19272654012fSReza Sabdar case NDMP_ADDR_TCP: 19282654012fSReza Sabdar rv = "TCP"; 19292654012fSReza Sabdar break; 19302654012fSReza Sabdar case NDMP_ADDR_FC: 19312654012fSReza Sabdar rv = "FC"; 19322654012fSReza Sabdar break; 19332654012fSReza Sabdar case NDMP_ADDR_IPC: 19342654012fSReza Sabdar rv = "IPC"; 19352654012fSReza Sabdar break; 19362654012fSReza Sabdar default: 19372654012fSReza Sabdar rv = "Unknown"; 19382654012fSReza Sabdar } 19392654012fSReza Sabdar 19402654012fSReza Sabdar return (rv); 19412654012fSReza Sabdar } 19422654012fSReza Sabdar 19432654012fSReza Sabdar 19442654012fSReza Sabdar /* 19452654012fSReza Sabdar * ndmp_valid_v3addr_type 19462654012fSReza Sabdar * 19472654012fSReza Sabdar * Make sure that the NDMP address is from any of the 19482654012fSReza Sabdar * valid types 19492654012fSReza Sabdar * 19502654012fSReza Sabdar * Parameters: 19512654012fSReza Sabdar * type (input) - address type 19522654012fSReza Sabdar * 19532654012fSReza Sabdar * Returns: 19542654012fSReza Sabdar * 1: valid 19552654012fSReza Sabdar * 0: invalid 19562654012fSReza Sabdar */ 19572654012fSReza Sabdar boolean_t 19582654012fSReza Sabdar ndmp_valid_v3addr_type(ndmp_addr_type type) 19592654012fSReza Sabdar { 19602654012fSReza Sabdar boolean_t rv; 19612654012fSReza Sabdar 19622654012fSReza Sabdar switch (type) { 19632654012fSReza Sabdar case NDMP_ADDR_LOCAL: 19642654012fSReza Sabdar case NDMP_ADDR_TCP: 19652654012fSReza Sabdar case NDMP_ADDR_FC: 19662654012fSReza Sabdar case NDMP_ADDR_IPC: 19672654012fSReza Sabdar rv = TRUE; 19682654012fSReza Sabdar break; 19692654012fSReza Sabdar default: 19702654012fSReza Sabdar rv = FALSE; 19712654012fSReza Sabdar } 19722654012fSReza Sabdar 19732654012fSReza Sabdar return (rv); 19742654012fSReza Sabdar } 19752654012fSReza Sabdar 19762654012fSReza Sabdar 19772654012fSReza Sabdar /* 19782654012fSReza Sabdar * ndmp_copy_addr_v3 19792654012fSReza Sabdar * 19802654012fSReza Sabdar * Copy NDMP address from source to destination (V2 and V3 only) 19812654012fSReza Sabdar * 19822654012fSReza Sabdar * Parameters: 19832654012fSReza Sabdar * dst (ouput) - destination address 19842654012fSReza Sabdar * src (input) - source address 19852654012fSReza Sabdar * 19862654012fSReza Sabdar * Returns: 19872654012fSReza Sabdar * void 19882654012fSReza Sabdar */ 19892654012fSReza Sabdar void 19902654012fSReza Sabdar ndmp_copy_addr_v3(ndmp_addr_v3 *dst, ndmp_addr_v3 *src) 19912654012fSReza Sabdar { 19922654012fSReza Sabdar dst->addr_type = src->addr_type; 19932654012fSReza Sabdar switch (src->addr_type) { 19942654012fSReza Sabdar case NDMP_ADDR_LOCAL: 19952654012fSReza Sabdar /* nothing */ 19962654012fSReza Sabdar break; 19972654012fSReza Sabdar case NDMP_ADDR_TCP: 19982654012fSReza Sabdar dst->tcp_ip_v3 = htonl(src->tcp_ip_v3); 19992654012fSReza Sabdar dst->tcp_port_v3 = src->tcp_port_v3; 20002654012fSReza Sabdar break; 20012654012fSReza Sabdar case NDMP_ADDR_FC: 20022654012fSReza Sabdar case NDMP_ADDR_IPC: 20032654012fSReza Sabdar default: 20042654012fSReza Sabdar break; 20052654012fSReza Sabdar } 20062654012fSReza Sabdar } 20072654012fSReza Sabdar 20082654012fSReza Sabdar 20092654012fSReza Sabdar /* 20102654012fSReza Sabdar * ndmp_copy_addr_v4 20112654012fSReza Sabdar * 20122654012fSReza Sabdar * Copy NDMP address from source to destination. V4 has a extra 20132654012fSReza Sabdar * environment list inside the address too which needs to be copied. 20142654012fSReza Sabdar * 20152654012fSReza Sabdar * Parameters: 20162654012fSReza Sabdar * dst (ouput) - destination address 20172654012fSReza Sabdar * src (input) - source address 20182654012fSReza Sabdar * 20192654012fSReza Sabdar * Returns: 20202654012fSReza Sabdar * void 20212654012fSReza Sabdar */ 20222654012fSReza Sabdar void 20232654012fSReza Sabdar ndmp_copy_addr_v4(ndmp_addr_v4 *dst, ndmp_addr_v4 *src) 20242654012fSReza Sabdar { 20252654012fSReza Sabdar int i; 20262654012fSReza Sabdar 20272654012fSReza Sabdar dst->addr_type = src->addr_type; 20282654012fSReza Sabdar dst->tcp_len_v4 = src->tcp_len_v4; 20292654012fSReza Sabdar switch (src->addr_type) { 20302654012fSReza Sabdar case NDMP_ADDR_LOCAL: 20312654012fSReza Sabdar /* nothing */ 20322654012fSReza Sabdar break; 20332654012fSReza Sabdar case NDMP_ADDR_TCP: 20342654012fSReza Sabdar dst->tcp_addr_v4 = ndmp_malloc(sizeof (ndmp_tcp_addr_v4) * 20352654012fSReza Sabdar src->tcp_len_v4); 20362654012fSReza Sabdar if (dst->tcp_addr_v4 == 0) 20372654012fSReza Sabdar return; 20382654012fSReza Sabdar 20392654012fSReza Sabdar for (i = 0; i < src->tcp_len_v4; i++) { 20402654012fSReza Sabdar dst->tcp_ip_v4(i) = htonl(src->tcp_ip_v4(i)); 20412654012fSReza Sabdar dst->tcp_port_v4(i) = src->tcp_port_v4(i); 20422654012fSReza Sabdar dst->tcp_env_v4(i).addr_env_len = 0; /* Solaris */ 20432654012fSReza Sabdar dst->tcp_env_v4(i).addr_env_val = 0; /* Solaris */ 20442654012fSReza Sabdar } 20452654012fSReza Sabdar break; 20462654012fSReza Sabdar case NDMP_ADDR_FC: 20472654012fSReza Sabdar case NDMP_ADDR_IPC: 20482654012fSReza Sabdar default: 20492654012fSReza Sabdar break; 20502654012fSReza Sabdar } 20512654012fSReza Sabdar } 20522654012fSReza Sabdar 20532654012fSReza Sabdar 20542654012fSReza Sabdar /* 20552654012fSReza Sabdar * ndmp_connect_sock_v3 20562654012fSReza Sabdar * 20572654012fSReza Sabdar * Creates a socket and connects to the specified address/port 20582654012fSReza Sabdar * 20592654012fSReza Sabdar * Parameters: 20602654012fSReza Sabdar * addr (input) - IP address 20612654012fSReza Sabdar * port (input) - port number 20622654012fSReza Sabdar * 20632654012fSReza Sabdar * Returns: 20642654012fSReza Sabdar * 0: on success 20652654012fSReza Sabdar * -1: otherwise 20662654012fSReza Sabdar */ 20672654012fSReza Sabdar int 20682654012fSReza Sabdar ndmp_connect_sock_v3(ulong_t addr, ushort_t port) 20692654012fSReza Sabdar { 20702654012fSReza Sabdar int sock; 20712654012fSReza Sabdar struct sockaddr_in sin; 20722654012fSReza Sabdar int flag = 1; 20732654012fSReza Sabdar 20742654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "addr %s:%d", inet_ntoa(IN_ADDR(addr)), port); 20752654012fSReza Sabdar 20762654012fSReza Sabdar sock = socket(AF_INET, SOCK_STREAM, 0); 20772654012fSReza Sabdar if (sock < 0) { 20782654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Socket error: %m"); 20792654012fSReza Sabdar return (-1); 20802654012fSReza Sabdar } 20812654012fSReza Sabdar 20822654012fSReza Sabdar (void) memset((void *) &sin, 0, sizeof (sin)); 20832654012fSReza Sabdar sin.sin_family = AF_INET; 20842654012fSReza Sabdar sin.sin_addr.s_addr = htonl(addr); 20852654012fSReza Sabdar sin.sin_port = htons(port); 20862654012fSReza Sabdar if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 20872654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Connect error: %m"); 20882654012fSReza Sabdar (void) close(sock); 20892654012fSReza Sabdar sock = -1; 20902654012fSReza Sabdar } else { 20912654012fSReza Sabdar if (ndmp_sbs > 0) 20922654012fSReza Sabdar ndmp_set_socket_snd_buf(sock, ndmp_sbs*KILOBYTE); 20932654012fSReza Sabdar if (ndmp_rbs > 0) 20942654012fSReza Sabdar ndmp_set_socket_rcv_buf(sock, ndmp_rbs*KILOBYTE); 20952654012fSReza Sabdar 20962654012fSReza Sabdar ndmp_set_socket_nodelay(sock); 20972654012fSReza Sabdar (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &flag, 20982654012fSReza Sabdar sizeof (flag)); 20992654012fSReza Sabdar 21002654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sock %d", sock); 21012654012fSReza Sabdar } 21022654012fSReza Sabdar 21032654012fSReza Sabdar return (sock); 21042654012fSReza Sabdar } 21052654012fSReza Sabdar 21062654012fSReza Sabdar /* 21072654012fSReza Sabdar * ndmp_create_socket 21082654012fSReza Sabdar * 21092654012fSReza Sabdar * Creates a socket for listening for accepting data connections. 21102654012fSReza Sabdar * 21112654012fSReza Sabdar * Parameters: 21122654012fSReza Sabdar * session (input) - session pointer. 21132654012fSReza Sabdar * addr (output) - location to store address of socket. 21142654012fSReza Sabdar * port (output) - location to store port of socket. 21152654012fSReza Sabdar * 21162654012fSReza Sabdar * Returns: 21172654012fSReza Sabdar * 0 - success. 21182654012fSReza Sabdar * -1 - error. 21192654012fSReza Sabdar */ 21202654012fSReza Sabdar int 21212654012fSReza Sabdar ndmp_create_socket(ulong_t *addr, ushort_t *port) 21222654012fSReza Sabdar { 21232654012fSReza Sabdar char *p; 21242654012fSReza Sabdar int length; 21252654012fSReza Sabdar int sd; 21262654012fSReza Sabdar struct sockaddr_in sin; 21272654012fSReza Sabdar 21282654012fSReza Sabdar p = ndmpd_get_prop(NDMP_MOVER_NIC); 21292654012fSReza Sabdar 21302654012fSReza Sabdar if (!p || *p == 0) 21312654012fSReza Sabdar p = gethostaddr(); 21322654012fSReza Sabdar 21332654012fSReza Sabdar if (!p) { 21342654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Undetermined network port."); 21352654012fSReza Sabdar return (-1); 21362654012fSReza Sabdar } 21372654012fSReza Sabdar 21382654012fSReza Sabdar *addr = inet_addr(p); 21392654012fSReza Sabdar 21402654012fSReza Sabdar sd = socket(AF_INET, SOCK_STREAM, 0); 21412654012fSReza Sabdar if (sd < 0) { 21422654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Socket error: %m"); 21432654012fSReza Sabdar return (-1); 21442654012fSReza Sabdar } 21452654012fSReza Sabdar sin.sin_family = AF_INET; 21462654012fSReza Sabdar sin.sin_addr.s_addr = INADDR_ANY; 21472654012fSReza Sabdar sin.sin_port = 0; 21482654012fSReza Sabdar length = sizeof (sin); 21492654012fSReza Sabdar 21502654012fSReza Sabdar if (bind(sd, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 21512654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Bind error: %m"); 21522654012fSReza Sabdar (void) close(sd); 21532654012fSReza Sabdar sd = -1; 21542654012fSReza Sabdar } else if (getsockname(sd, (struct sockaddr *)&sin, &length) < 0) { 21552654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "getsockname error: %m"); 21562654012fSReza Sabdar (void) close(sd); 21572654012fSReza Sabdar sd = -1; 21582654012fSReza Sabdar } else if (listen(sd, 5) < 0) { 21592654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Listen error: %m"); 21602654012fSReza Sabdar (void) close(sd); 21612654012fSReza Sabdar sd = -1; 21622654012fSReza Sabdar } else 21632654012fSReza Sabdar *port = sin.sin_port; 21642654012fSReza Sabdar 21652654012fSReza Sabdar return (sd); 21662654012fSReza Sabdar } 21672654012fSReza Sabdar 21682654012fSReza Sabdar 21692654012fSReza Sabdar /* 21702654012fSReza Sabdar * cctime 21712654012fSReza Sabdar * 21722654012fSReza Sabdar * Convert the specified time into a string. It's like 21732654012fSReza Sabdar * ctime(), but: 21742654012fSReza Sabdar * - chops the trailing '\n' of ctime. 21752654012fSReza Sabdar * - and returns "the epoch" if time is 0. 21762654012fSReza Sabdar * 21772654012fSReza Sabdar * Returns: 21782654012fSReza Sabdar * "": invalid argument. 21792654012fSReza Sabdar * "the epoch": if time is 0. 21802654012fSReza Sabdar * string format of the time. 21812654012fSReza Sabdar */ 21822654012fSReza Sabdar char * 21832654012fSReza Sabdar cctime(time_t *t) 21842654012fSReza Sabdar { 21852654012fSReza Sabdar char *bp, *cp; 218689f9eb87SReza Sabdar static char tbuf[BUFSIZ]; 21872654012fSReza Sabdar 21882654012fSReza Sabdar if (!t) 21892654012fSReza Sabdar return (""); 21902654012fSReza Sabdar 21912654012fSReza Sabdar if (*t == (time_t)0) 21922654012fSReza Sabdar return ("the epoch"); 21932654012fSReza Sabdar 219489f9eb87SReza Sabdar if ((bp = ctime_r(t, tbuf, BUFSIZ)) == NULL) 219589f9eb87SReza Sabdar return (""); 219689f9eb87SReza Sabdar 21972654012fSReza Sabdar cp = strchr(bp, '\n'); 21982654012fSReza Sabdar if (cp) 21992654012fSReza Sabdar *cp = '\0'; 22002654012fSReza Sabdar 22012654012fSReza Sabdar return (bp); 22022654012fSReza Sabdar } 22032654012fSReza Sabdar 22042654012fSReza Sabdar 22052654012fSReza Sabdar /* 22062654012fSReza Sabdar * ndmp_new_job_name 22072654012fSReza Sabdar * 22082654012fSReza Sabdar * Create a job name for each backup/restore to keep track 22092654012fSReza Sabdar * 22102654012fSReza Sabdar * Parameters: 22112654012fSReza Sabdar * jname (output) - job name 22122654012fSReza Sabdar * 22132654012fSReza Sabdar * Returns: 22142654012fSReza Sabdar * jname 22152654012fSReza Sabdar */ 22162654012fSReza Sabdar char * 22172654012fSReza Sabdar ndmp_new_job_name(char *jname) 22182654012fSReza Sabdar { 22192654012fSReza Sabdar if (jname != NULL) { 22202654012fSReza Sabdar (void) snprintf(jname, TLM_MAX_BACKUP_JOB_NAME, "%s%d", 22212654012fSReza Sabdar NDMP_RCF_BASENAME, ndmp_job_cnt++); 22222654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "jname: \"%s\"", jname); 22232654012fSReza Sabdar } 22242654012fSReza Sabdar 22252654012fSReza Sabdar return (jname); 22262654012fSReza Sabdar } 22272654012fSReza Sabdar 22282654012fSReza Sabdar 22292654012fSReza Sabdar /* 22302654012fSReza Sabdar * fs_is_valid_logvol 22312654012fSReza Sabdar * 22322654012fSReza Sabdar * Check if the log path exists 22332654012fSReza Sabdar * 22342654012fSReza Sabdar * Parameters: 22352654012fSReza Sabdar * path (input) - log path 22362654012fSReza Sabdar * 22372654012fSReza Sabdar * Returns: 22382654012fSReza Sabdar * FALSE: invalid 22392654012fSReza Sabdar * TRUE: valid 22402654012fSReza Sabdar */ 22412654012fSReza Sabdar boolean_t 22422654012fSReza Sabdar fs_is_valid_logvol(char *path) 22432654012fSReza Sabdar { 22442654012fSReza Sabdar struct stat64 st; 22452654012fSReza Sabdar 22462654012fSReza Sabdar if (stat64(path, &st) < 0) 22472654012fSReza Sabdar return (FALSE); 22482654012fSReza Sabdar 22492654012fSReza Sabdar return (TRUE); 22502654012fSReza Sabdar } 22512654012fSReza Sabdar 22522654012fSReza Sabdar 22532654012fSReza Sabdar /* 22542654012fSReza Sabdar * ndmpd_mk_temp 22552654012fSReza Sabdar * 22562654012fSReza Sabdar * Make a temporary file using the working directory path and the 22572654012fSReza Sabdar * jobname 22582654012fSReza Sabdar * 22592654012fSReza Sabdar * Parameters: 22602654012fSReza Sabdar * buf (output) - the temporary file name path 22612654012fSReza Sabdar * 22622654012fSReza Sabdar * Returns: 22632654012fSReza Sabdar * buf 22642654012fSReza Sabdar */ 22652654012fSReza Sabdar char * 22662654012fSReza Sabdar ndmpd_mk_temp(char *buf) 22672654012fSReza Sabdar { 22682654012fSReza Sabdar char fname[TLM_MAX_BACKUP_JOB_NAME]; 22692654012fSReza Sabdar const char *dir; 22702654012fSReza Sabdar char *rv; 22712654012fSReza Sabdar 22722654012fSReza Sabdar if (!buf) 22732654012fSReza Sabdar return (NULL); 22742654012fSReza Sabdar 22752654012fSReza Sabdar dir = ndmpd_get_prop(NDMP_DEBUG_PATH); 22762654012fSReza Sabdar if (dir == 0 || *dir == '\0') { 22772654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NDMP work path not specified"); 22782654012fSReza Sabdar return (0); 22792654012fSReza Sabdar } 22802654012fSReza Sabdar 22812654012fSReza Sabdar if (!fs_is_valid_logvol((char *)dir)) { 22822654012fSReza Sabdar NDMP_LOG(LOG_ERR, 22832654012fSReza Sabdar "Log file path cannot be on system volumes."); 22842654012fSReza Sabdar return (0); 22852654012fSReza Sabdar } 22862654012fSReza Sabdar 22872654012fSReza Sabdar dir += strspn(dir, " \t"); 22882654012fSReza Sabdar if (!*dir) { 22892654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NDMP work path not specified"); 22902654012fSReza Sabdar return (0); 22912654012fSReza Sabdar } 22922654012fSReza Sabdar 22932654012fSReza Sabdar rv = buf; 22942654012fSReza Sabdar (void) ndmp_new_job_name(fname); 22952654012fSReza Sabdar (void) tlm_cat_path(buf, (char *)dir, fname); 22962654012fSReza Sabdar 22972654012fSReza Sabdar return (rv); 22982654012fSReza Sabdar } 22992654012fSReza Sabdar 23002654012fSReza Sabdar 23012654012fSReza Sabdar /* 23022654012fSReza Sabdar * ndmpd_make_bk_dir_path 23032654012fSReza Sabdar * 23042654012fSReza Sabdar * Make a directory path for temporary files under the NDMP 23052654012fSReza Sabdar * working directory. 23062654012fSReza Sabdar * 23072654012fSReza Sabdar * Parameters: 23082654012fSReza Sabdar * buf (output) - result path 23092654012fSReza Sabdar * fname (input) - the file name 23102654012fSReza Sabdar * 23112654012fSReza Sabdar * Returns: 23122654012fSReza Sabdar * buf 23132654012fSReza Sabdar */ 23142654012fSReza Sabdar char * 23152654012fSReza Sabdar ndmpd_make_bk_dir_path(char *buf, char *fname) 23162654012fSReza Sabdar { 23172654012fSReza Sabdar const char *p; 23182654012fSReza Sabdar char *name; 23192654012fSReza Sabdar char path[PATH_MAX]; 23202654012fSReza Sabdar 23212654012fSReza Sabdar if (!buf || !fname || !*fname) 23222654012fSReza Sabdar return (NULL); 23232654012fSReza Sabdar 23242654012fSReza Sabdar p = ndmpd_get_prop(NDMP_DEBUG_PATH); 23252654012fSReza Sabdar if (p == NULL || *p == '\0' || !fs_is_valid_logvol((char *)p)) { 23262654012fSReza Sabdar return (NULL); 23272654012fSReza Sabdar } 23282654012fSReza Sabdar 23292654012fSReza Sabdar (void) strlcpy(path, (char *)p, PATH_MAX); 23302654012fSReza Sabdar (void) trim_whitespace(path); 23312654012fSReza Sabdar 23322654012fSReza Sabdar if ((name = strrchr(fname, '/')) == 0) 23332654012fSReza Sabdar name = fname; 23342654012fSReza Sabdar 23352654012fSReza Sabdar (void) tlm_cat_path(buf, path, name); 23362654012fSReza Sabdar return (buf); 23372654012fSReza Sabdar } 23382654012fSReza Sabdar 23392654012fSReza Sabdar 23402654012fSReza Sabdar /* 23412654012fSReza Sabdar * ndmp_is_chkpnt_root 23422654012fSReza Sabdar * 23432654012fSReza Sabdar * Is this a root checkpoint (snapshot) directory. 23442654012fSReza Sabdar * Note: a temporary function 23452654012fSReza Sabdar */ 23462654012fSReza Sabdar boolean_t 23472654012fSReza Sabdar ndmp_is_chkpnt_root(char *path) 23482654012fSReza Sabdar { 23492654012fSReza Sabdar struct stat64 st; 23502654012fSReza Sabdar 23512654012fSReza Sabdar if (stat64(path, &st) != 0) { 23522654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Couldn't stat path \"%s\"", path); 23532654012fSReza Sabdar return (TRUE); 23542654012fSReza Sabdar } 23552654012fSReza Sabdar return (FALSE); 23562654012fSReza Sabdar } 23572654012fSReza Sabdar 23582654012fSReza Sabdar 23592654012fSReza Sabdar /* 23602654012fSReza Sabdar * ndmpd_make_exc_list 23612654012fSReza Sabdar * 23622654012fSReza Sabdar * Make a list of files that should not be backed up. 23632654012fSReza Sabdar * 23642654012fSReza Sabdar * Parameters: 23652654012fSReza Sabdar * void 23662654012fSReza Sabdar * 23672654012fSReza Sabdar * Returns: 23682654012fSReza Sabdar * list - array of character strings 23692654012fSReza Sabdar */ 23702654012fSReza Sabdar char ** 23712654012fSReza Sabdar ndmpd_make_exc_list(void) 23722654012fSReza Sabdar { 23732654012fSReza Sabdar char *val, **cpp; 23742654012fSReza Sabdar int i, n; 23752654012fSReza Sabdar 23762654012fSReza Sabdar n = sizeof (exls); 23772654012fSReza Sabdar if ((cpp = ndmp_malloc(n)) != NULL) { 23782654012fSReza Sabdar for (i = 0; exls[i] != NULL; i++) 23792654012fSReza Sabdar cpp[i] = exls[i]; 23802654012fSReza Sabdar 23812654012fSReza Sabdar /* 23822654012fSReza Sabdar * If ndmpd_get_prop returns NULL, the array will be 23832654012fSReza Sabdar * null-terminated. 23842654012fSReza Sabdar */ 23852654012fSReza Sabdar val = ndmpd_get_prop(NDMP_DEBUG_PATH); 23862654012fSReza Sabdar cpp[i] = val; 23872654012fSReza Sabdar } 23882654012fSReza Sabdar 23892654012fSReza Sabdar return (cpp); 23902654012fSReza Sabdar } 23912654012fSReza Sabdar 23922654012fSReza Sabdar 23932654012fSReza Sabdar /* 23942654012fSReza Sabdar * ndmp_get_bk_dir_ino 23952654012fSReza Sabdar * 23962654012fSReza Sabdar * Get the inode number of the backup directory 23972654012fSReza Sabdar */ 23982654012fSReza Sabdar int 23992654012fSReza Sabdar ndmp_get_bk_dir_ino(ndmp_lbr_params_t *nlp) 24002654012fSReza Sabdar { 24012654012fSReza Sabdar int rv; 24022654012fSReza Sabdar struct stat64 st; 24032654012fSReza Sabdar 24042654012fSReza Sabdar if (stat64(nlp->nlp_backup_path, &st) != 0) { 24052654012fSReza Sabdar rv = -1; 24062654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Getting inode # of \"%s\"", 24072654012fSReza Sabdar nlp->nlp_backup_path); 24082654012fSReza Sabdar } else { 24092654012fSReza Sabdar rv = 0; 24102654012fSReza Sabdar nlp->nlp_bkdirino = st.st_ino; 24112654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkdirino: %lu", 24122654012fSReza Sabdar (uint_t)nlp->nlp_bkdirino); 24132654012fSReza Sabdar } 24142654012fSReza Sabdar 24152654012fSReza Sabdar return (rv); 24162654012fSReza Sabdar } 24172654012fSReza Sabdar 24182654012fSReza Sabdar 24192654012fSReza Sabdar /* 24202654012fSReza Sabdar * ndmp_check_utf8magic 24212654012fSReza Sabdar * 24222654012fSReza Sabdar * Check if the magic string for exists in the tar header. This 24232654012fSReza Sabdar * magic string (which also indicates that the file names are in 24242654012fSReza Sabdar * UTF8 format) is used as a crest to indetify our own tapes. 24252654012fSReza Sabdar * This checking is always done before all restores except DAR 24262654012fSReza Sabdar * restores. 24272654012fSReza Sabdar */ 24282654012fSReza Sabdar boolean_t 24292654012fSReza Sabdar ndmp_check_utf8magic(tlm_cmd_t *cmd) 24302654012fSReza Sabdar { 24312654012fSReza Sabdar char *cp; 24322654012fSReza Sabdar int err, len, actual_size; 24332654012fSReza Sabdar 24342654012fSReza Sabdar if (cmd == NULL) { 24352654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd == NULL"); 24362654012fSReza Sabdar return (FALSE); 24372654012fSReza Sabdar } 24382654012fSReza Sabdar if (cmd->tc_buffers == NULL) { 24392654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd->tc_buffers == NULL"); 24402654012fSReza Sabdar return (FALSE); 24412654012fSReza Sabdar } 24422654012fSReza Sabdar 24432654012fSReza Sabdar /* wait until the first buffer gets full. */ 24442654012fSReza Sabdar tlm_buffer_in_buf_wait(cmd->tc_buffers); 24452654012fSReza Sabdar 24462654012fSReza Sabdar err = actual_size = 0; 24472654012fSReza Sabdar cp = tlm_get_read_buffer(RECORDSIZE, &err, cmd->tc_buffers, 24482654012fSReza Sabdar &actual_size); 24492654012fSReza Sabdar if (cp == NULL) { 24502654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Can't read from buffers, err: %d", err); 24512654012fSReza Sabdar return (FALSE); 24522654012fSReza Sabdar } 24532654012fSReza Sabdar len = strlen(NDMPUTF8MAGIC); 24542654012fSReza Sabdar if (actual_size < len) { 24552654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Not enough data in the buffers"); 24562654012fSReza Sabdar return (FALSE); 24572654012fSReza Sabdar } 24582654012fSReza Sabdar 24592654012fSReza Sabdar return ((strncmp(cp, NDMPUTF8MAGIC, len) == 0) ? TRUE : FALSE); 24602654012fSReza Sabdar } 24612654012fSReza Sabdar 24622654012fSReza Sabdar 24632654012fSReza Sabdar /* 24642654012fSReza Sabdar * ndmp_get_cur_bk_time 24652654012fSReza Sabdar * 24662654012fSReza Sabdar * Get the backup checkpoint time. 24672654012fSReza Sabdar */ 24682654012fSReza Sabdar int 24692654012fSReza Sabdar ndmp_get_cur_bk_time(ndmp_lbr_params_t *nlp, time_t *tp, char *jname) 24702654012fSReza Sabdar { 24712654012fSReza Sabdar int err; 24722654012fSReza Sabdar 24732654012fSReza Sabdar if (!nlp || !nlp->nlp_backup_path || !tp) { 24742654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 24752654012fSReza Sabdar return (-1); 24762654012fSReza Sabdar } 24772654012fSReza Sabdar 24782654012fSReza Sabdar if (!fs_is_chkpnt_enabled(nlp->nlp_backup_path)) { 24792654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Not a chkpnt volume %s", 24802654012fSReza Sabdar nlp->nlp_backup_path); 24812654012fSReza Sabdar *tp = time(NULL); 24822654012fSReza Sabdar return (0); 24832654012fSReza Sabdar } 24842654012fSReza Sabdar 24852654012fSReza Sabdar err = tlm_get_chkpnt_time(nlp->nlp_backup_path, !NLP_ISCHKPNTED(nlp), 24862654012fSReza Sabdar tp, jname); 24872654012fSReza Sabdar if (err != 0) { 24882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Can't checkpoint time"); 24892654012fSReza Sabdar } else { 24902654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s", cctime(tp)); 24912654012fSReza Sabdar } 24922654012fSReza Sabdar 24932654012fSReza Sabdar return (err); 24942654012fSReza Sabdar } 24952654012fSReza Sabdar 24962654012fSReza Sabdar 24972654012fSReza Sabdar /* 24982654012fSReza Sabdar * get_relative_path 24992654012fSReza Sabdar */ 25002654012fSReza Sabdar char * 25012654012fSReza Sabdar ndmp_get_relative_path(char *base, char *fullpath) 25022654012fSReza Sabdar { 25032654012fSReza Sabdar char *p = fullpath; 25042654012fSReza Sabdar 25052654012fSReza Sabdar if (!base || !*base) 25062654012fSReza Sabdar return (fullpath); 25072654012fSReza Sabdar 25082654012fSReza Sabdar while (*base) { 25092654012fSReza Sabdar if (*base != *p) 25102654012fSReza Sabdar break; 25112654012fSReza Sabdar p++; base++; 25122654012fSReza Sabdar } 25132654012fSReza Sabdar 25142654012fSReza Sabdar if (*p == '/') 25152654012fSReza Sabdar p++; 25162654012fSReza Sabdar 25172654012fSReza Sabdar return ((*base) ? fullpath : p); 25182654012fSReza Sabdar } 25192654012fSReza Sabdar 25202654012fSReza Sabdar 25212654012fSReza Sabdar /* 25222654012fSReza Sabdar * ndmp_get_nlp 25232654012fSReza Sabdar * 25242654012fSReza Sabdar * Get NDMP local backup parameters 25252654012fSReza Sabdar * 25262654012fSReza Sabdar * Parameter: 25272654012fSReza Sabdar * session cooke 25282654012fSReza Sabdar * 25292654012fSReza Sabdar * Returns: 25302654012fSReza Sabdar * LBR structure 25312654012fSReza Sabdar */ 25322654012fSReza Sabdar ndmp_lbr_params_t * 25332654012fSReza Sabdar ndmp_get_nlp(void *cookie) 25342654012fSReza Sabdar { 25352654012fSReza Sabdar if (cookie == NULL) 25362654012fSReza Sabdar return (NULL); 25372654012fSReza Sabdar 25382654012fSReza Sabdar return (((ndmpd_session_t *)cookie)->ns_ndmp_lbr_params); 25392654012fSReza Sabdar } 25402654012fSReza Sabdar 25412654012fSReza Sabdar 25422654012fSReza Sabdar /* 25432654012fSReza Sabdar * is_tape_unit_ready 25442654012fSReza Sabdar * 25452654012fSReza Sabdar * Check if the tape device is ready or not 25462654012fSReza Sabdar */ 25472654012fSReza Sabdar boolean_t 25482654012fSReza Sabdar is_tape_unit_ready(char *adptnm, int dev_id) 25492654012fSReza Sabdar { 25502654012fSReza Sabdar int try; 25512654012fSReza Sabdar int fd = 0; 25522654012fSReza Sabdar 25532654012fSReza Sabdar try = TUR_MAX_TRY; 2554295e611fSReza Sabdar if (dev_id <= 0) { 2555295e611fSReza Sabdar if ((fd = open(adptnm, O_RDONLY | O_NDELAY)) < 0) 2556295e611fSReza Sabdar return (FALSE); 2557295e611fSReza Sabdar } else { 25582654012fSReza Sabdar fd = dev_id; 2559295e611fSReza Sabdar } 25602654012fSReza Sabdar do { 25612654012fSReza Sabdar if (scsi_test_unit_ready(fd) >= 0) { 25622654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unit is ready"); 25632654012fSReza Sabdar 256486c48bbfSReza Sabdar if (dev_id <= 0) 25652654012fSReza Sabdar (void) close(fd); 25662654012fSReza Sabdar 25672654012fSReza Sabdar return (TRUE); 25682654012fSReza Sabdar } 25692654012fSReza Sabdar 25702654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unit not ready"); 25712654012fSReza Sabdar (void) usleep(TUR_WAIT); 25722654012fSReza Sabdar 25732654012fSReza Sabdar } while (--try > 0); 25742654012fSReza Sabdar 257586c48bbfSReza Sabdar if (dev_id <= 0) 25762654012fSReza Sabdar (void) close(fd); 25772654012fSReza Sabdar 25782654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unit didn't get ready"); 25792654012fSReza Sabdar return (FALSE); 25802654012fSReza Sabdar } 25812654012fSReza Sabdar 25822654012fSReza Sabdar 25832654012fSReza Sabdar /* 25842654012fSReza Sabdar * scsi_test_unit_ready 25852654012fSReza Sabdar * 25862654012fSReza Sabdar * This is for Test Unit Read, without this function, the only 25872654012fSReza Sabdar * impact is getting EBUSY's before each operation which we have 25882654012fSReza Sabdar * busy waiting loops checking EBUSY error code. 25892654012fSReza Sabdar */ 25902654012fSReza Sabdar static int 25912654012fSReza Sabdar scsi_test_unit_ready(int dev_id) 25922654012fSReza Sabdar { 25932654012fSReza Sabdar struct uscsi_cmd ucmd; 25942654012fSReza Sabdar union scsi_cdb cdb; 25952654012fSReza Sabdar int retval; 25962654012fSReza Sabdar 25972654012fSReza Sabdar (void) memset(&ucmd, 0, sizeof (struct uscsi_cmd)); 25982654012fSReza Sabdar (void) memset(&cdb, 0, sizeof (union scsi_cdb)); 25992654012fSReza Sabdar cdb.scc_cmd = SCMD_TEST_UNIT_READY; 26002654012fSReza Sabdar ucmd.uscsi_cdb = (caddr_t)&cdb; 26012654012fSReza Sabdar ucmd.uscsi_cdblen = CDB_GROUP0; 26022654012fSReza Sabdar ucmd.uscsi_flags |= USCSI_SILENT; 2603c211fc47SReza Sabdar ucmd.uscsi_timeout = 60; /* Allow maximum 1 min */ 26042654012fSReza Sabdar 26052654012fSReza Sabdar retval = ioctl(dev_id, USCSICMD, &ucmd); 26062654012fSReza Sabdar 26072654012fSReza Sabdar if (retval != 0 && errno != EIO) { 26082654012fSReza Sabdar NDMP_LOG(LOG_ERR, 26092654012fSReza Sabdar "Failed to send inquiry request to device: %m."); 26102654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Inquiry request failed for" 26112654012fSReza Sabdar " dev_id:%d err=%d -%m", dev_id, errno); 26122654012fSReza Sabdar retval = -errno; 26132654012fSReza Sabdar } else 26142654012fSReza Sabdar retval = -(ucmd.uscsi_status); 26152654012fSReza Sabdar 26162654012fSReza Sabdar return (retval); 26172654012fSReza Sabdar } 26182654012fSReza Sabdar 26192654012fSReza Sabdar 26202654012fSReza Sabdar /* 26212654012fSReza Sabdar * ndmp_load_params 26222654012fSReza Sabdar * 26232654012fSReza Sabdar * Load the parameters. 26242654012fSReza Sabdar * 26252654012fSReza Sabdar * Parameter: 26262654012fSReza Sabdar * void 26272654012fSReza Sabdar * 26282654012fSReza Sabdar * Returns: 26292654012fSReza Sabdar * void 26302654012fSReza Sabdar */ 26312654012fSReza Sabdar void 26322654012fSReza Sabdar ndmp_load_params(void) 26332654012fSReza Sabdar { 26342654012fSReza Sabdar ndmp_dump_path_node = ndmpd_get_prop_yorn(NDMP_DUMP_PATHNODE_ENV) ? 26352654012fSReza Sabdar TRUE : FALSE; 26362654012fSReza Sabdar ndmp_tar_path_node = ndmpd_get_prop_yorn(NDMP_TAR_PATHNODE_ENV) ? 26372654012fSReza Sabdar TRUE : FALSE; 26382654012fSReza Sabdar ndmp_ignore_ctime = 26392654012fSReza Sabdar ndmpd_get_prop_yorn(NDMP_IGNCTIME_ENV) ? TRUE : FALSE; 26402654012fSReza Sabdar ndmp_include_lmtime = ndmpd_get_prop_yorn(NDMP_INCLMTIME_ENV) ? 26412654012fSReza Sabdar TRUE : FALSE; 26422654012fSReza Sabdar ndmp_max_tok_seq = atoi(ndmpd_get_prop_default(NDMP_MAXSEQ_ENV, "9")); 26432654012fSReza Sabdar 26442654012fSReza Sabdar ndmp_full_restore_path = ndmpd_get_prop_yorn(NDMP_FULL_RESTORE_PATH) ? 26452654012fSReza Sabdar TRUE : FALSE; 26462654012fSReza Sabdar 26472654012fSReza Sabdar ndmp_fhinode = ndmpd_get_prop_yorn(NDMP_FHIST_INCR_ENV) ? TRUE : FALSE; 26482654012fSReza Sabdar 26492654012fSReza Sabdar /* Get the value from ndmp SMF property. */ 26502654012fSReza Sabdar ndmp_dar_support = ndmpd_get_prop_yorn(NDMP_DAR_SUPPORT); 26512654012fSReza Sabdar 26522654012fSReza Sabdar if ((ndmp_ver = atoi(ndmpd_get_prop(NDMP_VERSION_ENV))) == 0) 26532654012fSReza Sabdar ndmp_ver = NDMPVER; 26542654012fSReza Sabdar } 26552654012fSReza Sabdar 26562654012fSReza Sabdar /* 26572654012fSReza Sabdar * randomize 26582654012fSReza Sabdar * 26592654012fSReza Sabdar * Randomize the contents of a buffer 26602654012fSReza Sabdar * 26612654012fSReza Sabdar * Parameter: 26622654012fSReza Sabdar * buffer (output) - destination buffer 26632654012fSReza Sabdar * size (input) - buffer size 26642654012fSReza Sabdar * 26652654012fSReza Sabdar * Returns: 26662654012fSReza Sabdar * void 26672654012fSReza Sabdar */ 26682654012fSReza Sabdar void 26692654012fSReza Sabdar randomize(unsigned char *buffer, int size) 26702654012fSReza Sabdar { 26712654012fSReza Sabdar /* LINTED improper alignment */ 26722654012fSReza Sabdar unsigned int *p = (unsigned int *)buffer; 26732654012fSReza Sabdar unsigned int dwlen = size / sizeof (unsigned int); 26742654012fSReza Sabdar unsigned int remlen = size % sizeof (unsigned int); 26752654012fSReza Sabdar unsigned int tmp; 26762654012fSReza Sabdar unsigned int i; 26772654012fSReza Sabdar 26782654012fSReza Sabdar for (i = 0; i < dwlen; i++) 26792654012fSReza Sabdar *p++ = random(); 26802654012fSReza Sabdar 26812654012fSReza Sabdar if (remlen) { 26822654012fSReza Sabdar tmp = random(); 26832654012fSReza Sabdar (void) memcpy(p, &tmp, remlen); 26842654012fSReza Sabdar } 26852654012fSReza Sabdar } 26862654012fSReza Sabdar 26872654012fSReza Sabdar /* 26882654012fSReza Sabdar * ndmpd_get_file_entry_type 26892654012fSReza Sabdar * 26902654012fSReza Sabdar * Converts the mode to the NDMP file type 26912654012fSReza Sabdar * 26922654012fSReza Sabdar * Parameter: 26932654012fSReza Sabdar * mode (input) - file mode 26942654012fSReza Sabdar * ftype (output) - file type 26952654012fSReza Sabdar * 26962654012fSReza Sabdar * Returns: 26972654012fSReza Sabdar * void 26982654012fSReza Sabdar */ 26992654012fSReza Sabdar void 27002654012fSReza Sabdar ndmpd_get_file_entry_type(int mode, ndmp_file_type *ftype) 27012654012fSReza Sabdar { 27022654012fSReza Sabdar switch (mode & S_IFMT) { 27032654012fSReza Sabdar case S_IFIFO: 27042654012fSReza Sabdar *ftype = NDMP_FILE_FIFO; 27052654012fSReza Sabdar break; 27062654012fSReza Sabdar case S_IFCHR: 27072654012fSReza Sabdar *ftype = NDMP_FILE_CSPEC; 27082654012fSReza Sabdar break; 27092654012fSReza Sabdar case S_IFDIR: 27102654012fSReza Sabdar *ftype = NDMP_FILE_DIR; 27112654012fSReza Sabdar break; 27122654012fSReza Sabdar case S_IFBLK: 27132654012fSReza Sabdar *ftype = NDMP_FILE_BSPEC; 27142654012fSReza Sabdar break; 27152654012fSReza Sabdar case S_IFREG: 27162654012fSReza Sabdar *ftype = NDMP_FILE_REG; 27172654012fSReza Sabdar break; 27182654012fSReza Sabdar case S_IFLNK: 27192654012fSReza Sabdar *ftype = NDMP_FILE_SLINK; 27202654012fSReza Sabdar break; 27212654012fSReza Sabdar default: 27222654012fSReza Sabdar *ftype = NDMP_FILE_SOCK; 27232654012fSReza Sabdar break; 27242654012fSReza Sabdar } 27252654012fSReza Sabdar } 27262654012fSReza Sabdar 27272654012fSReza Sabdar /* 27282654012fSReza Sabdar * Set a private data in the plugin context 27292654012fSReza Sabdar */ 27302654012fSReza Sabdar void 27312654012fSReza Sabdar ndmp_context_set_specific(ndmp_context_t *nctx, void *ptr) 27322654012fSReza Sabdar { 27332654012fSReza Sabdar nctx->nc_pldata = ptr; 27342654012fSReza Sabdar } 27352654012fSReza Sabdar 27362654012fSReza Sabdar /* 27372654012fSReza Sabdar * Get a private data in the plugin context 27382654012fSReza Sabdar */ 27392654012fSReza Sabdar void * 27402654012fSReza Sabdar ndmp_context_get_specific(ndmp_context_t *nctx) 27412654012fSReza Sabdar { 27422654012fSReza Sabdar return (nctx->nc_pldata); 27432654012fSReza Sabdar } 2744*8c4f9701SJanice Chang 2745*8c4f9701SJanice Chang ndmpd_backup_type_t 2746*8c4f9701SJanice Chang ndmp_get_backup_type(ndmp_context_t *ctx) 2747*8c4f9701SJanice Chang { 2748*8c4f9701SJanice Chang ndmpd_session_t *session = (ndmpd_session_t *)ctx->nc_ddata; 2749*8c4f9701SJanice Chang 2750*8c4f9701SJanice Chang return (session->ns_butype); 2751*8c4f9701SJanice Chang } 2752