⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tape.c

📁 网络数据管理协议的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                               -*- 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 + -