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