📄 simple_dump.c
字号:
/* -*- Mode: C -*- * simple_dump.c * * Description : Simple dump functions. * * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: simple_dump.c,v 1.9 1998/05/26 03:52:22 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: simple_dump.c,v 1.9 1998/05/26 03:52:22 tim Exp $";#endif#include <sys/param.h>#include <sys/types.h>#include <sys/mman.h>#include <errno.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include <string.h>#include "simple_private.h"#include "log.h"typedef struct DumpInfo{ SimpleParams *params; char* path; bool_t fileHistory;} DumpInfo;static intdumpFile(DumpInfo* dmpInfo, char* path);static intdumpDirectory(DumpInfo* dmpInfo, char* path);static intwriteFile(DumpInfo* dmpInfo, char* path, off_t size);static intwriteLink(DumpInfo* dmpInfo, char* path);/* * simpleDump * Implements a simple dump. * For each file, file status, the file name, and the file * data (regular files only) is written to tape. * File history data is generated for each file dumped. * * Parameters: * params (input) - dump parameters. * * Returns: * 0 - success. * -1 - failure. */intsimpleDump(SimpleParams* params){ int err; DumpInfo info; char* var_str; NdmpdModuleParams* modParams = params->modParams; struct stat fileStat; char cwd[MAXPATHLEN+1]; info.params = params; info.path = (*modParams->getEnvFunc)(modParams->daemonCookie, "FILESYSTEM"); if (info.path == 0) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: Required environment variable:%s not specified.\n", "FILESYSTEM"); return(EINVAL); } if (info.path[0] != '/') { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: relative dump path not allowed.\n"); return(EINVAL); } if (stat(info.path, &fileStat) < 0) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: stat %s: %s.\n", info.path, strerror(errno)); return(EINVAL); } if ((fileStat.st_mode & S_IFMT) != S_IFDIR) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: %s is not a directory.\n", info.path); return(EINVAL); } (void)getcwd(cwd, sizeof(cwd)); if (chdir(info.path) < 0) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: can't chdir to %s.\n", info.path); return(EINVAL); } var_str = (*modParams->getEnvFunc)(modParams->daemonCookie, "HIST"); if (var_str) { if (var_str[0] == 't' || var_str[0] == 'T' || var_str[0] == 'y' || var_str[0] == 'Y') info.fileHistory = TRUE; else info.fileHistory = FALSE; } else info.fileHistory = FALSE; (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: dumping %s.\n", info.path); err = dumpFile(&info, "."); if (err == 0) { /* Mark the end of the dump with a zerod file status structure. */ memset((void*)&fileStat, 0, sizeof(fileStat)); err = (*modParams->writeFunc)(modParams->daemonCookie, (char*)&fileStat, sizeof(fileStat)); if (err == 0) { modParams->stats->bytesProcessed += sizeof(fileStat); /* Flush buffered data to tape. */ err = (modParams->writeFunc)(modParams->daemonCookie, 0, 0); } } if (err) (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: aborted.\n"); else (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: successfully completed.\n"); (void)chdir(cwd); return(err);}static intdumpFile(DumpInfo* dmpInfo, char* path){ struct stat fileStat; u_long pathLen; u_longlong_t fh_info; NdmpdModuleParams* modParams = dmpInfo->params->modParams; Debug(DBG_CAT_BACKUP|DBG_FOC_DETAIL, "dumpFile: dumping %s.\n", path); if (lstat(path, &fileStat) < 0) { Error(LOG_ERR, "dumpFile: lstat error: %s.\n", strerror(errno)); (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: lstat(%s): %s.\n", path, strerror(errno)); return(0); } if ((fileStat.st_mode & S_IFMT) == S_IFREG) { /* * Catch access errors before writing the file meta data. * This eliminates the need to perform recovery if the meta * data is written and then the file data can not be written. */ if (access(path, R_OK) < 0) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: accessing %s: %s.\n", path, strerror(errno)); return(0); } } /* Record the current data stream position for use in file history. */ fh_info = modParams->stats->bytesProcessed; /* * Write the file status data to tape. */ if ((*modParams->writeFunc)(modParams->daemonCookie, (char*)&fileStat, sizeof(fileStat)) < 0) return(-1); modParams->stats->bytesProcessed += sizeof(fileStat); /* * Write the file name length to tape. */ pathLen = strlen(path); if ((*modParams->writeFunc)(modParams->daemonCookie, (char*)&pathLen, sizeof(pathLen)) < 0) return(-1); modParams->stats->bytesProcessed += sizeof(pathLen); /* * Write the file name to tape. */ if ((*modParams->writeFunc)(modParams->daemonCookie, path, pathLen) < 0) return(-1); modParams->stats->bytesProcessed += pathLen; /* * Write the file data to tape. */ if ((fileStat.st_mode & S_IFMT) == S_IFREG) { if (writeFile(dmpInfo, path, fileStat.st_size) < 0) return(-1); } else if ((fileStat.st_mode & S_IFMT) == S_IFLNK) { if (writeLink(dmpInfo, path) < 0) return(-1); } if (dmpInfo->fileHistory) (*modParams->fileHistoryFileFunc)(modParams->daemonCookie, path, &fileStat, fh_info); if ((fileStat.st_mode & S_IFMT) == S_IFDIR) return(dumpDirectory(dmpInfo, path)); return(0);}static intdumpDirectory(DumpInfo* dmpInfo, char* dirpath){ DIR* dir; struct dirent* dirp; int err; char path[MAXPATHLEN]; u_long dirpathlen; NdmpdModuleParams* modParams = dmpInfo->params->modParams; Debug(DBG_CAT_BACKUP|DBG_FOC_DETAIL, "dumpDirectory: dumping %s.\n", dirpath); /* * Give the daemon a chance to process any pending requests, * one of which may be an abort request. */ (*modParams->dispatchFunc)(modParams->daemonCookie, FALSE); if (dmpInfo->params->abortFlag == TRUE) return(EINTR); if ((dir = opendir(dirpath)) == 0) { Error(LOG_ERR, "dumpDirectory: opendir(%s) error: %s.\n", dirpath, strerror(errno)); (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: opendir(%s): %s.\n", path, strerror(errno)); return(0); } strcpy(path, dirpath); dirpathlen = strlen(dirpath); path[dirpathlen++] = '/'; while ((dirp = readdir(dir)) != 0) { if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) continue; if (strlen(dirp->d_name) + dirpathlen > MAXPATHLEN) { Error(LOG_ERR, "dumpDirectory: MAXPATHLEN exceeded; %s/%s not dumped.\n", dirpath, dirp->d_name); continue; } strcpy(&path[dirpathlen], dirp->d_name); err = dumpFile(dmpInfo, path); if (err != 0) { (void)closedir(dir); return(err); } } (void)closedir(dir); return(0);}static intwriteFile(DumpInfo* dmpInfo, char* path, off_t size){ int fd; caddr_t addr; int err; NdmpdModuleParams* modParams = dmpInfo->params->modParams; if (size == 0) return(0); fd = open(path, O_RDONLY); if (fd < 0) { Error(LOG_ERR, "writeFile: error opening: %s: %s.\n", path, strerror(errno)); (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: opening %s: %s.\n", path, strerror(errno)); return(-1); } addr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { Error(LOG_ERR, "writeFile: error mapping: %s: %s.\n", path, strerror(errno)); (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: mapping %s: %s.\n", path, strerror(errno)); close(fd); return(-1); } err = (*modParams->writeFunc)(modParams->daemonCookie, (char*)addr, size); if (err == 0) modParams->stats->bytesProcessed += size; close(fd); munmap(addr, size); return(err);}/* * writeLink * Write symbolic link data to tape. The data consists of the * link name. * * Parameters: * dmpInfo (input) - info pointer. * path (input) - symbolic link path. * * Returns: * 0 - success. * -1 - error */static intwriteLink(DumpInfo* dmpInfo, char* path){ char buf[MAXPATHLEN]; int n; NdmpdModuleParams* modParams = dmpInfo->params->modParams; n = readlink(path, buf, sizeof(buf)); if (n < 0) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: reading link %s: %s.\n", path, strerror(errno)); return(-1); } /* * Write the link name to tape. */ if ((*modParams->writeFunc)(modParams->daemonCookie, buf, n) < 0) { (*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0, "Dump: ERROR: writing link name: %s: %s.\n", path, strerror(errno)); return(-1); } modParams->stats->bytesProcessed += n; return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -