📄 file_history.c
字号:
/* -*- Mode: C -*- * file_history.c * * Description : File history callback functions called by backup modules. * NDMP file history supports 2 file history models: * path based and inode/directory based. * Backup/recover modules similar to unix dump/restore * utilize the inode/directory based model. * During the filesystem scan pass, NdmpdFileHistoryDir() is * called. During the file backup pass, * NdmpdFileHistoryNode() is called. This model is * appropriate for modules whose code is structured such * that file name and file attribute data is not available * at the same time. * Backup/recover modules similar to tar or cpio utilize * the path based model. The simple dump/restore module * included with the SDK uses the path based model. * * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: file_history.c,v 1.8 1998/05/26 03:52:16 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: file_history.c,v 1.8 1998/05/26 03:52:16 tim Exp $";#endif#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include "ndmpd.h"#define N_FILE_ENTRIES 1000#define N_DIR_ENTRIES 1000#define N_NODE_ENTRIES 1000/* Figure an average of 32 bytes per path name */#define FILE_NAME_BUF_SIZE (N_FILE_ENTRIES * 32)/* Figure an average of 16 bytes per file name */#define DIR_NAME_BUF_SIZE (N_DIR_ENTRIES * 16)/* * ndmpdFileHistoryInit * Initialize file history variables. * Note that the entry and name buffers are not allocated here. * Since it is not known if the backup module will be sending file history * data or what kind of data (path or dir/node), the entry and name * buffers are not allocated until the first call to one of the file history * entry functions is made. This way resources are only allocated as * needed. * * Parameters: * session (input) - session pointer. * * Returns: * void */voidndmpdFileHistoryInit(NdmpdSession* session){ session->fh.files = 0; session->fh.dirs = 0; session->fh.nodes = 0; session->fh.fileNames = 0; session->fh.dirNames = 0; session->fh.fileStats = 0; session->fh.nodeStats = 0; session->fh.fileNameBuf = 0; session->fh.dirNameBuf = 0; session->fh.fileIndex = 0; session->fh.dirIndex = 0; session->fh.nodeIndex = 0; session->fh.fileNameBufIndex = 0; session->fh.dirNameBufIndex = 0;}/* * ndmpdFileHistoryCleanup * Send (or discard) any buffered file history entries. * * Parameters: * session (input) - session pointer. * sendFlag (input) - if TRUE buffered entries are sent. * if FALSE buffered entries are discarded. * * Returns: * void */voidndmpdFileHistoryCleanup(NdmpdSession* session, bool_t sendFlag){ if (sendFlag == TRUE) { ndmpdApiFileHistoryFile(session, 0, 0, 0); ndmpdApiFileHistoryDir(session, 0, 0, 0); ndmpdApiFileHistoryNode(session, 0, 0, 0); } if (session->fh.files != 0) { free((void*)session->fh.files); session->fh.files = 0; } if (session->fh.dirs != 0) { free((void*)session->fh.dirs); session->fh.dirs = 0; } if (session->fh.nodes != 0) { free((void*)session->fh.nodes); session->fh.nodes = 0; } if (session->fh.fileNames != 0) { free((void*)session->fh.fileNames); session->fh.fileNames = 0; } if (session->fh.dirNames != 0) { free((void*)session->fh.dirNames); session->fh.dirNames = 0; } if (session->fh.fileStats != 0) { free((void*)session->fh.fileStats); session->fh.fileStats = 0; } if (session->fh.nodeStats != 0) { free((void*)session->fh.nodeStats); session->fh.nodeStats = 0; } if (session->fh.fileNameBuf != 0) { free((void*)session->fh.fileNameBuf); session->fh.fileNameBuf = 0; } if (session->fh.dirNameBuf != 0) { free((void*)session->fh.dirNameBuf); session->fh.dirNameBuf = 0; } session->fh.fileIndex = 0; session->fh.dirIndex = 0; session->fh.nodeIndex = 0; session->fh.fileNameBufIndex = 0; session->fh.dirNameBufIndex = 0;}/* * ndmpdApiFileHistoryFIle * Add a file history file entry to the buffer. * History data is buffered until the buffer is filled. * Full buffers are then sent to the client. * * Parameters: * cookie (input) - session pointer. * name (input) - file name. * NULL forces buffered data to be sent. * fileStat (input) - file status pointer. * fh_info (input) - data stream position of file data used during * fast restore. * * Returns: * 0 - success * -1 - error */intndmpdApiFileHistoryFile(void *cookie, char *name, struct stat *fileStat, u_longlong_t fh_info){ NdmpdSession* session = (NdmpdSession *)cookie; ndmp_file* fileEntry; ndmp_file_name* fileNameEntry; ndmp_file_stat* fileStatEntry; Debug(DBG_CAT_HISTORY|DBG_FOC_FLOW, "ndmpdApiFileHistoryFile: name:%s\n", name == 0 ? "nil" : name); if (name == 0 && session->fh.fileIndex == 0) return(0); /* * If the buffer does not have space * for the current entry, send the buffered data to the client. * A NULL name indicates that any buffered data should be sent. */ if (name == 0 || session->fh.fileIndex == N_FILE_ENTRIES || session->fh.fileNameBufIndex + strlen(name) + 1 > FILE_NAME_BUF_SIZE) { ndmp_fh_add_file_request request; Debug(DBG_CAT_HISTORY|DBG_FOC_FLOW, "ndmpdApiFileHistoryFile: sending %ld entries\n", session->fh.fileIndex); request.files.files_len = session->fh.fileIndex; request.files.files_val = session->fh.files; if (ndmpSendRequest(session->connection, NDMP_FH_ADD_FILE, NDMP_NO_ERR, (void *)&request, 0) < 0) { Error(LOG_ERR, "ndmpdApiFileHistoryFile: error sending ndmp_fh_add_file_request.\n"); return(-1); } session->fh.fileIndex = 0; session->fh.fileNameBufIndex = 0; } if (name == 0) return(0); if (session->fh.files == 0) { session->fh.files = (ndmp_file*)malloc(N_FILE_ENTRIES * sizeof(ndmp_file)); if (session->fh.files == 0) { Error(LOG_ERR, "ndmpdApiFileHistoryFile: malloc error: %s.\n", strerror(errno)); return(-1); } } if (session->fh.fileNames == 0) { session->fh.fileNames = (ndmp_file_name*)malloc(N_FILE_ENTRIES * sizeof(ndmp_file_name)); if (session->fh.fileNames == 0) { Error(LOG_ERR, "ndmpdApiFileHistoryFile: malloc error: %s.\n", strerror(errno)); return(-1); } } if (session->fh.fileNameBuf == 0) { session->fh.fileNameBuf = (char*)malloc(FILE_NAME_BUF_SIZE); if (session->fh.fileNameBuf == 0) { Error(LOG_ERR, "ndmpdApiFileHistoryFile: malloc error: %s.\n", strerror(errno)); return(-1); } } if (session->fh.fileStats == 0) { session->fh.fileStats = (ndmp_file_stat*)malloc(N_FILE_ENTRIES * sizeof(ndmp_file_stat)); if (session->fh.fileStats == 0) { Error(LOG_ERR, "ndmpdApiFileHistoryFile: malloc error: %s.\n", strerror(errno)); return(-1); } } fileEntry = &session->fh.files[session->fh.fileIndex]; fileNameEntry = &session->fh.fileNames[session->fh.fileIndex]; fileStatEntry = &session->fh.fileStats[session->fh.fileIndex]; fileEntry->names.names_len = 1; fileEntry->names.names_val = fileNameEntry; fileEntry->stats.stats_len = 1; fileEntry->stats.stats_val = fileStatEntry; fileEntry->node = longLongToQuad(fileStat->st_ino); fileEntry->fh_info = longLongToQuad(fh_info); fileNameEntry->fs_type = NDMP_FS_UNIX; fileNameEntry->ndmp_file_name_u.unix_name = &session->fh.fileNameBuf[session->fh.fileNameBufIndex]; strcpy(&session->fh.fileNameBuf[session->fh.fileNameBufIndex], name); session->fh.fileNameBufIndex += strlen(name) + 1; switch (fileStat->st_mode & S_IFMT) { case S_IFIFO: fileStatEntry->ftype = NDMP_FILE_FIFO; break; case S_IFCHR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -