ndmpd_util.c revision 89f9eb8701145fa396cfc2ac0b468bd5c8466494
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* BSD 3 Clause License
*
* Copyright (c) 2007, The Storage Networking Industry Association.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* - Neither the name of The Storage Networking Industry Association (SNIA)
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Copyright (c) 2007, The Storage Networking Industry Association. */
/* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <time.h>
#include "ndmpd.h"
#include <bitmap.h>
#include <sys/socketvar.h>
#include <netdb.h>
#include "tlm.h"
/*
* Mutex to protect Nlp
*/
/*
* Patchable socket buffer sizes in kilobytes.
* ssb: send buffer size.
* rsb: receive buffer size.
*/
int ndmp_sbs = 60;
int ndmp_rbs = 60;
/*
* Force to backup all the intermediate directories leading to an object
* to be backed up in 'dump' format backup.
*/
/*
* Force to backup all the intermediate directories leading to an object
* to be backed up in 'tar' format backup.
*/
/*
* Should the 'st_ctime' be ignored during incremental level backup?
*/
/*
* Should the 'st_lmtime' be included during incremental level backup?
*/
/*
* Force to send the file history node entries along with the file history
* dir entries for all directories containing the changed files to the client
* for incremental backup.
*
* Note: This variable is added to support Bakbone Software's Netvault DMA
* which expects to get the FH ADD NODES for all upper directories which
* contain the changed files in incremental backup along with the FH ADD DIRS.
*/
/*
* Maximum permitted sequence number in the token-based backup. The
* value of this variable can be changed by the administrator and is
* saved in the NDMP configuration file.
*/
static int ndmp_max_tok_seq = NDMP_MAX_TOKSEQ;
/*
* Force backup directories in incremental backups. If the
* directory is not modified itself, it's not backed up by
* default.
*/
int ndmp_force_bk_dirs = 0;
/*
* Keeps track of the open SCSI (including tape and robot) devices.
* When a SCSI device is opened its name must be added to this list and
* when it's closed its name must be removed from this list. The main
* purpose of this list is the robot device. If the robot devices are not
* attached in SASD layer, Local Backup won't see them. If they are
* attached and we open the robot devices, then wrong commands are sent
* to robot by SASD since it assumes that the robot is a tape (sequential
* access) device.
*/
struct open_list {
int ol_nref;
char *ol_devnm;
int ol_sid;
int ol_lun;
int ol_fd;
};
/*
* Head of the opened SCSI devices list.
*/
/*
* List of things to be exluded from backup.
*/
static char *exls[] = {
NULL, /* reserved for a copy of the "backup.directory" */
};
/*
* The counter for creating unique names with "ndmp.%d" format.
*/
#define NDMP_RCF_BASENAME "ndmp."
static int ndmp_job_cnt = 0;
static int scsi_test_unit_ready(int dev_id);
/*
* ndmpd_add_file_handler
*
* Adds a file handler to the file handler list.
* The file handler list is used by ndmpd_api_dispatch.
*
* Parameters:
* session (input) - session pointer.
* cookie (input) - opaque data to be passed to file hander when called.
* fd (input) - file descriptor.
* mode (input) - bitmask of the following:
* 1 = watch file for ready for reading
* 2 = watch file for ready for writing
* 4 = watch file for exception
* class (input) - handler class. (HC_CLIENT, HC_MOVER, HC_MODULE)
* func (input) - function to call when the file meets one of the
* conditions specified by mode.
*
* Returns:
* 0 - success.
* -1 - error.
*/
int
{
if (new == 0)
return (-1);
return (0);
}
/*
* ndmpd_remove_file_handler
*
* Removes a file handler from the file handler list.
*
* Parameters:
* session (input) - session pointer.
* fd (input) - file descriptor.
*
* Returns:
* 0 - success.
* -1 - error.
*/
int
{
while (*last != 0) {
return (1);
}
}
return (0);
}
/*
* ndmp_connection_closed
*
* If the connection closed or not.
*
* Parameters:
* fd (input) : file descriptor
*
* Returns:
* 0 - connection is still valid
* 1 - connection is not valid anymore
* -1 - Internal kernel error
*/
int
ndmp_connection_closed(int fd)
{
if (fd < 0) /* We are not using the mover */
return (-1);
return (closed);
}
/*
* ndmp_check_mover_state
*
* Checks the mover connection status and sends an appropriate
* NDMP message to client based on that.
*
* Parameters:
* ndmpd_session_t *session (input) : session pointer
*
* Returns:
* void.
*/
void
{
int moverfd;
/*
* NDMPV3 Spec (Three-way restore):
* Once all of the files have been recovered, NDMP DATA Server closes
* the connection to the mover on the NDMP TAPE Server. THEN
* The NDMP client should receive an NDMP_NOTIFY_MOVER_HALTED message
* with an NDMP_MOVER_CONNECT_CLOSED reason from the NDMP TAPE Server
*/
/* If connection is closed by the peer */
if (moverfd >= 0 &&
if (closed) {
/* Connection closed or internal error */
if (closed > 0) {
"ndmp mover: connection closed by peer");
} else {
"ndmp mover: Internal error");
}
}
}
}
/*
* ndmpd_select
*
* Calls select on the the set of file descriptors from the
* file handler list masked by the fd_class argument.
* Calls the file handler function for each
* file descriptor that is ready for I/O.
*
* Parameters:
* session (input) - session pointer.
* block (input) - if TRUE, ndmpd_select waits until at least one
* file descriptor is ready for I/O. Otherwise,
* it returns immediately if no file descriptors are
* ready for I/O.
* class_mask (input) - bit mask of handler classes to be examined.
* Provides for excluding some of the handlers from
* being called.
*
* Returns:
* -1 - error.
* 0 - no handlers were called.
* 1 - at least one handler was called.
*/
int
{
int n;
nlp_event_rv_set(session, 0);
if (session->ns_file_handler_list == 0)
return (0);
/*
* If select should be blocked, then we poll every ten seconds.
* The reason is in case of three-way restore we should be able
* to detect if the other end closed the connection or not.
* NDMP client(DMA) does not send any information about the connection
* that was closed in the other end.
*/
else
do {
/* Create the fd_sets for select. */
continue;
}
if (n < 0) {
return (0);
continue;
}
}
}
}
return (-1);
}
if (n == 0)
return (0);
while (handler != 0) {
continue;
}
}
}
}
}
}
}
if (mode) {
/*
* K.L. The list can be modified during the execution
* of handler->fh_func. Therefore, handler will start
* from the beginning of the handler list after
* each execution.
*/
/*
* Release the thread which is waiting for a request
* to be proccessed.
*/
} else
}
return (1);
}
/*
* ndmpd_save_env
*
* Saves a copy of the environment variable list from the data_start_backup
* request or data_start_recover request.
*
* Parameters:
* session (input) - session pointer.
* env (input) - environment variable list to be saved.
* envlen (input) - length of variable array.
*
* Returns:
* error code.
*/
{
ulong_t i;
char *namebuf;
char *valbuf;
if (envlen == 0)
return (NDMP_NO_ERR);
return (NDMP_NO_MEM_ERR);
for (i = 0; i < envlen; i++) {
if (namebuf == 0)
return (NDMP_NO_MEM_ERR);
if (valbuf == 0) {
return (NDMP_NO_MEM_ERR);
}
}
return (NDMP_NO_ERR);
}
/*
* ndmpd_free_env
*
* Free the previously saved environment variable array.
*
* Parameters:
* session - NDMP session pointer.
*
* Returns:
* void.
*/
void
{
ulong_t i;
for (i = 0; i < count; i++) {
}
}
/*
* ndmpd_save_nlist_v2
*
* Save a copy of list of file names to be restored.
*
* Parameters:
* nlist (input) - name list from data_start_recover request.
* nlistlen (input) - length of name list.
*
* Returns:
* array of file name pointers.
*
* Notes:
* free_nlist should be called to free the returned list.
* A null pointer indicates the end of the list.
*/
{
ulong_t i;
char *namebuf;
char *destbuf;
if (nlistlen == 0)
return (NDMP_NO_ERR);
return (NDMP_NO_MEM_ERR);
for (i = 0; i < nlistlen; i++) {
if (namebuf == 0)
return (NDMP_NO_MEM_ERR);
if (destbuf == 0) {
return (NDMP_NO_MEM_ERR);
}
}
return (NDMP_NO_ERR);
}
/*
* ndmpd_free_nlist_v2
*
* Free a list created by ndmpd_save_nlist_v2.
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
ulong_t i;
}
}
/*
* ndmpd_free_nlist_v3
*
* Free a list created by ndmpd_save_nlist_v3.
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
ulong_t i;
}
}
/*
* ndmpd_save_nlist_v3
*
* Save a copy of list of file names to be restored.
*
* Parameters:
* nlist (input) - name list from data_start_recover request.
* nlistlen (input) - length of name list.
*
* Returns:
* array of file name pointers.
*
* Notes:
* free_nlist should be called to free the returned list.
* A null pointer indicates the end of the list.
*/
{
ulong_t i;
if (nlistlen == 0)
return (NDMP_ILLEGAL_ARGS_ERR);
return (NDMP_NO_MEM_ERR);
rv = NDMP_NO_ERR;
break;
}
if (!*sp->destination_dir) {
/* In V4 destination dir cannot be NULL */
break;
}
break;
}
break;
}
}
if (rv != NDMP_NO_ERR)
return (rv);
}
/*
* ndmpd_free_nlist
*
* Free the recovery list based on the version
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
switch (session->ns_protocol_version) {
case 1:
case 2:
break;
case 3:
case 4:
break;
default:
}
}
/*
* fh_cmpv3
*
* Comparison function used in sorting the Nlist based on their
* file history info (offset of the entry on the tape)
*
* Parameters:
* p (input) - pointer to P
* q (input) - pointer to Q
*
* Returns:
* -1: P < Q
* 0: P = Q
* 1: P > Q
*/
static int
fh_cmpv3(const void *p,
const void *q)
{
return (-1);
return (0);
else
return (1);
}
/*
* ndmp_sort_nlist_v3
*
* Sort the recovery list based on their offset on the tape
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
return;
sizeof (mem_ndmp_name_v3_t), fh_cmpv3);
}
/*
* ndmp_send_reply
*
* Send the reply, check for error and print the msg if any error
* occured when sending the reply.
*
* Parameters:
* connection (input) - connection pointer.
*
* Return:
* void
*/
void
{
}
/*
* ndmp_mtioctl
*
* Performs numerous filemark operations.
*
* Parameters:
* fd - file descriptor of the device
* cmd - filemark or record command
* count - the number of operations to be performed
*/
int
{
return (-1);
}
return (0);
}
/*
* quad_to_long_long
*
* Convert type quad to longlong_t
*/
{
return (ull);
}
/*
* long_long_to_quad
*
* Convert long long to quad type
*/
{
ndmp_u_quad q;
return (q);
}
/*
* ndmp_set_socket_nodelay
*
* Set the TCP socket option to nodelay mode
*/
void
{
int flag = 1;
}
/*
* ndmp_set_socket_snd_buf
*
* Set the socket send buffer size
*/
void
{
}
/*
* ndmp_set_socket_rcv_buf
*
* Set the socket receive buffer size
*/
void
{
}
/*
* ndmp_get_max_tok_seq
*
* Get the maximum permitted token sequence for token-based
* backups.
*
* Parameters:
* void
*
* Returns:
* ndmp_max_tok_seq
*/
int
ndmp_get_max_tok_seq(void)
{
return (ndmp_max_tok_seq);
}
/*
* ndmp_buffer_get_size
*
* Return the NDMP transfer buffer size
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* buffer size
*/
long
{
long xfer_size;
return (0);
"60"));
if (xfer_size > 0)
else
} else {
}
return (xfer_size);
}
/*
* ndmp_lbr_init
*
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* 0: on success
* -1: otherwise
*/
int
{
return (0);
}
return (-1);
return (0);
}
/*
* ndmp_lbr_cleanup
*
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* 0: on success
* -1: otherwise
*/
void
{
/*
* If in 3-way restore, the connection close is detected after
* check in tape_read(), the reader thread of mover may wait forever
* for the tape to be changed. Force the reader thread to exit.
*/
if (session->ns_ndmp_lbr_params) {
}
}
/*
* nlp_ref_nw
*
* unwanted release
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
(void) mutex_lock(&nlp_mtx);
} else
(void) mutex_unlock(&nlp_mtx);
}
/*
* nlp_unref_nw
*
* release
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
(void) mutex_lock(&nlp_mtx);
} else
(void) mutex_unlock(&nlp_mtx);
}
/*
* nlp_wait_nw
*
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
(void) mutex_lock(&nlp_mtx);
}
} else
(void) mutex_unlock(&nlp_mtx);
}
/*
* nlp_event_nw
*
* threads waiting on that
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* void
*/
void
{
(void) mutex_lock(&nlp_mtx);
}
} else
(void) mutex_unlock(&nlp_mtx);
}
/*
* nlp_event_rv_get
*
* Get the return value for each NLP
*
* Parameters:
* session (input) - session pointer.
*
* Returns:
* return value
*/
int
{
return (0);
}
}
/*
* nlp_event_rv_set
*
* Set the return value for an NLP
*
* Parameters:
* session (input) - session pointer.
* rv (input) - return value
*
* Returns:
* void
*/
void
int rv)
{
(void) mutex_lock(&nlp_mtx);
if (rv != 0)
else
(void) mutex_unlock(&nlp_mtx);
}
/*
* is_buffer_erroneous
*
* Run a sanity check on the buffer
*
* returns:
* TRUE: if the buffer seems to have error
* FALSE: if the buffer is full and has valid data.
*/
{
if (rv) {
} else {
}
}
return (rv);
}
/*
* ndmp_execute_cdb
*
* Main SCSI CDB execution program, this is used by message handler
* USCSI interface to run the CDB command and sets all the CDB parameters
* in the SCSI query before calling the USCSI ioctl. The result of the
* CDB is returned in two places:
* cmd.uscsi_status The status of CDB execution
* cmd.uscsi_rqstatus The status of sense requests
* reply.error The general errno (ioctl)
*
* Parameters:
* session (input) - session pointer
* adapter_name (input) - name of SCSI adapter
* sid (input) - SCSI target ID
* lun (input) - LUN number
* request (input) - NDMP client CDB request
*
* Returns:
* void
*/
/*ARGSUSED*/
void
{
int fd;
char rq_buf[255];
if ((cmd.uscsi_bufaddr =
NDMP_NO_ERR, (void *)&reply) < 0)
" scsi_execute_cdb reply.");
return;
}
} else {
cmd.uscsi_bufaddr = 0;
cmd.uscsi_buflen = 0;
}
"sending execute_cdb reply");
return;
}
} else {
"sending execute_cdb reply");
return;
}
if (cmd.uscsi_status == 0)
}
} else {
}
(void *)&reply) < 0)
}
/*
* ndmp_stop_local_reader
*
* Stops a mover reader thread (for local backup only)
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
/*
* 2-way restore.
*/
}
}
}
}
/*
* Stops a mover reader thread (for remote backup only)
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
/*
* 3-way restore.
*/
}
}
}
/*
* ndmp_wait_for_reader
*
* Wait for a reader until get done (busy wait)
*/
void
{
} else {
while (cmds->tcs_reader_count > 0)
(void) sleep(1);
}
}
/*
* ndmp_open_list_find
*
* Find a specific device in the open list
*
* Parameters:
* dev (input) - device name
* sid (input) - SCSI target ID
* lun (input) - LUN number
*
* Returns:
* pointer to the open list entry
*/
struct open_list *
{
return (NULL);
}
(void) mutex_lock(&ol_mutex);
(void) mutex_unlock(&ol_mutex);
return (olp);
}
(void) mutex_unlock(&ol_mutex);
return (NULL);
}
/*
* ndmp_open_list_add
*
* Add a specific device to the open list
*
* Parameters:
* conn (input) - connection pointer
* dev (input) - device name
* sid (input) - SCSI target ID
* lun (input) - LUN number
* fd (input) - the device file descriptor
*
* Returns:
* errno
*/
int
{
int err;
return (EINVAL);
}
err = 0;
/*
* The adapter handle can be opened many times by the clients.
* Only when the target is set, we must check and reject the
* open request if the device is already being used by another
* session.
*/
if (sid == -1)
else
} else {
if (fd > 0)
else
(void) mutex_lock(&ol_mutex);
(void) mutex_unlock(&ol_mutex);
}
return (err);
}
/*
* ndmp_open_list_del
*
* Delete a specific device from the open list
*
* Parameters:
* dev (input) - device name
* sid (input) - SCSI target ID
* lun (input) - LUN number
*
* Returns:
* errno
*/
int
{
return (EINVAL);
}
return (ENOENT);
}
(void) mutex_lock(&ol_mutex);
}
(void) mutex_unlock(&ol_mutex);
return (0);
}
/*
* ndmp_open_list_release
*
* Close all the resources belonging to this connection.
*
* Parameters:
* ndmp_connection_t *conn : connection identifier
*
* Returns:
* void
*/
void
{
(void) mutex_lock(&ol_mutex);
"Removed dev: %s, sid: %d, lun: %d",
}
}
(void) mutex_unlock(&ol_mutex);
}
/*
* ndmp_stop_buffer_worker
*
* Stop all reader and writer threads for a specific buffer.
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
} else {
} else {
while (cmds->tcs_reader_count > 0 ||
cmds->tcs_writer_count > 0) {
"trying to stop buffer worker");
(void) sleep(1);
}
}
}
}
/*
* ndmp_stop_reader_thread
*
* Stop only the reader threads of a specific buffer
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
} else {
} else {
while (cmds->tcs_reader_count > 0) {
"trying to stop reader thread");
(void) sleep(1);
}
}
}
}
/*
* ndmp_stop_reader_thread
*
* Stop only the writer threads of a specific buffer
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
} else {
} else {
while (cmds->tcs_writer_count > 0) {
"trying to stop writer thread");
(void) sleep(1);
}
}
}
}
/*
* ndmp_free_reader_writer_ipc
*
* for reader and writer threads.
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
}
}
}
/*
* ndmp_waitfor_op
*
* Wait for a session reference count to drop to zero
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
(void) sleep(1);
}
}
}
/*
* ndmp_session_ref
*
* Increment the reference count of the session
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
}
/*
* ndmp_session_unref
*
* Decrement the reference count of the session
*
* Parameters:
* session (input) - session pointer
*
* Returns:
* void
*/
void
{
}
/*
* ndmp_addr2str_v3
*
* Convert the address type to a string
*
* Parameters:
* type (input) - address type
*
* Returns:
* type in string
*/
char *
{
char *rv;
switch (type) {
case NDMP_ADDR_LOCAL:
rv = "Local";
break;
case NDMP_ADDR_TCP:
rv = "TCP";
break;
case NDMP_ADDR_FC:
rv = "FC";
break;
case NDMP_ADDR_IPC:
rv = "IPC";
break;
default:
rv = "Unknown";
}
return (rv);
}
/*
* ndmp_valid_v3addr_type
*
* Make sure that the NDMP address is from any of the
* valid types
*
* Parameters:
* type (input) - address type
*
* Returns:
* 1: valid
* 0: invalid
*/
{
switch (type) {
case NDMP_ADDR_LOCAL:
case NDMP_ADDR_TCP:
case NDMP_ADDR_FC:
case NDMP_ADDR_IPC:
break;
default:
}
return (rv);
}
/*
* ndmp_copy_addr_v3
*
* Copy NDMP address from source to destination (V2 and V3 only)
*
* Parameters:
* dst (ouput) - destination address
* src (input) - source address
*
* Returns:
* void
*/
void
{
case NDMP_ADDR_LOCAL:
/* nothing */
break;
case NDMP_ADDR_TCP:
break;
case NDMP_ADDR_FC:
case NDMP_ADDR_IPC:
default:
break;
}
}
/*
* ndmp_copy_addr_v4
*
* Copy NDMP address from source to destination. V4 has a extra
* environment list inside the address too which needs to be copied.
*
* Parameters:
* dst (ouput) - destination address
* src (input) - source address
*
* Returns:
* void
*/
void
{
int i;
case NDMP_ADDR_LOCAL:
/* nothing */
break;
case NDMP_ADDR_TCP:
src->tcp_len_v4);
if (dst->tcp_addr_v4 == 0)
return;
for (i = 0; i < src->tcp_len_v4; i++) {
}
break;
case NDMP_ADDR_FC:
case NDMP_ADDR_IPC:
default:
break;
}
}
/*
* ndmp_connect_sock_v3
*
*
* Parameters:
* addr (input) - IP address
* port (input) - port number
*
* Returns:
* 0: on success
* -1: otherwise
*/
int
{
int sock;
struct sockaddr_in sin;
int flag = 1;
if (sock < 0) {
return (-1);
}
sock = -1;
} else {
if (ndmp_sbs > 0)
if (ndmp_rbs > 0)
sizeof (flag));
}
return (sock);
}
/*
* ndmp_create_socket
*
* Creates a socket for listening for accepting data connections.
*
* Parameters:
* session (input) - session pointer.
* addr (output) - location to store address of socket.
* port (output) - location to store port of socket.
*
* Returns:
* 0 - success.
* -1 - error.
*/
int
{
char *p;
int length;
int sd;
struct sockaddr_in sin;
p = ndmpd_get_prop(NDMP_MOVER_NIC);
if (!p || *p == 0)
p = gethostaddr();
if (!p) {
return (-1);
}
if (sd < 0) {
return (-1);
}
sd = -1;
sd = -1;
sd = -1;
} else
return (sd);
}
/*
* cctime
*
* Convert the specified time into a string. It's like
* ctime(), but:
* - chops the trailing '\n' of ctime.
* - and returns "the epoch" if time is 0.
*
* Returns:
* "": invalid argument.
* "the epoch": if time is 0.
* string format of the time.
*/
char *
{
if (!t)
return ("");
if (*t == (time_t)0)
return ("the epoch");
return ("");
if (cp)
*cp = '\0';
return (bp);
}
/*
* ndmp_new_job_name
*
*
* Parameters:
* jname (output) - job name
*
* Returns:
* jname
*/
char *
ndmp_new_job_name(char *jname)
{
}
return (jname);
}
/*
* fs_is_valid_logvol
*
* Check if the log path exists
*
* Parameters:
* path (input) - log path
*
* Returns:
* FALSE: invalid
* TRUE: valid
*/
fs_is_valid_logvol(char *path)
{
return (FALSE);
return (TRUE);
}
/*
* ndmpd_mk_temp
*
* Make a temporary file using the working directory path and the
* jobname
*
* Parameters:
* buf (output) - the temporary file name path
*
* Returns:
* buf
*/
char *
ndmpd_mk_temp(char *buf)
{
char fname[TLM_MAX_BACKUP_JOB_NAME];
const char *dir;
char *rv;
if (!buf)
return (NULL);
return (0);
}
if (!fs_is_valid_logvol((char *)dir)) {
"Log file path cannot be on system volumes.");
return (0);
}
if (!*dir) {
return (0);
}
(void) ndmp_new_job_name(fname);
return (rv);
}
/*
* ndmpd_make_bk_dir_path
*
* Make a directory path for temporary files under the NDMP
* working directory.
*
* Parameters:
* buf (output) - result path
* fname (input) - the file name
*
* Returns:
* buf
*/
char *
{
const char *p;
char *name;
return (NULL);
return (NULL);
}
(void) trim_whitespace(path);
return (buf);
}
/*
* ndmp_is_chkpnt_root
*
* Is this a root checkpoint (snapshot) directory.
* Note: a temporary function
*/
ndmp_is_chkpnt_root(char *path)
{
return (TRUE);
}
return (FALSE);
}
/*
* ndmpd_make_exc_list
*
* Make a list of files that should not be backed up.
*
* Parameters:
* void
*
* Returns:
* list - array of character strings
*/
char **
ndmpd_make_exc_list(void)
{
int i, n;
n = sizeof (exls);
/*
* If ndmpd_get_prop returns NULL, the array will be
* null-terminated.
*/
}
return (cpp);
}
/*
* ndmp_get_bk_dir_ino
*
* Get the inode number of the backup directory
*/
int
{
int rv;
rv = -1;
} else {
rv = 0;
}
return (rv);
}
/*
* ndmp_check_utf8magic
*
* Check if the magic string for exists in the tar header. This
* magic string (which also indicates that the file names are in
* UTF8 format) is used as a crest to indetify our own tapes.
* This checking is always done before all restores except DAR
* restores.
*/
{
char *cp;
return (FALSE);
}
return (FALSE);
}
/* wait until the first buffer gets full. */
err = actual_size = 0;
&actual_size);
return (FALSE);
}
if (actual_size < len) {
return (FALSE);
}
}
/*
* ndmp_get_cur_bk_time
*
* Get the backup checkpoint time.
*/
int
{
int err;
return (-1);
}
return (0);
}
if (err != 0) {
} else {
}
return (err);
}
/*
* get_relative_path
*/
char *
{
char *p = fullpath;
return (fullpath);
while (*base) {
if (*base != *p)
break;
p++; base++;
}
if (*p == '/')
p++;
}
/*
* ndmp_get_nlp
*
* Get NDMP local backup parameters
*
* Parameter:
* session cooke
*
* Returns:
* LBR structure
*/
ndmp_get_nlp(void *cookie)
{
return (NULL);
}
/*
* is_tape_unit_ready
*
* Check if the tape device is ready or not
*/
{
int try;
int fd = 0;
try = TUR_MAX_TRY;
if (dev_id <= 0) {
return (FALSE);
} else {
}
do {
if (scsi_test_unit_ready(fd) >= 0) {
if (dev_id <= 0)
return (TRUE);
}
} while (--try > 0);
if (dev_id <= 0)
return (FALSE);
}
/*
* scsi_test_unit_ready
*
* This is for Test Unit Read, without this function, the only
* impact is getting EBUSY's before each operation which we have
* busy waiting loops checking EBUSY error code.
*/
static int
{
int retval;
"Failed to send inquiry request to device: %m.");
} else
return (retval);
}
/*
* ndmp_load_params
*
* Load the parameters.
*
* Parameter:
* void
*
* Returns:
* void
*/
void
ndmp_load_params(void)
{
/* Get the value from ndmp SMF property. */
}
/*
* randomize
*
* Randomize the contents of a buffer
*
* Parameter:
* buffer (output) - destination buffer
* size (input) - buffer size
*
* Returns:
* void
*/
void
{
/* LINTED improper alignment */
unsigned int *p = (unsigned int *)buffer;
unsigned int tmp;
unsigned int i;
for (i = 0; i < dwlen; i++)
*p++ = random();
if (remlen) {
}
}
/*
* ndmpd_get_file_entry_type
*
* Converts the mode to the NDMP file type
*
* Parameter:
* mode (input) - file mode
* ftype (output) - file type
*
* Returns:
* void
*/
void
{
case S_IFIFO:
*ftype = NDMP_FILE_FIFO;
break;
case S_IFCHR:
*ftype = NDMP_FILE_CSPEC;
break;
case S_IFDIR:
*ftype = NDMP_FILE_DIR;
break;
case S_IFBLK:
*ftype = NDMP_FILE_BSPEC;
break;
case S_IFREG:
*ftype = NDMP_FILE_REG;
break;
case S_IFLNK:
*ftype = NDMP_FILE_SLINK;
break;
default:
*ftype = NDMP_FILE_SOCK;
break;
}
}
/*
* Set a private data in the plugin context
*/
void
{
}
/*
* Get a private data in the plugin context
*/
void *
{
}