2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use is subject to license terms.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 *
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 *
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 */
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 Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/param.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <fcntl.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/mtio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <errno.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <string.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd_common.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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 Sabdar ndmp_tape_read_reply *reply);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t validmode(int mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void common_tape_open(ndmp_connection_t *connection, char *devname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int ndmpmode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void common_tape_close(ndmp_connection_t *connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Configurable delay & time when the tape is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * busy during opening the tape.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint ndmp_tape_open_retries = 5;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint ndmp_tape_open_delay = 1000;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl/*
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * A few words about EOT (end-of-tape) and EOM handling on tapes with SVR4
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * semantic:
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl *
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 *
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.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl */
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP V2 HANDLERS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_open_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler opens the specified tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_open_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
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 char adptnm[SCSI_MAX_NAME];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int mode;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int sid, lun;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scsi_adapter_t *sa;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int devid;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_INFO,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Connection already has a tape or scsi device open");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_DEVICE_OPENED_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (request->mode != NDMP_TAPE_READ_MODE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request->mode != NDMP_TAPE_WRITE_MODE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request->mode != NDMP_TAPE_RAW1_MODE) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_ILLEGAL_ARGS_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((sa = scsi_get_adapter(0)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Adapter device opened: %s", request->device.name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(adptnm, request->device.name, SCSI_MAX_NAME-2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar adptnm[SCSI_MAX_NAME-1] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sid = lun = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* try to get the scsi id etc.... */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (sa) {
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 (devid = tape_open(request->device.name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar O_RDWR | O_NDELAY)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to open device %s: %m.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request->device.name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_DEVICE_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(devid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "%s: No such tape device.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request->device.name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_DEVICE_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err != NDMP_NO_ERR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (ndmp_open_list_add(connection, adptnm, sid, lun, devid)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case 0:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EBUSY:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ENOMEM:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_MEM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err != NDMP_NO_ERR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
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 */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (request->mode != NDMP_TAPE_RAW1_MODE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar !is_tape_unit_ready(adptnm, 0)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_open_list_del(adptnm, sid, lun);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, NDMP_NO_TAPE_LOADED_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode = (request->mode == NDMP_TAPE_READ_MODE) ? O_RDONLY : O_RDWR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode |= O_NDELAY;
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 request->device.name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (errno) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EACCES:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_WRITE_PROTECT_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ENXIO:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ENOENT:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_DEVICE_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EBUSY:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_open_list_del(adptnm, sid, lun);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_mode = request->mode;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_sid = sid;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_lun = lun;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(session->ns_tape.td_adapter_name, adptnm, SCSI_MAX_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_record_count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Tape is opened fd: %d", session->ns_tape.td_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, NDMP_NO_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_close_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler closes the currently open tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_close_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_close_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar common_tape_close(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_get_state_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles the tape_get_state request.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Status information for the currently open tape device is returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_get_state_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_get_state_reply_v2 reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtget mtstatus;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtdrivetype_request dtpr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtdrivetype dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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 reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtpr.size = sizeof (struct mtdrivetype);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtpr.mtdtp = &dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get drive type information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.flags = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.file_num = mtstatus.mt_fileno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.soft_errors = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.block_size = dtp.bsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dtp.bsize == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.blockno = mtstatus.mt_blkno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.blockno = mtstatus.mt_blkno *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_record_size / dtp.bsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.soft_errors = 0;
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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_mtio_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_mtio requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_mtio_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_mtio_request *request = (ndmp_tape_mtio_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_mtio_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtop tapeop;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtget mtstatus;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int retry = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rc;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.resid_count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (request->tape_op) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_FSF:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTFSF;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_BSF:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTBSF;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_FSR:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTFSR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_BSR:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTBSR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_REW:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTREW;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_EOF:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_PERMISSION_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTWEOF;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_OFF:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_op = MTOFFL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_MTIO_TUR: /* test unit ready */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_tape_unit_ready(session->ns_tape.td_adapter_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_fd) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* tape not ready ? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_TAPE_LOADED_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (reply.error == NDMP_NO_ERR && request->tape_op != NDMP_MTIO_TUR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tapeop.mt_count = request->count;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_UPD(twait, trun);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl errno = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rc = ioctl(session->ns_tape.td_fd, MTIOCTOP, &tapeop);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_UPD(trun, twait);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "ioctl MTIO rc:%d, cmd:%d, retry:%d, error: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rc, tapeop.mt_op, retry, errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (rc < 0 && errno == EIO &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar retry++ < 5);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
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 */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rc < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to send command to tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCTOP) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* MTWEOF doesnt have residual count */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tapeop.mt_op == MTWEOF)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.resid_count = tapeop.mt_count;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (request->tape_op != NDMP_MTIO_REW &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request->tape_op != NDMP_MTIO_OFF) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGET,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &mtstatus) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to send command to tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "ioctl(MTIOCGET) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.resid_count = labs(mtstatus.mt_resid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "resid_count: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.resid_count);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_mtio reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_read_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_read_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_request *request = (ndmp_tape_read_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.data_in.data_in_len = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (request->count == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((buf = ndmp_malloc(request->count)) == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_MEM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar unbuffered_read(session, buf, request->count, &reply);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) free(buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_execute_cdb_v2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler handles tape_execute_cdb requests.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_execute_cdb_v2(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_execute_cdb_request *request;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_execute_cdb_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request = (ndmp_tape_execute_cdb_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *) &reply, 0, sizeof (reply));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_execute_cdb reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
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 (ndmp_execute_cdb_request *)request);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP V3 HANDLERS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_open_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler opens the specified tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_open_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_open_request_v3 *request = (ndmp_tape_open_request_v3 *)body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar common_tape_open(connection, request->device, request->mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_get_state_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_get_state_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_get_state_reply_v3 reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtdrivetype_request dtpr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtdrivetype dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtget mtstatus;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtpr.size = sizeof (struct mtdrivetype);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtpr.mtdtp = &dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get drive type information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.flags = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.file_num = mtstatus.mt_fileno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.soft_errors = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.block_size = dtp.bsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dtp.bsize == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.blockno = mtstatus.mt_blkno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.blockno = mtstatus.mt_blkno *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_record_size / dtp.bsize);
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.partition = 0; /* not supported */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.soft_errors = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.total_space = long_long_to_quad(0LL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.space_remain = long_long_to_quad(0LL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.invalid = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_TAPE_STATE_TOTAL_SPACE_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_TAPE_STATE_SPACE_REMAIN_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_TAPE_STATE_PARTITION_INVALID;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl/*
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * tape_is_at_bot
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl *
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * Returns 1 if tape is at BOT, 0 on error or not at BOT.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl *
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl */
9ee94b97c8654689d6a034daec08757fda75d21aJan Krylint
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryltape_is_at_bot(ndmpd_session_t *session)
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl{
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl struct mtget mtstatus;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl
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
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl return (0);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl}
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl/*
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 *
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * Returns 1 if tape is at BOF, 0 on error or not at BOF.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl */
9ee94b97c8654689d6a034daec08757fda75d21aJan Krylint
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryltape_is_at_bof(ndmpd_session_t *session)
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl{
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl struct mtget mtstatus;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl
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
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl return (0);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl}
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl/*
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 *
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 *
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 */
9ee94b97c8654689d6a034daec08757fda75d21aJan Krylvoid
9ee94b97c8654689d6a034daec08757fda75d21aJan Krylfm_dance(ndmpd_session_t *session)
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl{
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSF, 1);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_write_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 *
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
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * reached.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
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 =
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl ndmp_get_client_data(connection); ssize_t n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
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 reply.error = NDMP_PERMISSION_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (request->data_out.data_out_len == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that this should not be accepted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when mover is in listen or active state
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_protocol_version == NDMPV4 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = write(session->ns_tape.td_fd, request->data_out.data_out_val,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar request->data_out.data_out_len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape write error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl } else if (n == 0) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_INFO, "EOM detected");
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.error = NDMP_EOM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NS_ADD(wtape, n);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.count = n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl if (n < request->data_out.data_out_len)
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_DEBUG,
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl "EOM is coming (partial write of %d bytes)", n);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_write reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_read_v3
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 *
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 *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_read_v3(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_request *request = (ndmp_tape_read_request *) body;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *buf;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl int n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.data_in.data_in_len = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (request->count == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that this should not be accepted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when mover is in listen or active state
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_protocol_version == NDMPV4 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((buf = ndmp_malloc(request->count)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_MEM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = read(session->ns_tape.td_fd, buf, request->count);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This fix is for Symantec during importing
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of spanned data between the tapes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (errno == ENOSPC) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_EOF_ERR;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl }
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl /*
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 */
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl else if (errno == EIO && tape_is_at_bof(session)) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_DEBUG, "Repeated read at EOT");
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.error = NDMP_EOM_ERR;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl }
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl /*
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * According to NDMPv4 spec preferred error code when
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl * trying to read from blank tape is NDMP_EOM_ERR.
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl */
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl else if (errno == EIO && tape_is_at_bot(session)) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_ERR, "Blank tape detected, returning EOM");
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.error = NDMP_EOM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape read error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (n == 0) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl if (tape_is_at_bof(session)) {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_DEBUG, "EOT detected");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_EOM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl /* reposition the tape to BOT side of FM */
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl fm_dance(session);
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl NDMP_LOG(LOG_DEBUG, "EOF detected");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_EOF_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl session->ns_tape.td_pos += n;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.data_in.data_in_len = n;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.data_in.data_in_val = buf;
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_ADD(rtape, n);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_read reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP V4 HANDLERS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_get_state_v4
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_get_state_v4(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_get_state_reply_v4 reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtget mtstatus;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtdrivetype_request dtpr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct mtdrivetype dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Need code to detect NDMP_TAPE_STATE_NOREWIND
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get status information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtpr.size = sizeof (struct mtdrivetype);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtpr.mtdtp = &dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to get drive type information from tape: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *)&reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar reply.flags = NDMP_TAPE_NOREWIND;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.file_num = mtstatus.mt_fileno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.soft_errors = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.block_size = dtp.bsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dtp.bsize == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.blockno = mtstatus.mt_blkno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
9ee94b97c8654689d6a034daec08757fda75d21aJan Kryl reply.blockno = mtstatus.mt_blkno /
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (session->ns_mover.md_record_size / dtp.bsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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.soft_errors = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.unsupported = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_TAPE_STATE_TOTAL_SPACE_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_TAPE_STATE_SPACE_REMAIN_INVALID |
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_TAPE_STATE_PARTITION_INVALID;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_get_state reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmpd_tape_close_v4
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This handler (v4) closes the currently open tape device.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * body (input) - request message body.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_tape_close_v4(ndmp_connection_t *connection, void *body)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_close_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape device is not open.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEV_NOT_OPEN_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * V4 suggests that this should not be accepted
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when mover is in listen or active state
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar common_tape_close(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LOCALS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ************************************************************************
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tape_open_send_reply
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Send a reply to the tape open message
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * err (input) - NDMP error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartape_open_send_reply(ndmp_connection_t *connection, int err)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_open_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply, "sending tape_open reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * unbuffered_read
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Perform tape read without read-ahead
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarunbuffered_read(ndmpd_session_t *session, char *buf, long wanted,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_read_reply *reply)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int n, len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = read(session->ns_tape.td_fd, buf, wanted);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (n < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This fix is for Symantec during importing
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of spanned data between the tapes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (errno == ENOSPC) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply->error = NDMP_EOF_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Tape read error: %m.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply->error = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (n == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "NDMP_EOF_ERR");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply->error = NDMP_EOF_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar len = strlen(NDMP_EOM_MAGIC);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(buf, 0, len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = read(session->ns_tape.td_fd, buf, len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf[len] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Checking EOM: nread %d [%s]", n, buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strncmp(buf, NDMP_EOM_MAGIC, len) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_pos += n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply->data_in.data_in_len = n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply->data_in.data_in_val = buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply->error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_ADD(rtape, n);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * validmode
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check the tape read mode is valid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvalidmode(int mode)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (mode) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_TAPE_READ_MODE:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_TAPE_WRITE_MODE:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_TAPE_RAW1_MODE:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case NDMP_TAPE_RAW2_MODE:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * common_tape_open
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function for opening the tape for all versions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
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 Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcommon_tape_open(ndmp_connection_t *connection, char *devname, int ndmpmode)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char adptnm[SCSI_MAX_NAME];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int mode;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int sid, lun;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scsi_adapter_t *sa;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int devid;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_INFO,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Connection already has a tape or scsi device open");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_DEVICE_OPENED_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!validmode(ndmpmode))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_ILLEGAL_ARGS_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((sa = scsi_get_adapter(0)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Adapter device opened: %s", devname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(adptnm, devname, SCSI_MAX_NAME-2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar adptnm[SCSI_MAX_NAME-1] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sid = lun = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (sa) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scsi_find_sid_lun(sa, devname, &sid, &lun);
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,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Failed to open device %s: %m.", devname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_DEVICE_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(devid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "%s: No such tape device.", devname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_DEVICE_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err != NDMP_NO_ERR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If tape is not opened in raw mode and tape is not loaded
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * return error.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmpmode != NDMP_TAPE_RAW1_MODE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpmode != NDMP_TAPE_RAW2_MODE &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar !is_tape_unit_ready(adptnm, 0)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, NDMP_NO_TAPE_LOADED_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode = (ndmpmode == NDMP_TAPE_READ_MODE) ? O_RDONLY : O_RDWR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode |= O_NDELAY;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_fd = open(devname, mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_protocol_version == NDMPV4 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_fd < 0 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpmode == NDMP_TAPE_RAW_MODE && errno == EACCES) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
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 */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpmode = NDMP_TAPE_READ_MODE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_fd = open(devname, O_RDONLY);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (session->ns_tape.td_fd < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Failed to open tape device %s: %m.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar devname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (errno) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EACCES:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_WRITE_PROTECT_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ENOENT:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_DEVICE_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EBUSY:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EPERM:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_PERMISSION_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (ndmp_open_list_add(connection,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar adptnm, sid, lun, session->ns_tape.td_fd)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case 0:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case EBUSY:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_DEVICE_BUSY_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ENOMEM:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_NO_MEM_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = NDMP_IO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err != NDMP_NO_ERR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_mode = ndmpmode;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_sid = sid;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_lun = lun;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(session->ns_tape.td_adapter_name, adptnm, SCSI_MAX_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_record_count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Tape is opened fd: %d", session->ns_tape.td_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tape_open_send_reply(connection, NDMP_NO_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * common_tape_close
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function for closing the tape
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * connection (input) - connection handle.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcommon_tape_close(ndmp_connection_t *connection)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd_session_t *session = ndmp_get_client_data(connection);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_tape_close_reply reply;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
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) close(session->ns_tape.td_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_fd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_sid = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_lun = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(session->ns_tape.td_adapter_name, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (session->ns_tape.td_adapter_name));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar session->ns_tape.td_record_count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar reply.error = NDMP_NO_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_send_reply(connection, (void *) &reply,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "sending tape_close reply");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tape_open
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Will try to open the tape with the given flags and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * path using the given retries and delay intervals
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartape_open(char *path, int flags)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((fd = open(path, flags)) == -1 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i++ < ndmp_tape_open_retries) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (errno != EBUSY)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) usleep(ndmp_tape_open_delay);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}