86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use is subject to license terms.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 2007, The Storage Networking Industry Association. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl/* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void tape_open_send_reply(ndmp_connection_t *connection, int err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void unbuffered_read(ndmpd_session_t *session, char *buf, long wanted,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void common_tape_open(ndmp_connection_t *connection, char *devname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void common_tape_close(ndmp_connection_t *connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Configurable delay & time when the tape is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * busy during opening the tape.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * A few words about EOT (end-of-tape) and EOM handling on tapes with SVR4
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * semantic:
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * We adhere to terminology as used in st driver. EOT means end of recorded
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * data on a tape. This is different from EOM (somewhere referred to as LEOT)
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * which is the end of tape medium. EOT is meaningful only for reads while EOM
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * is meaningful only for writes. It's not possible to read after EOT (fails
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * with EIO), but it's possible to write data after EOM. EOM returned by st
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * driver on modern tape drives is just indication that the physical end of
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * tape medium is nearing and that writer should write just the necessary
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * minimum and stop writing. When physical end of tape is reached all writes
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * return EIO. If EOM is crossed during read operation then st driver doesn't
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * bother to report it to client and that's alright because reads don't care
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * where medium physically ends but they care about meaningful data recorded on
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * the tape and as long as there are such data reads should continue to work.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * When reading EOT is signalled by st driver by two empty consecutive reads
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * (with FSF done between them). When writing EOM is signalled by empty write
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * (a write which writes zero bytes). Following writes succeed until physical
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * end of tape is reached in which case EIO is returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP V2 HANDLERS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_open_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler opens the specified tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_open_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_open_request_v2 *request = (ndmp_tape_open_request_v2 *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Connection already has a tape or scsi device open");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (request->mode != NDMP_TAPE_READ_MODE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Adapter device opened: %s", request->device.name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(adptnm, request->device.name, SCSI_MAX_NAME-2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* try to get the scsi id etc.... */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scsi_find_sid_lun(sa, request->device.name, &sid, &lun);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_open_list_find(request->device.name, sid, lun) == 0 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to open device %s: %m.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (ndmp_open_list_add(connection, adptnm, sid, lun, devid)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * According to Connectathon 2001, the 0x7fffffff is a secret
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * code between "Workstartion Solutions" and * net_app.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If mode is set to this value, tape_open() won't fail if
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the tape device is not ready.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, NDMP_NO_TAPE_LOADED_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode = (request->mode == NDMP_TAPE_READ_MODE) ? O_RDONLY : O_RDWR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((session->ns_tape.td_fd = open(request->device.name, mode)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to open tape device %s: %m.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(session->ns_tape.td_adapter_name, adptnm, SCSI_MAX_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Tape is opened fd: %d", session->ns_tape.td_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_close_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler closes the currently open tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_close_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_get_state_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles the tape_get_state request.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Status information for the currently open tape device is returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_get_state_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to get status from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get drive type information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.total_space = long_long_to_quad(0); /* not supported */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.space_remain = long_long_to_quad(0); /* not supported */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "flags: 0x%x, file_num: %d, block_size: %d, blockno: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.flags, reply.file_num, reply.block_size, reply.blockno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_mtio_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_mtio requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_mtio_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_mtio_request *request = (ndmp_tape_mtio_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_tape_unit_ready(session->ns_tape.td_adapter_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* tape not ready ? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (reply.error == NDMP_NO_ERR && request->tape_op != NDMP_MTIO_TUR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rc = ioctl(session->ns_tape.td_fd, MTIOCTOP, &tapeop);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "ioctl MTIO rc:%d, cmd:%d, retry:%d, error: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Ignore I/O errors since these usually are the result of
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * attempting to position past the beginning or end of the tape.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The residual count will be returned and can be used to
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * determine that the call was not completely successful.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to send command to tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCTOP) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* MTWEOF doesnt have residual count */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to send command to tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "ioctl(MTIOCGET) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_read_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_read requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This interface is a non-buffered interface. Each read request
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * maps directly to a read to the tape device. It is the responsibility
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of the NDMP client to issue read requests with a length that is at
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * least as large as the record size used write the tape. The tape driver
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * always reads a full record. Data is discarded if the read request is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * smaller than the record size.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * It is the responsibility of the NDMP client to ensure that the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * length is a multiple of the tape block size if the tape device
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is in fixed block mode.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_read_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_request *request = (ndmp_tape_read_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar unbuffered_read(session, buf, request->count, &reply);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_execute_cdb_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_execute_cdb requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_execute_cdb_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request = (ndmp_tape_execute_cdb_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *) &reply, 0, sizeof (reply));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_execute_cdb reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_execute_cdb(session, session->ns_tape.td_adapter_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_sid, session->ns_tape.td_lun,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP V3 HANDLERS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_open_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler opens the specified tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_open_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_open_request_v3 *request = (ndmp_tape_open_request_v3 *)body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar common_tape_open(connection, request->device, request->mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_get_state_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles the ndmp_tape_get_state_request.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Status information for the currently open tape device is returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_get_state_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to get status from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get drive type information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.total_space = long_long_to_quad(0); /* not supported */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.space_remain = long_long_to_quad(0); /* not supported */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.invalid = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "f 0x%x, fnum %d, bsize %d, bno: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.flags, reply.file_num, reply.block_size, reply.blockno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * tape_is_at_bot
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * Returns 1 if tape is at BOT, 0 on error or not at BOT.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == 0 &&
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl return (1);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl return (0);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * If we are at the beginning of a file (block # is zero) and read returns
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * zero bytes then this has to be end of recorded data on the tape. Repeated
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * reads at EOT return EIO. In both cases (zero read and EIO read) this
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * function should be used to test if we are at EOT.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * Returns 1 if tape is at BOF, 0 on error or not at BOF.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl if ((ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == 0) &&
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl (mtstatus.mt_fileno > 0) && (mtstatus.mt_blkno == 0))
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl return (1);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl return (0);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * Skips forward over a file mark and then back before the file mark. Why is
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * this needed? There are two reasons for it:
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * 1) Because NDMPv4 spec requires that when EOF is encountered, the tape
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * position should remain on BOT side of the file mark. When st driver reaches
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * end of file get-position mtioctl reports position before file mark, however
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * the file mark has already been read and the real position is thus after the
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * file mark (real position as reported for example by uscsi commands). Thus we
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * need to do FSF, which does nothing but only updates file & block counter in
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * st driver and then BSF, which sets the position before the file mark. Thus
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * current position as reported by scsi and mtioctl will be in sync.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * 2) st driver returns EIO for repeated reads at EOF while according to NDMP
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * spec we should continue to return zero bytes until FSF is done. By skipping
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * forward and backward, st driver will return zero bytes for the next read
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * again and we don't need to specifically handle this case.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_write_v3
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * This handler handles tape_write requests. This interface is a non-buffered
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * interface. Each write request maps directly to a write to the tape device.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * It is the responsibility of the NDMP client to pad the data to the desired
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * record size. It is the responsibility of the NDMP client to ensure that the
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * length is a multiple of the tape block size if the tape device is in fixed
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * block mode.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * A logical end of tape will return number of bytes written less than
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * requested, and one more request to write will give 0 and NDMP_EOM_ERR,
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * followed by NDMP_NO_ERR until NDMP_IO_ERR when physical end of tape is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
9ee94b97c8654689d6a034daec08757fda75d21aJan Krylvoid ndmpd_tape_write_v3(ndmp_connection_t *connection, void *body) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl ndmp_tape_write_request *request = (ndmp_tape_write_request *)body;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl ndmp_tape_write_reply reply; ndmpd_session_t *session =
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_INFO, "Tape device opened in read-only mode");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that this should not be accepted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when mover is in listen or active state
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = write(session->ns_tape.td_fd, request->data_out.data_out_val,
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl if (n < 0) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl } else if (n == 0) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl "EOM is coming (partial write of %d bytes)", n);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_read_v3
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * This handler handles tape_read requests. This interface is a non-buffered
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * interface. Each read request maps directly to a read to the tape device. It
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * is the responsibility of the NDMP client to issue read requests with a
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * length that is at least as large as the record size used write the tape. The
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * tape driver always reads a full record. Data is discarded if the read
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * request is smaller than the record size. It is the responsibility of the
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * NDMP client to ensure that the length is a multiple of the tape block size
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * if the tape device is in fixed block mode.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * A logical end of tape will return less bytes than requested, and one more
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * request to read will give 0 and NDMP_EOM_ERR. All subsequent reads will
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * return NDMP_EOM_ERR until the tape is repositioned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_read_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_request *request = (ndmp_tape_read_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that this should not be accepted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when mover is in listen or active state
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((buf = ndmp_malloc(request->count)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = read(session->ns_tape.td_fd, buf, request->count);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This fix is for Symantec during importing
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of spanned data between the tapes.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * If at beginning of file and read fails with EIO, then it's
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * repeated attempt to read at EOT.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl else if (errno == EIO && tape_is_at_bof(session)) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * According to NDMPv4 spec preferred error code when
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * trying to read from blank tape is NDMP_EOM_ERR.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl else if (errno == EIO && tape_is_at_bot(session)) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_ERR, "Blank tape detected, returning EOM");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (n == 0) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl /* reposition the tape to BOT side of FM */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP V4 HANDLERS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_get_state_v4
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles the ndmp_tape_get_state_request.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Status information for the currently open tape device is returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_get_state_v4(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Need code to detect NDMP_TAPE_STATE_NOREWIND
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get status information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get drive type information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.total_space = long_long_to_quad(0LL); /* not supported */
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.space_remain = long_long_to_quad(0LL); /* not supported */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.unsupported = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "f 0x%x, fnum %d, bsize %d, bno: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.flags, reply.file_num, reply.block_size, reply.blockno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_close_v4
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler (v4) closes the currently open tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_close_v4(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that this should not be accepted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when mover is in listen or active state
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tape_open_send_reply
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Send a reply to the tape open message
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * err (input) - NDMP error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartape_open_send_reply(ndmp_connection_t *connection, int err)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_open reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * unbuffered_read
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Perform tape read without read-ahead
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * session (input) - session handle
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bp (output) - read buffer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * wanted (input) - number of bytes wanted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reply (output) - tape read reply message
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarunbuffered_read(ndmpd_session_t *session, char *buf, long wanted,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This fix is for Symantec during importing
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of spanned data between the tapes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (n == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Checking EOM: nread %d [%s]", n, buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check the tape read mode is valid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * common_tape_open
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function for opening the tape for all versions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * devname (input) - tape device name to open.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpmode (input) - mode of opening (read, write, raw)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcommon_tape_open(ndmp_connection_t *connection, char *devname, int ndmpmode)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Connection already has a tape or scsi device open");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Adapter device opened: %s", devname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(adptnm, devname, SCSI_MAX_NAME-2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_open_list_find(devname, sid, lun) == 0 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (devid = open(devname, O_RDWR | O_NDELAY)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "%s: No such tape device.", devname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If tape is not opened in raw mode and tape is not loaded
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * return error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, NDMP_NO_TAPE_LOADED_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode = (ndmpmode == NDMP_TAPE_READ_MODE) ? O_RDONLY : O_RDWR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpmode == NDMP_TAPE_RAW_MODE && errno == EACCES) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that if the tape is open in raw mode
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and could not be opened with write access, it should
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * be opened read only instead.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_fd = open(devname, O_RDONLY);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to open tape device %s: %m.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(session->ns_tape.td_adapter_name, adptnm, SCSI_MAX_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Tape is opened fd: %d", session->ns_tape.td_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * common_tape_close
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function for closing the tape
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_open_list_del(session->ns_tape.td_adapter_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_sid, session->ns_tape.td_lun);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(session->ns_tape.td_adapter_name, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Will try to open the tape with the given flags and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * path using the given retries and delay intervals