📄 tape.c
字号:
/* -*- Mode: C -*- * tape.c * * Description : NDMP tape operation request handler functions. * * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: tape.c,v 1.7 1998/05/26 03:52:24 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: tape.c,v 1.7 1998/05/26 03:52:24 tim Exp $";#endif#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/mtio.h>#include <sys/stat.h>#include <string.h>#include "ndmp_common.h"#include "ndmpd.h"voidexecuteCdb(NdmpdSession* session, int fd, ndmp_execute_cdb_request* request);/* * ndmpdTapeOpen * * This handler opens the specified tape device. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeOpen(NdmpConnection connection, void* body){ ndmp_tape_open_request* request = (ndmp_tape_open_request *)body; ndmp_tape_open_reply reply; NdmpdSession* session = ndmpGetClientData(connection); int mode; Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeOpen: device:%s mode:%s.\n", request->device, request->mode == NDMP_TAPE_READ_MODE ? "R" : "RW"); memset((void*)&reply, 0, sizeof(reply)); if (session->tape.fd != -1 || session->scsi.fd != -1) { Error(LOG_ERR, "ndmpdTapeOpen: connection already has a tape or scsi device open.\n"); reply.error = NDMP_DEVICE_OPENED_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeOpen: error sending ndmp_tape_open_reply.\n"); return; } if (request->mode == NDMP_TAPE_READ_MODE) mode = O_RDONLY; else mode = O_RDWR; if ((session->tape.fd = open(request->device, mode)) < 0) { Error(LOG_ERR, "ndmpdTapeOpen: error opening tape device: %s: %s.\n", request->device, strerror(errno)); switch (errno) { case EACCES: reply.error = NDMP_WRITE_PROTECT_ERR; break; case ENOENT: reply.error = NDMP_NO_DEVICE_ERR; break; case EBUSY: reply.error = NDMP_DEVICE_BUSY_ERR; break; default: reply.error = NDMP_IO_ERR; break; } if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeOpen: error sending ndmp_tape_open_reply.\n"); return; } session->tape.mode = request->mode; session->tape.recordCount = 0; reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeOpen: error sending ndmp_tape_open_reply.\n");}/* * ndmpdTapeClose * * This handler closes the currently open tape device. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeClose(NdmpConnection connection, void* body __attribute__ ((unused))){ ndmp_tape_close_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeClose: \n"); memset((void*)&reply, 0, sizeof(reply)); if (session->tape.fd == -1) { Error(LOG_ERR, "ndmpdTapeClose: tape device is not open.\n"); reply.error = NDMP_DEV_NOT_OPEN_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_close_reply.\n"); return; } (void) close(session->tape.fd); session->tape.fd = -1; reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_close_reply.\n");}/* * ndmpdTapeGetState * * This handler handles the ndmp_tape_get_state_request. * Status information for the currently open tape device is returned. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeGetState(NdmpConnection connection, void* body __attribute__ ((unused))){ ndmp_tape_get_state_reply reply; NdmpdSession* session = ndmpGetClientData(connection); struct mtop tapeop; struct mtget mtstatus; struct stat statbuf; Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeGetState:\n"); memset((void*)&reply, 0, sizeof(reply)); if (session->tape.fd == -1) { Error(LOG_ERR, "ndmpdTapeGetState: tape device is not open.\n"); reply.error = NDMP_DEV_NOT_OPEN_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeGetState: error sending ndmp_tape_get_state_reply.\n"); return; } if (fstat(session->tape.fd, &statbuf) < 0) { Error(LOG_ERR, "ndmpdTapeGetState: fstat error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeGetState: error sending ndmp_tape_get_state_reply.\n"); return; } if (ioctl(session->tape.fd, MTIOCGET, &mtstatus) < 0) { Error(LOG_ERR, "ndmpdTapeGetState: ioctl(MTIOGET) error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeGetState: error sending ndmp_tape_get_state_reply.\n"); return; } tapeop.mt_op = MTGRSZ; tapeop.mt_count = 1; if (ioctl(session->tape.fd, MTIOCTOP, &tapeop) < 0) { Error(LOG_ERR, "ndmpdTapeGetState: ioctl(MTIOCTOP) error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeGetState: error sending ndmp_tape_get_state_reply.\n"); return; } reply.flags = 0; if (statbuf.st_rdev & MT_NOREWIND) reply.flags |= NDMP_TAPE_STATE_NOREWIND; /* NDMP_TAPE_UNLOAD not supported */ /* NDMP_TAPE_ERROR not supported */ /* I don't know how to determine NDMP_TAPE_WR_PROT */ reply.file_num = mtstatus.mt_fileno; reply.soft_errors = 0; reply.block_size = tapeop.mt_count; if (tapeop.mt_count == 0) reply.blockno = mtstatus.mt_blkno; else reply.blockno = mtstatus.mt_blkno*(session->mover.recordSize/ tapeop.mt_count); reply.total_space = longLongToQuad(0); /* not supported */ reply.space_remain = longLongToQuad(0); /* not supported */ reply.partition = 0; /* not supported */ reply.invalid = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID | NDMP_TAPE_STATE_TOTAL_SPACE_INVALID | NDMP_TAPE_STATE_SPACE_REMAIN_INVALID | NDMP_TAPE_STATE_PARTITION_INVALID; reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeGetState: error sending ndmp_tape_get_state_reply.\n");} /* * ndmpdTapeMtio * * This handler handles tape_mtio requests. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeMtio(NdmpConnection connection, void* body){ ndmp_tape_mtio_request* request = (ndmp_tape_mtio_request*)body; ndmp_tape_mtio_reply reply; NdmpdSession* session = ndmpGetClientData(connection); struct mtop tapeop; struct mtget mtstatus; int err; Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeMtio: op:%s count:%d.\n", request->tape_op == NDMP_MTIO_FSF ? "fsf" : request->tape_op == NDMP_MTIO_BSF ? "bsf" : request->tape_op == NDMP_MTIO_FSR ? "fsr" : request->tape_op == NDMP_MTIO_BSR ? "bsr" : request->tape_op == NDMP_MTIO_REW ? "rew" : request->tape_op == NDMP_MTIO_EOF ? "weof" : request->tape_op == NDMP_MTIO_OFF ? "off" : "unknown", request->count); memset((void*)&reply, 0, sizeof(reply)); reply.resid_count = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -