📄 data.c
字号:
/* -*- Mode: C -*- * data.c * * Description : NDMP data request handler functions * * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: data.c,v 1.13 1998/05/26 03:52:15 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused))= "@(#) $Id: data.c,v 1.13 1998/05/26 03:52:15 tim Exp $";#endif#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <sys/utsname.h>#include <fcntl.h>#include <string.h>#include <sys/mman.h>#include "ndmp_common.h"#include "ndmpd.h"#include "module.h"#include "simple.h"static ndmp_errorstartBackup(NdmpdSession* session, char* bu_type, ndmp_pval* env_val, u_long env_len);static ndmp_errorstartRecover(NdmpdSession* session, char* bu_type, ndmp_pval* env_val, u_long env_len, ndmp_name* nlist_val, u_long nlist_len);static intdataListen(NdmpdSession* session, u_long *addr, u_short *port);static voiddataAcceptConnection(void* cookie, int fd, u_long mode);static voiddataReady(void* cookie, int fd, u_long mode);static intdiscardData(NdmpdSession* session, u_long length);/* * ndmpdDataGetState * Request handler. Returns current data state. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdDataGetState(NdmpConnection connection, void* body __attribute__ ((unused))){ ndmp_data_get_state_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataGetState: \n"); memset((void*)&reply, 0, sizeof(reply)); reply.error = NDMP_NO_ERR; reply.invalid = 0; reply.operation = session->data.operation; reply.state = session->data.state; reply.halt_reason = session->data.haltReason; reply.bytes_processed = longLongToQuad(session->data.module.stats.bytesProcessed); reply.est_bytes_remain = longLongToQuad(session->data.module.stats.estBytesRemaining); reply.est_time_remain = session->data.module.stats.estTimeRemaining; reply.data_connection_addr = session->data.moverAddr; reply.read_offset = longLongToQuad(session->data.readOffset); reply.read_length = longLongToQuad(session->data.readLength); if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataGetState: error sending ndmp_data_get_state_reply.\n");}/* * ndmpdDataStartBackup * Request handler. Starts a backup. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void. */voidndmpdDataStartBackup(NdmpConnection connection, void* body){ ndmp_data_start_backup_request* request = (ndmp_data_start_backup_request*)body; ndmp_data_start_backup_reply reply; NdmpdSession* session = ndmpGetClientData(connection); ndmp_error err; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataStartBackup: bu_type:%s\n", request->bu_type); memset((void*)&reply, 0, sizeof(reply)); err = startBackup(session, request->bu_type, request->env.env_val, request->env.env_len); /* * startBackup sends the reply if the backup is successfully started. * Otherwise, send the reply containing the error here. */ if (err != NDMP_NO_ERR) { reply.error = err; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataStartBackup: error sending data_start_backup reply.\n"); ndmpdDataCleanup(session); return; }}/* * ndmpdDataStartRecover * Request handler. Starts a restore. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void. */voidndmpdDataStartRecover(NdmpConnection connection, void* body){ ndmp_data_start_recover_request* request = (ndmp_data_start_recover_request*)body; ndmp_data_start_recover_reply reply; NdmpdSession* session = ndmpGetClientData(connection); ndmp_error err; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataStartRecover: bu_type:%s\n", request->bu_type); memset((void*)&reply, 0, sizeof(reply)); err = startRecover(session, request->bu_type, request->env.env_val, request->env.env_len, request->nlist.nlist_val, request->nlist.nlist_len); /* * startRecover sends the reply if the recover is successfully started. * Otherwise, send the reply containing the error here. */ if (err != NDMP_NO_ERR) { reply.error = err; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataStartRecover: error sending data_get_env reply.\n"); ndmpdDataCleanup(session); }}/* * ndmpdDataGetEnv * Request handler. Returns the environment variable array sent * with the backup request. This request may only be sent with * a backup operation is in progress. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void. */voidndmpdDataGetEnv(NdmpConnection connection, void* body __attribute__ ((unused))){ ndmp_data_get_env_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataGetEnv:\n"); memset((void*)&reply, 0, sizeof(reply)); if (session->data.operation != NDMP_DATA_OP_BACKUP) { Error(LOG_ERR, "ndmpdDataGetEnv: backup operation not active.\n"); reply.error = NDMP_ILLEGAL_STATE_ERR; reply.env.env_len = 0; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataGetEnv: error sending data_get_env reply.\n"); return; } reply.error = NDMP_NO_ERR; reply.env.env_len = session->data.envLen; reply.env.env_val = session->data.env; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataGetEnv: error sending ndmp_data_get_env_reply.\n");}/* * ndmpdDataStop * Request handler. Stops the current data operation. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void. */voidndmpdDataStop(NdmpConnection connection, void* body __attribute__ ((unused))){ ndmp_data_stop_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataStop:\n"); memset((void*)&reply, 0, sizeof(reply)); if (session->data.state != NDMP_DATA_STATE_HALTED) { Error(LOG_ERR, "ndmpdDataStop: invalid state to process stop request.\n"); reply.error = NDMP_ILLEGAL_STATE_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataStop: error sending ndmp_data_stop_reply.\n"); return; } ndmpdDataCleanup(session); ndmpdFileHistoryCleanup(session, FALSE); /* prepare for another data operation */ ndmpdDataInit(session); ndmpdFileHistoryInit(session); reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataStop: error sending ndmp_data_stop_reply.\n");}/* * ndmpdDataAbort * Request handler. Aborts the current backup/restore. The operation * state is not changed to the halted state until after the operation * has actually been aborted and the notify_halt request has been sent. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void. */voidndmpdDataAbort(NdmpConnection connection, void* body __attribute__ ((unused))){ ndmp_data_abort_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataAbort:\n"); memset((void*)&reply, 0, sizeof(reply)); if ((session->data.state == NDMP_DATA_STATE_IDLE || session->data.state == NDMP_DATA_STATE_HALTED)) { Error(LOG_ERR, "ndmpdDataAbort: invalid state to process abort request.\n"); reply.error = NDMP_ILLEGAL_STATE_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataAbort: error sending ndmp_data_abort_reply.\n"); return; } if (session->data.state == NDMP_DATA_STATE_ACTIVE) { /* * Don't go to HALTED state yet. Need to wait for data operation to * abort. When this happens, ndmpdDone will get called and will * perform the halt processing. */ session->data.abortFlag = TRUE; (*session->data.module.abortFunc)(session->data.module.moduleCookie); } else ndmpdDataError(session, NDMP_DATA_HALT_ABORTED); reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataAbort: error sending ndmp_data_abort_reply.\n");}/* * ndmpdDataListen * Request handler. Configures the server to listen for a connection * from a remote mover. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdDataListen(NdmpConnection connection, void* body){ ndmp_data_listen_request* request = (ndmp_data_listen_request*)body; ndmp_data_listen_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataListen: \n"); memset((void*)&reply, 0, sizeof(reply)); if (session->data.state != NDMP_DATA_STATE_IDLE) { Error(LOG_ERR, "ndmpdDataListen: 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, "ndmpdDataListen: error sending ndmp_data_listen_reply.\n"); return; } if (session->mover.state != NDMP_MOVER_STATE_IDLE) { Error(LOG_ERR, "ndmpdDataListen: 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, "ndmpdDataListen: error sending ndmp_data_listen_reply.\n"); return; } switch (request->addr_type) { case NDMP_ADDR_LOCAL: { reply.error = NDMP_NO_ERR; reply.data_connection_addr.addr_type = NDMP_ADDR_LOCAL; break; } case NDMP_ADDR_TCP: { u_long addr; u_short port; if (dataListen(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 = htonl(port); break; } default: { Error(LOG_ERR, "ndmpdDataListen: invalid address type: %d.\n", request->addr_type); reply.error = NDMP_ILLEGAL_ARGS_ERR; break; } } if (reply.error == NDMP_NO_ERR) { session->data.state = NDMP_DATA_STATE_LISTEN; session->data.moverAddr = reply.data_connection_addr; } if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdDataListen: error sending ndmp_data_listen_reply.\n");}/* * ndmpdDataConnect * Request handler. Connects the data server to either a local * or remote mover. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdDataConnect(NdmpConnection connection, void* body){ ndmp_data_connect_request* request = (ndmp_data_connect_request*)body; ndmp_data_connect_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdDataConnect: \n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -