📄 data.c
字号:
* env_len (input) - length of env_val. * * Returns: * NDMP_NO_ERR - backup successfully started. * otherwise - error code of backup start error. */static ndmp_errorstartBackup(NdmpdSession* session, char* bu_type, ndmp_pval* env_val, u_long env_len){ ndmp_data_start_backup_reply reply; NdmpdModuleParams params; int err; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "startBackup: bu_type:%s\n", bu_type); memset((void*)&reply, 0, sizeof(reply)); if (session->data.state != NDMP_DATA_STATE_CONNECTED) { Error(LOG_ERR, "startBackup: can't start new backup in current state.\n"); return(NDMP_ILLEGAL_STATE_ERR); } if (session->data.moverAddr.addr_type == NDMP_ADDR_LOCAL) { if (session->tape.mode == NDMP_TAPE_READ_MODE) { Error(LOG_ERR, "startBackup: write protected device.\n"); return(NDMP_WRITE_PROTECT_ERR); } } if (strcmp(bu_type, "dump") != 0) { Error(LOG_ERR, "startBackup: Invalid backup type:%s specified.\n", bu_type); return(NDMP_ILLEGAL_ARGS_ERR); } if ((err = ndmpdSaveEnv(session, env_val, env_len)) != NDMP_NO_ERR) { return(err); } params.daemonCookie = (void *)session; params.moduleCookie = &session->data.module.moduleCookie; params.protocolVersion = session->protocolVersion; params.operation = NDMP_DATA_OP_BACKUP; params.getEnvFunc = ndmpdApiGetEnv; params.addEnvFunc = ndmpdApiAddEnv; params.getNameFunc = ndmpdApiGetName; params.dispatchFunc = ndmpdApiDispatch; params.doneFunc = ndmpdApiDone; params.logFunc = ndmpdApiLog; params.addFileHandlerFunc = ndmpdApiAddFileHandler; params.removeFileHandlerFunc = ndmpdApiRemoveFileHandler; params.writeFunc = ndmpdApiWrite; params.fileHistoryFileFunc = ndmpdApiFileHistoryFile; params.fileHistoryDirFunc = ndmpdApiFileHistoryDir; params.fileHistoryNodeFunc = ndmpdApiFileHistoryNode; params.readFunc = 0; params.fileRecoveredFunc = 0; params.stats = &session->data.module.stats; session->data.module.moduleCookie = 0; session->data.module.startFunc = simpleStart; session->data.module.abortFunc = simpleAbort; session->data.module.stats.bytesProcessed = 0; session->data.module.stats.estBytesRemaining = 0; session->data.module.stats.estTimeRemaining = 0; session->data.nlist = 0; session->data.nlistLen = 0; session->data.readOffset = 0; session->data.readLength = 0; reply.error = NDMP_NO_ERR; if (ndmpSendReply(session->connection, NDMP_NO_ERR, (void *)&reply) < 0) { Error(LOG_ERR, "startBackup: error sending data_start_backup reply.\n"); return(NDMP_NO_ERR); } session->data.state = NDMP_DATA_STATE_ACTIVE; session->data.operation = NDMP_DATA_OP_BACKUP; session->data.abortFlag = FALSE; /* Perform the dump. */ err = (*session->data.module.startFunc)(¶ms); if (err != 0) ndmpdApiDone((void*)session, err); return(NDMP_NO_ERR);}/* * startRecover * * Parameters: * session (input) - session pointer. * bu_type (input) - backup type. * env_val (input) - environment variable array. * env_len (input) - length of env_val. * * Returns: * NDMP_NO_ERR - recover successfully started. * otherwise - error code of recover start error. */static ndmp_errorstartRecover(NdmpdSession* session, char* bu_type, ndmp_pval* env_val, u_long env_len, ndmp_name* nlist_val, u_long nlist_len){ ndmp_data_start_recover_reply reply; NdmpdModuleParams params; int err; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "startRecover: bu_type:%s\n", bu_type); memset((void*)&reply, 0, sizeof(reply)); if (session->data.state != NDMP_DATA_STATE_CONNECTED) { Error(LOG_ERR, "startRecover: can't start new recover in current state.\n"); return(NDMP_ILLEGAL_STATE_ERR); } if ((reply.error = ndmpdSaveEnv(session, env_val, env_len)) != NDMP_NO_ERR) { return(NDMP_NO_MEM_ERR); } if ((reply.error = ndmpdSaveNlist(session, nlist_val, nlist_len)) != NDMP_NO_ERR) { return(NDMP_NO_MEM_ERR); } reply.error = NDMP_NO_ERR; if (ndmpSendReply(session->connection, NDMP_NO_ERR, (void *)&reply) < 0) { Error(LOG_ERR, "startRecover: error sending ndmp_data_start_recover_reply.\n"); ndmpdDataError(session, NDMP_DATA_HALT_INTERNAL_ERROR); return(NDMP_NO_ERR); } /* * Setup restore parameters. */ params.daemonCookie = (void *)session; params.moduleCookie = &session->data.module.moduleCookie; params.protocolVersion = session->protocolVersion; params.operation = NDMP_DATA_OP_RESTORE; params.getEnvFunc = ndmpdApiGetEnv; params.addEnvFunc = ndmpdApiAddEnv; params.getNameFunc = ndmpdApiGetName; params.dispatchFunc = ndmpdApiDispatch; params.doneFunc = ndmpdApiDone; params.logFunc = ndmpdApiLog; params.addFileHandlerFunc = ndmpdApiAddFileHandler; params.removeFileHandlerFunc = ndmpdApiRemoveFileHandler; params.writeFunc = 0; params.fileHistoryFileFunc = 0; params.fileHistoryDirFunc = 0; params.fileHistoryNodeFunc = 0; params.readFunc = ndmpdApiRead; params.seekFunc = ndmpdApiSeek; params.fileRecoveredFunc = ndmpdApiFileRecovered; params.stats = &session->data.module.stats; session->data.module.moduleCookie = 0; session->data.module.startFunc = simpleStart; session->data.module.abortFunc = simpleAbort; session->data.module.stats.bytesProcessed = 0; session->data.module.stats.estBytesRemaining = 0; session->data.module.stats.estTimeRemaining = 0; session->data.readOffset = 0; session->data.readLength = 0; session->data.state = NDMP_DATA_STATE_ACTIVE; session->data.operation = NDMP_DATA_OP_RESTORE; session->data.abortFlag = FALSE; err = 0; /* Perform the restore. */ err = (*session->data.module.startFunc)(¶ms); if (err != 0) ndmpdApiDone((void*)session, err); return(NDMP_NO_ERR);}/* * dataListen * Creates a socket for listening for TCP/IP data connections * initiated by a remote mover. Configures the server to listen * and accept a connection. * * Parameters: * session (input) - session pointer. * addr (output) - location to store address of socket. * port (output) - location to store port of socket. * * Returns: * 0 - success. * -1 - error. */static intdataListen(NdmpdSession* session, u_long *addr, u_short *port){ struct hostent* hp; struct sockaddr_in sin; struct utsname uts; int length; if (uname(&uts) < 0) { Error(LOG_ERR, "dataListen: uname error: %s\n", strerror(errno)); return(-1); } if ((hp = gethostbyname(uts.nodename)) == 0) { Error(LOG_ERR, "dataListen: unknown host: %s\n", uts.nodename); return(-1); } *addr = ((struct in_addr*)(hp->h_addr))->s_addr; session->data.listenSock = socket(AF_INET, SOCK_STREAM, 0); if (session->data.listenSock < 0) { Error(LOG_ERR, "dataListen: socket error: %s.\n", strerror(errno)); return(-1); } sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = 0; if (bind(session->data.listenSock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { Error(LOG_ERR, "dataListen: bind error: %s.\n", strerror(errno)); (void)close(session->data.listenSock); session->data.listenSock = -1; return(-1); } length = sizeof(sin); if (getsockname(session->data.listenSock, (struct sockaddr *) &sin, &length) < 0) { Error(LOG_ERR, "dataListen: getsockname error: %s.\n", strerror(errno)); (void)close(session->data.listenSock); session->data.listenSock = -1; return(-1); } if (listen(session->data.listenSock, 5) < 0) { Error(LOG_ERR, "dataListen: listen error: %s.\n", strerror(errno)); (void)close(session->data.listenSock); session->data.listenSock = -1; return(-1); } /* * Add a file handler for the listen socket. * ndmpdSelect will call dataAcceptConnection when a * connection is ready to be accepted. */ if (ndmpdAddFileHandler(session, (void*)session, session->data.listenSock, NDMPD_SELECT_MODE_READ, HC_MOVER, dataAcceptConnection) < 0) { (void)close(session->data.listenSock); session->data.listenSock = -1; return(-1); } *port = sin.sin_port; return(0);}/* * dataAcceptConnection * Accept a data connection from a remote mover. * Called by ndmpdSelect when a connection is pending on * the data listen socket. * * Parameters: * cookie (input) - session pointer. * fd (input) - file descriptor. * mode (input) - select mode. * * Returns: * void. */static voiddataAcceptConnection(void* cookie, int fd, u_long mode __attribute__ ((unused))){ NdmpdSession* session = (NdmpdSession*)cookie; struct sockaddr_in from; int from_len = sizeof(from); int flags; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "dataAcceptConnection\n"); session->data.sock = accept(fd, (struct sockaddr *)&from, &from_len); (void)ndmpdRemoveFileHandler(session, fd); (void)close(session->data.listenSock); session->data.listenSock = -1; if (session->data.sock < 0) { Error(LOG_ERR, "dataAcceptConnection: accept error: %s.\n", strerror(errno)); ndmpdDataError(session, NDMP_DATA_HALT_CONNECT_ERROR); return; } /* * Set the O_NDELAY flag on the socket to prevent * reads and writes from blocking. */ if ((flags = fcntl(session->data.sock, F_GETFL)) < 0) { Error(LOG_ERR, "dataAcceptConnection: fcntl(F_GETFL) error: %s.\n", strerror(errno)); ndmpdDataError(session, NDMP_DATA_HALT_CONNECT_ERROR); return; } if ((flags = fcntl(session->data.sock, F_SETFL, flags|O_NDELAY|O_NONBLOCK)) < 0) { Error(LOG_ERR, "dataAcceptConnection: fcntl(F_SETFL) error: %s.\n", strerror(errno)); ndmpdDataError(session, NDMP_DATA_HALT_CONNECT_ERROR); return; } Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "dataAcceptConnection: Received connection from %s\n", inet_ntoa(from.sin_addr)); session->data.state = NDMP_DATA_STATE_CONNECTED;}/* * dataReady * File handler that is called when the data server side of * of the data connection is ready for I/O. * * Parameters: * cookie (input) - session pointer. * fd (input) - file descriptor. * mode (input) - select mode. * * Returns: * void. */static voiddataReady(void* cookie, int fd, u_long mode __attribute__ ((unused))){ NdmpdSession* session = (NdmpdSession*)cookie; Debug(DBG_CAT_MOVER|DBG_FOC_FLOW, "dataReady.\n"); session->data.ioReady = TRUE; (void)ndmpdRemoveFileHandler(session, fd);}/* * discardData * Read and discard data from the data connection. * Called when a module has called ndmpdSeek() prior to * reading all of the data from the previous seek. * * Parameters: * session (input) - session pointer. * * Returns: * number of bytes read and discarded. * -1 - error. */static intdiscardData(NdmpdSession* session, u_long length){ int fd; caddr_t addr; int n; if ((fd = open("/dev/zero", O_RDWR)) < 0) { Error(LOG_ERR, "discardData: error opening /dev/zero: %s.\n", strerror(errno)); return(-1); } addr = mmap(0, length, PROT_WRITE, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { Error(LOG_ERR, "discardData: error mapping /dev/zero: %s.\n", strerror(errno)); (void)close(fd); return(-1); } /* Read and discard the data. */ n = read(session->data.sock, addr, length); if (n < 0) { Error(LOG_ERR, "discardData: read error: %s.\n", strerror(errno)); (void)munmap(addr, length); (void)close(fd); return(-1); } (void)munmap(addr, length); (void)close(fd); return(n);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -