ndmpd_tape.c revision 2654012f83cec5dc15b61dfe3e4a4915f186e7a6
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright 2008 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 */
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.
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_write_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_write requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This interface is a non-buffered interface. Each write request
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * maps directly to a write to the tape device. It is the responsibility
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of the NDMP client to pad the data to the desired 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_write_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_write_request *request = (ndmp_tape_write_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
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 * Refer to the comment at the top of this file for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Mammoth2 tape drives.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = write(session->ns_tape.td_fd, request->data_out.data_out_val,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n >= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a logical end of tape will return number of bytes written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * less than rquested, and one more request to write will
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * give 0, and then no-space
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write 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");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_write_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_write requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This interface is a non-buffered interface. Each write request
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * maps directly to a write to the tape device. It is the responsibility
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of the NDMP client to pad the data to the desired 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_write_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_write_request *request = (ndmp_tape_write_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
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 * Refer to the comment at the top of this file for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Mammoth2 tape drives.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = write(session->ns_tape.td_fd, request->data_out.data_out_val,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n >= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_read_v3
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_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.
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 if (strncmp(buf, NDMP_EOM_MAGIC, len) == 0 || n == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSR, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Symantec fix for import phase
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * As import process from symantec skips filemarks
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * they can come across to NDMP_EOM_MAGIC and treat
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it as data. This fix prevents the magic to be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * sent to the client and the read will return zero bytes
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and set the NDMP_EOM_ERR error. The tape should
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * be positioned at the EOT side of the file mark.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n == len && strncmp(buf, NDMP_EOM_MAGIC, len) == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
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");
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.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