1*2654012fSReza Sabdar /* 2*2654012fSReza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3*2654012fSReza Sabdar * Use is subject to license terms. 4*2654012fSReza Sabdar */ 5*2654012fSReza Sabdar 6*2654012fSReza Sabdar /* 7*2654012fSReza Sabdar * BSD 3 Clause License 8*2654012fSReza Sabdar * 9*2654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 10*2654012fSReza Sabdar * 11*2654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 12*2654012fSReza Sabdar * modification, are permitted provided that the following conditions 13*2654012fSReza Sabdar * are met: 14*2654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 15*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 16*2654012fSReza Sabdar * 17*2654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 18*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 19*2654012fSReza Sabdar * the documentation and/or other materials provided with the 20*2654012fSReza Sabdar * distribution. 21*2654012fSReza Sabdar * 22*2654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 23*2654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 24*2654012fSReza Sabdar * products derived from this software without specific prior written 25*2654012fSReza Sabdar * permission. 26*2654012fSReza Sabdar * 27*2654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28*2654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29*2654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30*2654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31*2654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32*2654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33*2654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34*2654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35*2654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36*2654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37*2654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 38*2654012fSReza Sabdar */ 39*2654012fSReza Sabdar /* Copyright (c) 2007, The Storage Networking Industry Association. */ 40*2654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */ 41*2654012fSReza Sabdar 42*2654012fSReza Sabdar #include <sys/types.h> 43*2654012fSReza Sabdar #include <sys/socket.h> 44*2654012fSReza Sabdar #include <assert.h> 45*2654012fSReza Sabdar #include <ctype.h> 46*2654012fSReza Sabdar #include <errno.h> 47*2654012fSReza Sabdar #include <stdio.h> 48*2654012fSReza Sabdar #include <stdlib.h> 49*2654012fSReza Sabdar #include <unistd.h> 50*2654012fSReza Sabdar #include <strings.h> 51*2654012fSReza Sabdar #include <time.h> 52*2654012fSReza Sabdar #include <libgen.h> 53*2654012fSReza Sabdar #include "ndmpd.h" 54*2654012fSReza Sabdar #include <bitmap.h> 55*2654012fSReza Sabdar #include <sys/queue.h> 56*2654012fSReza Sabdar #include <sys/socket.h> 57*2654012fSReza Sabdar #include <netinet/in.h> 58*2654012fSReza Sabdar #include <netinet/tcp.h> 59*2654012fSReza Sabdar #include <arpa/inet.h> 60*2654012fSReza Sabdar #include <sys/socketvar.h> 61*2654012fSReza Sabdar #include <net/if.h> 62*2654012fSReza Sabdar #include <netdb.h> 63*2654012fSReza Sabdar #include <sys/filio.h> 64*2654012fSReza Sabdar #include <sys/mtio.h> 65*2654012fSReza Sabdar #include <sys/scsi/impl/uscsi.h> 66*2654012fSReza Sabdar #include <sys/scsi/scsi.h> 67*2654012fSReza Sabdar #include "tlm.h" 68*2654012fSReza Sabdar 69*2654012fSReza Sabdar /* 70*2654012fSReza Sabdar * Mutex to protect Nlp 71*2654012fSReza Sabdar */ 72*2654012fSReza Sabdar mutex_t nlp_mtx; 73*2654012fSReza Sabdar 74*2654012fSReza Sabdar /* 75*2654012fSReza Sabdar * Patchable socket buffer sizes in kilobytes. 76*2654012fSReza Sabdar * ssb: send buffer size. 77*2654012fSReza Sabdar * rsb: receive buffer size. 78*2654012fSReza Sabdar */ 79*2654012fSReza Sabdar int ndmp_sbs = 60; 80*2654012fSReza Sabdar int ndmp_rbs = 60; 81*2654012fSReza Sabdar 82*2654012fSReza Sabdar 83*2654012fSReza Sabdar /* 84*2654012fSReza Sabdar * Force to backup all the intermediate directories leading to an object 85*2654012fSReza Sabdar * to be backed up in 'dump' format backup. 86*2654012fSReza Sabdar */ 87*2654012fSReza Sabdar boolean_t ndmp_dump_path_node = FALSE; 88*2654012fSReza Sabdar 89*2654012fSReza Sabdar 90*2654012fSReza Sabdar /* 91*2654012fSReza Sabdar * Force to backup all the intermediate directories leading to an object 92*2654012fSReza Sabdar * to be backed up in 'tar' format backup. 93*2654012fSReza Sabdar */ 94*2654012fSReza Sabdar boolean_t ndmp_tar_path_node = FALSE; 95*2654012fSReza Sabdar 96*2654012fSReza Sabdar 97*2654012fSReza Sabdar /* 98*2654012fSReza Sabdar * Should the 'st_ctime' be ignored during incremental level backup? 99*2654012fSReza Sabdar */ 100*2654012fSReza Sabdar boolean_t ndmp_ignore_ctime = FALSE; 101*2654012fSReza Sabdar 102*2654012fSReza Sabdar /* 103*2654012fSReza Sabdar * Should the 'st_lmtime' be included during incremental level backup? 104*2654012fSReza Sabdar */ 105*2654012fSReza Sabdar boolean_t ndmp_include_lmtime = FALSE; 106*2654012fSReza Sabdar 107*2654012fSReza Sabdar /* 108*2654012fSReza Sabdar * Force to send the file history node entries along with the file history 109*2654012fSReza Sabdar * dir entries for all directories containing the changed files to the client 110*2654012fSReza Sabdar * for incremental backup. 111*2654012fSReza Sabdar * 112*2654012fSReza Sabdar * Note: This variable is added to support Bakbone Software's Netvault DMA 113*2654012fSReza Sabdar * which expects to get the FH ADD NODES for all upper directories which 114*2654012fSReza Sabdar * contain the changed files in incremental backup along with the FH ADD DIRS. 115*2654012fSReza Sabdar */ 116*2654012fSReza Sabdar boolean_t ndmp_fhinode = FALSE; 117*2654012fSReza Sabdar 118*2654012fSReza Sabdar /* 119*2654012fSReza Sabdar * Maximum permitted sequence number in the token-based backup. The 120*2654012fSReza Sabdar * value of this variable can be changed by the administrator and is 121*2654012fSReza Sabdar * saved in the NDMP configuration file. 122*2654012fSReza Sabdar */ 123*2654012fSReza Sabdar static int ndmp_max_tok_seq = NDMP_MAX_TOKSEQ; 124*2654012fSReza Sabdar 125*2654012fSReza Sabdar /* 126*2654012fSReza Sabdar * Force backup directories in incremental backups. If the 127*2654012fSReza Sabdar * directory is not modified itself, it's not backed up by 128*2654012fSReza Sabdar * default. 129*2654012fSReza Sabdar */ 130*2654012fSReza Sabdar int ndmp_force_bk_dirs = 0; 131*2654012fSReza Sabdar 132*2654012fSReza Sabdar /* 133*2654012fSReza Sabdar * Keeps track of the open SCSI (including tape and robot) devices. 134*2654012fSReza Sabdar * When a SCSI device is opened its name must be added to this list and 135*2654012fSReza Sabdar * when it's closed its name must be removed from this list. The main 136*2654012fSReza Sabdar * purpose of this list is the robot device. If the robot devices are not 137*2654012fSReza Sabdar * attached in SASD layer, Local Backup won't see them. If they are 138*2654012fSReza Sabdar * attached and we open the robot devices, then wrong commands are sent 139*2654012fSReza Sabdar * to robot by SASD since it assumes that the robot is a tape (sequential 140*2654012fSReza Sabdar * access) device. 141*2654012fSReza Sabdar */ 142*2654012fSReza Sabdar struct open_list { 143*2654012fSReza Sabdar LIST_ENTRY(open_list) ol_q; 144*2654012fSReza Sabdar int ol_nref; 145*2654012fSReza Sabdar char *ol_devnm; 146*2654012fSReza Sabdar int ol_sid; 147*2654012fSReza Sabdar int ol_lun; 148*2654012fSReza Sabdar int ol_fd; 149*2654012fSReza Sabdar ndmp_connection_t *cl_conn; 150*2654012fSReza Sabdar }; 151*2654012fSReza Sabdar LIST_HEAD(ol_head, open_list); 152*2654012fSReza Sabdar 153*2654012fSReza Sabdar 154*2654012fSReza Sabdar /* 155*2654012fSReza Sabdar * Head of the opened SCSI devices list. 156*2654012fSReza Sabdar */ 157*2654012fSReza Sabdar static struct ol_head ol_head; 158*2654012fSReza Sabdar 159*2654012fSReza Sabdar mutex_t ol_mutex = DEFAULTMUTEX; 160*2654012fSReza Sabdar 161*2654012fSReza Sabdar 162*2654012fSReza Sabdar /* 163*2654012fSReza Sabdar * List of things to be exluded from backup. 164*2654012fSReza Sabdar */ 165*2654012fSReza Sabdar static char *exls[] = { 166*2654012fSReza Sabdar EXCL_PROC, 167*2654012fSReza Sabdar EXCL_TMP, 168*2654012fSReza Sabdar NULL, /* reserved for a copy of the "backup.directory" */ 169*2654012fSReza Sabdar NULL 170*2654012fSReza Sabdar }; 171*2654012fSReza Sabdar 172*2654012fSReza Sabdar 173*2654012fSReza Sabdar /* 174*2654012fSReza Sabdar * The counter for creating unique names with "ndmp.%d" format. 175*2654012fSReza Sabdar */ 176*2654012fSReza Sabdar #define NDMP_RCF_BASENAME "ndmp." 177*2654012fSReza Sabdar static int ndmp_job_cnt = 0; 178*2654012fSReza Sabdar 179*2654012fSReza Sabdar static int scsi_test_unit_ready(int dev_id); 180*2654012fSReza Sabdar 181*2654012fSReza Sabdar /* 182*2654012fSReza Sabdar * ndmpd_add_file_handler 183*2654012fSReza Sabdar * 184*2654012fSReza Sabdar * Adds a file handler to the file handler list. 185*2654012fSReza Sabdar * The file handler list is used by ndmpd_api_dispatch. 186*2654012fSReza Sabdar * 187*2654012fSReza Sabdar * Parameters: 188*2654012fSReza Sabdar * session (input) - session pointer. 189*2654012fSReza Sabdar * cookie (input) - opaque data to be passed to file hander when called. 190*2654012fSReza Sabdar * fd (input) - file descriptor. 191*2654012fSReza Sabdar * mode (input) - bitmask of the following: 192*2654012fSReza Sabdar * 1 = watch file for ready for reading 193*2654012fSReza Sabdar * 2 = watch file for ready for writing 194*2654012fSReza Sabdar * 4 = watch file for exception 195*2654012fSReza Sabdar * class (input) - handler class. (HC_CLIENT, HC_MOVER, HC_MODULE) 196*2654012fSReza Sabdar * func (input) - function to call when the file meets one of the 197*2654012fSReza Sabdar * conditions specified by mode. 198*2654012fSReza Sabdar * 199*2654012fSReza Sabdar * Returns: 200*2654012fSReza Sabdar * 0 - success. 201*2654012fSReza Sabdar * -1 - error. 202*2654012fSReza Sabdar */ 203*2654012fSReza Sabdar int 204*2654012fSReza Sabdar ndmpd_add_file_handler(ndmpd_session_t *session, void *cookie, int fd, 205*2654012fSReza Sabdar ulong_t mode, ulong_t class, ndmpd_file_handler_func_t *func) 206*2654012fSReza Sabdar { 207*2654012fSReza Sabdar ndmpd_file_handler_t *new; 208*2654012fSReza Sabdar 209*2654012fSReza Sabdar new = ndmp_malloc(sizeof (ndmpd_file_handler_t)); 210*2654012fSReza Sabdar if (new == 0) 211*2654012fSReza Sabdar return (-1); 212*2654012fSReza Sabdar 213*2654012fSReza Sabdar new->fh_cookie = cookie; 214*2654012fSReza Sabdar new->fh_fd = fd; 215*2654012fSReza Sabdar new->fh_mode = mode; 216*2654012fSReza Sabdar new->fh_class = class; 217*2654012fSReza Sabdar new->fh_func = func; 218*2654012fSReza Sabdar new->fh_next = session->ns_file_handler_list; 219*2654012fSReza Sabdar session->ns_file_handler_list = new; 220*2654012fSReza Sabdar return (0); 221*2654012fSReza Sabdar } 222*2654012fSReza Sabdar 223*2654012fSReza Sabdar 224*2654012fSReza Sabdar /* 225*2654012fSReza Sabdar * ndmpd_remove_file_handler 226*2654012fSReza Sabdar * 227*2654012fSReza Sabdar * Removes a file handler from the file handler list. 228*2654012fSReza Sabdar * 229*2654012fSReza Sabdar * Parameters: 230*2654012fSReza Sabdar * session (input) - session pointer. 231*2654012fSReza Sabdar * fd (input) - file descriptor. 232*2654012fSReza Sabdar * 233*2654012fSReza Sabdar * Returns: 234*2654012fSReza Sabdar * 0 - success. 235*2654012fSReza Sabdar * -1 - error. 236*2654012fSReza Sabdar */ 237*2654012fSReza Sabdar int 238*2654012fSReza Sabdar ndmpd_remove_file_handler(ndmpd_session_t *session, int fd) 239*2654012fSReza Sabdar { 240*2654012fSReza Sabdar ndmpd_file_handler_t **last; 241*2654012fSReza Sabdar ndmpd_file_handler_t *handler; 242*2654012fSReza Sabdar 243*2654012fSReza Sabdar last = &session->ns_file_handler_list; 244*2654012fSReza Sabdar while (*last != 0) { 245*2654012fSReza Sabdar handler = *last; 246*2654012fSReza Sabdar 247*2654012fSReza Sabdar if (handler->fh_fd == fd) { 248*2654012fSReza Sabdar *last = handler->fh_next; 249*2654012fSReza Sabdar (void) free(handler); 250*2654012fSReza Sabdar return (1); 251*2654012fSReza Sabdar } 252*2654012fSReza Sabdar last = &handler->fh_next; 253*2654012fSReza Sabdar } 254*2654012fSReza Sabdar 255*2654012fSReza Sabdar return (0); 256*2654012fSReza Sabdar } 257*2654012fSReza Sabdar 258*2654012fSReza Sabdar 259*2654012fSReza Sabdar /* 260*2654012fSReza Sabdar * ndmp_connection_closed 261*2654012fSReza Sabdar * 262*2654012fSReza Sabdar * If the connection closed or not. 263*2654012fSReza Sabdar * 264*2654012fSReza Sabdar * Parameters: 265*2654012fSReza Sabdar * fd (input) : file descriptor 266*2654012fSReza Sabdar * 267*2654012fSReza Sabdar * Returns: 268*2654012fSReza Sabdar * 0 - connection is still valid 269*2654012fSReza Sabdar * 1 - connection is not valid anymore 270*2654012fSReza Sabdar * -1 - Internal kernel error 271*2654012fSReza Sabdar */ 272*2654012fSReza Sabdar int 273*2654012fSReza Sabdar ndmp_connection_closed(int fd) 274*2654012fSReza Sabdar { 275*2654012fSReza Sabdar fd_set fds; 276*2654012fSReza Sabdar int closed, ret; 277*2654012fSReza Sabdar struct timeval timeout; 278*2654012fSReza Sabdar 279*2654012fSReza Sabdar if (fd < 0) /* We are not using the mover */ 280*2654012fSReza Sabdar return (-1); 281*2654012fSReza Sabdar 282*2654012fSReza Sabdar timeout.tv_sec = 0; 283*2654012fSReza Sabdar timeout.tv_usec = 1000; 284*2654012fSReza Sabdar 285*2654012fSReza Sabdar FD_ZERO(&fds); 286*2654012fSReza Sabdar FD_SET(fd, &fds); 287*2654012fSReza Sabdar ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); 288*2654012fSReza Sabdar 289*2654012fSReza Sabdar closed = (ret == -1 && errno == EBADF); 290*2654012fSReza Sabdar 291*2654012fSReza Sabdar return (closed); 292*2654012fSReza Sabdar } 293*2654012fSReza Sabdar 294*2654012fSReza Sabdar /* 295*2654012fSReza Sabdar * ndmp_check_mover_state 296*2654012fSReza Sabdar * 297*2654012fSReza Sabdar * Checks the mover connection status and sends an appropriate 298*2654012fSReza Sabdar * NDMP message to client based on that. 299*2654012fSReza Sabdar * 300*2654012fSReza Sabdar * Parameters: 301*2654012fSReza Sabdar * ndmpd_session_t *session (input) : session pointer 302*2654012fSReza Sabdar * 303*2654012fSReza Sabdar * Returns: 304*2654012fSReza Sabdar * void. 305*2654012fSReza Sabdar */ 306*2654012fSReza Sabdar void 307*2654012fSReza Sabdar ndmp_check_mover_state(ndmpd_session_t *session) 308*2654012fSReza Sabdar { 309*2654012fSReza Sabdar int moverfd; 310*2654012fSReza Sabdar /* 311*2654012fSReza Sabdar * NDMPV3 Spec (Three-way restore): 312*2654012fSReza Sabdar * Once all of the files have been recovered, NDMP DATA Server closes 313*2654012fSReza Sabdar * the connection to the mover on the NDMP TAPE Server. THEN 314*2654012fSReza Sabdar * The NDMP client should receive an NDMP_NOTIFY_MOVER_HALTED message 315*2654012fSReza Sabdar * with an NDMP_MOVER_CONNECT_CLOSED reason from the NDMP TAPE Server 316*2654012fSReza Sabdar */ 317*2654012fSReza Sabdar moverfd = session->ns_mover.md_sock; 318*2654012fSReza Sabdar /* If connection is closed by the peer */ 319*2654012fSReza Sabdar if (moverfd >= 0 && 320*2654012fSReza Sabdar session->ns_mover.md_mode == NDMP_MOVER_MODE_WRITE) { 321*2654012fSReza Sabdar int closed, reason; 322*2654012fSReza Sabdar 323*2654012fSReza Sabdar closed = ndmp_connection_closed(moverfd); 324*2654012fSReza Sabdar if (closed) { 325*2654012fSReza Sabdar /* Connection closed or internal error */ 326*2654012fSReza Sabdar if (closed > 0) { 327*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 328*2654012fSReza Sabdar "ndmp mover: connection closed by peer"); 329*2654012fSReza Sabdar reason = NDMP_MOVER_HALT_CONNECT_CLOSED; 330*2654012fSReza Sabdar } else { 331*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 332*2654012fSReza Sabdar "ndmp mover: Internal error"); 333*2654012fSReza Sabdar reason = NDMP_MOVER_HALT_INTERNAL_ERROR; 334*2654012fSReza Sabdar } 335*2654012fSReza Sabdar ndmpd_mover_error(session, reason); 336*2654012fSReza Sabdar 337*2654012fSReza Sabdar } 338*2654012fSReza Sabdar } 339*2654012fSReza Sabdar } 340*2654012fSReza Sabdar 341*2654012fSReza Sabdar 342*2654012fSReza Sabdar /* 343*2654012fSReza Sabdar * ndmpd_select 344*2654012fSReza Sabdar * 345*2654012fSReza Sabdar * Calls select on the the set of file descriptors from the 346*2654012fSReza Sabdar * file handler list masked by the fd_class argument. 347*2654012fSReza Sabdar * Calls the file handler function for each 348*2654012fSReza Sabdar * file descriptor that is ready for I/O. 349*2654012fSReza Sabdar * 350*2654012fSReza Sabdar * Parameters: 351*2654012fSReza Sabdar * session (input) - session pointer. 352*2654012fSReza Sabdar * block (input) - if TRUE, ndmpd_select waits until at least one 353*2654012fSReza Sabdar * file descriptor is ready for I/O. Otherwise, 354*2654012fSReza Sabdar * it returns immediately if no file descriptors are 355*2654012fSReza Sabdar * ready for I/O. 356*2654012fSReza Sabdar * class_mask (input) - bit mask of handler classes to be examined. 357*2654012fSReza Sabdar * Provides for excluding some of the handlers from 358*2654012fSReza Sabdar * being called. 359*2654012fSReza Sabdar * 360*2654012fSReza Sabdar * Returns: 361*2654012fSReza Sabdar * -1 - error. 362*2654012fSReza Sabdar * 0 - no handlers were called. 363*2654012fSReza Sabdar * 1 - at least one handler was called. 364*2654012fSReza Sabdar */ 365*2654012fSReza Sabdar int 366*2654012fSReza Sabdar ndmpd_select(ndmpd_session_t *session, boolean_t block, ulong_t class_mask) 367*2654012fSReza Sabdar { 368*2654012fSReza Sabdar fd_set rfds; 369*2654012fSReza Sabdar fd_set wfds; 370*2654012fSReza Sabdar fd_set efds; 371*2654012fSReza Sabdar int n; 372*2654012fSReza Sabdar ndmpd_file_handler_t *handler; 373*2654012fSReza Sabdar struct timeval timeout; 374*2654012fSReza Sabdar 375*2654012fSReza Sabdar nlp_event_rv_set(session, 0); 376*2654012fSReza Sabdar 377*2654012fSReza Sabdar if (session->ns_file_handler_list == 0) 378*2654012fSReza Sabdar return (0); 379*2654012fSReza Sabdar 380*2654012fSReza Sabdar 381*2654012fSReza Sabdar /* 382*2654012fSReza Sabdar * If select should be blocked, then we poll every ten seconds. 383*2654012fSReza Sabdar * The reason is in case of three-way restore we should be able 384*2654012fSReza Sabdar * to detect if the other end closed the connection or not. 385*2654012fSReza Sabdar * NDMP client(DMA) does not send any information about the connection 386*2654012fSReza Sabdar * that was closed in the other end. 387*2654012fSReza Sabdar */ 388*2654012fSReza Sabdar 389*2654012fSReza Sabdar if (block == TRUE) 390*2654012fSReza Sabdar timeout.tv_sec = 10; 391*2654012fSReza Sabdar else 392*2654012fSReza Sabdar timeout.tv_sec = 0; 393*2654012fSReza Sabdar timeout.tv_usec = 0; 394*2654012fSReza Sabdar 395*2654012fSReza Sabdar do { 396*2654012fSReza Sabdar /* Create the fd_sets for select. */ 397*2654012fSReza Sabdar FD_ZERO(&rfds); 398*2654012fSReza Sabdar FD_ZERO(&wfds); 399*2654012fSReza Sabdar FD_ZERO(&efds); 400*2654012fSReza Sabdar 401*2654012fSReza Sabdar for (handler = session->ns_file_handler_list; handler != 0; 402*2654012fSReza Sabdar handler = handler->fh_next) { 403*2654012fSReza Sabdar if ((handler->fh_class & class_mask) == 0) 404*2654012fSReza Sabdar continue; 405*2654012fSReza Sabdar 406*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_READ) 407*2654012fSReza Sabdar FD_SET(handler->fh_fd, &rfds); 408*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) 409*2654012fSReza Sabdar FD_SET(handler->fh_fd, &wfds); 410*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) 411*2654012fSReza Sabdar FD_SET(handler->fh_fd, &efds); 412*2654012fSReza Sabdar } 413*2654012fSReza Sabdar ndmp_check_mover_state(session); 414*2654012fSReza Sabdar n = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout); 415*2654012fSReza Sabdar } while (n == 0 && block == TRUE); 416*2654012fSReza Sabdar 417*2654012fSReza Sabdar if (n < 0) { 418*2654012fSReza Sabdar int connection_fd = ndmp_get_fd(session->ns_connection); 419*2654012fSReza Sabdar 420*2654012fSReza Sabdar if (errno == EINTR) 421*2654012fSReza Sabdar return (0); 422*2654012fSReza Sabdar 423*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Select error: %m"); 424*2654012fSReza Sabdar 425*2654012fSReza Sabdar for (handler = session->ns_file_handler_list; handler != 0; 426*2654012fSReza Sabdar handler = handler->fh_next) { 427*2654012fSReza Sabdar if ((handler->fh_class & class_mask) == 0) 428*2654012fSReza Sabdar continue; 429*2654012fSReza Sabdar 430*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_READ) { 431*2654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &rfds) && 432*2654012fSReza Sabdar connection_fd == handler->fh_fd) 433*2654012fSReza Sabdar session->ns_eof = TRUE; 434*2654012fSReza Sabdar } 435*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) { 436*2654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &wfds) && 437*2654012fSReza Sabdar connection_fd == handler->fh_fd) 438*2654012fSReza Sabdar session->ns_eof = TRUE; 439*2654012fSReza Sabdar } 440*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) { 441*2654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &efds) && 442*2654012fSReza Sabdar connection_fd == handler->fh_fd) 443*2654012fSReza Sabdar session->ns_eof = TRUE; 444*2654012fSReza Sabdar } 445*2654012fSReza Sabdar } 446*2654012fSReza Sabdar 447*2654012fSReza Sabdar nlp_event_rv_set(session, -1); 448*2654012fSReza Sabdar return (-1); 449*2654012fSReza Sabdar } 450*2654012fSReza Sabdar if (n == 0) 451*2654012fSReza Sabdar return (0); 452*2654012fSReza Sabdar 453*2654012fSReza Sabdar handler = session->ns_file_handler_list; 454*2654012fSReza Sabdar while (handler != 0) { 455*2654012fSReza Sabdar ulong_t mode = 0; 456*2654012fSReza Sabdar 457*2654012fSReza Sabdar if ((handler->fh_class & class_mask) == 0) { 458*2654012fSReza Sabdar handler = handler->fh_next; 459*2654012fSReza Sabdar continue; 460*2654012fSReza Sabdar } 461*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_READ) { 462*2654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &rfds)) { 463*2654012fSReza Sabdar mode |= NDMPD_SELECT_MODE_READ; 464*2654012fSReza Sabdar FD_CLR(handler->fh_fd, &rfds); 465*2654012fSReza Sabdar } 466*2654012fSReza Sabdar } 467*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) { 468*2654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &wfds)) { 469*2654012fSReza Sabdar mode |= NDMPD_SELECT_MODE_WRITE; 470*2654012fSReza Sabdar FD_CLR(handler->fh_fd, &wfds); 471*2654012fSReza Sabdar } 472*2654012fSReza Sabdar } 473*2654012fSReza Sabdar if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) { 474*2654012fSReza Sabdar if (FD_ISSET(handler->fh_fd, &efds)) { 475*2654012fSReza Sabdar mode |= NDMPD_SELECT_MODE_EXCEPTION; 476*2654012fSReza Sabdar FD_CLR(handler->fh_fd, &efds); 477*2654012fSReza Sabdar } 478*2654012fSReza Sabdar } 479*2654012fSReza Sabdar if (mode) { 480*2654012fSReza Sabdar (*handler->fh_func) (handler->fh_cookie, 481*2654012fSReza Sabdar handler->fh_fd, mode); 482*2654012fSReza Sabdar 483*2654012fSReza Sabdar /* 484*2654012fSReza Sabdar * K.L. The list can be modified during the execution 485*2654012fSReza Sabdar * of handler->fh_func. Therefore, handler will start 486*2654012fSReza Sabdar * from the beginning of the handler list after 487*2654012fSReza Sabdar * each execution. 488*2654012fSReza Sabdar */ 489*2654012fSReza Sabdar handler = session->ns_file_handler_list; 490*2654012fSReza Sabdar 491*2654012fSReza Sabdar /* 492*2654012fSReza Sabdar * Release the thread which is waiting for a request 493*2654012fSReza Sabdar * to be proccessed. 494*2654012fSReza Sabdar */ 495*2654012fSReza Sabdar nlp_event_nw(session); 496*2654012fSReza Sabdar } else 497*2654012fSReza Sabdar handler = handler->fh_next; 498*2654012fSReza Sabdar 499*2654012fSReza Sabdar } 500*2654012fSReza Sabdar 501*2654012fSReza Sabdar nlp_event_rv_set(session, 1); 502*2654012fSReza Sabdar return (1); 503*2654012fSReza Sabdar } 504*2654012fSReza Sabdar 505*2654012fSReza Sabdar 506*2654012fSReza Sabdar /* 507*2654012fSReza Sabdar * ndmpd_save_env 508*2654012fSReza Sabdar * 509*2654012fSReza Sabdar * Saves a copy of the environment variable list from the data_start_backup 510*2654012fSReza Sabdar * request or data_start_recover request. 511*2654012fSReza Sabdar * 512*2654012fSReza Sabdar * Parameters: 513*2654012fSReza Sabdar * session (input) - session pointer. 514*2654012fSReza Sabdar * env (input) - environment variable list to be saved. 515*2654012fSReza Sabdar * envlen (input) - length of variable array. 516*2654012fSReza Sabdar * 517*2654012fSReza Sabdar * Returns: 518*2654012fSReza Sabdar * error code. 519*2654012fSReza Sabdar */ 520*2654012fSReza Sabdar ndmp_error 521*2654012fSReza Sabdar ndmpd_save_env(ndmpd_session_t *session, ndmp_pval *env, ulong_t envlen) 522*2654012fSReza Sabdar { 523*2654012fSReza Sabdar ulong_t i; 524*2654012fSReza Sabdar char *namebuf; 525*2654012fSReza Sabdar char *valbuf; 526*2654012fSReza Sabdar 527*2654012fSReza Sabdar session->ns_data.dd_env_len = 0; 528*2654012fSReza Sabdar 529*2654012fSReza Sabdar if (envlen == 0) 530*2654012fSReza Sabdar return (NDMP_NO_ERR); 531*2654012fSReza Sabdar 532*2654012fSReza Sabdar session->ns_data.dd_env = ndmp_malloc(sizeof (ndmp_pval) * envlen); 533*2654012fSReza Sabdar if (session->ns_data.dd_env == 0) 534*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 535*2654012fSReza Sabdar 536*2654012fSReza Sabdar for (i = 0; i < envlen; i++) { 537*2654012fSReza Sabdar namebuf = strdup(env[i].name); 538*2654012fSReza Sabdar if (namebuf == 0) 539*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 540*2654012fSReza Sabdar 541*2654012fSReza Sabdar valbuf = strdup(env[i].value); 542*2654012fSReza Sabdar if (valbuf == 0) { 543*2654012fSReza Sabdar free(namebuf); 544*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 545*2654012fSReza Sabdar } 546*2654012fSReza Sabdar 547*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "env(%s): \"%s\"", 548*2654012fSReza Sabdar namebuf, valbuf); 549*2654012fSReza Sabdar 550*2654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 551*2654012fSReza Sabdar session->ns_data.dd_env[i].name = namebuf; 552*2654012fSReza Sabdar session->ns_data.dd_env[i].value = valbuf; 553*2654012fSReza Sabdar session->ns_data.dd_env_len++; 554*2654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 555*2654012fSReza Sabdar } 556*2654012fSReza Sabdar 557*2654012fSReza Sabdar return (NDMP_NO_ERR); 558*2654012fSReza Sabdar } 559*2654012fSReza Sabdar 560*2654012fSReza Sabdar 561*2654012fSReza Sabdar /* 562*2654012fSReza Sabdar * ndmpd_free_env 563*2654012fSReza Sabdar * 564*2654012fSReza Sabdar * Free the previously saved environment variable array. 565*2654012fSReza Sabdar * 566*2654012fSReza Sabdar * Parameters: 567*2654012fSReza Sabdar * session - NDMP session pointer. 568*2654012fSReza Sabdar * 569*2654012fSReza Sabdar * Returns: 570*2654012fSReza Sabdar * void. 571*2654012fSReza Sabdar */ 572*2654012fSReza Sabdar void 573*2654012fSReza Sabdar ndmpd_free_env(ndmpd_session_t *session) 574*2654012fSReza Sabdar { 575*2654012fSReza Sabdar ulong_t i; 576*2654012fSReza Sabdar int count = session->ns_data.dd_env_len; 577*2654012fSReza Sabdar 578*2654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 579*2654012fSReza Sabdar session->ns_data.dd_env_len = 0; 580*2654012fSReza Sabdar for (i = 0; i < count; i++) { 581*2654012fSReza Sabdar free(session->ns_data.dd_env[i].name); 582*2654012fSReza Sabdar free(session->ns_data.dd_env[i].value); 583*2654012fSReza Sabdar } 584*2654012fSReza Sabdar 585*2654012fSReza Sabdar free((char *)session->ns_data.dd_env); 586*2654012fSReza Sabdar session->ns_data.dd_env = 0; 587*2654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 588*2654012fSReza Sabdar } 589*2654012fSReza Sabdar 590*2654012fSReza Sabdar 591*2654012fSReza Sabdar /* 592*2654012fSReza Sabdar * ndmpd_save_nlist_v2 593*2654012fSReza Sabdar * 594*2654012fSReza Sabdar * Save a copy of list of file names to be restored. 595*2654012fSReza Sabdar * 596*2654012fSReza Sabdar * Parameters: 597*2654012fSReza Sabdar * nlist (input) - name list from data_start_recover request. 598*2654012fSReza Sabdar * nlistlen (input) - length of name list. 599*2654012fSReza Sabdar * 600*2654012fSReza Sabdar * Returns: 601*2654012fSReza Sabdar * array of file name pointers. 602*2654012fSReza Sabdar * 603*2654012fSReza Sabdar * Notes: 604*2654012fSReza Sabdar * free_nlist should be called to free the returned list. 605*2654012fSReza Sabdar * A null pointer indicates the end of the list. 606*2654012fSReza Sabdar */ 607*2654012fSReza Sabdar ndmp_error 608*2654012fSReza Sabdar ndmpd_save_nlist_v2(ndmpd_session_t *session, ndmp_name *nlist, 609*2654012fSReza Sabdar ulong_t nlistlen) 610*2654012fSReza Sabdar { 611*2654012fSReza Sabdar ulong_t i; 612*2654012fSReza Sabdar char *namebuf; 613*2654012fSReza Sabdar char *destbuf; 614*2654012fSReza Sabdar 615*2654012fSReza Sabdar if (nlistlen == 0) 616*2654012fSReza Sabdar return (NDMP_NO_ERR); 617*2654012fSReza Sabdar 618*2654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 619*2654012fSReza Sabdar session->ns_data.dd_nlist = ndmp_malloc(sizeof (ndmp_name)*nlistlen); 620*2654012fSReza Sabdar if (session->ns_data.dd_nlist == 0) 621*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 622*2654012fSReza Sabdar 623*2654012fSReza Sabdar for (i = 0; i < nlistlen; i++) { 624*2654012fSReza Sabdar namebuf = ndmp_malloc(strlen(nlist[i].name) + 1); 625*2654012fSReza Sabdar if (namebuf == 0) 626*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 627*2654012fSReza Sabdar 628*2654012fSReza Sabdar destbuf = ndmp_malloc(strlen(nlist[i].dest) + 1); 629*2654012fSReza Sabdar if (destbuf == 0) { 630*2654012fSReza Sabdar free(namebuf); 631*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 632*2654012fSReza Sabdar } 633*2654012fSReza Sabdar (void) strlcpy(namebuf, nlist[i].name, 634*2654012fSReza Sabdar strlen(nlist[i].name) + 1); 635*2654012fSReza Sabdar (void) strlcpy(destbuf, nlist[i].dest, 636*2654012fSReza Sabdar strlen(nlist[i].dest) + 1); 637*2654012fSReza Sabdar 638*2654012fSReza Sabdar session->ns_data.dd_nlist[i].name = namebuf; 639*2654012fSReza Sabdar session->ns_data.dd_nlist[i].dest = destbuf; 640*2654012fSReza Sabdar session->ns_data.dd_nlist[i].ssid = nlist[i].ssid; 641*2654012fSReza Sabdar session->ns_data.dd_nlist[i].fh_info = nlist[i].fh_info; 642*2654012fSReza Sabdar session->ns_data.dd_nlist_len++; 643*2654012fSReza Sabdar } 644*2654012fSReza Sabdar 645*2654012fSReza Sabdar return (NDMP_NO_ERR); 646*2654012fSReza Sabdar } 647*2654012fSReza Sabdar 648*2654012fSReza Sabdar 649*2654012fSReza Sabdar /* 650*2654012fSReza Sabdar * ndmpd_free_nlist_v2 651*2654012fSReza Sabdar * 652*2654012fSReza Sabdar * Free a list created by ndmpd_save_nlist_v2. 653*2654012fSReza Sabdar * 654*2654012fSReza Sabdar * Parameters: 655*2654012fSReza Sabdar * session (input) - session pointer. 656*2654012fSReza Sabdar * 657*2654012fSReza Sabdar * Returns: 658*2654012fSReza Sabdar * void 659*2654012fSReza Sabdar */ 660*2654012fSReza Sabdar void 661*2654012fSReza Sabdar ndmpd_free_nlist_v2(ndmpd_session_t *session) 662*2654012fSReza Sabdar { 663*2654012fSReza Sabdar ulong_t i; 664*2654012fSReza Sabdar 665*2654012fSReza Sabdar for (i = 0; i < session->ns_data.dd_nlist_len; i++) { 666*2654012fSReza Sabdar free(session->ns_data.dd_nlist[i].name); 667*2654012fSReza Sabdar free(session->ns_data.dd_nlist[i].dest); 668*2654012fSReza Sabdar } 669*2654012fSReza Sabdar 670*2654012fSReza Sabdar if (session->ns_data.dd_nlist != NULL) 671*2654012fSReza Sabdar free((char *)session->ns_data.dd_nlist); 672*2654012fSReza Sabdar session->ns_data.dd_nlist = 0; 673*2654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 674*2654012fSReza Sabdar } 675*2654012fSReza Sabdar 676*2654012fSReza Sabdar 677*2654012fSReza Sabdar /* 678*2654012fSReza Sabdar * ndmpd_free_nlist_v3 679*2654012fSReza Sabdar * 680*2654012fSReza Sabdar * Free a list created by ndmpd_save_nlist_v3. 681*2654012fSReza Sabdar * 682*2654012fSReza Sabdar * Parameters: 683*2654012fSReza Sabdar * session (input) - session pointer. 684*2654012fSReza Sabdar * 685*2654012fSReza Sabdar * Returns: 686*2654012fSReza Sabdar * void 687*2654012fSReza Sabdar */ 688*2654012fSReza Sabdar void 689*2654012fSReza Sabdar ndmpd_free_nlist_v3(ndmpd_session_t *session) 690*2654012fSReza Sabdar { 691*2654012fSReza Sabdar ulong_t i; 692*2654012fSReza Sabdar mem_ndmp_name_v3_t *tp; /* destination entry */ 693*2654012fSReza Sabdar 694*2654012fSReza Sabdar tp = session->ns_data.dd_nlist_v3; 695*2654012fSReza Sabdar for (i = 0; i < session->ns_data.dd_nlist_len; tp++, i++) { 696*2654012fSReza Sabdar NDMP_FREE(tp->nm3_opath); 697*2654012fSReza Sabdar NDMP_FREE(tp->nm3_dpath); 698*2654012fSReza Sabdar NDMP_FREE(tp->nm3_newnm); 699*2654012fSReza Sabdar } 700*2654012fSReza Sabdar 701*2654012fSReza Sabdar NDMP_FREE(session->ns_data.dd_nlist_v3); 702*2654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 703*2654012fSReza Sabdar } 704*2654012fSReza Sabdar 705*2654012fSReza Sabdar 706*2654012fSReza Sabdar /* 707*2654012fSReza Sabdar * ndmpd_save_nlist_v3 708*2654012fSReza Sabdar * 709*2654012fSReza Sabdar * Save a copy of list of file names to be restored. 710*2654012fSReza Sabdar * 711*2654012fSReza Sabdar * Parameters: 712*2654012fSReza Sabdar * nlist (input) - name list from data_start_recover request. 713*2654012fSReza Sabdar * nlistlen (input) - length of name list. 714*2654012fSReza Sabdar * 715*2654012fSReza Sabdar * Returns: 716*2654012fSReza Sabdar * array of file name pointers. 717*2654012fSReza Sabdar * 718*2654012fSReza Sabdar * Notes: 719*2654012fSReza Sabdar * free_nlist should be called to free the returned list. 720*2654012fSReza Sabdar * A null pointer indicates the end of the list. 721*2654012fSReza Sabdar */ 722*2654012fSReza Sabdar ndmp_error 723*2654012fSReza Sabdar ndmpd_save_nlist_v3(ndmpd_session_t *session, ndmp_name_v3 *nlist, 724*2654012fSReza Sabdar ulong_t nlistlen) 725*2654012fSReza Sabdar { 726*2654012fSReza Sabdar ulong_t i; 727*2654012fSReza Sabdar ndmp_error rv; 728*2654012fSReza Sabdar ndmp_name_v3 *sp; /* source entry */ 729*2654012fSReza Sabdar mem_ndmp_name_v3_t *tp; /* destination entry */ 730*2654012fSReza Sabdar 731*2654012fSReza Sabdar if (nlistlen == 0) 732*2654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 733*2654012fSReza Sabdar 734*2654012fSReza Sabdar session->ns_data.dd_nlist_len = 0; 735*2654012fSReza Sabdar tp = session->ns_data.dd_nlist_v3 = 736*2654012fSReza Sabdar ndmp_malloc(sizeof (mem_ndmp_name_v3_t) * nlistlen); 737*2654012fSReza Sabdar if (session->ns_data.dd_nlist_v3 == 0) 738*2654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 739*2654012fSReza Sabdar 740*2654012fSReza Sabdar rv = NDMP_NO_ERR; 741*2654012fSReza Sabdar sp = nlist; 742*2654012fSReza Sabdar for (i = 0; i < nlistlen; tp++, sp++, i++) { 743*2654012fSReza Sabdar tp->nm3_opath = strdup(sp->original_path); 744*2654012fSReza Sabdar if (!tp->nm3_opath) { 745*2654012fSReza Sabdar rv = NDMP_NO_MEM_ERR; 746*2654012fSReza Sabdar break; 747*2654012fSReza Sabdar } 748*2654012fSReza Sabdar if (!*sp->destination_dir) { 749*2654012fSReza Sabdar tp->nm3_dpath = NULL; 750*2654012fSReza Sabdar /* In V4 destination dir cannot be NULL */ 751*2654012fSReza Sabdar if (session->ns_protocol_version == NDMPV4) { 752*2654012fSReza Sabdar rv = NDMP_ILLEGAL_ARGS_ERR; 753*2654012fSReza Sabdar break; 754*2654012fSReza Sabdar } 755*2654012fSReza Sabdar } else if (!(tp->nm3_dpath = strdup(sp->destination_dir))) { 756*2654012fSReza Sabdar rv = NDMP_NO_MEM_ERR; 757*2654012fSReza Sabdar break; 758*2654012fSReza Sabdar } 759*2654012fSReza Sabdar if (!*sp->new_name) 760*2654012fSReza Sabdar tp->nm3_newnm = NULL; 761*2654012fSReza Sabdar else if (!(tp->nm3_newnm = strdup(sp->new_name))) { 762*2654012fSReza Sabdar rv = NDMP_NO_MEM_ERR; 763*2654012fSReza Sabdar break; 764*2654012fSReza Sabdar } 765*2654012fSReza Sabdar 766*2654012fSReza Sabdar tp->nm3_node = quad_to_long_long(sp->node); 767*2654012fSReza Sabdar tp->nm3_fh_info = quad_to_long_long(sp->fh_info); 768*2654012fSReza Sabdar tp->nm3_err = NDMP_NO_ERR; 769*2654012fSReza Sabdar session->ns_data.dd_nlist_len++; 770*2654012fSReza Sabdar 771*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "orig \"%s\"", tp->nm3_opath); 772*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dest \"%s\"", NDMP_SVAL(tp->nm3_dpath)); 773*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "name \"%s\"", NDMP_SVAL(tp->nm3_newnm)); 774*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "node %lld", tp->nm3_node); 775*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "fh_info %lld", tp->nm3_fh_info); 776*2654012fSReza Sabdar } 777*2654012fSReza Sabdar 778*2654012fSReza Sabdar if (rv != NDMP_NO_ERR) 779*2654012fSReza Sabdar ndmpd_free_nlist_v3(session); 780*2654012fSReza Sabdar 781*2654012fSReza Sabdar return (rv); 782*2654012fSReza Sabdar } 783*2654012fSReza Sabdar 784*2654012fSReza Sabdar 785*2654012fSReza Sabdar /* 786*2654012fSReza Sabdar * ndmpd_free_nlist 787*2654012fSReza Sabdar * 788*2654012fSReza Sabdar * Free the recovery list based on the version 789*2654012fSReza Sabdar * 790*2654012fSReza Sabdar * Parameters: 791*2654012fSReza Sabdar * session (input) - session pointer. 792*2654012fSReza Sabdar * 793*2654012fSReza Sabdar * Returns: 794*2654012fSReza Sabdar * void 795*2654012fSReza Sabdar */ 796*2654012fSReza Sabdar void 797*2654012fSReza Sabdar ndmpd_free_nlist(ndmpd_session_t *session) 798*2654012fSReza Sabdar { 799*2654012fSReza Sabdar switch (session->ns_protocol_version) { 800*2654012fSReza Sabdar case 1: 801*2654012fSReza Sabdar case 2: 802*2654012fSReza Sabdar ndmpd_free_nlist_v2(session); 803*2654012fSReza Sabdar break; 804*2654012fSReza Sabdar case 3: 805*2654012fSReza Sabdar case 4: 806*2654012fSReza Sabdar ndmpd_free_nlist_v3(session); 807*2654012fSReza Sabdar break; 808*2654012fSReza Sabdar 809*2654012fSReza Sabdar default: 810*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown version %d", 811*2654012fSReza Sabdar session->ns_protocol_version); 812*2654012fSReza Sabdar } 813*2654012fSReza Sabdar } 814*2654012fSReza Sabdar 815*2654012fSReza Sabdar 816*2654012fSReza Sabdar /* 817*2654012fSReza Sabdar * fh_cmpv3 818*2654012fSReza Sabdar * 819*2654012fSReza Sabdar * Comparison function used in sorting the Nlist based on their 820*2654012fSReza Sabdar * file history info (offset of the entry on the tape) 821*2654012fSReza Sabdar * 822*2654012fSReza Sabdar * Parameters: 823*2654012fSReza Sabdar * p (input) - pointer to P 824*2654012fSReza Sabdar * q (input) - pointer to Q 825*2654012fSReza Sabdar * 826*2654012fSReza Sabdar * Returns: 827*2654012fSReza Sabdar * -1: P < Q 828*2654012fSReza Sabdar * 0: P = Q 829*2654012fSReza Sabdar * 1: P > Q 830*2654012fSReza Sabdar */ 831*2654012fSReza Sabdar static int 832*2654012fSReza Sabdar fh_cmpv3(const void *p, 833*2654012fSReza Sabdar const void *q) 834*2654012fSReza Sabdar { 835*2654012fSReza Sabdar #define FH_INFOV3(p) (((mem_ndmp_name_v3_t *)p)->nm3_fh_info) 836*2654012fSReza Sabdar 837*2654012fSReza Sabdar if (FH_INFOV3(p) < FH_INFOV3(q)) 838*2654012fSReza Sabdar return (-1); 839*2654012fSReza Sabdar else if (FH_INFOV3(p) == FH_INFOV3(q)) 840*2654012fSReza Sabdar return (0); 841*2654012fSReza Sabdar else 842*2654012fSReza Sabdar return (1); 843*2654012fSReza Sabdar 844*2654012fSReza Sabdar #undef FH_INFOV3 845*2654012fSReza Sabdar } 846*2654012fSReza Sabdar 847*2654012fSReza Sabdar 848*2654012fSReza Sabdar /* 849*2654012fSReza Sabdar * ndmp_sort_nlist_v3 850*2654012fSReza Sabdar * 851*2654012fSReza Sabdar * Sort the recovery list based on their offset on the tape 852*2654012fSReza Sabdar * 853*2654012fSReza Sabdar * Parameters: 854*2654012fSReza Sabdar * session (input) - session pointer. 855*2654012fSReza Sabdar * 856*2654012fSReza Sabdar * Returns: 857*2654012fSReza Sabdar * void 858*2654012fSReza Sabdar */ 859*2654012fSReza Sabdar void 860*2654012fSReza Sabdar ndmp_sort_nlist_v3(ndmpd_session_t *session) 861*2654012fSReza Sabdar { 862*2654012fSReza Sabdar if (!session || session->ns_data.dd_nlist_len == 0 || 863*2654012fSReza Sabdar !session->ns_data.dd_nlist_v3) 864*2654012fSReza Sabdar return; 865*2654012fSReza Sabdar 866*2654012fSReza Sabdar (void) qsort(session->ns_data.dd_nlist_v3, 867*2654012fSReza Sabdar session->ns_data.dd_nlist_len, 868*2654012fSReza Sabdar sizeof (mem_ndmp_name_v3_t), fh_cmpv3); 869*2654012fSReza Sabdar } 870*2654012fSReza Sabdar 871*2654012fSReza Sabdar 872*2654012fSReza Sabdar /* 873*2654012fSReza Sabdar * ndmp_send_reply 874*2654012fSReza Sabdar * 875*2654012fSReza Sabdar * Send the reply, check for error and print the msg if any error 876*2654012fSReza Sabdar * occured when sending the reply. 877*2654012fSReza Sabdar * 878*2654012fSReza Sabdar * Parameters: 879*2654012fSReza Sabdar * connection (input) - connection pointer. 880*2654012fSReza Sabdar * 881*2654012fSReza Sabdar * Return: 882*2654012fSReza Sabdar * void 883*2654012fSReza Sabdar */ 884*2654012fSReza Sabdar void 885*2654012fSReza Sabdar ndmp_send_reply(ndmp_connection_t *connection, void *reply, char *msg) 886*2654012fSReza Sabdar { 887*2654012fSReza Sabdar if (ndmp_send_response(connection, NDMP_NO_ERR, reply) < 0) 888*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s", msg); 889*2654012fSReza Sabdar } 890*2654012fSReza Sabdar 891*2654012fSReza Sabdar 892*2654012fSReza Sabdar /* 893*2654012fSReza Sabdar * ndmp_mtioctl 894*2654012fSReza Sabdar * 895*2654012fSReza Sabdar * Performs numerous filemark operations. 896*2654012fSReza Sabdar * 897*2654012fSReza Sabdar * Parameters: 898*2654012fSReza Sabdar * fd - file descriptor of the device 899*2654012fSReza Sabdar * cmd - filemark or record command 900*2654012fSReza Sabdar * count - the number of operations to be performed 901*2654012fSReza Sabdar */ 902*2654012fSReza Sabdar int 903*2654012fSReza Sabdar ndmp_mtioctl(int fd, int cmd, int count) 904*2654012fSReza Sabdar { 905*2654012fSReza Sabdar struct mtop mp; 906*2654012fSReza Sabdar 907*2654012fSReza Sabdar mp.mt_op = cmd; 908*2654012fSReza Sabdar mp.mt_count = count; 909*2654012fSReza Sabdar if (ioctl(fd, MTIOCTOP, &mp) < 0) { 910*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Failed to send command to tape: %m."); 911*2654012fSReza Sabdar return (-1); 912*2654012fSReza Sabdar } 913*2654012fSReza Sabdar 914*2654012fSReza Sabdar return (0); 915*2654012fSReza Sabdar } 916*2654012fSReza Sabdar 917*2654012fSReza Sabdar 918*2654012fSReza Sabdar /* 919*2654012fSReza Sabdar * quad_to_long_long 920*2654012fSReza Sabdar * 921*2654012fSReza Sabdar * Convert type quad to longlong_t 922*2654012fSReza Sabdar */ 923*2654012fSReza Sabdar u_longlong_t 924*2654012fSReza Sabdar quad_to_long_long(ndmp_u_quad q) 925*2654012fSReza Sabdar { 926*2654012fSReza Sabdar u_longlong_t ull; 927*2654012fSReza Sabdar 928*2654012fSReza Sabdar ull = ((u_longlong_t)q.high << 32) + q.low; 929*2654012fSReza Sabdar return (ull); 930*2654012fSReza Sabdar } 931*2654012fSReza Sabdar 932*2654012fSReza Sabdar 933*2654012fSReza Sabdar /* 934*2654012fSReza Sabdar * long_long_to_quad 935*2654012fSReza Sabdar * 936*2654012fSReza Sabdar * Convert long long to quad type 937*2654012fSReza Sabdar */ 938*2654012fSReza Sabdar ndmp_u_quad 939*2654012fSReza Sabdar long_long_to_quad(u_longlong_t ull) 940*2654012fSReza Sabdar { 941*2654012fSReza Sabdar ndmp_u_quad q; 942*2654012fSReza Sabdar 943*2654012fSReza Sabdar q.high = (ulong_t)(ull >> 32); 944*2654012fSReza Sabdar q.low = (ulong_t)ull; 945*2654012fSReza Sabdar return (q); 946*2654012fSReza Sabdar } 947*2654012fSReza Sabdar 948*2654012fSReza Sabdar 949*2654012fSReza Sabdar /* 950*2654012fSReza Sabdar * ndmp_set_socket_nodelay 951*2654012fSReza Sabdar * 952*2654012fSReza Sabdar * Set the TCP socket option to nodelay mode 953*2654012fSReza Sabdar */ 954*2654012fSReza Sabdar void 955*2654012fSReza Sabdar ndmp_set_socket_nodelay(int sock) 956*2654012fSReza Sabdar { 957*2654012fSReza Sabdar int flag = 1; 958*2654012fSReza Sabdar 959*2654012fSReza Sabdar (void) setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof (flag)); 960*2654012fSReza Sabdar } 961*2654012fSReza Sabdar 962*2654012fSReza Sabdar 963*2654012fSReza Sabdar /* 964*2654012fSReza Sabdar * ndmp_set_socket_snd_buf 965*2654012fSReza Sabdar * 966*2654012fSReza Sabdar * Set the socket send buffer size 967*2654012fSReza Sabdar */ 968*2654012fSReza Sabdar void 969*2654012fSReza Sabdar ndmp_set_socket_snd_buf(int sock, int size) 970*2654012fSReza Sabdar { 971*2654012fSReza Sabdar if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 972*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "SO_SNDBUF failed errno=%d", errno); 973*2654012fSReza Sabdar } 974*2654012fSReza Sabdar 975*2654012fSReza Sabdar 976*2654012fSReza Sabdar /* 977*2654012fSReza Sabdar * ndmp_set_socket_rcv_buf 978*2654012fSReza Sabdar * 979*2654012fSReza Sabdar * Set the socket receive buffer size 980*2654012fSReza Sabdar */ 981*2654012fSReza Sabdar void 982*2654012fSReza Sabdar ndmp_set_socket_rcv_buf(int sock, int size) 983*2654012fSReza Sabdar { 984*2654012fSReza Sabdar if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) 985*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "SO_RCVBUF failed errno=%d", errno); 986*2654012fSReza Sabdar } 987*2654012fSReza Sabdar 988*2654012fSReza Sabdar /* 989*2654012fSReza Sabdar * ndmp_get_max_tok_seq 990*2654012fSReza Sabdar * 991*2654012fSReza Sabdar * Get the maximum permitted token sequence for token-based 992*2654012fSReza Sabdar * backups. 993*2654012fSReza Sabdar * 994*2654012fSReza Sabdar * Parameters: 995*2654012fSReza Sabdar * void 996*2654012fSReza Sabdar * 997*2654012fSReza Sabdar * Returns: 998*2654012fSReza Sabdar * ndmp_max_tok_seq 999*2654012fSReza Sabdar */ 1000*2654012fSReza Sabdar int 1001*2654012fSReza Sabdar ndmp_get_max_tok_seq(void) 1002*2654012fSReza Sabdar { 1003*2654012fSReza Sabdar return (ndmp_max_tok_seq); 1004*2654012fSReza Sabdar } 1005*2654012fSReza Sabdar 1006*2654012fSReza Sabdar /* 1007*2654012fSReza Sabdar * ndmp_buffer_get_size 1008*2654012fSReza Sabdar * 1009*2654012fSReza Sabdar * Return the NDMP transfer buffer size 1010*2654012fSReza Sabdar * 1011*2654012fSReza Sabdar * Parameters: 1012*2654012fSReza Sabdar * session (input) - session pointer. 1013*2654012fSReza Sabdar * 1014*2654012fSReza Sabdar * Returns: 1015*2654012fSReza Sabdar * buffer size 1016*2654012fSReza Sabdar */ 1017*2654012fSReza Sabdar long 1018*2654012fSReza Sabdar ndmp_buffer_get_size(ndmpd_session_t *session) 1019*2654012fSReza Sabdar { 1020*2654012fSReza Sabdar long xfer_size; 1021*2654012fSReza Sabdar 1022*2654012fSReza Sabdar if (session == NULL) 1023*2654012fSReza Sabdar return (0); 1024*2654012fSReza Sabdar 1025*2654012fSReza Sabdar if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) { 1026*2654012fSReza Sabdar xfer_size = atoi(ndmpd_get_prop_default(NDMP_MOVER_RECSIZE, 1027*2654012fSReza Sabdar "60")); 1028*2654012fSReza Sabdar if (xfer_size > 0) 1029*2654012fSReza Sabdar xfer_size *= KILOBYTE; 1030*2654012fSReza Sabdar else 1031*2654012fSReza Sabdar xfer_size = REMOTE_RECORD_SIZE; 1032*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Remote operation: %d", xfer_size); 1033*2654012fSReza Sabdar } else { 1034*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1035*2654012fSReza Sabdar "Local operation: %lu", session->ns_mover.md_record_size); 1036*2654012fSReza Sabdar if ((xfer_size = session->ns_mover.md_record_size) == 0) 1037*2654012fSReza Sabdar xfer_size = MAX_RECORD_SIZE; 1038*2654012fSReza Sabdar } 1039*2654012fSReza Sabdar 1040*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "xfer_size: %d", xfer_size); 1041*2654012fSReza Sabdar return (xfer_size); 1042*2654012fSReza Sabdar } 1043*2654012fSReza Sabdar 1044*2654012fSReza Sabdar 1045*2654012fSReza Sabdar /* 1046*2654012fSReza Sabdar * ndmp_lbr_init 1047*2654012fSReza Sabdar * 1048*2654012fSReza Sabdar * Initialize the LBR/NDMP backup parameters 1049*2654012fSReza Sabdar * 1050*2654012fSReza Sabdar * Parameters: 1051*2654012fSReza Sabdar * session (input) - session pointer. 1052*2654012fSReza Sabdar * 1053*2654012fSReza Sabdar * Returns: 1054*2654012fSReza Sabdar * 0: on success 1055*2654012fSReza Sabdar * -1: otherwise 1056*2654012fSReza Sabdar */ 1057*2654012fSReza Sabdar int 1058*2654012fSReza Sabdar ndmp_lbr_init(ndmpd_session_t *session) 1059*2654012fSReza Sabdar { 1060*2654012fSReza Sabdar if (session->ns_ndmp_lbr_params != NULL) { 1061*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_lbr_params already allocated."); 1062*2654012fSReza Sabdar return (0); 1063*2654012fSReza Sabdar } 1064*2654012fSReza Sabdar 1065*2654012fSReza Sabdar session->ns_ndmp_lbr_params = ndmp_malloc(sizeof (ndmp_lbr_params_t)); 1066*2654012fSReza Sabdar if (session->ns_ndmp_lbr_params == NULL) 1067*2654012fSReza Sabdar return (-1); 1068*2654012fSReza Sabdar 1069*2654012fSReza Sabdar session->ns_ndmp_lbr_params->nlp_bkmap = -1; 1070*2654012fSReza Sabdar session->ns_ndmp_lbr_params->nlp_session = session; 1071*2654012fSReza Sabdar (void) cond_init(&session->ns_ndmp_lbr_params->nlp_cv, 0, NULL); 1072*2654012fSReza Sabdar (void) mutex_init(&session->ns_lock, 0, NULL); 1073*2654012fSReza Sabdar session->ns_nref = 0; 1074*2654012fSReza Sabdar return (0); 1075*2654012fSReza Sabdar } 1076*2654012fSReza Sabdar 1077*2654012fSReza Sabdar 1078*2654012fSReza Sabdar /* 1079*2654012fSReza Sabdar * ndmp_lbr_cleanup 1080*2654012fSReza Sabdar * 1081*2654012fSReza Sabdar * Deallocate and cleanup all NDMP/LBR parameters 1082*2654012fSReza Sabdar * 1083*2654012fSReza Sabdar * Parameters: 1084*2654012fSReza Sabdar * session (input) - session pointer. 1085*2654012fSReza Sabdar * 1086*2654012fSReza Sabdar * Returns: 1087*2654012fSReza Sabdar * 0: on success 1088*2654012fSReza Sabdar * -1: otherwise 1089*2654012fSReza Sabdar */ 1090*2654012fSReza Sabdar void 1091*2654012fSReza Sabdar ndmp_lbr_cleanup(ndmpd_session_t *session) 1092*2654012fSReza Sabdar { 1093*2654012fSReza Sabdar /* 1094*2654012fSReza Sabdar * If in 3-way restore, the connection close is detected after 1095*2654012fSReza Sabdar * check in tape_read(), the reader thread of mover may wait forever 1096*2654012fSReza Sabdar * for the tape to be changed. Force the reader thread to exit. 1097*2654012fSReza Sabdar */ 1098*2654012fSReza Sabdar nlp_event_rv_set(session, -2); 1099*2654012fSReza Sabdar nlp_event_nw(session); 1100*2654012fSReza Sabdar 1101*2654012fSReza Sabdar ndmpd_abort_marking_v2(session); 1102*2654012fSReza Sabdar ndmp_stop_buffer_worker(session); 1103*2654012fSReza Sabdar ndmp_waitfor_op(session); 1104*2654012fSReza Sabdar ndmp_free_reader_writer_ipc(session); 1105*2654012fSReza Sabdar if (session->ns_ndmp_lbr_params) { 1106*2654012fSReza Sabdar if (session->ns_ndmp_lbr_params->nlp_bkmap != -1) 1107*2654012fSReza Sabdar (void) dbm_free(session->ns_ndmp_lbr_params->nlp_bkmap); 1108*2654012fSReza Sabdar tlm_release_list(session->ns_ndmp_lbr_params->nlp_exl); 1109*2654012fSReza Sabdar tlm_release_list(session->ns_ndmp_lbr_params->nlp_inc); 1110*2654012fSReza Sabdar (void) cond_destroy(&session->ns_ndmp_lbr_params->nlp_cv); 1111*2654012fSReza Sabdar } 1112*2654012fSReza Sabdar 1113*2654012fSReza Sabdar NDMP_FREE(session->ns_ndmp_lbr_params); 1114*2654012fSReza Sabdar } 1115*2654012fSReza Sabdar 1116*2654012fSReza Sabdar 1117*2654012fSReza Sabdar /* 1118*2654012fSReza Sabdar * nlp_ref_nw 1119*2654012fSReza Sabdar * 1120*2654012fSReza Sabdar * Increase the references to the NDMP/LBR parameter to prevent 1121*2654012fSReza Sabdar * unwanted release 1122*2654012fSReza Sabdar * 1123*2654012fSReza Sabdar * Parameters: 1124*2654012fSReza Sabdar * session (input) - session pointer. 1125*2654012fSReza Sabdar * 1126*2654012fSReza Sabdar * Returns: 1127*2654012fSReza Sabdar * void 1128*2654012fSReza Sabdar */ 1129*2654012fSReza Sabdar void 1130*2654012fSReza Sabdar nlp_ref_nw(ndmpd_session_t *session) 1131*2654012fSReza Sabdar { 1132*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1133*2654012fSReza Sabdar 1134*2654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 1135*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 1136*2654012fSReza Sabdar nlp->nlp_nw++; 1137*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 1138*2654012fSReza Sabdar } else 1139*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1140*2654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 1141*2654012fSReza Sabdar } 1142*2654012fSReza Sabdar 1143*2654012fSReza Sabdar 1144*2654012fSReza Sabdar /* 1145*2654012fSReza Sabdar * nlp_unref_nw 1146*2654012fSReza Sabdar * 1147*2654012fSReza Sabdar * Decrease the references to the NDMP/LBR parameter before 1148*2654012fSReza Sabdar * release 1149*2654012fSReza Sabdar * 1150*2654012fSReza Sabdar * Parameters: 1151*2654012fSReza Sabdar * session (input) - session pointer. 1152*2654012fSReza Sabdar * 1153*2654012fSReza Sabdar * Returns: 1154*2654012fSReza Sabdar * void 1155*2654012fSReza Sabdar */ 1156*2654012fSReza Sabdar void 1157*2654012fSReza Sabdar nlp_unref_nw(ndmpd_session_t *session) 1158*2654012fSReza Sabdar { 1159*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1160*2654012fSReza Sabdar 1161*2654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 1162*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 1163*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 1164*2654012fSReza Sabdar if (nlp->nlp_nw > 0) 1165*2654012fSReza Sabdar nlp->nlp_nw--; 1166*2654012fSReza Sabdar } else 1167*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1168*2654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 1169*2654012fSReza Sabdar } 1170*2654012fSReza Sabdar 1171*2654012fSReza Sabdar 1172*2654012fSReza Sabdar /* 1173*2654012fSReza Sabdar * nlp_wait_nw 1174*2654012fSReza Sabdar * 1175*2654012fSReza Sabdar * Wait for a NDMP/LBR parameter to get available 1176*2654012fSReza Sabdar * 1177*2654012fSReza Sabdar * Parameters: 1178*2654012fSReza Sabdar * session (input) - session pointer. 1179*2654012fSReza Sabdar * 1180*2654012fSReza Sabdar * Returns: 1181*2654012fSReza Sabdar * void 1182*2654012fSReza Sabdar */ 1183*2654012fSReza Sabdar void 1184*2654012fSReza Sabdar nlp_wait_nw(ndmpd_session_t *session) 1185*2654012fSReza Sabdar { 1186*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1187*2654012fSReza Sabdar 1188*2654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 1189*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 1190*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 1191*2654012fSReza Sabdar if (nlp->nlp_nw > 0) { 1192*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Waiting"); 1193*2654012fSReza Sabdar while ((nlp->nlp_flag & NLP_READY) == 0) 1194*2654012fSReza Sabdar (void) cond_wait(&nlp->nlp_cv, &nlp_mtx); 1195*2654012fSReza Sabdar } 1196*2654012fSReza Sabdar } else 1197*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1198*2654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 1199*2654012fSReza Sabdar } 1200*2654012fSReza Sabdar 1201*2654012fSReza Sabdar 1202*2654012fSReza Sabdar /* 1203*2654012fSReza Sabdar * nlp_event_nw 1204*2654012fSReza Sabdar * 1205*2654012fSReza Sabdar * Signal that a NDMP/LBR parameter is available to wake up the 1206*2654012fSReza Sabdar * threads waiting on that 1207*2654012fSReza Sabdar * 1208*2654012fSReza Sabdar * Parameters: 1209*2654012fSReza Sabdar * session (input) - session pointer. 1210*2654012fSReza Sabdar * 1211*2654012fSReza Sabdar * Returns: 1212*2654012fSReza Sabdar * void 1213*2654012fSReza Sabdar */ 1214*2654012fSReza Sabdar void 1215*2654012fSReza Sabdar nlp_event_nw(ndmpd_session_t *session) 1216*2654012fSReza Sabdar { 1217*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1218*2654012fSReza Sabdar 1219*2654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 1220*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 1221*2654012fSReza Sabdar if (nlp->nlp_nw > 0) { 1222*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nlp->nlp_nw); 1223*2654012fSReza Sabdar nlp->nlp_flag |= NLP_READY; 1224*2654012fSReza Sabdar (void) cond_signal(&nlp->nlp_cv); 1225*2654012fSReza Sabdar } 1226*2654012fSReza Sabdar } else 1227*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1228*2654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 1229*2654012fSReza Sabdar } 1230*2654012fSReza Sabdar 1231*2654012fSReza Sabdar 1232*2654012fSReza Sabdar /* 1233*2654012fSReza Sabdar * nlp_event_rv_get 1234*2654012fSReza Sabdar * 1235*2654012fSReza Sabdar * Get the return value for each NLP 1236*2654012fSReza Sabdar * 1237*2654012fSReza Sabdar * Parameters: 1238*2654012fSReza Sabdar * session (input) - session pointer. 1239*2654012fSReza Sabdar * 1240*2654012fSReza Sabdar * Returns: 1241*2654012fSReza Sabdar * return value 1242*2654012fSReza Sabdar */ 1243*2654012fSReza Sabdar int 1244*2654012fSReza Sabdar nlp_event_rv_get(ndmpd_session_t *session) 1245*2654012fSReza Sabdar { 1246*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1247*2654012fSReza Sabdar 1248*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 1249*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1250*2654012fSReza Sabdar return (0); 1251*2654012fSReza Sabdar } 1252*2654012fSReza Sabdar 1253*2654012fSReza Sabdar return (nlp->nlp_rv); 1254*2654012fSReza Sabdar } 1255*2654012fSReza Sabdar 1256*2654012fSReza Sabdar 1257*2654012fSReza Sabdar /* 1258*2654012fSReza Sabdar * nlp_event_rv_set 1259*2654012fSReza Sabdar * 1260*2654012fSReza Sabdar * Set the return value for an NLP 1261*2654012fSReza Sabdar * 1262*2654012fSReza Sabdar * Parameters: 1263*2654012fSReza Sabdar * session (input) - session pointer. 1264*2654012fSReza Sabdar * rv (input) - return value 1265*2654012fSReza Sabdar * 1266*2654012fSReza Sabdar * Returns: 1267*2654012fSReza Sabdar * void 1268*2654012fSReza Sabdar */ 1269*2654012fSReza Sabdar void 1270*2654012fSReza Sabdar nlp_event_rv_set(ndmpd_session_t *session, 1271*2654012fSReza Sabdar int rv) 1272*2654012fSReza Sabdar { 1273*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1274*2654012fSReza Sabdar 1275*2654012fSReza Sabdar (void) mutex_lock(&nlp_mtx); 1276*2654012fSReza Sabdar if (rv != 0) 1277*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "rv: %d", rv); 1278*2654012fSReza Sabdar 1279*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) 1280*2654012fSReza Sabdar nlp->nlp_rv = rv; 1281*2654012fSReza Sabdar else 1282*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1283*2654012fSReza Sabdar (void) mutex_unlock(&nlp_mtx); 1284*2654012fSReza Sabdar } 1285*2654012fSReza Sabdar 1286*2654012fSReza Sabdar /* 1287*2654012fSReza Sabdar * is_buffer_erroneous 1288*2654012fSReza Sabdar * 1289*2654012fSReza Sabdar * Run a sanity check on the buffer 1290*2654012fSReza Sabdar * 1291*2654012fSReza Sabdar * returns: 1292*2654012fSReza Sabdar * TRUE: if the buffer seems to have error 1293*2654012fSReza Sabdar * FALSE: if the buffer is full and has valid data. 1294*2654012fSReza Sabdar */ 1295*2654012fSReza Sabdar boolean_t 1296*2654012fSReza Sabdar is_buffer_erroneous(tlm_buffer_t *buf) 1297*2654012fSReza Sabdar { 1298*2654012fSReza Sabdar boolean_t rv; 1299*2654012fSReza Sabdar 1300*2654012fSReza Sabdar rv = (buf == NULL || buf->tb_eot || buf->tb_eof || 1301*2654012fSReza Sabdar buf->tb_errno != 0); 1302*2654012fSReza Sabdar if (rv) { 1303*2654012fSReza Sabdar if (buf == NULL) { 1304*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "buf == NULL"); 1305*2654012fSReza Sabdar } else { 1306*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "eot: %u, eof: %u, errno: %d", 1307*2654012fSReza Sabdar buf->tb_eot, buf->tb_eof, buf->tb_errno); 1308*2654012fSReza Sabdar } 1309*2654012fSReza Sabdar } 1310*2654012fSReza Sabdar 1311*2654012fSReza Sabdar return (rv); 1312*2654012fSReza Sabdar } 1313*2654012fSReza Sabdar 1314*2654012fSReza Sabdar /* 1315*2654012fSReza Sabdar * ndmp_execute_cdb 1316*2654012fSReza Sabdar * 1317*2654012fSReza Sabdar * Main SCSI CDB execution program, this is used by message handler 1318*2654012fSReza Sabdar * for the NDMP tape/SCSI execute CDB requests. This function uses 1319*2654012fSReza Sabdar * USCSI interface to run the CDB command and sets all the CDB parameters 1320*2654012fSReza Sabdar * in the SCSI query before calling the USCSI ioctl. The result of the 1321*2654012fSReza Sabdar * CDB is returned in two places: 1322*2654012fSReza Sabdar * cmd.uscsi_status The status of CDB execution 1323*2654012fSReza Sabdar * cmd.uscsi_rqstatus The status of sense requests 1324*2654012fSReza Sabdar * reply.error The general errno (ioctl) 1325*2654012fSReza Sabdar * 1326*2654012fSReza Sabdar * Parameters: 1327*2654012fSReza Sabdar * session (input) - session pointer 1328*2654012fSReza Sabdar * adapter_name (input) - name of SCSI adapter 1329*2654012fSReza Sabdar * sid (input) - SCSI target ID 1330*2654012fSReza Sabdar * lun (input) - LUN number 1331*2654012fSReza Sabdar * request (input) - NDMP client CDB request 1332*2654012fSReza Sabdar * 1333*2654012fSReza Sabdar * Returns: 1334*2654012fSReza Sabdar * void 1335*2654012fSReza Sabdar */ 1336*2654012fSReza Sabdar /*ARGSUSED*/ 1337*2654012fSReza Sabdar void 1338*2654012fSReza Sabdar ndmp_execute_cdb(ndmpd_session_t *session, char *adapter_name, int sid, int lun, 1339*2654012fSReza Sabdar ndmp_execute_cdb_request *request) 1340*2654012fSReza Sabdar { 1341*2654012fSReza Sabdar ndmp_execute_cdb_reply reply; 1342*2654012fSReza Sabdar struct uscsi_cmd cmd; 1343*2654012fSReza Sabdar int fd; 1344*2654012fSReza Sabdar struct open_list *olp; 1345*2654012fSReza Sabdar char rq_buf[255]; 1346*2654012fSReza Sabdar 1347*2654012fSReza Sabdar (void) memset((void *)&cmd, 0, sizeof (cmd)); 1348*2654012fSReza Sabdar (void) memset((void *)&reply, 0, sizeof (reply)); 1349*2654012fSReza Sabdar (void) memset((void *)rq_buf, 0, sizeof (rq_buf)); 1350*2654012fSReza Sabdar 1351*2654012fSReza Sabdar cmd.uscsi_flags = USCSI_RQENABLE; 1352*2654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) { 1353*2654012fSReza Sabdar cmd.uscsi_flags |= USCSI_READ; 1354*2654012fSReza Sabdar if ((cmd.uscsi_bufaddr = 1355*2654012fSReza Sabdar ndmp_malloc(request->datain_len)) == 0) { 1356*2654012fSReza Sabdar reply.error = NDMP_NO_MEM_ERR; 1357*2654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, 1358*2654012fSReza Sabdar NDMP_NO_ERR, (void *)&reply) < 0) 1359*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "error sending" 1360*2654012fSReza Sabdar " scsi_execute_cdb reply."); 1361*2654012fSReza Sabdar return; 1362*2654012fSReza Sabdar } 1363*2654012fSReza Sabdar 1364*2654012fSReza Sabdar cmd.uscsi_buflen = request->datain_len; 1365*2654012fSReza Sabdar cmd.uscsi_rqlen = sizeof (rq_buf); 1366*2654012fSReza Sabdar cmd.uscsi_rqbuf = rq_buf; 1367*2654012fSReza Sabdar } else if (request->flags == NDMP_SCSI_DATA_OUT) { 1368*2654012fSReza Sabdar cmd.uscsi_flags = USCSI_RQENABLE | USCSI_WRITE; 1369*2654012fSReza Sabdar cmd.uscsi_bufaddr = request->dataout.dataout_val; 1370*2654012fSReza Sabdar cmd.uscsi_buflen = request->dataout.dataout_len; 1371*2654012fSReza Sabdar } else { 1372*2654012fSReza Sabdar cmd.uscsi_bufaddr = 0; 1373*2654012fSReza Sabdar cmd.uscsi_buflen = 0; 1374*2654012fSReza Sabdar cmd.uscsi_rqlen = sizeof (rq_buf); 1375*2654012fSReza Sabdar cmd.uscsi_rqbuf = rq_buf; 1376*2654012fSReza Sabdar } 1377*2654012fSReza Sabdar 1378*2654012fSReza Sabdar cmd.uscsi_timeout = (request->timeout < 1000) ? 1379*2654012fSReza Sabdar 1 : (request->timeout / 1000); 1380*2654012fSReza Sabdar 1381*2654012fSReza Sabdar cmd.uscsi_cdb = (caddr_t)request->cdb.cdb_val; 1382*2654012fSReza Sabdar cmd.uscsi_cdblen = request->cdb.cdb_len; 1383*2654012fSReza Sabdar 1384*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd: 0x%x, len: %d, flags: %d, datain_len: %d", 1385*2654012fSReza Sabdar request->cdb.cdb_val[0] & 0xff, request->cdb.cdb_len, 1386*2654012fSReza Sabdar request->flags, request->datain_len); 1387*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dataout_len: %d, timeout: %d", 1388*2654012fSReza Sabdar request->dataout.dataout_len, request->timeout); 1389*2654012fSReza Sabdar 1390*2654012fSReza Sabdar if (request->cdb.cdb_len > 12) { 1391*2654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR; 1392*2654012fSReza Sabdar ndmp_send_reply(session->ns_connection, (void *) &reply, 1393*2654012fSReza Sabdar "sending execute_cdb reply"); 1394*2654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) 1395*2654012fSReza Sabdar free(cmd.uscsi_bufaddr); 1396*2654012fSReza Sabdar return; 1397*2654012fSReza Sabdar } 1398*2654012fSReza Sabdar 1399*2654012fSReza Sabdar reply.error = NDMP_NO_ERR; 1400*2654012fSReza Sabdar 1401*2654012fSReza Sabdar if ((olp = ndmp_open_list_find(adapter_name, sid, lun)) != NULL) { 1402*2654012fSReza Sabdar fd = olp->ol_fd; 1403*2654012fSReza Sabdar } else { 1404*2654012fSReza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR; 1405*2654012fSReza Sabdar ndmp_send_reply(session->ns_connection, (void *) &reply, 1406*2654012fSReza Sabdar "sending execute_cdb reply"); 1407*2654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) 1408*2654012fSReza Sabdar free(cmd.uscsi_bufaddr); 1409*2654012fSReza Sabdar return; 1410*2654012fSReza Sabdar } 1411*2654012fSReza Sabdar 1412*2654012fSReza Sabdar if (ioctl(fd, USCSICMD, &cmd) < 0) { 1413*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Failed to send command to device: %m"); 1414*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(USCSICMD) error: %m"); 1415*2654012fSReza Sabdar if (cmd.uscsi_status == 0) 1416*2654012fSReza Sabdar reply.error = NDMP_IO_ERR; 1417*2654012fSReza Sabdar } 1418*2654012fSReza Sabdar 1419*2654012fSReza Sabdar reply.status = cmd.uscsi_status; 1420*2654012fSReza Sabdar 1421*2654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) { 1422*2654012fSReza Sabdar reply.datain.datain_len = cmd.uscsi_buflen; 1423*2654012fSReza Sabdar reply.datain.datain_val = cmd.uscsi_bufaddr; 1424*2654012fSReza Sabdar } else { 1425*2654012fSReza Sabdar reply.dataout_len = request->dataout.dataout_len; 1426*2654012fSReza Sabdar } 1427*2654012fSReza Sabdar 1428*2654012fSReza Sabdar reply.ext_sense.ext_sense_len = cmd.uscsi_rqlen - cmd.uscsi_rqresid; 1429*2654012fSReza Sabdar reply.ext_sense.ext_sense_val = rq_buf; 1430*2654012fSReza Sabdar 1431*2654012fSReza Sabdar if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR, 1432*2654012fSReza Sabdar (void *)&reply) < 0) 1433*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Error sending scsi_execute_cdb reply."); 1434*2654012fSReza Sabdar 1435*2654012fSReza Sabdar if (request->flags == NDMP_SCSI_DATA_IN) 1436*2654012fSReza Sabdar free(cmd.uscsi_bufaddr); 1437*2654012fSReza Sabdar } 1438*2654012fSReza Sabdar 1439*2654012fSReza Sabdar 1440*2654012fSReza Sabdar /* 1441*2654012fSReza Sabdar * ndmp_stop_local_reader 1442*2654012fSReza Sabdar * 1443*2654012fSReza Sabdar * Stops a mover reader thread (for local backup only) 1444*2654012fSReza Sabdar * 1445*2654012fSReza Sabdar * Parameters: 1446*2654012fSReza Sabdar * session (input) - session pointer 1447*2654012fSReza Sabdar * cmds (input) - reader/writer command struct 1448*2654012fSReza Sabdar * 1449*2654012fSReza Sabdar * Returns: 1450*2654012fSReza Sabdar * void 1451*2654012fSReza Sabdar */ 1452*2654012fSReza Sabdar void 1453*2654012fSReza Sabdar ndmp_stop_local_reader(ndmpd_session_t *session, tlm_commands_t *cmds) 1454*2654012fSReza Sabdar { 1455*2654012fSReza Sabdar if (session != NULL) { 1456*2654012fSReza Sabdar if (session->ns_data.dd_sock == -1) { 1457*2654012fSReza Sabdar /* 1458*2654012fSReza Sabdar * 2-way restore. 1459*2654012fSReza Sabdar */ 1460*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "2-way restore"); 1461*2654012fSReza Sabdar if (cmds != NULL && cmds->tcs_reader_count > 0) { 1462*2654012fSReza Sabdar nlp_event_rv_set(session, -2); 1463*2654012fSReza Sabdar nlp_event_nw(session); 1464*2654012fSReza Sabdar } 1465*2654012fSReza Sabdar } 1466*2654012fSReza Sabdar } 1467*2654012fSReza Sabdar } 1468*2654012fSReza Sabdar 1469*2654012fSReza Sabdar 1470*2654012fSReza Sabdar /* 1471*2654012fSReza Sabdar * Stops a mover reader thread (for remote backup only) 1472*2654012fSReza Sabdar * 1473*2654012fSReza Sabdar * Parameters: 1474*2654012fSReza Sabdar * session (input) - session pointer 1475*2654012fSReza Sabdar * cmds (input) - reader/writer command struct 1476*2654012fSReza Sabdar * 1477*2654012fSReza Sabdar * Returns: 1478*2654012fSReza Sabdar * void 1479*2654012fSReza Sabdar */ 1480*2654012fSReza Sabdar void 1481*2654012fSReza Sabdar ndmp_stop_remote_reader(ndmpd_session_t *session) 1482*2654012fSReza Sabdar { 1483*2654012fSReza Sabdar if (session != NULL) { 1484*2654012fSReza Sabdar if (session->ns_data.dd_sock >= 0) { 1485*2654012fSReza Sabdar /* 1486*2654012fSReza Sabdar * 3-way restore. 1487*2654012fSReza Sabdar */ 1488*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1489*2654012fSReza Sabdar "data.sock: %d", session->ns_data.dd_sock); 1490*2654012fSReza Sabdar (void) close(session->ns_data.dd_sock); 1491*2654012fSReza Sabdar session->ns_data.dd_sock = -1; 1492*2654012fSReza Sabdar } 1493*2654012fSReza Sabdar } 1494*2654012fSReza Sabdar } 1495*2654012fSReza Sabdar 1496*2654012fSReza Sabdar 1497*2654012fSReza Sabdar /* 1498*2654012fSReza Sabdar * ndmp_wait_for_reader 1499*2654012fSReza Sabdar * 1500*2654012fSReza Sabdar * Wait for a reader until get done (busy wait) 1501*2654012fSReza Sabdar */ 1502*2654012fSReza Sabdar void 1503*2654012fSReza Sabdar ndmp_wait_for_reader(tlm_commands_t *cmds) 1504*2654012fSReza Sabdar { 1505*2654012fSReza Sabdar if (cmds == NULL) { 1506*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 1507*2654012fSReza Sabdar } else { 1508*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1509*2654012fSReza Sabdar "reader_count: %d", cmds->tcs_reader_count); 1510*2654012fSReza Sabdar 1511*2654012fSReza Sabdar while (cmds->tcs_reader_count > 0) 1512*2654012fSReza Sabdar (void) sleep(1); 1513*2654012fSReza Sabdar } 1514*2654012fSReza Sabdar } 1515*2654012fSReza Sabdar 1516*2654012fSReza Sabdar 1517*2654012fSReza Sabdar /* 1518*2654012fSReza Sabdar * ndmp_open_list_find 1519*2654012fSReza Sabdar * 1520*2654012fSReza Sabdar * Find a specific device in the open list 1521*2654012fSReza Sabdar * 1522*2654012fSReza Sabdar * Parameters: 1523*2654012fSReza Sabdar * dev (input) - device name 1524*2654012fSReza Sabdar * sid (input) - SCSI target ID 1525*2654012fSReza Sabdar * lun (input) - LUN number 1526*2654012fSReza Sabdar * 1527*2654012fSReza Sabdar * Returns: 1528*2654012fSReza Sabdar * pointer to the open list entry 1529*2654012fSReza Sabdar */ 1530*2654012fSReza Sabdar struct open_list * 1531*2654012fSReza Sabdar ndmp_open_list_find(char *dev, int sid, int lun) 1532*2654012fSReza Sabdar { 1533*2654012fSReza Sabdar struct ol_head *olhp; 1534*2654012fSReza Sabdar struct open_list *olp; 1535*2654012fSReza Sabdar 1536*2654012fSReza Sabdar if (dev == NULL || *dev == '\0') { 1537*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 1538*2654012fSReza Sabdar return (NULL); 1539*2654012fSReza Sabdar } 1540*2654012fSReza Sabdar 1541*2654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 1542*2654012fSReza Sabdar olhp = &ol_head; 1543*2654012fSReza Sabdar for (olp = LIST_FIRST(olhp); olp != NULL; olp = LIST_NEXT(olp, ol_q)) 1544*2654012fSReza Sabdar if (strcmp(olp->ol_devnm, dev) == 0 && olp->ol_sid == sid && 1545*2654012fSReza Sabdar olp->ol_lun == lun) { 1546*2654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 1547*2654012fSReza Sabdar return (olp); 1548*2654012fSReza Sabdar } 1549*2654012fSReza Sabdar 1550*2654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 1551*2654012fSReza Sabdar return (NULL); 1552*2654012fSReza Sabdar } 1553*2654012fSReza Sabdar 1554*2654012fSReza Sabdar 1555*2654012fSReza Sabdar /* 1556*2654012fSReza Sabdar * ndmp_open_list_add 1557*2654012fSReza Sabdar * 1558*2654012fSReza Sabdar * Add a specific device to the open list 1559*2654012fSReza Sabdar * 1560*2654012fSReza Sabdar * Parameters: 1561*2654012fSReza Sabdar * conn (input) - connection pointer 1562*2654012fSReza Sabdar * dev (input) - device name 1563*2654012fSReza Sabdar * sid (input) - SCSI target ID 1564*2654012fSReza Sabdar * lun (input) - LUN number 1565*2654012fSReza Sabdar * fd (input) - the device file descriptor 1566*2654012fSReza Sabdar * 1567*2654012fSReza Sabdar * Returns: 1568*2654012fSReza Sabdar * errno 1569*2654012fSReza Sabdar */ 1570*2654012fSReza Sabdar int 1571*2654012fSReza Sabdar ndmp_open_list_add(ndmp_connection_t *conn, char *dev, int sid, int lun, int fd) 1572*2654012fSReza Sabdar { 1573*2654012fSReza Sabdar int err; 1574*2654012fSReza Sabdar struct ol_head *olhp; 1575*2654012fSReza Sabdar struct open_list *olp; 1576*2654012fSReza Sabdar 1577*2654012fSReza Sabdar if (dev == NULL || *dev == '\0') { 1578*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 1579*2654012fSReza Sabdar return (EINVAL); 1580*2654012fSReza Sabdar } 1581*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1582*2654012fSReza Sabdar "conn: 0x%08x, dev: %s, sid: %d, lun: %d", conn, dev, sid, lun); 1583*2654012fSReza Sabdar 1584*2654012fSReza Sabdar err = 0; 1585*2654012fSReza Sabdar olhp = &ol_head; 1586*2654012fSReza Sabdar 1587*2654012fSReza Sabdar if ((olp = ndmp_open_list_find(dev, sid, lun)) != NULL) { 1588*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "already in list"); 1589*2654012fSReza Sabdar /* 1590*2654012fSReza Sabdar * The adapter handle can be opened many times by the clients. 1591*2654012fSReza Sabdar * Only when the target is set, we must check and reject the 1592*2654012fSReza Sabdar * open request if the device is already being used by another 1593*2654012fSReza Sabdar * session. 1594*2654012fSReza Sabdar */ 1595*2654012fSReza Sabdar if (sid == -1) 1596*2654012fSReza Sabdar olp->ol_nref++; 1597*2654012fSReza Sabdar else 1598*2654012fSReza Sabdar err = EBUSY; 1599*2654012fSReza Sabdar } else if ((olp = ndmp_malloc(sizeof (struct open_list))) == NULL) { 1600*2654012fSReza Sabdar err = ENOMEM; 1601*2654012fSReza Sabdar } else if ((olp->ol_devnm = strdup(dev)) == NULL) { 1602*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Out of memory."); 1603*2654012fSReza Sabdar free(olp); 1604*2654012fSReza Sabdar err = ENOMEM; 1605*2654012fSReza Sabdar } else { 1606*2654012fSReza Sabdar olp->cl_conn = conn; 1607*2654012fSReza Sabdar olp->ol_nref = 1; 1608*2654012fSReza Sabdar olp->ol_sid = sid; 1609*2654012fSReza Sabdar olp->ol_lun = lun; 1610*2654012fSReza Sabdar if (fd > 0) 1611*2654012fSReza Sabdar olp->ol_fd = fd; 1612*2654012fSReza Sabdar else 1613*2654012fSReza Sabdar olp->ol_fd = -1; 1614*2654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 1615*2654012fSReza Sabdar /* LINTED: E_CONSTANT_CONDITION */ 1616*2654012fSReza Sabdar LIST_INSERT_HEAD(olhp, olp, ol_q); 1617*2654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 1618*2654012fSReza Sabdar } 1619*2654012fSReza Sabdar 1620*2654012fSReza Sabdar return (err); 1621*2654012fSReza Sabdar } 1622*2654012fSReza Sabdar 1623*2654012fSReza Sabdar 1624*2654012fSReza Sabdar /* 1625*2654012fSReza Sabdar * ndmp_open_list_del 1626*2654012fSReza Sabdar * 1627*2654012fSReza Sabdar * Delete a specific device from the open list 1628*2654012fSReza Sabdar * 1629*2654012fSReza Sabdar * Parameters: 1630*2654012fSReza Sabdar * dev (input) - device name 1631*2654012fSReza Sabdar * sid (input) - SCSI target ID 1632*2654012fSReza Sabdar * lun (input) - LUN number 1633*2654012fSReza Sabdar * 1634*2654012fSReza Sabdar * Returns: 1635*2654012fSReza Sabdar * errno 1636*2654012fSReza Sabdar */ 1637*2654012fSReza Sabdar int 1638*2654012fSReza Sabdar ndmp_open_list_del(char *dev, int sid, int lun) 1639*2654012fSReza Sabdar { 1640*2654012fSReza Sabdar struct open_list *olp; 1641*2654012fSReza Sabdar 1642*2654012fSReza Sabdar if (dev == NULL || *dev == '\0') { 1643*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 1644*2654012fSReza Sabdar return (EINVAL); 1645*2654012fSReza Sabdar } 1646*2654012fSReza Sabdar if ((olp = ndmp_open_list_find(dev, sid, lun)) == NULL) { 1647*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s not found", dev); 1648*2654012fSReza Sabdar return (ENOENT); 1649*2654012fSReza Sabdar } 1650*2654012fSReza Sabdar 1651*2654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 1652*2654012fSReza Sabdar if (--olp->ol_nref <= 0) { 1653*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1654*2654012fSReza Sabdar "Removed dev: %s, sid: %d, lun: %d", dev, sid, lun); 1655*2654012fSReza Sabdar /* LINTED: E_CONSTANT_CONDITION */ 1656*2654012fSReza Sabdar LIST_REMOVE(olp, ol_q); 1657*2654012fSReza Sabdar free(olp->ol_devnm); 1658*2654012fSReza Sabdar free(olp); 1659*2654012fSReza Sabdar } 1660*2654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 1661*2654012fSReza Sabdar 1662*2654012fSReza Sabdar return (0); 1663*2654012fSReza Sabdar } 1664*2654012fSReza Sabdar 1665*2654012fSReza Sabdar 1666*2654012fSReza Sabdar /* 1667*2654012fSReza Sabdar * ndmp_open_list_release 1668*2654012fSReza Sabdar * 1669*2654012fSReza Sabdar * Close all the resources belonging to this connection. 1670*2654012fSReza Sabdar * 1671*2654012fSReza Sabdar * Parameters: 1672*2654012fSReza Sabdar * ndmp_connection_t *conn : connection identifier 1673*2654012fSReza Sabdar * 1674*2654012fSReza Sabdar * Returns: 1675*2654012fSReza Sabdar * void 1676*2654012fSReza Sabdar */ 1677*2654012fSReza Sabdar void 1678*2654012fSReza Sabdar ndmp_open_list_release(ndmp_connection_t *conn) 1679*2654012fSReza Sabdar { 1680*2654012fSReza Sabdar struct ol_head *olhp = &ol_head; 1681*2654012fSReza Sabdar struct open_list *olp; 1682*2654012fSReza Sabdar struct open_list *next; 1683*2654012fSReza Sabdar 1684*2654012fSReza Sabdar (void) mutex_lock(&ol_mutex); 1685*2654012fSReza Sabdar olp = LIST_FIRST(olhp); 1686*2654012fSReza Sabdar while (olp != NULL) { 1687*2654012fSReza Sabdar next = LIST_NEXT(olp, ol_q); 1688*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "olp->conn 0x%08x", olp->cl_conn); 1689*2654012fSReza Sabdar if (olp->cl_conn == conn) { 1690*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1691*2654012fSReza Sabdar "Removed dev: %s, sid: %d, lun: %d", 1692*2654012fSReza Sabdar olp->ol_devnm, olp->ol_sid, olp->ol_lun); 1693*2654012fSReza Sabdar /* LINTED: E_CONSTANT_CONDITION */ 1694*2654012fSReza Sabdar LIST_REMOVE(olp, ol_q); 1695*2654012fSReza Sabdar if (olp->ol_fd > 0) 1696*2654012fSReza Sabdar (void) close(olp->ol_fd); 1697*2654012fSReza Sabdar free(olp->ol_devnm); 1698*2654012fSReza Sabdar free(olp); 1699*2654012fSReza Sabdar } 1700*2654012fSReza Sabdar olp = next; 1701*2654012fSReza Sabdar } 1702*2654012fSReza Sabdar (void) mutex_unlock(&ol_mutex); 1703*2654012fSReza Sabdar } 1704*2654012fSReza Sabdar 1705*2654012fSReza Sabdar 1706*2654012fSReza Sabdar /* 1707*2654012fSReza Sabdar * ndmp_stop_buffer_worker 1708*2654012fSReza Sabdar * 1709*2654012fSReza Sabdar * Stop all reader and writer threads for a specific buffer. 1710*2654012fSReza Sabdar * 1711*2654012fSReza Sabdar * Parameters: 1712*2654012fSReza Sabdar * session (input) - session pointer 1713*2654012fSReza Sabdar * 1714*2654012fSReza Sabdar * Returns: 1715*2654012fSReza Sabdar * void 1716*2654012fSReza Sabdar */ 1717*2654012fSReza Sabdar void 1718*2654012fSReza Sabdar ndmp_stop_buffer_worker(ndmpd_session_t *session) 1719*2654012fSReza Sabdar { 1720*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1721*2654012fSReza Sabdar tlm_commands_t *cmds; 1722*2654012fSReza Sabdar 1723*2654012fSReza Sabdar session->ns_tape.td_pos = 0; 1724*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 1725*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1726*2654012fSReza Sabdar } else { 1727*2654012fSReza Sabdar cmds = &nlp->nlp_cmds; 1728*2654012fSReza Sabdar if (cmds->tcs_command == NULL) { 1729*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL"); 1730*2654012fSReza Sabdar } else { 1731*2654012fSReza Sabdar cmds->tcs_reader = cmds->tcs_writer = TLM_ABORT; 1732*2654012fSReza Sabdar cmds->tcs_command->tc_reader = TLM_ABORT; 1733*2654012fSReza Sabdar cmds->tcs_command->tc_writer = TLM_ABORT; 1734*2654012fSReza Sabdar while (cmds->tcs_reader_count > 0 || 1735*2654012fSReza Sabdar cmds->tcs_writer_count > 0) { 1736*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1737*2654012fSReza Sabdar "trying to stop buffer worker"); 1738*2654012fSReza Sabdar (void) sleep(1); 1739*2654012fSReza Sabdar } 1740*2654012fSReza Sabdar } 1741*2654012fSReza Sabdar } 1742*2654012fSReza Sabdar } 1743*2654012fSReza Sabdar 1744*2654012fSReza Sabdar 1745*2654012fSReza Sabdar /* 1746*2654012fSReza Sabdar * ndmp_stop_reader_thread 1747*2654012fSReza Sabdar * 1748*2654012fSReza Sabdar * Stop only the reader threads of a specific buffer 1749*2654012fSReza Sabdar * 1750*2654012fSReza Sabdar * Parameters: 1751*2654012fSReza Sabdar * session (input) - session pointer 1752*2654012fSReza Sabdar * 1753*2654012fSReza Sabdar * Returns: 1754*2654012fSReza Sabdar * void 1755*2654012fSReza Sabdar */ 1756*2654012fSReza Sabdar void 1757*2654012fSReza Sabdar ndmp_stop_reader_thread(ndmpd_session_t *session) 1758*2654012fSReza Sabdar { 1759*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1760*2654012fSReza Sabdar tlm_commands_t *cmds; 1761*2654012fSReza Sabdar 1762*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 1763*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1764*2654012fSReza Sabdar } else { 1765*2654012fSReza Sabdar cmds = &nlp->nlp_cmds; 1766*2654012fSReza Sabdar if (cmds->tcs_command == NULL) { 1767*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL"); 1768*2654012fSReza Sabdar } else { 1769*2654012fSReza Sabdar cmds->tcs_reader = TLM_ABORT; 1770*2654012fSReza Sabdar cmds->tcs_command->tc_reader = TLM_ABORT; 1771*2654012fSReza Sabdar while (cmds->tcs_reader_count > 0) { 1772*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1773*2654012fSReza Sabdar "trying to stop reader thread"); 1774*2654012fSReza Sabdar (void) sleep(1); 1775*2654012fSReza Sabdar } 1776*2654012fSReza Sabdar } 1777*2654012fSReza Sabdar } 1778*2654012fSReza Sabdar } 1779*2654012fSReza Sabdar 1780*2654012fSReza Sabdar 1781*2654012fSReza Sabdar /* 1782*2654012fSReza Sabdar * ndmp_stop_reader_thread 1783*2654012fSReza Sabdar * 1784*2654012fSReza Sabdar * Stop only the writer threads of a specific buffer 1785*2654012fSReza Sabdar * 1786*2654012fSReza Sabdar * Parameters: 1787*2654012fSReza Sabdar * session (input) - session pointer 1788*2654012fSReza Sabdar * 1789*2654012fSReza Sabdar * Returns: 1790*2654012fSReza Sabdar * void 1791*2654012fSReza Sabdar */ 1792*2654012fSReza Sabdar void 1793*2654012fSReza Sabdar ndmp_stop_writer_thread(ndmpd_session_t *session) 1794*2654012fSReza Sabdar { 1795*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1796*2654012fSReza Sabdar tlm_commands_t *cmds; 1797*2654012fSReza Sabdar 1798*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 1799*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1800*2654012fSReza Sabdar } else { 1801*2654012fSReza Sabdar cmds = &nlp->nlp_cmds; 1802*2654012fSReza Sabdar if (cmds->tcs_command == NULL) { 1803*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL"); 1804*2654012fSReza Sabdar } else { 1805*2654012fSReza Sabdar cmds->tcs_writer = TLM_ABORT; 1806*2654012fSReza Sabdar cmds->tcs_command->tc_writer = TLM_ABORT; 1807*2654012fSReza Sabdar while (cmds->tcs_writer_count > 0) { 1808*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1809*2654012fSReza Sabdar "trying to stop writer thread"); 1810*2654012fSReza Sabdar (void) sleep(1); 1811*2654012fSReza Sabdar } 1812*2654012fSReza Sabdar } 1813*2654012fSReza Sabdar } 1814*2654012fSReza Sabdar } 1815*2654012fSReza Sabdar 1816*2654012fSReza Sabdar 1817*2654012fSReza Sabdar /* 1818*2654012fSReza Sabdar * ndmp_free_reader_writer_ipc 1819*2654012fSReza Sabdar * 1820*2654012fSReza Sabdar * Free and release the reader/writer buffers and the IPC structure 1821*2654012fSReza Sabdar * for reader and writer threads. 1822*2654012fSReza Sabdar * 1823*2654012fSReza Sabdar * Parameters: 1824*2654012fSReza Sabdar * session (input) - session pointer 1825*2654012fSReza Sabdar * 1826*2654012fSReza Sabdar * Returns: 1827*2654012fSReza Sabdar * void 1828*2654012fSReza Sabdar */ 1829*2654012fSReza Sabdar void 1830*2654012fSReza Sabdar ndmp_free_reader_writer_ipc(ndmpd_session_t *session) 1831*2654012fSReza Sabdar { 1832*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1833*2654012fSReza Sabdar tlm_commands_t *cmds; 1834*2654012fSReza Sabdar 1835*2654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) != NULL) { 1836*2654012fSReza Sabdar cmds = &nlp->nlp_cmds; 1837*2654012fSReza Sabdar if (cmds->tcs_command != NULL) { 1838*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds->tcs_command->tc_ref: %d", 1839*2654012fSReza Sabdar cmds->tcs_command->tc_ref); 1840*2654012fSReza Sabdar tlm_release_reader_writer_ipc(cmds->tcs_command); 1841*2654012fSReza Sabdar } 1842*2654012fSReza Sabdar } 1843*2654012fSReza Sabdar } 1844*2654012fSReza Sabdar 1845*2654012fSReza Sabdar 1846*2654012fSReza Sabdar /* 1847*2654012fSReza Sabdar * ndmp_waitfor_op 1848*2654012fSReza Sabdar * 1849*2654012fSReza Sabdar * Wait for a session reference count to drop to zero 1850*2654012fSReza Sabdar * 1851*2654012fSReza Sabdar * Parameters: 1852*2654012fSReza Sabdar * session (input) - session pointer 1853*2654012fSReza Sabdar * 1854*2654012fSReza Sabdar * Returns: 1855*2654012fSReza Sabdar * void 1856*2654012fSReza Sabdar */ 1857*2654012fSReza Sabdar void 1858*2654012fSReza Sabdar ndmp_waitfor_op(ndmpd_session_t *session) 1859*2654012fSReza Sabdar { 1860*2654012fSReza Sabdar if (session != NULL) { 1861*2654012fSReza Sabdar while (session->ns_nref > 0) { 1862*2654012fSReza Sabdar (void) sleep(1); 1863*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 1864*2654012fSReza Sabdar "waiting for session nref: %d", session->ns_nref); 1865*2654012fSReza Sabdar } 1866*2654012fSReza Sabdar } 1867*2654012fSReza Sabdar } 1868*2654012fSReza Sabdar 1869*2654012fSReza Sabdar 1870*2654012fSReza Sabdar /* 1871*2654012fSReza Sabdar * ndmp_session_ref 1872*2654012fSReza Sabdar * 1873*2654012fSReza Sabdar * Increment the reference count of the session 1874*2654012fSReza Sabdar * 1875*2654012fSReza Sabdar * Parameters: 1876*2654012fSReza Sabdar * session (input) - session pointer 1877*2654012fSReza Sabdar * 1878*2654012fSReza Sabdar * Returns: 1879*2654012fSReza Sabdar * void 1880*2654012fSReza Sabdar */ 1881*2654012fSReza Sabdar void 1882*2654012fSReza Sabdar ndmp_session_ref(ndmpd_session_t *session) 1883*2654012fSReza Sabdar { 1884*2654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 1885*2654012fSReza Sabdar session->ns_nref++; 1886*2654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 1887*2654012fSReza Sabdar } 1888*2654012fSReza Sabdar 1889*2654012fSReza Sabdar 1890*2654012fSReza Sabdar /* 1891*2654012fSReza Sabdar * ndmp_session_unref 1892*2654012fSReza Sabdar * 1893*2654012fSReza Sabdar * Decrement the reference count of the session 1894*2654012fSReza Sabdar * 1895*2654012fSReza Sabdar * Parameters: 1896*2654012fSReza Sabdar * session (input) - session pointer 1897*2654012fSReza Sabdar * 1898*2654012fSReza Sabdar * Returns: 1899*2654012fSReza Sabdar * void 1900*2654012fSReza Sabdar */ 1901*2654012fSReza Sabdar void 1902*2654012fSReza Sabdar ndmp_session_unref(ndmpd_session_t *session) 1903*2654012fSReza Sabdar { 1904*2654012fSReza Sabdar (void) mutex_lock(&session->ns_lock); 1905*2654012fSReza Sabdar session->ns_nref--; 1906*2654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock); 1907*2654012fSReza Sabdar } 1908*2654012fSReza Sabdar 1909*2654012fSReza Sabdar 1910*2654012fSReza Sabdar /* 1911*2654012fSReza Sabdar * ndmp_addr2str_v3 1912*2654012fSReza Sabdar * 1913*2654012fSReza Sabdar * Convert the address type to a string 1914*2654012fSReza Sabdar * 1915*2654012fSReza Sabdar * Parameters: 1916*2654012fSReza Sabdar * type (input) - address type 1917*2654012fSReza Sabdar * 1918*2654012fSReza Sabdar * Returns: 1919*2654012fSReza Sabdar * type in string 1920*2654012fSReza Sabdar */ 1921*2654012fSReza Sabdar char * 1922*2654012fSReza Sabdar ndmp_addr2str_v3(ndmp_addr_type type) 1923*2654012fSReza Sabdar { 1924*2654012fSReza Sabdar char *rv; 1925*2654012fSReza Sabdar 1926*2654012fSReza Sabdar switch (type) { 1927*2654012fSReza Sabdar case NDMP_ADDR_LOCAL: 1928*2654012fSReza Sabdar rv = "Local"; 1929*2654012fSReza Sabdar break; 1930*2654012fSReza Sabdar case NDMP_ADDR_TCP: 1931*2654012fSReza Sabdar rv = "TCP"; 1932*2654012fSReza Sabdar break; 1933*2654012fSReza Sabdar case NDMP_ADDR_FC: 1934*2654012fSReza Sabdar rv = "FC"; 1935*2654012fSReza Sabdar break; 1936*2654012fSReza Sabdar case NDMP_ADDR_IPC: 1937*2654012fSReza Sabdar rv = "IPC"; 1938*2654012fSReza Sabdar break; 1939*2654012fSReza Sabdar default: 1940*2654012fSReza Sabdar rv = "Unknown"; 1941*2654012fSReza Sabdar } 1942*2654012fSReza Sabdar 1943*2654012fSReza Sabdar return (rv); 1944*2654012fSReza Sabdar } 1945*2654012fSReza Sabdar 1946*2654012fSReza Sabdar 1947*2654012fSReza Sabdar /* 1948*2654012fSReza Sabdar * ndmp_valid_v3addr_type 1949*2654012fSReza Sabdar * 1950*2654012fSReza Sabdar * Make sure that the NDMP address is from any of the 1951*2654012fSReza Sabdar * valid types 1952*2654012fSReza Sabdar * 1953*2654012fSReza Sabdar * Parameters: 1954*2654012fSReza Sabdar * type (input) - address type 1955*2654012fSReza Sabdar * 1956*2654012fSReza Sabdar * Returns: 1957*2654012fSReza Sabdar * 1: valid 1958*2654012fSReza Sabdar * 0: invalid 1959*2654012fSReza Sabdar */ 1960*2654012fSReza Sabdar boolean_t 1961*2654012fSReza Sabdar ndmp_valid_v3addr_type(ndmp_addr_type type) 1962*2654012fSReza Sabdar { 1963*2654012fSReza Sabdar boolean_t rv; 1964*2654012fSReza Sabdar 1965*2654012fSReza Sabdar switch (type) { 1966*2654012fSReza Sabdar case NDMP_ADDR_LOCAL: 1967*2654012fSReza Sabdar case NDMP_ADDR_TCP: 1968*2654012fSReza Sabdar case NDMP_ADDR_FC: 1969*2654012fSReza Sabdar case NDMP_ADDR_IPC: 1970*2654012fSReza Sabdar rv = TRUE; 1971*2654012fSReza Sabdar break; 1972*2654012fSReza Sabdar default: 1973*2654012fSReza Sabdar rv = FALSE; 1974*2654012fSReza Sabdar } 1975*2654012fSReza Sabdar 1976*2654012fSReza Sabdar return (rv); 1977*2654012fSReza Sabdar } 1978*2654012fSReza Sabdar 1979*2654012fSReza Sabdar 1980*2654012fSReza Sabdar /* 1981*2654012fSReza Sabdar * ndmp_copy_addr_v3 1982*2654012fSReza Sabdar * 1983*2654012fSReza Sabdar * Copy NDMP address from source to destination (V2 and V3 only) 1984*2654012fSReza Sabdar * 1985*2654012fSReza Sabdar * Parameters: 1986*2654012fSReza Sabdar * dst (ouput) - destination address 1987*2654012fSReza Sabdar * src (input) - source address 1988*2654012fSReza Sabdar * 1989*2654012fSReza Sabdar * Returns: 1990*2654012fSReza Sabdar * void 1991*2654012fSReza Sabdar */ 1992*2654012fSReza Sabdar void 1993*2654012fSReza Sabdar ndmp_copy_addr_v3(ndmp_addr_v3 *dst, ndmp_addr_v3 *src) 1994*2654012fSReza Sabdar { 1995*2654012fSReza Sabdar dst->addr_type = src->addr_type; 1996*2654012fSReza Sabdar switch (src->addr_type) { 1997*2654012fSReza Sabdar case NDMP_ADDR_LOCAL: 1998*2654012fSReza Sabdar /* nothing */ 1999*2654012fSReza Sabdar break; 2000*2654012fSReza Sabdar case NDMP_ADDR_TCP: 2001*2654012fSReza Sabdar dst->tcp_ip_v3 = htonl(src->tcp_ip_v3); 2002*2654012fSReza Sabdar dst->tcp_port_v3 = src->tcp_port_v3; 2003*2654012fSReza Sabdar break; 2004*2654012fSReza Sabdar case NDMP_ADDR_FC: 2005*2654012fSReza Sabdar case NDMP_ADDR_IPC: 2006*2654012fSReza Sabdar default: 2007*2654012fSReza Sabdar break; 2008*2654012fSReza Sabdar } 2009*2654012fSReza Sabdar } 2010*2654012fSReza Sabdar 2011*2654012fSReza Sabdar 2012*2654012fSReza Sabdar /* 2013*2654012fSReza Sabdar * ndmp_copy_addr_v4 2014*2654012fSReza Sabdar * 2015*2654012fSReza Sabdar * Copy NDMP address from source to destination. V4 has a extra 2016*2654012fSReza Sabdar * environment list inside the address too which needs to be copied. 2017*2654012fSReza Sabdar * 2018*2654012fSReza Sabdar * Parameters: 2019*2654012fSReza Sabdar * dst (ouput) - destination address 2020*2654012fSReza Sabdar * src (input) - source address 2021*2654012fSReza Sabdar * 2022*2654012fSReza Sabdar * Returns: 2023*2654012fSReza Sabdar * void 2024*2654012fSReza Sabdar */ 2025*2654012fSReza Sabdar void 2026*2654012fSReza Sabdar ndmp_copy_addr_v4(ndmp_addr_v4 *dst, ndmp_addr_v4 *src) 2027*2654012fSReza Sabdar { 2028*2654012fSReza Sabdar int i; 2029*2654012fSReza Sabdar 2030*2654012fSReza Sabdar dst->addr_type = src->addr_type; 2031*2654012fSReza Sabdar dst->tcp_len_v4 = src->tcp_len_v4; 2032*2654012fSReza Sabdar switch (src->addr_type) { 2033*2654012fSReza Sabdar case NDMP_ADDR_LOCAL: 2034*2654012fSReza Sabdar /* nothing */ 2035*2654012fSReza Sabdar break; 2036*2654012fSReza Sabdar case NDMP_ADDR_TCP: 2037*2654012fSReza Sabdar dst->tcp_addr_v4 = ndmp_malloc(sizeof (ndmp_tcp_addr_v4) * 2038*2654012fSReza Sabdar src->tcp_len_v4); 2039*2654012fSReza Sabdar if (dst->tcp_addr_v4 == 0) 2040*2654012fSReza Sabdar return; 2041*2654012fSReza Sabdar 2042*2654012fSReza Sabdar for (i = 0; i < src->tcp_len_v4; i++) { 2043*2654012fSReza Sabdar dst->tcp_ip_v4(i) = htonl(src->tcp_ip_v4(i)); 2044*2654012fSReza Sabdar dst->tcp_port_v4(i) = src->tcp_port_v4(i); 2045*2654012fSReza Sabdar dst->tcp_env_v4(i).addr_env_len = 0; /* Solaris */ 2046*2654012fSReza Sabdar dst->tcp_env_v4(i).addr_env_val = 0; /* Solaris */ 2047*2654012fSReza Sabdar } 2048*2654012fSReza Sabdar break; 2049*2654012fSReza Sabdar case NDMP_ADDR_FC: 2050*2654012fSReza Sabdar case NDMP_ADDR_IPC: 2051*2654012fSReza Sabdar default: 2052*2654012fSReza Sabdar break; 2053*2654012fSReza Sabdar } 2054*2654012fSReza Sabdar } 2055*2654012fSReza Sabdar 2056*2654012fSReza Sabdar 2057*2654012fSReza Sabdar /* 2058*2654012fSReza Sabdar * ndmp_connect_sock_v3 2059*2654012fSReza Sabdar * 2060*2654012fSReza Sabdar * Creates a socket and connects to the specified address/port 2061*2654012fSReza Sabdar * 2062*2654012fSReza Sabdar * Parameters: 2063*2654012fSReza Sabdar * addr (input) - IP address 2064*2654012fSReza Sabdar * port (input) - port number 2065*2654012fSReza Sabdar * 2066*2654012fSReza Sabdar * Returns: 2067*2654012fSReza Sabdar * 0: on success 2068*2654012fSReza Sabdar * -1: otherwise 2069*2654012fSReza Sabdar */ 2070*2654012fSReza Sabdar int 2071*2654012fSReza Sabdar ndmp_connect_sock_v3(ulong_t addr, ushort_t port) 2072*2654012fSReza Sabdar { 2073*2654012fSReza Sabdar int sock; 2074*2654012fSReza Sabdar struct sockaddr_in sin; 2075*2654012fSReza Sabdar int flag = 1; 2076*2654012fSReza Sabdar 2077*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "addr %s:%d", inet_ntoa(IN_ADDR(addr)), port); 2078*2654012fSReza Sabdar 2079*2654012fSReza Sabdar sock = socket(AF_INET, SOCK_STREAM, 0); 2080*2654012fSReza Sabdar if (sock < 0) { 2081*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Socket error: %m"); 2082*2654012fSReza Sabdar return (-1); 2083*2654012fSReza Sabdar } 2084*2654012fSReza Sabdar 2085*2654012fSReza Sabdar (void) memset((void *) &sin, 0, sizeof (sin)); 2086*2654012fSReza Sabdar sin.sin_family = AF_INET; 2087*2654012fSReza Sabdar sin.sin_addr.s_addr = htonl(addr); 2088*2654012fSReza Sabdar sin.sin_port = htons(port); 2089*2654012fSReza Sabdar if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 2090*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Connect error: %m"); 2091*2654012fSReza Sabdar (void) close(sock); 2092*2654012fSReza Sabdar sock = -1; 2093*2654012fSReza Sabdar } else { 2094*2654012fSReza Sabdar if (ndmp_sbs > 0) 2095*2654012fSReza Sabdar ndmp_set_socket_snd_buf(sock, ndmp_sbs*KILOBYTE); 2096*2654012fSReza Sabdar if (ndmp_rbs > 0) 2097*2654012fSReza Sabdar ndmp_set_socket_rcv_buf(sock, ndmp_rbs*KILOBYTE); 2098*2654012fSReza Sabdar 2099*2654012fSReza Sabdar ndmp_set_socket_nodelay(sock); 2100*2654012fSReza Sabdar (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &flag, 2101*2654012fSReza Sabdar sizeof (flag)); 2102*2654012fSReza Sabdar 2103*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sock %d", sock); 2104*2654012fSReza Sabdar } 2105*2654012fSReza Sabdar 2106*2654012fSReza Sabdar return (sock); 2107*2654012fSReza Sabdar } 2108*2654012fSReza Sabdar 2109*2654012fSReza Sabdar /* 2110*2654012fSReza Sabdar * ndmp_create_socket 2111*2654012fSReza Sabdar * 2112*2654012fSReza Sabdar * Creates a socket for listening for accepting data connections. 2113*2654012fSReza Sabdar * 2114*2654012fSReza Sabdar * Parameters: 2115*2654012fSReza Sabdar * session (input) - session pointer. 2116*2654012fSReza Sabdar * addr (output) - location to store address of socket. 2117*2654012fSReza Sabdar * port (output) - location to store port of socket. 2118*2654012fSReza Sabdar * 2119*2654012fSReza Sabdar * Returns: 2120*2654012fSReza Sabdar * 0 - success. 2121*2654012fSReza Sabdar * -1 - error. 2122*2654012fSReza Sabdar */ 2123*2654012fSReza Sabdar int 2124*2654012fSReza Sabdar ndmp_create_socket(ulong_t *addr, ushort_t *port) 2125*2654012fSReza Sabdar { 2126*2654012fSReza Sabdar char *p; 2127*2654012fSReza Sabdar int length; 2128*2654012fSReza Sabdar int sd; 2129*2654012fSReza Sabdar struct sockaddr_in sin; 2130*2654012fSReza Sabdar 2131*2654012fSReza Sabdar p = ndmpd_get_prop(NDMP_MOVER_NIC); 2132*2654012fSReza Sabdar 2133*2654012fSReza Sabdar if (!p || *p == 0) 2134*2654012fSReza Sabdar p = gethostaddr(); 2135*2654012fSReza Sabdar 2136*2654012fSReza Sabdar if (!p) { 2137*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Undetermined network port."); 2138*2654012fSReza Sabdar return (-1); 2139*2654012fSReza Sabdar } 2140*2654012fSReza Sabdar 2141*2654012fSReza Sabdar *addr = inet_addr(p); 2142*2654012fSReza Sabdar 2143*2654012fSReza Sabdar sd = socket(AF_INET, SOCK_STREAM, 0); 2144*2654012fSReza Sabdar if (sd < 0) { 2145*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Socket error: %m"); 2146*2654012fSReza Sabdar return (-1); 2147*2654012fSReza Sabdar } 2148*2654012fSReza Sabdar sin.sin_family = AF_INET; 2149*2654012fSReza Sabdar sin.sin_addr.s_addr = INADDR_ANY; 2150*2654012fSReza Sabdar sin.sin_port = 0; 2151*2654012fSReza Sabdar length = sizeof (sin); 2152*2654012fSReza Sabdar 2153*2654012fSReza Sabdar if (bind(sd, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 2154*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Bind error: %m"); 2155*2654012fSReza Sabdar (void) close(sd); 2156*2654012fSReza Sabdar sd = -1; 2157*2654012fSReza Sabdar } else if (getsockname(sd, (struct sockaddr *)&sin, &length) < 0) { 2158*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "getsockname error: %m"); 2159*2654012fSReza Sabdar (void) close(sd); 2160*2654012fSReza Sabdar sd = -1; 2161*2654012fSReza Sabdar } else if (listen(sd, 5) < 0) { 2162*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Listen error: %m"); 2163*2654012fSReza Sabdar (void) close(sd); 2164*2654012fSReza Sabdar sd = -1; 2165*2654012fSReza Sabdar } else 2166*2654012fSReza Sabdar *port = sin.sin_port; 2167*2654012fSReza Sabdar 2168*2654012fSReza Sabdar return (sd); 2169*2654012fSReza Sabdar } 2170*2654012fSReza Sabdar 2171*2654012fSReza Sabdar 2172*2654012fSReza Sabdar /* 2173*2654012fSReza Sabdar * cctime 2174*2654012fSReza Sabdar * 2175*2654012fSReza Sabdar * Convert the specified time into a string. It's like 2176*2654012fSReza Sabdar * ctime(), but: 2177*2654012fSReza Sabdar * - chops the trailing '\n' of ctime. 2178*2654012fSReza Sabdar * - and returns "the epoch" if time is 0. 2179*2654012fSReza Sabdar * 2180*2654012fSReza Sabdar * Returns: 2181*2654012fSReza Sabdar * "": invalid argument. 2182*2654012fSReza Sabdar * "the epoch": if time is 0. 2183*2654012fSReza Sabdar * string format of the time. 2184*2654012fSReza Sabdar */ 2185*2654012fSReza Sabdar char * 2186*2654012fSReza Sabdar cctime(time_t *t) 2187*2654012fSReza Sabdar { 2188*2654012fSReza Sabdar char *bp, *cp; 2189*2654012fSReza Sabdar char tbuf[BUFSIZ]; 2190*2654012fSReza Sabdar 2191*2654012fSReza Sabdar if (!t) 2192*2654012fSReza Sabdar return (""); 2193*2654012fSReza Sabdar 2194*2654012fSReza Sabdar if (*t == (time_t)0) 2195*2654012fSReza Sabdar return ("the epoch"); 2196*2654012fSReza Sabdar 2197*2654012fSReza Sabdar bp = ctime_r(t, tbuf, BUFSIZ); 2198*2654012fSReza Sabdar cp = strchr(bp, '\n'); 2199*2654012fSReza Sabdar if (cp) 2200*2654012fSReza Sabdar *cp = '\0'; 2201*2654012fSReza Sabdar 2202*2654012fSReza Sabdar return (bp); 2203*2654012fSReza Sabdar } 2204*2654012fSReza Sabdar 2205*2654012fSReza Sabdar 2206*2654012fSReza Sabdar /* 2207*2654012fSReza Sabdar * ndmp_new_job_name 2208*2654012fSReza Sabdar * 2209*2654012fSReza Sabdar * Create a job name for each backup/restore to keep track 2210*2654012fSReza Sabdar * 2211*2654012fSReza Sabdar * Parameters: 2212*2654012fSReza Sabdar * jname (output) - job name 2213*2654012fSReza Sabdar * 2214*2654012fSReza Sabdar * Returns: 2215*2654012fSReza Sabdar * jname 2216*2654012fSReza Sabdar */ 2217*2654012fSReza Sabdar char * 2218*2654012fSReza Sabdar ndmp_new_job_name(char *jname) 2219*2654012fSReza Sabdar { 2220*2654012fSReza Sabdar if (jname != NULL) { 2221*2654012fSReza Sabdar (void) snprintf(jname, TLM_MAX_BACKUP_JOB_NAME, "%s%d", 2222*2654012fSReza Sabdar NDMP_RCF_BASENAME, ndmp_job_cnt++); 2223*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "jname: \"%s\"", jname); 2224*2654012fSReza Sabdar } 2225*2654012fSReza Sabdar 2226*2654012fSReza Sabdar return (jname); 2227*2654012fSReza Sabdar } 2228*2654012fSReza Sabdar 2229*2654012fSReza Sabdar 2230*2654012fSReza Sabdar /* 2231*2654012fSReza Sabdar * fs_is_valid_logvol 2232*2654012fSReza Sabdar * 2233*2654012fSReza Sabdar * Check if the log path exists 2234*2654012fSReza Sabdar * 2235*2654012fSReza Sabdar * Parameters: 2236*2654012fSReza Sabdar * path (input) - log path 2237*2654012fSReza Sabdar * 2238*2654012fSReza Sabdar * Returns: 2239*2654012fSReza Sabdar * FALSE: invalid 2240*2654012fSReza Sabdar * TRUE: valid 2241*2654012fSReza Sabdar */ 2242*2654012fSReza Sabdar boolean_t 2243*2654012fSReza Sabdar fs_is_valid_logvol(char *path) 2244*2654012fSReza Sabdar { 2245*2654012fSReza Sabdar struct stat64 st; 2246*2654012fSReza Sabdar 2247*2654012fSReza Sabdar if (stat64(path, &st) < 0) 2248*2654012fSReza Sabdar return (FALSE); 2249*2654012fSReza Sabdar 2250*2654012fSReza Sabdar return (TRUE); 2251*2654012fSReza Sabdar } 2252*2654012fSReza Sabdar 2253*2654012fSReza Sabdar 2254*2654012fSReza Sabdar /* 2255*2654012fSReza Sabdar * ndmpd_mk_temp 2256*2654012fSReza Sabdar * 2257*2654012fSReza Sabdar * Make a temporary file using the working directory path and the 2258*2654012fSReza Sabdar * jobname 2259*2654012fSReza Sabdar * 2260*2654012fSReza Sabdar * Parameters: 2261*2654012fSReza Sabdar * buf (output) - the temporary file name path 2262*2654012fSReza Sabdar * 2263*2654012fSReza Sabdar * Returns: 2264*2654012fSReza Sabdar * buf 2265*2654012fSReza Sabdar */ 2266*2654012fSReza Sabdar char * 2267*2654012fSReza Sabdar ndmpd_mk_temp(char *buf) 2268*2654012fSReza Sabdar { 2269*2654012fSReza Sabdar char fname[TLM_MAX_BACKUP_JOB_NAME]; 2270*2654012fSReza Sabdar const char *dir; 2271*2654012fSReza Sabdar char *rv; 2272*2654012fSReza Sabdar 2273*2654012fSReza Sabdar if (!buf) 2274*2654012fSReza Sabdar return (NULL); 2275*2654012fSReza Sabdar 2276*2654012fSReza Sabdar dir = ndmpd_get_prop(NDMP_DEBUG_PATH); 2277*2654012fSReza Sabdar if (dir == 0 || *dir == '\0') { 2278*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NDMP work path not specified"); 2279*2654012fSReza Sabdar return (0); 2280*2654012fSReza Sabdar } 2281*2654012fSReza Sabdar 2282*2654012fSReza Sabdar if (!fs_is_valid_logvol((char *)dir)) { 2283*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, 2284*2654012fSReza Sabdar "Log file path cannot be on system volumes."); 2285*2654012fSReza Sabdar return (0); 2286*2654012fSReza Sabdar } 2287*2654012fSReza Sabdar 2288*2654012fSReza Sabdar dir += strspn(dir, " \t"); 2289*2654012fSReza Sabdar if (!*dir) { 2290*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NDMP work path not specified"); 2291*2654012fSReza Sabdar return (0); 2292*2654012fSReza Sabdar } 2293*2654012fSReza Sabdar 2294*2654012fSReza Sabdar rv = buf; 2295*2654012fSReza Sabdar (void) ndmp_new_job_name(fname); 2296*2654012fSReza Sabdar (void) tlm_cat_path(buf, (char *)dir, fname); 2297*2654012fSReza Sabdar 2298*2654012fSReza Sabdar return (rv); 2299*2654012fSReza Sabdar } 2300*2654012fSReza Sabdar 2301*2654012fSReza Sabdar 2302*2654012fSReza Sabdar /* 2303*2654012fSReza Sabdar * ndmpd_make_bk_dir_path 2304*2654012fSReza Sabdar * 2305*2654012fSReza Sabdar * Make a directory path for temporary files under the NDMP 2306*2654012fSReza Sabdar * working directory. 2307*2654012fSReza Sabdar * 2308*2654012fSReza Sabdar * Parameters: 2309*2654012fSReza Sabdar * buf (output) - result path 2310*2654012fSReza Sabdar * fname (input) - the file name 2311*2654012fSReza Sabdar * 2312*2654012fSReza Sabdar * Returns: 2313*2654012fSReza Sabdar * buf 2314*2654012fSReza Sabdar */ 2315*2654012fSReza Sabdar char * 2316*2654012fSReza Sabdar ndmpd_make_bk_dir_path(char *buf, char *fname) 2317*2654012fSReza Sabdar { 2318*2654012fSReza Sabdar const char *p; 2319*2654012fSReza Sabdar char *name; 2320*2654012fSReza Sabdar char path[PATH_MAX]; 2321*2654012fSReza Sabdar 2322*2654012fSReza Sabdar if (!buf || !fname || !*fname) 2323*2654012fSReza Sabdar return (NULL); 2324*2654012fSReza Sabdar 2325*2654012fSReza Sabdar p = ndmpd_get_prop(NDMP_DEBUG_PATH); 2326*2654012fSReza Sabdar if (p == NULL || *p == '\0' || !fs_is_valid_logvol((char *)p)) { 2327*2654012fSReza Sabdar return (NULL); 2328*2654012fSReza Sabdar } 2329*2654012fSReza Sabdar 2330*2654012fSReza Sabdar (void) strlcpy(path, (char *)p, PATH_MAX); 2331*2654012fSReza Sabdar (void) trim_whitespace(path); 2332*2654012fSReza Sabdar 2333*2654012fSReza Sabdar if ((name = strrchr(fname, '/')) == 0) 2334*2654012fSReza Sabdar name = fname; 2335*2654012fSReza Sabdar 2336*2654012fSReza Sabdar (void) tlm_cat_path(buf, path, name); 2337*2654012fSReza Sabdar return (buf); 2338*2654012fSReza Sabdar } 2339*2654012fSReza Sabdar 2340*2654012fSReza Sabdar 2341*2654012fSReza Sabdar /* 2342*2654012fSReza Sabdar * ndmp_is_chkpnt_root 2343*2654012fSReza Sabdar * 2344*2654012fSReza Sabdar * Is this a root checkpoint (snapshot) directory. 2345*2654012fSReza Sabdar * Note: a temporary function 2346*2654012fSReza Sabdar */ 2347*2654012fSReza Sabdar boolean_t 2348*2654012fSReza Sabdar ndmp_is_chkpnt_root(char *path) 2349*2654012fSReza Sabdar { 2350*2654012fSReza Sabdar struct stat64 st; 2351*2654012fSReza Sabdar 2352*2654012fSReza Sabdar if (stat64(path, &st) != 0) { 2353*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Couldn't stat path \"%s\"", path); 2354*2654012fSReza Sabdar return (TRUE); 2355*2654012fSReza Sabdar } 2356*2654012fSReza Sabdar return (FALSE); 2357*2654012fSReza Sabdar } 2358*2654012fSReza Sabdar 2359*2654012fSReza Sabdar 2360*2654012fSReza Sabdar /* 2361*2654012fSReza Sabdar * ndmpd_make_exc_list 2362*2654012fSReza Sabdar * 2363*2654012fSReza Sabdar * Make a list of files that should not be backed up. 2364*2654012fSReza Sabdar * 2365*2654012fSReza Sabdar * Parameters: 2366*2654012fSReza Sabdar * void 2367*2654012fSReza Sabdar * 2368*2654012fSReza Sabdar * Returns: 2369*2654012fSReza Sabdar * list - array of character strings 2370*2654012fSReza Sabdar */ 2371*2654012fSReza Sabdar char ** 2372*2654012fSReza Sabdar ndmpd_make_exc_list(void) 2373*2654012fSReza Sabdar { 2374*2654012fSReza Sabdar char *val, **cpp; 2375*2654012fSReza Sabdar int i, n; 2376*2654012fSReza Sabdar 2377*2654012fSReza Sabdar n = sizeof (exls); 2378*2654012fSReza Sabdar if ((cpp = ndmp_malloc(n)) != NULL) { 2379*2654012fSReza Sabdar for (i = 0; exls[i] != NULL; i++) 2380*2654012fSReza Sabdar cpp[i] = exls[i]; 2381*2654012fSReza Sabdar 2382*2654012fSReza Sabdar /* 2383*2654012fSReza Sabdar * If ndmpd_get_prop returns NULL, the array will be 2384*2654012fSReza Sabdar * null-terminated. 2385*2654012fSReza Sabdar */ 2386*2654012fSReza Sabdar val = ndmpd_get_prop(NDMP_DEBUG_PATH); 2387*2654012fSReza Sabdar cpp[i] = val; 2388*2654012fSReza Sabdar } 2389*2654012fSReza Sabdar 2390*2654012fSReza Sabdar return (cpp); 2391*2654012fSReza Sabdar } 2392*2654012fSReza Sabdar 2393*2654012fSReza Sabdar 2394*2654012fSReza Sabdar /* 2395*2654012fSReza Sabdar * ndmp_get_bk_dir_ino 2396*2654012fSReza Sabdar * 2397*2654012fSReza Sabdar * Get the inode number of the backup directory 2398*2654012fSReza Sabdar */ 2399*2654012fSReza Sabdar int 2400*2654012fSReza Sabdar ndmp_get_bk_dir_ino(ndmp_lbr_params_t *nlp) 2401*2654012fSReza Sabdar { 2402*2654012fSReza Sabdar int rv; 2403*2654012fSReza Sabdar struct stat64 st; 2404*2654012fSReza Sabdar 2405*2654012fSReza Sabdar if (stat64(nlp->nlp_backup_path, &st) != 0) { 2406*2654012fSReza Sabdar rv = -1; 2407*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Getting inode # of \"%s\"", 2408*2654012fSReza Sabdar nlp->nlp_backup_path); 2409*2654012fSReza Sabdar } else { 2410*2654012fSReza Sabdar rv = 0; 2411*2654012fSReza Sabdar nlp->nlp_bkdirino = st.st_ino; 2412*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkdirino: %lu", 2413*2654012fSReza Sabdar (uint_t)nlp->nlp_bkdirino); 2414*2654012fSReza Sabdar } 2415*2654012fSReza Sabdar 2416*2654012fSReza Sabdar return (rv); 2417*2654012fSReza Sabdar } 2418*2654012fSReza Sabdar 2419*2654012fSReza Sabdar 2420*2654012fSReza Sabdar /* 2421*2654012fSReza Sabdar * ndmp_check_utf8magic 2422*2654012fSReza Sabdar * 2423*2654012fSReza Sabdar * Check if the magic string for exists in the tar header. This 2424*2654012fSReza Sabdar * magic string (which also indicates that the file names are in 2425*2654012fSReza Sabdar * UTF8 format) is used as a crest to indetify our own tapes. 2426*2654012fSReza Sabdar * This checking is always done before all restores except DAR 2427*2654012fSReza Sabdar * restores. 2428*2654012fSReza Sabdar */ 2429*2654012fSReza Sabdar boolean_t 2430*2654012fSReza Sabdar ndmp_check_utf8magic(tlm_cmd_t *cmd) 2431*2654012fSReza Sabdar { 2432*2654012fSReza Sabdar char *cp; 2433*2654012fSReza Sabdar int err, len, actual_size; 2434*2654012fSReza Sabdar 2435*2654012fSReza Sabdar if (cmd == NULL) { 2436*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd == NULL"); 2437*2654012fSReza Sabdar return (FALSE); 2438*2654012fSReza Sabdar } 2439*2654012fSReza Sabdar if (cmd->tc_buffers == NULL) { 2440*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd->tc_buffers == NULL"); 2441*2654012fSReza Sabdar return (FALSE); 2442*2654012fSReza Sabdar } 2443*2654012fSReza Sabdar 2444*2654012fSReza Sabdar /* wait until the first buffer gets full. */ 2445*2654012fSReza Sabdar tlm_buffer_in_buf_wait(cmd->tc_buffers); 2446*2654012fSReza Sabdar 2447*2654012fSReza Sabdar err = actual_size = 0; 2448*2654012fSReza Sabdar cp = tlm_get_read_buffer(RECORDSIZE, &err, cmd->tc_buffers, 2449*2654012fSReza Sabdar &actual_size); 2450*2654012fSReza Sabdar if (cp == NULL) { 2451*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Can't read from buffers, err: %d", err); 2452*2654012fSReza Sabdar return (FALSE); 2453*2654012fSReza Sabdar } 2454*2654012fSReza Sabdar len = strlen(NDMPUTF8MAGIC); 2455*2654012fSReza Sabdar if (actual_size < len) { 2456*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Not enough data in the buffers"); 2457*2654012fSReza Sabdar return (FALSE); 2458*2654012fSReza Sabdar } 2459*2654012fSReza Sabdar 2460*2654012fSReza Sabdar return ((strncmp(cp, NDMPUTF8MAGIC, len) == 0) ? TRUE : FALSE); 2461*2654012fSReza Sabdar } 2462*2654012fSReza Sabdar 2463*2654012fSReza Sabdar 2464*2654012fSReza Sabdar /* 2465*2654012fSReza Sabdar * ndmp_get_cur_bk_time 2466*2654012fSReza Sabdar * 2467*2654012fSReza Sabdar * Get the backup checkpoint time. 2468*2654012fSReza Sabdar */ 2469*2654012fSReza Sabdar int 2470*2654012fSReza Sabdar ndmp_get_cur_bk_time(ndmp_lbr_params_t *nlp, time_t *tp, char *jname) 2471*2654012fSReza Sabdar { 2472*2654012fSReza Sabdar int err; 2473*2654012fSReza Sabdar 2474*2654012fSReza Sabdar if (!nlp || !nlp->nlp_backup_path || !tp) { 2475*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 2476*2654012fSReza Sabdar return (-1); 2477*2654012fSReza Sabdar } 2478*2654012fSReza Sabdar 2479*2654012fSReza Sabdar if (!fs_is_chkpnt_enabled(nlp->nlp_backup_path)) { 2480*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Not a chkpnt volume %s", 2481*2654012fSReza Sabdar nlp->nlp_backup_path); 2482*2654012fSReza Sabdar *tp = time(NULL); 2483*2654012fSReza Sabdar return (0); 2484*2654012fSReza Sabdar } 2485*2654012fSReza Sabdar 2486*2654012fSReza Sabdar err = tlm_get_chkpnt_time(nlp->nlp_backup_path, !NLP_ISCHKPNTED(nlp), 2487*2654012fSReza Sabdar tp, jname); 2488*2654012fSReza Sabdar if (err != 0) { 2489*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Can't checkpoint time"); 2490*2654012fSReza Sabdar } else { 2491*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s", cctime(tp)); 2492*2654012fSReza Sabdar } 2493*2654012fSReza Sabdar 2494*2654012fSReza Sabdar return (err); 2495*2654012fSReza Sabdar } 2496*2654012fSReza Sabdar 2497*2654012fSReza Sabdar 2498*2654012fSReza Sabdar /* 2499*2654012fSReza Sabdar * get_relative_path 2500*2654012fSReza Sabdar */ 2501*2654012fSReza Sabdar char * 2502*2654012fSReza Sabdar ndmp_get_relative_path(char *base, char *fullpath) 2503*2654012fSReza Sabdar { 2504*2654012fSReza Sabdar char *p = fullpath; 2505*2654012fSReza Sabdar 2506*2654012fSReza Sabdar if (!base || !*base) 2507*2654012fSReza Sabdar return (fullpath); 2508*2654012fSReza Sabdar 2509*2654012fSReza Sabdar while (*base) { 2510*2654012fSReza Sabdar if (*base != *p) 2511*2654012fSReza Sabdar break; 2512*2654012fSReza Sabdar p++; base++; 2513*2654012fSReza Sabdar } 2514*2654012fSReza Sabdar 2515*2654012fSReza Sabdar if (*p == '/') 2516*2654012fSReza Sabdar p++; 2517*2654012fSReza Sabdar 2518*2654012fSReza Sabdar return ((*base) ? fullpath : p); 2519*2654012fSReza Sabdar } 2520*2654012fSReza Sabdar 2521*2654012fSReza Sabdar 2522*2654012fSReza Sabdar /* 2523*2654012fSReza Sabdar * ndmp_get_nlp 2524*2654012fSReza Sabdar * 2525*2654012fSReza Sabdar * Get NDMP local backup parameters 2526*2654012fSReza Sabdar * 2527*2654012fSReza Sabdar * Parameter: 2528*2654012fSReza Sabdar * session cooke 2529*2654012fSReza Sabdar * 2530*2654012fSReza Sabdar * Returns: 2531*2654012fSReza Sabdar * LBR structure 2532*2654012fSReza Sabdar */ 2533*2654012fSReza Sabdar ndmp_lbr_params_t * 2534*2654012fSReza Sabdar ndmp_get_nlp(void *cookie) 2535*2654012fSReza Sabdar { 2536*2654012fSReza Sabdar if (cookie == NULL) 2537*2654012fSReza Sabdar return (NULL); 2538*2654012fSReza Sabdar 2539*2654012fSReza Sabdar return (((ndmpd_session_t *)cookie)->ns_ndmp_lbr_params); 2540*2654012fSReza Sabdar } 2541*2654012fSReza Sabdar 2542*2654012fSReza Sabdar 2543*2654012fSReza Sabdar /* 2544*2654012fSReza Sabdar * is_tape_unit_ready 2545*2654012fSReza Sabdar * 2546*2654012fSReza Sabdar * Check if the tape device is ready or not 2547*2654012fSReza Sabdar */ 2548*2654012fSReza Sabdar boolean_t 2549*2654012fSReza Sabdar is_tape_unit_ready(char *adptnm, int dev_id) 2550*2654012fSReza Sabdar { 2551*2654012fSReza Sabdar int try; 2552*2654012fSReza Sabdar int fd = 0; 2553*2654012fSReza Sabdar 2554*2654012fSReza Sabdar try = TUR_MAX_TRY; 2555*2654012fSReza Sabdar if (dev_id == 0) 2556*2654012fSReza Sabdar fd = open(adptnm, O_RDONLY | O_NDELAY); 2557*2654012fSReza Sabdar else 2558*2654012fSReza Sabdar fd = dev_id; 2559*2654012fSReza Sabdar do { 2560*2654012fSReza Sabdar if (scsi_test_unit_ready(fd) >= 0) { 2561*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unit is ready"); 2562*2654012fSReza Sabdar 2563*2654012fSReza Sabdar if (dev_id == 0) 2564*2654012fSReza Sabdar (void) close(fd); 2565*2654012fSReza Sabdar 2566*2654012fSReza Sabdar return (TRUE); 2567*2654012fSReza Sabdar } 2568*2654012fSReza Sabdar 2569*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unit not ready"); 2570*2654012fSReza Sabdar (void) usleep(TUR_WAIT); 2571*2654012fSReza Sabdar 2572*2654012fSReza Sabdar } while (--try > 0); 2573*2654012fSReza Sabdar 2574*2654012fSReza Sabdar if (dev_id == 0) 2575*2654012fSReza Sabdar (void) close(fd); 2576*2654012fSReza Sabdar 2577*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unit didn't get ready"); 2578*2654012fSReza Sabdar return (FALSE); 2579*2654012fSReza Sabdar } 2580*2654012fSReza Sabdar 2581*2654012fSReza Sabdar 2582*2654012fSReza Sabdar /* 2583*2654012fSReza Sabdar * scsi_test_unit_ready 2584*2654012fSReza Sabdar * 2585*2654012fSReza Sabdar * This is for Test Unit Read, without this function, the only 2586*2654012fSReza Sabdar * impact is getting EBUSY's before each operation which we have 2587*2654012fSReza Sabdar * busy waiting loops checking EBUSY error code. 2588*2654012fSReza Sabdar */ 2589*2654012fSReza Sabdar static int 2590*2654012fSReza Sabdar scsi_test_unit_ready(int dev_id) 2591*2654012fSReza Sabdar { 2592*2654012fSReza Sabdar struct uscsi_cmd ucmd; 2593*2654012fSReza Sabdar union scsi_cdb cdb; 2594*2654012fSReza Sabdar int retval; 2595*2654012fSReza Sabdar 2596*2654012fSReza Sabdar (void) memset(&ucmd, 0, sizeof (struct uscsi_cmd)); 2597*2654012fSReza Sabdar (void) memset(&cdb, 0, sizeof (union scsi_cdb)); 2598*2654012fSReza Sabdar cdb.scc_cmd = SCMD_TEST_UNIT_READY; 2599*2654012fSReza Sabdar ucmd.uscsi_cdb = (caddr_t)&cdb; 2600*2654012fSReza Sabdar ucmd.uscsi_cdblen = CDB_GROUP0; 2601*2654012fSReza Sabdar ucmd.uscsi_flags |= USCSI_SILENT; 2602*2654012fSReza Sabdar 2603*2654012fSReza Sabdar retval = ioctl(dev_id, USCSICMD, &ucmd); 2604*2654012fSReza Sabdar 2605*2654012fSReza Sabdar if (retval != 0 && errno != EIO) { 2606*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, 2607*2654012fSReza Sabdar "Failed to send inquiry request to device: %m."); 2608*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Inquiry request failed for" 2609*2654012fSReza Sabdar " dev_id:%d err=%d -%m", dev_id, errno); 2610*2654012fSReza Sabdar retval = -errno; 2611*2654012fSReza Sabdar } else 2612*2654012fSReza Sabdar retval = -(ucmd.uscsi_status); 2613*2654012fSReza Sabdar 2614*2654012fSReza Sabdar return (retval); 2615*2654012fSReza Sabdar } 2616*2654012fSReza Sabdar 2617*2654012fSReza Sabdar 2618*2654012fSReza Sabdar /* 2619*2654012fSReza Sabdar * ndmp_load_params 2620*2654012fSReza Sabdar * 2621*2654012fSReza Sabdar * Load the parameters. 2622*2654012fSReza Sabdar * 2623*2654012fSReza Sabdar * Parameter: 2624*2654012fSReza Sabdar * void 2625*2654012fSReza Sabdar * 2626*2654012fSReza Sabdar * Returns: 2627*2654012fSReza Sabdar * void 2628*2654012fSReza Sabdar */ 2629*2654012fSReza Sabdar void 2630*2654012fSReza Sabdar ndmp_load_params(void) 2631*2654012fSReza Sabdar { 2632*2654012fSReza Sabdar struct stat64 st; 2633*2654012fSReza Sabdar 2634*2654012fSReza Sabdar ndmp_dump_path_node = ndmpd_get_prop_yorn(NDMP_DUMP_PATHNODE_ENV) ? 2635*2654012fSReza Sabdar TRUE : FALSE; 2636*2654012fSReza Sabdar ndmp_tar_path_node = ndmpd_get_prop_yorn(NDMP_TAR_PATHNODE_ENV) ? 2637*2654012fSReza Sabdar TRUE : FALSE; 2638*2654012fSReza Sabdar ndmp_ignore_ctime = 2639*2654012fSReza Sabdar ndmpd_get_prop_yorn(NDMP_IGNCTIME_ENV) ? TRUE : FALSE; 2640*2654012fSReza Sabdar ndmp_include_lmtime = ndmpd_get_prop_yorn(NDMP_INCLMTIME_ENV) ? 2641*2654012fSReza Sabdar TRUE : FALSE; 2642*2654012fSReza Sabdar ndmp_max_tok_seq = atoi(ndmpd_get_prop_default(NDMP_MAXSEQ_ENV, "9")); 2643*2654012fSReza Sabdar 2644*2654012fSReza Sabdar ndmp_full_restore_path = ndmpd_get_prop_yorn(NDMP_FULL_RESTORE_PATH) ? 2645*2654012fSReza Sabdar TRUE : FALSE; 2646*2654012fSReza Sabdar 2647*2654012fSReza Sabdar ndmp_fhinode = ndmpd_get_prop_yorn(NDMP_FHIST_INCR_ENV) ? TRUE : FALSE; 2648*2654012fSReza Sabdar 2649*2654012fSReza Sabdar /* Get the value from ndmp SMF property. */ 2650*2654012fSReza Sabdar ndmp_dar_support = ndmpd_get_prop_yorn(NDMP_DAR_SUPPORT); 2651*2654012fSReza Sabdar 2652*2654012fSReza Sabdar ndmp_log_path = ndmpd_get_prop(NDMP_DEBUG_PATH); 2653*2654012fSReza Sabdar if ((ndmp_log_path == NULL) || (*ndmp_log_path == NULL)) 2654*2654012fSReza Sabdar ndmp_log_path = "/var/ndmp"; 2655*2654012fSReza Sabdar 2656*2654012fSReza Sabdar if (lstat64(ndmp_log_path, &st) < 0) { 2657*2654012fSReza Sabdar if (mkdirp(ndmp_log_path, 0755) < 0) 2658*2654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Could not create log path %s: %m.", 2659*2654012fSReza Sabdar ndmp_log_path); 2660*2654012fSReza Sabdar } 2661*2654012fSReza Sabdar 2662*2654012fSReza Sabdar if ((ndmp_ver = atoi(ndmpd_get_prop(NDMP_VERSION_ENV))) == 0) 2663*2654012fSReza Sabdar ndmp_ver = NDMPVER; 2664*2654012fSReza Sabdar } 2665*2654012fSReza Sabdar 2666*2654012fSReza Sabdar /* 2667*2654012fSReza Sabdar * randomize 2668*2654012fSReza Sabdar * 2669*2654012fSReza Sabdar * Randomize the contents of a buffer 2670*2654012fSReza Sabdar * 2671*2654012fSReza Sabdar * Parameter: 2672*2654012fSReza Sabdar * buffer (output) - destination buffer 2673*2654012fSReza Sabdar * size (input) - buffer size 2674*2654012fSReza Sabdar * 2675*2654012fSReza Sabdar * Returns: 2676*2654012fSReza Sabdar * void 2677*2654012fSReza Sabdar */ 2678*2654012fSReza Sabdar void 2679*2654012fSReza Sabdar randomize(unsigned char *buffer, int size) 2680*2654012fSReza Sabdar { 2681*2654012fSReza Sabdar /* LINTED improper alignment */ 2682*2654012fSReza Sabdar unsigned int *p = (unsigned int *)buffer; 2683*2654012fSReza Sabdar unsigned int dwlen = size / sizeof (unsigned int); 2684*2654012fSReza Sabdar unsigned int remlen = size % sizeof (unsigned int); 2685*2654012fSReza Sabdar unsigned int tmp; 2686*2654012fSReza Sabdar unsigned int i; 2687*2654012fSReza Sabdar 2688*2654012fSReza Sabdar for (i = 0; i < dwlen; i++) 2689*2654012fSReza Sabdar *p++ = random(); 2690*2654012fSReza Sabdar 2691*2654012fSReza Sabdar if (remlen) { 2692*2654012fSReza Sabdar tmp = random(); 2693*2654012fSReza Sabdar (void) memcpy(p, &tmp, remlen); 2694*2654012fSReza Sabdar } 2695*2654012fSReza Sabdar } 2696*2654012fSReza Sabdar 2697*2654012fSReza Sabdar /* 2698*2654012fSReza Sabdar * ndmpd_get_file_entry_type 2699*2654012fSReza Sabdar * 2700*2654012fSReza Sabdar * Converts the mode to the NDMP file type 2701*2654012fSReza Sabdar * 2702*2654012fSReza Sabdar * Parameter: 2703*2654012fSReza Sabdar * mode (input) - file mode 2704*2654012fSReza Sabdar * ftype (output) - file type 2705*2654012fSReza Sabdar * 2706*2654012fSReza Sabdar * Returns: 2707*2654012fSReza Sabdar * void 2708*2654012fSReza Sabdar */ 2709*2654012fSReza Sabdar void 2710*2654012fSReza Sabdar ndmpd_get_file_entry_type(int mode, ndmp_file_type *ftype) 2711*2654012fSReza Sabdar { 2712*2654012fSReza Sabdar switch (mode & S_IFMT) { 2713*2654012fSReza Sabdar case S_IFIFO: 2714*2654012fSReza Sabdar *ftype = NDMP_FILE_FIFO; 2715*2654012fSReza Sabdar break; 2716*2654012fSReza Sabdar case S_IFCHR: 2717*2654012fSReza Sabdar *ftype = NDMP_FILE_CSPEC; 2718*2654012fSReza Sabdar break; 2719*2654012fSReza Sabdar case S_IFDIR: 2720*2654012fSReza Sabdar *ftype = NDMP_FILE_DIR; 2721*2654012fSReza Sabdar break; 2722*2654012fSReza Sabdar case S_IFBLK: 2723*2654012fSReza Sabdar *ftype = NDMP_FILE_BSPEC; 2724*2654012fSReza Sabdar break; 2725*2654012fSReza Sabdar case S_IFREG: 2726*2654012fSReza Sabdar *ftype = NDMP_FILE_REG; 2727*2654012fSReza Sabdar break; 2728*2654012fSReza Sabdar case S_IFLNK: 2729*2654012fSReza Sabdar *ftype = NDMP_FILE_SLINK; 2730*2654012fSReza Sabdar break; 2731*2654012fSReza Sabdar default: 2732*2654012fSReza Sabdar *ftype = NDMP_FILE_SOCK; 2733*2654012fSReza Sabdar break; 2734*2654012fSReza Sabdar } 2735*2654012fSReza Sabdar } 2736*2654012fSReza Sabdar 2737*2654012fSReza Sabdar /* 2738*2654012fSReza Sabdar * Set a private data in the plugin context 2739*2654012fSReza Sabdar */ 2740*2654012fSReza Sabdar void 2741*2654012fSReza Sabdar ndmp_context_set_specific(ndmp_context_t *nctx, void *ptr) 2742*2654012fSReza Sabdar { 2743*2654012fSReza Sabdar nctx->nc_pldata = ptr; 2744*2654012fSReza Sabdar } 2745*2654012fSReza Sabdar 2746*2654012fSReza Sabdar /* 2747*2654012fSReza Sabdar * Get a private data in the plugin context 2748*2654012fSReza Sabdar */ 2749*2654012fSReza Sabdar void * 2750*2654012fSReza Sabdar ndmp_context_get_specific(ndmp_context_t *nctx) 2751*2654012fSReza Sabdar { 2752*2654012fSReza Sabdar return (nctx->nc_pldata); 2753*2654012fSReza Sabdar } 2754