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

📄 mover.c

📁 网络数据管理协议的开发
💻 C
📖 第 1 页 / 共 4 页
字号:
		Error(LOG_ERR,			  "ndmpdMoverRead: 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,				  "ndmpdMoverRead: error sending ndmp_mover_read_reply.\n");		return;	}			reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverRead: error sending ndmp_mover_read_reply.\n");	err = ndmpdMoverSeek(session,						 quadToLongLong(request->offset),						 quadToLongLong(request->length));	if (err < 0)	{		ndmpdMoverError(session, NDMP_MOVER_HALT_INTERNAL_ERROR);		return;	}		/*	 * Just return if we are waiting for the NDMP client to	 * complete the seek.	 */	if (err == 1)		return;		/*	 * Setup a handler function that will be called when	 * data can be written to the data connection without blocking.	 */	if (ndmpdAddFileHandler(session, (void*)session,							session->mover.sock,							NDMPD_SELECT_MODE_WRITE,							HC_MOVER,							moverDataWrite) < 0)	{		ndmpdMoverError(session, NDMP_MOVER_HALT_INTERNAL_ERROR);		return;	}}/* * ndmpdMoverClose * * This handler handles ndmp_mover_close_requests. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverClose(NdmpConnection	connection,				void*			body __attribute__ ((unused))){	ndmp_mover_close_reply		reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverClose.\n");	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state != NDMP_MOVER_STATE_PAUSED)	{		Error(LOG_ERR,			  "ndmpdMoverClose: invalid state.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,			  "ndmpdMoverClose: error sending mover_close reply.\n");		return;	}	reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverClose: error sending mover_close reply.\n");	ndmpdMoverError(session, NDMP_MOVER_HALT_CONNECT_CLOSED);}/* * ndmpdMoverSetRecordSize * * This handler handles ndmp_mover_set_record_size_requests. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverSetRecordSize(NdmpConnection	connection,						void*			body){	ndmp_mover_set_record_size_request*	request	=		(ndmp_mover_set_record_size_request*)body;	ndmp_mover_set_record_size_reply	reply;	NdmpdSession*					session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverSetRecordSize: len:%llu.\n",		  request->len);	memset((void*)&reply, 0, sizeof(reply));		session->mover.recordSize = request->len;	reply.error = NDMP_NO_ERR;	if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverSetRecordSize: error sending ndmp_mover_set_record_size_reply.\n");}/* * ndmpdMoverConnect *   Request handler. Connects the mover to either a local *   or remote data server. * * Parameters: *   connection (input) - connection handle. *   body       (input) - request message body. * * Returns: *   void */voidndmpdMoverConnect(NdmpConnection	connection,				  void*				body){	ndmp_mover_connect_request*	request 		= (ndmp_mover_connect_request*)body;	ndmp_mover_connect_reply	reply;	NdmpdSession*				session = ndmpGetClientData(connection);		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdMoverConnect: mode:%s type:%s.\n",		  request->mode == NDMP_MOVER_MODE_READ ? "READ" : "WRITE",		  request->addr.addr_type == NDMP_ADDR_LOCAL ? "LOCAL" :		  request->addr.addr_type == NDMP_ADDR_TCP ? "TCP" :		  request->addr.addr_type == NDMP_ADDR_FC ? "FC" :		  request->addr.addr_type == NDMP_ADDR_IPC ? "IPC" :		  "undefined");	memset((void*)&reply, 0, sizeof(reply));		if (session->mover.state != NDMP_MOVER_STATE_IDLE)	{		Error(LOG_ERR,			  "ndmpdMoverConnect: invalid state to process connect request.\n");		reply.error = NDMP_ILLEGAL_STATE_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverConnect: error sending ndmp_mover_connect_reply.\n");		return;	}	if (session->tape.fd == -1)	{		Error(LOG_ERR,			  "ndmpdMoverConnect: no tape device open.\n");		reply.error = NDMP_DEV_NOT_OPEN_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverConnect: error sending ndmp_mover_connect_reply.\n");		return;	}		if (request->mode == NDMP_MOVER_MODE_READ &&		session->tape.mode == NDMP_TAPE_READ_MODE)	{		Error(LOG_ERR,			  "ndmpdMoverConnect: write protected device.\n");		reply.error = NDMP_WRITE_PROTECT_ERR;		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)			Error(LOG_ERR,				  "ndmpdMoverConnect: error sending ndmp_mover_connect_reply.\n");		return;	}	reply.error = NDMP_NO_ERR;	switch (request->addr.addr_type)	{		case NDMP_ADDR_LOCAL:		{			/* Verify that the data server is listening for a local connection */			if (session->data.state != NDMP_DATA_STATE_LISTEN ||				session->data.listenSock != -1)			{				Error(LOG_ERR,					  "ndmpdMoverConnect: data server is not in local listen state.\n");				reply.error = NDMP_ILLEGAL_STATE_ERR;				break;			}			session->data.state = NDMP_DATA_STATE_CONNECTED;			break;		}		case NDMP_ADDR_TCP:		{			struct sockaddr_in	sin;			int					sock;			int					flags;					memset((void*)&sin, 0, sizeof(sin));			sin.sin_family      = AF_INET;			sin.sin_addr.s_addr = htonl(request->addr.ndmp_addr_u.tcp_addr.ip_addr);			sin.sin_port        = htons(request->addr.ndmp_addr_u.tcp_addr.port);			Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,				  "ndmpdMoverConnect: addr:%s port:%u\n",				  inet_ntoa(sin.sin_addr),				  (u_long)sin.sin_port);			if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)			{				Error(LOG_ERR, "ndmpdMoverConnect: socket error: %s\n",					  strerror(errno));				reply.error = NDMP_CONNECT_ERR;				break;			}			if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)			{				Error(LOG_ERR, "ndmpdMoverConnect: connect error: %s\n",					  strerror(errno));				close(sock);				reply.error = NDMP_CONNECT_ERR;				break;			}			/*			 * Set the O_NDELAY flag on the socket to prevent			 * reads and writes from blocking.			 */			if ((flags = fcntl(sock, F_GETFL)) < 0)			{				Error(LOG_ERR, "ndmpdMoverConnect: fcntl(F_GETFL) error: %s.\n",					  strerror(errno));				close(sock);				reply.error = NDMP_CONNECT_ERR;				break;			}					if ((flags = fcntl(sock,							   F_SETFL, flags|O_NDELAY|O_NONBLOCK)) < 0)			{				Error(LOG_ERR, "ndmpdMoverConnect: fcntl(F_SETFL) error: %s.\n",					  strerror(errno));				close(sock);				reply.error = NDMP_CONNECT_ERR;				break;			}			if (request->mode == NDMP_MOVER_MODE_READ)			{				if (ndmpdAddFileHandler(session, (void*)session,										sock,										NDMPD_SELECT_MODE_READ,										HC_MOVER,										moverDataRead) < 0)				{					close(sock);					reply.error = NDMP_CONNECT_ERR;					break;				}			}				session->mover.sock = sock;			break;		}		default:		{			Error(LOG_ERR,				  "ndmpdMoverConnect: invalid address type.\n");			reply.error = NDMP_ILLEGAL_ARGS_ERR;			break;		}	}		if (reply.error == NDMP_NO_ERR)	{		session->mover.state = NDMP_MOVER_STATE_ACTIVE;		session->mover.mode  = request->mode;	}		if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0)		Error(LOG_ERR,			  "ndmpdMoverConnect: error sending ndmp_mover_listen_reply.\n");}/* * ndmpdLocalWrite *   Buffers and writes data to the tape device. *   A full tape record is buffered before being written. * * Parameters: *   session    (input) - session pointer. *   data       (input) - data to be written. *   length     (input) - data length. * * Returns: *   0 - data successfully written. *  -1 - error. */intndmpdLocalWrite(NdmpdSession*	session,				char*			data,				u_long			length){	u_long			count = 0;	ssize_t			n;	u_long			len;		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdLocalWrite: length:%u\n", length);	if (session->mover.state == NDMP_MOVER_STATE_IDLE ||		session->mover.state == NDMP_MOVER_STATE_LISTEN ||		session->mover.state == NDMP_MOVER_STATE_HALTED)	{		Error(LOG_ERR,			  "ndmpdLocalWrite: invalid mover state to write data.\n");		return(-1);	}		/*	 * A length of 0 indicates that any buffered data should be	 * flushed to tape.	 */	if (length == 0)	{		if (session->mover.wIndex == 0)			return(0);		memset((void*)&session->mover.buf[session->mover.wIndex],			   0, session->mover.recordSize - session->mover.wIndex);		n = moverTapeWrite(session,					  session->mover.buf,					  session->mover.recordSize);		if (n <= 0)		{			ndmpdMoverError(session, (n == 0 ? NDMP_MOVER_HALT_ABORTED									  : NDMP_MOVER_HALT_INTERNAL_ERROR));			return(-1);		}				session->mover.dataWritten += n;		session->mover.recordNum++;		session->mover.wIndex = 0;		return(0);	}		/* Break the data into records. */	while (count < length)	{		/*		 * Determine if data needs to be buffered or		 * can be written directly from user supplied location.		 * We can fast path the write if there is no pending		 * buffered data and there is at least a full records worth		 * of data to be written.		 */		if (session->mover.wIndex == 0 &&			length - count >= session->mover.recordSize)		{			n = moverTapeWrite(session, &data[count],						  session->mover.recordSize);			if (n <= 0)			{				ndmpdMoverError(session, (n == 0 ? NDMP_MOVER_HALT_ABORTED										  : NDMP_MOVER_HALT_INTERNAL_ERROR));				return(-1);			}						session->mover.dataWritten += n;			session->mover.recordNum++;			count += n;			continue;		}		/* Buffer the data */		len = length - count;		if (len > session->mover.recordSize - session->mover.wIndex)			len = session->mover.recordSize - session->mover.wIndex;				memcpy(&session->mover.buf[session->mover.wIndex],			   &data[count], len);		session->mover.wIndex += len;		count += len;		/* Write the buffer if its full */		if (session->mover.wIndex == session->mover.recordSize)		{			n = moverTapeWrite(session,						  session->mover.buf,						  session->mover.recordSize);			if (n < 0)			{				ndmpdMoverError(session, (n == 0 ? NDMP_MOVER_HALT_ABORTED										  : NDMP_MOVER_HALT_INTERNAL_ERROR));				return(-1);			}						session->mover.dataWritten += n;			session->mover.recordNum++;			session->mover.wIndex = 0;		}	}	return(0);}/* * ndmpdLocalRead *   Reads data from the local tape device. *   Full tape records are read and buffered. * * Parameters: *   session (input) - session pointer. *   data    (input) - location to store data. *   length  (input) - data length. * * Returns: *   0 - data successfully read. *  -1 - error. */intndmpdLocalRead(NdmpdSession*	session,			   char*			data,			   u_long			length){	u_long			count = 0;	ssize_t			n;	u_long			len;		Debug(DBG_CAT_MOVER|DBG_FOC_FLOW,		  "ndmpdLocalRead: length:%u\n", length);	if (session->mover.state == NDMP_MOVER_STATE_IDLE ||		session->mover.state == NDMP_MOVER_STATE_LISTEN ||		session->mover.state == NDMP_MOVER_STATE_HALTED)	{		Error(LOG_ERR,			  "ndmpdLocalRead: invalid mover state to read data.\n");		return(-1);	}		/*	 * Automatically increase the seek window if necessary.	 * This is needed in the event the module attempts to read	 * past a seek window set via a prior call to ndmpdSeek() or	 * the module has not issued a seek. If no seek was issued then	 * pretend that a seek was issued to read the entire tape.	 */	if (length > session->mover.bytesLeftToRead)	{		/* ndmpdSeek() never called? */		if (session->data.readLength == 0)		{			session->mover.bytesLeftToRead = ~0LL;			session->data.readOffset       = 0LL;			session->data.readLength       = ~0LL;		}		else		{			session->mover.bytesLeftToRead = length;			session->data.readOffset       = session->mover.position;			session->data.readLength       = length;		}	}	/*	 * Read as many records as necessary to satisfy the request.	 */	while (count < length)	{		/*		 * If the end of the mover window has been reached,		 * then notify the client that a new data window is needed.		 */		if (session->mover.position >=			session->mover.windowOffset + session->mover.windowLength)		{			ndmp_notify_mover_paused_request	pauseRequest;			session->mover.state        = NDMP_MOVER_STATE_PAUSED;			session->mover.pauseReason  = NDMP_MOVER_PAUSE_SEEK;			pauseRequest.reason         = NDMP_MOVER_PAUSE_SEEK;			pauseRequest.seek_position  = longLongToQuad(session->mover.position);			if (ndmpSendRequest(session->connection, NDMP_NOTIFY_MOVER_PAUSED,								NDMP_NO_ERR, (void *)&pauseRequest, 0) < 0)

⌨️ 快捷键说明

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