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

📄 mover.c

📁 网络数据管理协议的开发
💻 C
📖 第 1 页 / 共 4 页
字号:
/*                               -*- Mode: C -*-  * mover.c *  * Description     : Data mover functions. *  * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: mover.c,v 1.15 1998/05/26 03:52:19 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: mover.c,v 1.15 1998/05/26 03:52:19 tim Exp $";#endif#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/mtio.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <errno.h>#include <sys/utsname.h>#include <fcntl.h>#include <string.h>#include "ndmp_common.h"#include "ndmpd.h"/* * Set the following to force EOT processing to occur after  * DEBUG_TAPE_SIZE records have been read/written. * This makes it easier to do EOT testing. * Define to 0xffffffff for production. */#define DEBUG_TAPE_SIZE	0xffffffffstatic intmoverListen(NdmpdSession*	session,			u_long			*addr,			u_short			*port);static voidmoverAcceptConnection(void*			cookie,					  int			fd,					  u_long		mode);static voidmoverDataRead(void*			cookie,			  int			fd,			  u_long		mode);static voidmoverDataWrite(void*		cookie,			   int			fd,			   u_long		mode);static intmoverChangeTape(NdmpdSession*		session);static intmoverTapeWrite(NdmpdSession*	session,			   char*			data,			   ssize_t			length);static intmoverTapeFlush(NdmpdSession*	session);static intmoverTapeRead(NdmpdSession*	session,			  char*			data);/* * ndmpdMoverGetState * * This handler handles the ndmp_mover_get_state_request. * Status information for the mover state machine is returned. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverGetState(NdmpConnection	connection,				   void*			body __attribute__ ((unused))){	ndmp_mover_get_state_reply	reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverGetState:\n");	memset((void*)&reply, 0, sizeof(reply));		reply.error              = NDMP_NO_ERR;	reply.state              = session->mover.state;	reply.pause_reason       = session->mover.pauseReason;	reply.halt_reason        = session->mover.haltReason;	reply.record_size        = session->mover.recordSize;	reply.record_num         = session->mover.recordNum;	reply.data_written       = longLongToQuad(session->mover.dataWritten);	reply.seek_position      = longLongToQuad(session->mover.seekPosition);	reply.bytes_left_to_read = longLongToQuad(session->mover.bytesLeftToRead);	reply.window_offset      = longLongToQuad(session->mover.windowOffset);	reply.window_length      = longLongToQuad(session->mover.windowLength);	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverGetState: error sending ndmp_mover_get_state_reply.\n");}/* * ndmpdMoverListen * * This handler handles ndmp_mover_listen_requests. * A TCP/IP socket is created that is used to listen for * and accept data connections initiated by a remote * data server. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverListen(NdmpConnection	connection,				 void*			body){	ndmp_mover_listen_request*	request	= (ndmp_mover_listen_request*)body;	ndmp_mover_listen_reply		reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverListen: mode:%s type:%s.\n",		  request->mode == NDMP_MOVER_MODE_READ ? "READ" : "WRITE",		  request->addr_type == NDMP_ADDR_LOCAL ? "LOCAL" :		  request->addr_type == NDMP_ADDR_TCP ? "TCP" :		  request->addr_type == NDMP_ADDR_FC ? "FC" :		  request->addr_type == NDMP_ADDR_IPC ? "IPC" :		  "undefined");	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state != NDMP_MOVER_STATE_IDLE)	{		Error(LOG_ERR,			  "ndmpdMoverListen: invalid mover state to process listen request.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverListen: error sending ndmp_mover_listen_reply.\n");		return;	}		if (session->data.state != NDMP_DATA_STATE_IDLE)	{		Error(LOG_ERR,			  "ndmpdMoverListen: invalid data state to process listen request.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverListen: error sending ndmp_mover_listen_reply.\n");		return;	}	if (session->tape.fd == -1)	{		Error(LOG_ERR,			  "ndmpdMoverListen: no tape device open.\n");		reply.error = NDMP_DEV_NOT_OPEN_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverListen: error sending ndmp_mover_listen_reply.\n");		return;	}		if (request->mode == NDMP_MOVER_MODE_READ &&		session->tape.mode == NDMP_TAPE_READ_MODE)	{		Error(LOG_ERR,			  "ndmpdMoverListen: write protected device.\n");		reply.error = NDMP_WRITE_PROTECT_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverListen: error sending ndmp_mover_listen_reply.\n");		return;	}	switch (request->addr_type)	{		case NDMP_ADDR_LOCAL:		{			reply.data_connection_addr.addr_type = NDMP_ADDR_LOCAL;			reply.error = NDMP_NO_ERR;			break;		}		case NDMP_ADDR_TCP:		{			u_long	addr;			u_short	port;					if (moverListen(session, &addr, &port) < 0)			{				reply.error = NDMP_IO_ERR;				break;			}					reply.error = NDMP_NO_ERR;			reply.data_connection_addr.addr_type = NDMP_ADDR_TCP;			reply.data_connection_addr.ndmp_addr_u.tcp_addr.ip_addr = htonl(addr);			reply.data_connection_addr.ndmp_addr_u.tcp_addr.port    = htons(port);			break;		}		default:		{			Error(LOG_ERR,				  "ndmpdMoverListen: invalid address type: %d.\n",				  request->addr_type);			reply.error = NDMP_ILLEGAL_ARGS_ERR;		}	}		if (reply.error != NDMP_NO_ERR)	{		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverListen: error sending ndmp_mover_listen_reply.\n");		return;	}		session->mover.mode         = request->mode;	session->mover.state        = NDMP_MOVER_STATE_LISTEN;	/* Set the default window. */	session->mover.windowOffset = 0;	session->mover.windowLength = 0xffffffffffffffffLL;	session->mover.position     = 0;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverListen: error sending mover_listen reply.\n");}/* * ndmpdMoverContinue * * This handler handles ndmp_mover_continue_requests. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverContinue(NdmpConnection	connection,				   void*			body __attribute__ ((unused))){	ndmp_mover_continue_reply	reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverContinue.\n");	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state != NDMP_MOVER_STATE_PAUSED)	{		Error(LOG_ERR,			  "ndmpdMoverContinue: invalid state.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverContinue: error sending mover_continue reply.\n");		return;	}	session->mover.state = NDMP_MOVER_STATE_ACTIVE;	/*	 * Restore the file handler if the mover is remote to the data	 * server and the handler was removed pending the continuation of a	 * seek request. The handler is removed in moverDataWrite().	 */	if (session->mover.pauseReason == NDMP_MOVER_PAUSE_SEEK &&		session->mover.sock != -1)	{		if (ndmpdAddFileHandler(session, (void*)session,								session->mover.sock,								NDMPD_SELECT_MODE_WRITE,								HC_MOVER,								moverDataWrite) < 0)			ndmpdMoverError(session, NDMP_MOVER_HALT_INTERNAL_ERROR);	}		reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverContinue: error sending mover_continue reply.\n");}	/* * ndmpdMoverAbort * * This handler handles ndmp_mover_abort_requests. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverAbort(NdmpConnection	connection,				void*			body __attribute__ ((unused))){	ndmp_mover_abort_reply		reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverAbort.\n");	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state == NDMP_MOVER_STATE_IDLE ||		session->mover.state == NDMP_MOVER_STATE_HALTED)	{		Error(LOG_ERR,			  "ndmpdMoverAbort: invalid state.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverAbort: error sending mover_abort reply.\n");		return;	}	reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverAbort: error sending mover_abort reply.\n");	ndmpdMoverError(session, NDMP_MOVER_HALT_ABORTED);}/* * ndmpdMoverStop * * This handler handles ndmp_mover_stop_requests. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverStop(NdmpConnection	connection,			   void*			body __attribute__ ((unused))){	ndmp_mover_stop_reply		reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverStop.\n");	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state != NDMP_MOVER_STATE_HALTED)	{		Error(LOG_ERR,			  "ndmpdMoverStop: invalid state.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverStop: error sending mover_stop reply.\n");		return;	}	reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverStop: error sending mover_stop reply.\n");	ndmpdMoverCleanup(session);	ndmpdMoverInit(session);}/* * ndmpdMoverSetWindow * * This handler handles ndmp_mover_set_window_requests. *  * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverSetWindow(NdmpConnection	connection,					void*			body){	ndmp_mover_set_window_request*	request	=		(ndmp_mover_set_window_request*)body;	ndmp_mover_set_window_reply		reply;	NdmpdSession*					session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverSetWindow: offset:%llu length:%llu.\n",		  request->offset, request->length);	memset((void*)&reply, 0, sizeof(reply));		if (!(session->mover.state == NDMP_MOVER_STATE_LISTEN ||		  session->mover.state == NDMP_MOVER_STATE_PAUSED))	{		Error(LOG_ERR,			  "ndmpdMoverSetWindow: invalid state.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverSetWindow: error sending ndmp_mover_set_window_reply.\n");		return;	}	session->mover.windowOffset = quadToLongLong(request->offset);	session->mover.windowLength = quadToLongLong(request->length);	session->mover.position     = session->mover.windowOffset;		reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverSetWindow: error sending mover_set_window reply.\n");}/* * ndmpdMoverRead * * This handler handles ndmp_mover_read_requests. * If the requested offset is outside of the current window, * the mover is paused and a notify_mover_paused request is sent  * notifying the client that a seek is required. * If the requested offest is within the window but not within the * current record, then the tape is positioned to the record containing * the requested offest. * The requested amount of data is then read from the tape device and * written to the data connection. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverRead(NdmpConnection	connection,			   void*			body){	ndmp_mover_read_request*	request	=		(ndmp_mover_read_request*)body;	ndmp_mover_read_reply		reply;	NdmpdSession*				session = ndmpGetClientData(connection);	int							err;		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverRead: offset:%llu len:%llu.\n",		  quadToLongLong(request->offset),		  quadToLongLong(request->length));	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state != NDMP_MOVER_STATE_ACTIVE ||		session->mover.bytesLeftToRead != 0 ||		session->mover.mode != NDMP_MOVER_MODE_WRITE)	{		Error(LOG_ERR,			  "ndmpdMoverRead: invalid state.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverRead: error sending ndmp_mover_read_reply.\n");		return;	}		if (session->tape.fd == -1)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -