view release on metacpan or search on metacpan
BackupPC_XS.xs view on Meta::CPAN
* with this program; if not, visit the http://fsf.org website.
*/
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <backuppc.h>
typedef bpc_fileZIO_fd *BackupPC__XS__FileZIO;
typedef bpc_refCount_info *BackupPC__XS__PoolRefCnt;
typedef bpc_deltaCount_info *BackupPC__XS__DeltaRefCnt;
typedef bpc_poolWrite_info *BackupPC__XS__PoolWrite;
typedef bpc_attrib_dir *BackupPC__XS__Attrib;
typedef bpc_attribCache_info *BackupPC__XS__AttribCache;
#define hv_get_int(hv, key, value) { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvIV(*svp); }
#define hv_get_uint(hv, key, value) { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvUV(*svp); }
BackupPC_XS.xs view on Meta::CPAN
void
backwardCompat(writeOldStyleAttribFile, keepOldAttribFiles)
int writeOldStyleAttribFile;
int keepOldAttribFiles;
CODE:
bpc_attrib_backwardCompat(writeOldStyleAttribFile, keepOldAttribFiles);
MODULE = BackupPC::XS PACKAGE = BackupPC::XS::AttribCache
BackupPC::XS::AttribCache
new(host, backupNum, shareNameUM, compress)
char *host;
int backupNum;
char *shareNameUM;
int compress;
CODE:
{
RETVAL = calloc(1, sizeof(bpc_attribCache_info));
bpc_attribCache_init(RETVAL, host, backupNum, shareNameUM, compress);
}
OUTPUT:
RETVAL
void
DESTROY(ac)
BackupPC::XS::AttribCache ac;
CODE:
{
bpc_attribCache_destroy(ac);
0.62: June 20, 2020
- force rewrite of attr file if xattr key fixup was applied
- fixed attrib refCnt when attrib is unchanged
- bpc_attrib_dirWrite() doesn't create empty attrib files
0.61: June 8, 2020
- fix view of migrated v3 backup
- convert_hv2file() ensures xattr type is hash, and uses correct keyLen+1
- added BackupPC::XS::FileDigest::digest and bpc_fileDigest()
0.60: May 30, 2020
- allow mtime to be signed in attrib files
- added bpc_attrib_fileIterate() and BackupPC::XS::Attrib::iterate()
change in rsync-bpc and has no effect here since BackupPC::XS doesn't set
ac->currentDir[].
- bpc_attrib_dirWrite() updates dir->digest with new digest.
- updated configure.sh with package name and current version
0.57: Dec 2, 2017
- added BackupPC::XS::DirOps::refCountAllInodeMax() and bpc_path_refCountAllInodeMax() to allow
BackupPC_refCountAll to get the largest inode as the backup tree is traversed.
0.56: Jun 11, 2017
- change to Makefile.PL to ensure that parallel builds (make -j N) work with BSD make
(pull request #4 from Alexander Moisseev).
0.55: Jun 4, 2017
- updated Makefile.PL so ./configure is run before subdirs are built when parallel make (eg: make -j 4) is used
- updated config.guess and config.sub; fixes problem with aarch64 and ppc64le
reported by Denis Fateyev.
0.51: March 5, 2017
- added dynamic:: target to subdir Makefile.PLs to fix build issue on gentoo
(patch submitted by Slaven Rezic; see https://rt.cpan.org/Ticket/Display.html?id=120495)
0.50: March 3, 2017
- Reference counting is now per-backup; replaced static delta information with callable interface.
- Attribute files are now zero-length with the md5 digest encoded in the file name.
- several bug fixes
0.40: June 18, 2016
- Significant rewrite of bpc_hashTable.c so that resizing doesn't move the entries. The nodes are stored as pointers
(rather than flat); a freelist maintains unused nodes.
- Fixed bug triggered during certain smb transfers and tar/zip restore. Reported
by Steve Palm and Denis Jedig.
- Some clean up of perl RV/SV reference counting.
0.20: September 2, 2013
- BackupPC-XS-0.20/BackupPC_XS.xs: added lockRangeFd() and unlockRangeFd()
- BackupPC-XS-0.20/backuppc.h: changed BPC_POOL_WRITE_CONCURRENT_MATCH from 4 to 16
- BackupPC-XS-0.20/bpc_lib.c: bpc_lib_conf_init debug message now only logLevel >= 8
0.10: July 1, 2013
- BackupPC-XS-0.10/bpc_poolWrite.c: improved matching and redo logic
0.01: June 24, 2013
- original version; created by h2xs 1.23 with options
-A -n BackupPC-XS backuppc.h
MANIFEST
README
BackupPC_XS.xs
Changes
Makefile.PL
ppport.h
typemap
backuppc.h
bpc_attrib.c
bpc_attribCache.c
bpc_dirOps.c
bpc_fileDigest.c
bpc_fileZIO.c
bpc_hashtable.c
bpc_lib.c
bpc_poolWrite.c
bpc_refCount.c
byteorder.h
* reference counts.
*/
ushort isTemp;
uint32 mode;
uid_t uid;
gid_t gid;
uint32 nlinks;
time_t mtime;
OFF_T size;
ino_t inode;
int32 backupNum;
bpc_digest digest;
/*
* hash table of bpc_attrib_xattr entries, indexed by xattr key
*/
bpc_hashtable xattrHT;
} bpc_attrib_file;
/*
* A directory is a hash table of file attributes, indexed by file name
*/
int bpc_attrib_dirNeedRewrite(bpc_attrib_dir *dir);
ssize_t bpc_attrib_getEntries(bpc_attrib_dir *dir, char *entries, ssize_t entrySize);
void bpc_attrib_dirRefCount(bpc_deltaCount_info *deltaInfo, bpc_attrib_dir *dir, int incr);
void bpc_attrib_dirRefCountInodeMax(bpc_deltaCount_info *deltaInfo, bpc_attrib_dir *dir, int incr, unsigned int *inodeMax);
void bpc_attrib_attribFilePath(char *path, char *dir, char *attribFileName);
bpc_digest *bpc_attrib_dirDigestGet(bpc_attrib_dir *dir);
uchar *bpc_attrib_buf2file(bpc_attrib_file *file, uchar *buf, uchar *bufEnd, int xattrNumEntries, int *xattrFixup);
uchar *bpc_attrib_buf2fileFull(bpc_attrib_file *file, uchar *buf, uchar *bufEnd);
uchar *bpc_attrib_file2buf(bpc_attrib_file *file, uchar *buf, uchar *bufEnd);
int bpc_attrib_digestRead(bpc_attrib_dir *dir, bpc_digest *digest, char *attribPath);
int bpc_attrib_dirRead(bpc_attrib_dir *dir, char *dirPath, char *attribFileName, int backupNum);
int bpc_attrib_dirWrite(bpc_deltaCount_info *deltaInfo, bpc_attrib_dir *dir, char *dirPath, char *attribFileName, bpc_digest *oldDigest);
void bpc_attrib_backwardCompat(int writeOldStyleAttribFile, int keepOldAttribFiles);
/*
* Attrib caching
*/
#define BPC_FTYPE_FILE (0)
#define BPC_FTYPE_HARDLINK (1)
#define BPC_FTYPE_SYMLINK (2)
#define BPC_FTYPE_FIFO (6)
#define BPC_FTYPE_SOCKET (8)
#define BPC_FTYPE_UNKNOWN (9)
#define BPC_FTYPE_DELETED (10)
#define BPC_FTYPE_INVALID (11)
typedef struct {
int num;
int compress;
int version;
} bpc_backup_info;
typedef struct {
int backupNum;
int compress;
int readOnly;
uint cacheLruCnt;
/*
* optional merging of backups to create view for restore
*/
bpc_backup_info *bkupMergeList;
int bkupMergeCnt;
/*
* Hash table of cached file attributes.
* Key is the mangled attrib path (excluding backupTopDir[], and including attrib file name).
* Value is a bpc_attrib_dir structure.
* - Keys of the bpc_attrib_dir hash table are the file names in that directory.
*/
bpc_hashtable attrHT;
/*
* Hash table of cached inode attributes.
* Key is the inode attribute path (excluding backupTopDir[]).
* Value is a bpc_attrib_dir structure.
* - Keys of the bpc_attrib_dir hash table are the inode numbers converted to ascii hex, lsb first.
*/
bpc_hashtable inodeHT;
/*
* Delta reference count for any changes as we write/change files or attributes
*/
bpc_deltaCount_info *deltaInfo;
char shareName[BPC_MAXPATHLEN];
int shareNameLen;
char shareNameUM[BPC_MAXPATHLEN];
char hostName[BPC_MAXPATHLEN];
char hostDir[BPC_MAXPATHLEN];
char backupTopDir[BPC_MAXPATHLEN];
char currentDir[BPC_MAXPATHLEN];
} bpc_attribCache_info;
typedef struct {
bpc_hashtable_key key;
int dirty;
/*
* We flag directories whose parents either don't exist or aren't directories.
* We ignore attributes on bad directories.
* Initially this flag is zero, meaning we don't know if this directory is ok.
* After we check, > 0 means parent does exist and is a directory ; < 0 means dir is bad
*/
int dirOk;
uint lruCnt;
bpc_attrib_dir dir;
} bpc_attribCache_dir;
void bpc_attribCache_init(bpc_attribCache_info *ac, char *host, int backupNum, char *shareNameUM, int compress);
void bpc_attribCache_setDeltaInfo(bpc_attribCache_info *ac, bpc_deltaCount_info *deltaInfo);
void bpc_attribCache_setMergeList(bpc_attribCache_info *ac, bpc_backup_info *bkupList, int bkupCnt);
void bpc_attribCache_destroy(bpc_attribCache_info *ac);
int bpc_attribCache_readOnly(bpc_attribCache_info *ac, int readOnly);
void bpc_attribCache_setCurrentDirectory(bpc_attribCache_info *ac, char *dir);
bpc_attrib_file *bpc_attribCache_getFile(bpc_attribCache_info *ac, char *path, int allocate_if_missing, int dontReadInode);
int bpc_attribCache_setFile(bpc_attribCache_info *ac, char *path, bpc_attrib_file *file, int dontOverwriteInode);
int bpc_attribCache_deleteFile(bpc_attribCache_info *ac, char *path);
bpc_attrib_file *bpc_attribCache_getInode(bpc_attribCache_info *ac, ino_t inode, int allocate_if_missing);
int bpc_attribCache_setInode(bpc_attribCache_info *ac, ino_t inode, bpc_attrib_file *inodeSrc);
int bpc_attribCache_deleteInode(bpc_attribCache_info *ac, ino_t inode);
int bpc_attribCache_getDirEntryCnt(bpc_attribCache_info *ac, char *path);
ssize_t bpc_attribCache_getDirEntries(bpc_attribCache_info *ac, char *path, char *entries, ssize_t entrySize);
void bpc_attribCache_flush(bpc_attribCache_info *ac, int all, char *path);
void bpc_attribCache_getFullMangledPath(bpc_attribCache_info *ac, char *path, char *dirName, int backupNum);
#endif
bpc_attrib.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
/*
* Type of attribute file. This is saved as a magic number at the
* start of the file. This type is for V3 and earlier.
*/
#define BPC_ATTRIB_TYPE_UNIX (0x17555555)
/*
* super set of UNIX, including extended attribs and digest, for 4.x+
*/
#define BPC_ATTRIB_TYPE_XATTR (0x17565353)
/*
* starting in 4.x, attrib files in the pc backup tree are
* just digests that give the location of the real attrib file
* in the pool. attrib files written in the pc backup tree
* start with this magic number, followed by the digest.
*/
#define BPC_ATTRIB_TYPE_DIGEST (0x17585451)
static char *FileType2Text[] = {
"file",
"hardlink",
"symlink",
"chardev",
"blockdev",
bpc_attrib.c view on Meta::CPAN
fileDest->type = fileSrc->type;
fileDest->compress = fileSrc->compress;
fileDest->mode = fileSrc->mode;
fileDest->isTemp = fileSrc->isTemp;
fileDest->uid = fileSrc->uid;
fileDest->gid = fileSrc->gid;
fileDest->nlinks = fileSrc->nlinks;
fileDest->mtime = fileSrc->mtime;
fileDest->size = fileSrc->size;
fileDest->inode = fileSrc->inode;
fileDest->backupNum = fileSrc->backupNum;
if ( fileSrc->digest.len > 0 || overwriteEmptyDigest ) {
fileDest->digest = fileSrc->digest;
}
bpc_hashtable_iterate(&fileDest->xattrHT, (void*)bpc_attrib_xattrDestroy, NULL);
bpc_hashtable_erase(&fileDest->xattrHT);
bpc_hashtable_iterate(&fileSrc->xattrHT, (void*)bpc_attrib_xattrCopy, fileDest);
}
/*
* Copy all the attributes from fileSrc to fileDest. fileDest should already have a
bpc_attrib.c view on Meta::CPAN
bpc_attrib_xattrDeleteAll(file);
xattrNumEntries = getVarInt(&bufP, bufEnd);
if ( BPC_LogLevel >= 6 ) bpc_logMsgf("bpc_attrib_buf2fileFull: xattrNumEntries = %d\n", xattrNumEntries);
bufP = bpc_attrib_buf2file(file, bufP, bufEnd, xattrNumEntries, NULL);
return bufP;
}
/*
* Read the attribute file at dirPath/attribFilePath and populate dir
*/
int bpc_attrib_dirRead(bpc_attrib_dir *dir, char *dirPath, char *attribFilePath, int backupNum)
{
char attribPath[BPC_MAXPATHLEN];
bpc_fileZIO_fd fd;
size_t nRead;
uint32 magic = 0;
uchar buf[8 * 65536], *bufP;
STRUCT_STAT st;
char *p, *attribFileName;
bpc_attrib_attribFilePath(attribPath, dirPath, attribFilePath);
bpc_attrib.c view on Meta::CPAN
close(fdNum);
unlink(attribPath);
if ( BPC_LogLevel >= 4 ) bpc_logMsgf("bpc_attrib_dirRead: replaced %s with %s\n",
attribPath, attribPathNew);
}
}
if ( dir->digest.len > 0 ) {
/*
* Handle V4+ case - open the pool file directly
* For V3, digest.len == 0 since we opened the attrib file above (it is stored hardlinked in the backup
* directory; there is no digest)
*/
bpc_digest_md52path(attribPath, dir->compress, &dir->digest);
if ( bpc_fileZIO_open(&fd, attribPath, 0, dir->compress) ) {
bpc_logErrf("bpc_attrib_dirRead: can't open %s\n", attribPath);
return -1;
}
nRead = bpc_fileZIO_read(&fd, buf, sizeof(buf));
if ( nRead < 4 ) {
bpc_logErrf("bpc_attrib_dirRead: can't read at least 4 bytes from %s\n", attribPath);
bpc_attrib.c view on Meta::CPAN
* After we consume the next varint, we can safely NULL-terminate
* the fileName, which allows us to look up or create the file entry.
*/
fileName = (char*)bufP;
bufP += fileNameLen;
xattrNumEntries = getVarInt(&bufP, buf + nRead);
fileName[fileNameLen] = '\0';
file = bpc_attrib_fileGet(dir, fileName, 1);
bpc_attrib_fileInit(file, fileName, xattrNumEntries);
file->backupNum = backupNum;
bufP = bpc_attrib_buf2file(file, bufP, buf + nRead, xattrNumEntries, &xattrFixup);
dir->needRewrite |= xattrFixup;
if ( bufP > buf + nRead ) {
/*
* Need to get more data and try again. We have allocated file->name,
* and perhaps partially filled the xattr structure, which will be ok
* on the retry since the same structure will be used.
*/
if ( retry ) {
bpc_attrib.c view on Meta::CPAN
bpc_attrib_fileInit(file, fileName, 0);
file->type = type;
file->mode = getVarInt_v3(&bufP, buf + nRead);
file->uid = getVarInt_v3(&bufP, buf + nRead);
file->gid = getVarInt_v3(&bufP, buf + nRead);
sizeDiv4GB = getVarInt_v3(&bufP, buf + nRead);
file->size = (sizeDiv4GB << 32) + getVarInt_v3(&bufP, buf + nRead);
file->mtime = CONV_BUF_TO_UINT32(bufP); bufP += 4;
file->compress = dir->compress;
file->backupNum = backupNum;
if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attrib_dirRead(%s): Got v3 file %s: type = %d, mode = 0%o, uid/gid = %d/%d, size = %d\n",
attribPath, file->name, file->type, file->mode, file->uid, file->gid, file->size);
}
} else {
bpc_logErrf("Unexpected magic number 0x%x read from %s\n", magic, attribPath);
return -1;
}
/* TODO: make sure we are at EOF? */
bpc_fileZIO_close(&fd);
bpc_attribCache.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
#define BPC_ATTRIBCACHE_DIR_COUNT_MAX (380)
#define BPC_ATTRIBCACHE_DIR_HT_SIZE (512)
void bpc_attribCache_init(bpc_attribCache_info *ac, char *hostName, int backupNum, char *shareNameUM, int compress)
{
ac->backupNum = backupNum;
ac->compress = compress;
ac->cacheLruCnt = 0;
ac->bkupMergeList = NULL;
ac->bkupMergeCnt = 0;
ac->currentDir[0] = '\0';
ac->deltaInfo = NULL;
strncpy(ac->hostName, hostName, BPC_MAXPATHLEN);
ac->hostName[BPC_MAXPATHLEN - 1] = '\0';
strncpy(ac->shareNameUM, shareNameUM, BPC_MAXPATHLEN);
ac->shareNameUM[BPC_MAXPATHLEN - 1] = '\0';
bpc_fileNameEltMangle(ac->shareName, BPC_MAXPATHLEN, ac->shareNameUM);
ac->shareNameLen = strlen(ac->shareName);
snprintf(ac->hostDir, BPC_MAXPATHLEN, "%s/pc/%s", BPC_TopDir, hostName);
snprintf(ac->backupTopDir, BPC_MAXPATHLEN, "%s/pc/%s/%d", BPC_TopDir, hostName, ac->backupNum);
bpc_path_create(ac->backupTopDir);
bpc_hashtable_create(&ac->attrHT, BPC_ATTRIBCACHE_DIR_HT_SIZE, sizeof(bpc_attribCache_dir));
bpc_hashtable_create(&ac->inodeHT, BPC_ATTRIBCACHE_DIR_HT_SIZE, sizeof(bpc_attribCache_dir));
}
void bpc_attribCache_setDeltaInfo(bpc_attribCache_info *ac, bpc_deltaCount_info *deltaInfo)
{
ac->deltaInfo = deltaInfo;
}
/*
* Caller is responsible for calling malloc for bkupList.
*/
void bpc_attribCache_setMergeList(bpc_attribCache_info *ac, bpc_backup_info *bkupList, int bkupCnt)
{
ac->bkupMergeList = bkupList;
ac->bkupMergeCnt = bkupCnt;
}
static void bpc_attribCache_destroyEntry(bpc_attribCache_dir *attr)
{
bpc_attrib_dirDestroy(&attr->dir);
}
bpc_attribCache.c view on Meta::CPAN
void bpc_attribCache_setCurrentDirectory(bpc_attribCache_info *ac, char *dir)
{
char *p;
snprintf(ac->currentDir, BPC_MAXPATHLEN, "%s", dir);
p = ac->currentDir + strlen(ac->currentDir) - 1;
while ( p >= ac->currentDir && p[0] == '/' ) *p-- = '\0';
}
/*
* Given a backup path, split it into the directory, file name, and path to the directory (starting
* with the share name, ie: relative to ac->backupTopDir).
*
* splitPath will strip initial "./" and trailing "/." or "/" before splitting the path, but isn't
* capable of handling paths with "/." in the middle, or ".." anywhere.
*/
static void splitPath(bpc_attribCache_info *ac, char *dir, char *fileName, char *attribPath, char *path)
{
char *dirOrig = dir;
char fullPath[2*BPC_MAXPATHLEN];
size_t pathLen;
bpc_attribCache.c view on Meta::CPAN
bpc_attrib_dirInit(&attr->dir, ac->compress);
attr->dirty = 0;
attr->dirOk = 0;
attr->lruCnt = ac->cacheLruCnt++;
if ( ac->bkupMergeCnt > 0 ) {
int i;
char topDir[2*BPC_MAXPATHLEN], fullAttribPath[2*BPC_MAXPATHLEN];
/*
* Merge multiple attrib files to create the "view" for this backup.
* There are two cases: merging forward for v3, or merging in reverse
* for v4+. bkupMergeList is already in the order we need.
*/
for ( i = 0 ; i < ac->bkupMergeCnt ; i++ ) {
bpc_attrib_dir dir;
ssize_t entrySize;
char *entries, *entry;
snprintf(topDir, sizeof(topDir), "%s/pc/%s/%d", BPC_TopDir, ac->hostName, ac->bkupMergeList[i].num);
snprintf(fullAttribPath, sizeof(fullAttribPath), "%s/%s", topDir, attribPath);
bpc_attribCache.c view on Meta::CPAN
int attribDirExists = 1;
STRUCT_STAT st;
if ( (p = strrchr(fullAttribPath, '/')) ) {
*p = '\0';
attribDirExists = !stat(fullAttribPath, &st) && S_ISDIR(st.st_mode);
*p = '/';
}
if ( i == ac->bkupMergeCnt - 1 && !attribDirExists ) {
/*
* For V3, if the last backup doesn't have a directory, then the merged view is empty
*/
bpc_attrib_dirDestroy(&dir);
bpc_attrib_dirDestroy(&attr->dir);
bpc_attrib_dirInit(&attr->dir, ac->compress);
break;
}
if ( !attribDirExists ) {
/*
* nothing to update here - keep going
*/
bpc_attribCache.c view on Meta::CPAN
bpc_attrib_file *fileDest;
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, entry, 1)) ) return NULL;
if ( fileDest->key.key == entry ) {
/*
* new entry - initialize
*/
bpc_attrib_fileInit(fileDest, entry, 0);
}
bpc_attrib_fileCopy(fileDest, file);
fileDest->backupNum = ac->bkupMergeList[i].num;
}
}
} else {
bpc_logErrf("bpc_attribCache_loadPath(%s/%s): can't malloc %lu bytes for entries\n",
topDir, attribPath, (unsigned long)entrySize);
if ( entries ) free(entries);
bpc_attrib_dirDestroy(&dir);
return NULL;
}
free(entries);
bpc_attrib_dirDestroy(&dir);
}
} else {
/*
* non-merge case - read the single attrib file
*/
if ( (status = bpc_attrib_dirRead(&attr->dir, ac->backupTopDir, attribPath, ac->backupNum)) ) {
bpc_logErrf("bpc_attribCache_loadPath: bpc_attrib_dirRead(%s, %s) returned %d\n", ac->backupTopDir, attribPath, status);
}
if ( bpc_attrib_dirNeedRewrite(&attr->dir) ) {
attr->dirty = 1;
}
/*
* remove any extraneous BPC_FTYPE_DELETED file types
*/
bpc_hashtable_iterate(&attr->dir.filesHT, (void*)bpc_attribCache_removeDeletedEntries, attr);
}
if ( attr->dirty ) {
bpc_attribCache.c view on Meta::CPAN
strcpy(attr->key.key, attribPath);
bpc_attrib_dirInit(&attr->dir, ac->compress);
attr->dirty = 0;
attr->dirOk = 1;
attr->lruCnt = ac->cacheLruCnt++;
if ( ac->bkupMergeCnt > 0 ) {
int i;
char inodeDir[2*BPC_MAXPATHLEN], fullAttribPath[2*BPC_MAXPATHLEN];
/*
* Merge multiple attrib files to create the "view" for this backup.
* There is only one case here, v4, since v3 didn't have inodes.
*/
for ( i = 0 ; i < ac->bkupMergeCnt ; i++ ) {
bpc_attrib_dir dir;
ssize_t entrySize;
char *entries, *entry;
snprintf(inodeDir, sizeof(inodeDir), "%s/pc/%s/%d/%s", BPC_TopDir, ac->hostName, ac->bkupMergeList[i].num, attribDir);
snprintf(fullAttribPath, sizeof(fullAttribPath), "%s/%s", inodeDir, attribFile);
bpc_attribCache.c view on Meta::CPAN
return NULL;
}
free(entries);
bpc_attrib_dirDestroy(&dir);
}
} else {
/*
* non-merge case - read the single attrib file
*/
char inodeDir[2*BPC_MAXPATHLEN];
snprintf(inodeDir, sizeof(inodeDir), "%s/%s", ac->backupTopDir, attribDir);
if ( (status = bpc_attrib_dirRead(&attr->dir, inodeDir, attribFile, ac->backupNum)) ) {
bpc_logErrf("bpc_attribCache_loadInode: bpc_attrib_dirRead(%s/%s) returned %d\n", inodeDir, attribFile, status);
}
if ( bpc_attrib_dirNeedRewrite(&attr->dir) ) {
attr->dirty = 1;
}
}
if ( attr->dirty ) {
if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attribCache_loadInode: will rewrite path = %s -> dir = %s, fileName = %s\n", attribPath, attribDir, attribFile);
}
if ( bpc_hashtable_entryCount(&ac->inodeHT) > BPC_ATTRIBCACHE_DIR_COUNT_MAX ) {
bpc_attribCache.c view on Meta::CPAN
if ( BPC_LogLevel >= 9 ) bpc_logMsgf("bpc_attribCache_dirWrite: comparing %s vs key %s\n", info->path, attr->key.key);
if ( strncmp(info->path, attr->key.key, info->pathLen)
|| (((char*)attr->key.key)[info->pathLen] != '/' && ((char*)attr->key.key)[info->pathLen] != '\0') ) {
if ( BPC_LogLevel >= 9 ) bpc_logMsgf("bpc_attribCache_dirWrite: skipping %s (doesn't match %s)\n", (char*)attr->key.key, info->path);
return;
}
}
if ( !info->ac->readOnly && attr->dirty ) {
bpc_digest *oldDigest = bpc_attrib_dirDigestGet(&attr->dir);
if ( BPC_LogLevel >= 6 ) bpc_logMsgf("bpc_attribCache_dirWrite: writing %s/%s with %d entries (oldDigest = 0x%02x%02x...)\n",
info->ac->backupTopDir, (char*)attr->key.key, bpc_hashtable_entryCount(&attr->dir.filesHT),
oldDigest ? oldDigest->digest[0] : 0, oldDigest ? oldDigest->digest[1] : 0);
if ( (status = bpc_attrib_dirWrite(info->ac->deltaInfo, &attr->dir, info->ac->backupTopDir, attr->key.key, oldDigest)) ) {
bpc_logErrf("bpc_attribCache_dirWrite: failed to write attributes for dir %s\n", (char*)attr->key.key);
info->errorCnt++;
}
}
/*
* Now deallocate memory
*/
bpc_attrib_dirDestroy(&attr->dir);
if ( attr->key.key ) free(attr->key.key);
bpc_attribCache.c view on Meta::CPAN
info.ht = &ac->attrHT;
bpc_hashtable_iterate(&ac->attrHT, (void*)bpc_attribCache_dirWrite, &info);
info.ht = &ac->inodeHT;
bpc_hashtable_iterate(&ac->inodeHT, (void*)bpc_attribCache_dirWrite, &info);
}
if ( info.errorCnt ) {
/*
* Any errors likely mean the deltas are probably out of sync with the
* file system, so request an fsck.
*/
bpc_poolRefRequestFsck(ac->backupTopDir, 1);
}
}
/*
* Returns the full mangled path, given a file path.
*/
void bpc_attribCache_getFullMangledPath(bpc_attribCache_info *ac, char *path, char *dirName, int backupNum)
{
char *p;
int len;
do {
p = dirName;
while ( dirName[0] == '.' && dirName[1] == '/' ) dirName += 2;
while ( dirName[0] == '/' ) dirName++;
} while ( p != dirName );
if ( backupNum < 0 || ac->bkupMergeCnt <= 0 ) {
backupNum = ac->backupNum;
}
len = snprintf(path, BPC_MAXPATHLEN, "%s/pc/%s/%d/%s", BPC_TopDir, ac->hostName, backupNum, ac->shareName);
if ( (dirName[0] == '/' && dirName[1] == '\0') || dirName[0] == '\0' || len >= BPC_MAXPATHLEN - 1 ) {
return;
}
path[len++] = '/';
bpc_fileNameMangle(path + len, BPC_MAXPATHLEN - len, dirName);
}
bpc_dirOps.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
/*
* Create all the directories in the given path. Path must be non-const. Trailing '/' characters are removed.
*/
int bpc_path_create(char *path)
{
char *p = path;
STRUCT_STAT st;
int levels = 0;
bpc_fileDigest.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
/*
* Compute the md5 digest of a file. Returns 0 on success
*/
int bpc_fileDigest(char *fileName, int compress, bpc_digest *digest)
{
md_context md5;
bpc_fileZIO_fd fd;
ssize_t nRead;
uchar buffer[1 << 20];
bpc_fileZIO.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
/*
* A freelist of unused data buffers.
* We use the first sizeof(void*) bytes of the buffer as a single-linked
* list, with a NULL at the end.
*/
static void *DataBufferFreeList = (void*)NULL;
/*
* Open a regular or compressed file for reading or writing/create
bpc_hashtable.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
/*
* Simple freelist of hash table entries. We maintain a single linked list of
* unused entries of each size, indexed by the FREELIST_SIZE2IDX() macro.
*
* FreeList[0] isn't used,
* FreeList[1] is a free list of blocks of size 8,
* FreeList[2] is a free list of blocks of size 16, ...
*
* eg, if you ask for a block of size 9, a block of size 16 will be returned.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
char BPC_TopDir[BPC_MAXPATHLEN];
char BPC_PoolDir[BPC_MAXPATHLEN];
char BPC_CPoolDir[BPC_MAXPATHLEN];
char BPC_PoolDir3[BPC_MAXPATHLEN];
char BPC_CPoolDir3[BPC_MAXPATHLEN];
int BPC_HardLinkMax = 32000;
int BPC_PoolV3Enabled = 0;
int BPC_TmpFileUnique = -1;
bpc_poolWrite.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
static uint32 PoolWriteCnt = 0;
/*
* Buffer used in various places for copying, comparing etc
*/
#define COMPARE_BUF_SZ (1 << 20) /* 1.0 MB */
static uchar TempBuf[2 * COMPARE_BUF_SZ];
bpc_refCount.c view on Meta::CPAN
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "backuppc.h"
/*
* magic number that appears at the start of the reference count (or delta count file)
*/
#define BPC_POOL_REF_MAGIC (0x178e553c)
#define CONV_BUF_TO_UINT32(buf) ((buf)[0] << 24 | (buf)[1] << 16 | (buf)[2] << 8 | (buf)[3])
#define CONV_UINT32_TO_BUF(buf, val) { *(buf)++ = ((val) >> 24) & 0xff; \
*(buf)++ = ((val) >> 16) & 0xff; \
bpc_refCount.c view on Meta::CPAN
}
digestInfo->count = count;
}
close(fd);
return 0;
}
/*
* Mark this host backup as needing an fsck. Multiple requests can be supported with
* unique numbers. ext == 0 is used for the overall backup process, and it is removed when
* the backup finished. Various errors can use other extensions. If any files are
* present, an fsck is done either by the next backup, BackupPC_refCountUpdate or
* BackupPC_fsck.
*/
void bpc_poolRefRequestFsck(char *backupDir, int ext)
{
char fileName[BPC_MAXPATHLEN];
int fd;
snprintf(fileName, sizeof(fileName), "%s/refCnt/needFsck%d", backupDir, ext);
if ( (fd = open(fileName, O_CREAT | O_WRONLY, 0660)) < 0 ) {
bpc_logErrf("bpc_poolRefRequestFsck: can't open/create fsck request file %s (errno %d)\n", fileName, errno);
}
}
/***********************************************************************
* Reference count deltas - we maintain two hash tables for uncompressed
* and compressed deltas.
***********************************************************************/
bpc_refCount.c view on Meta::CPAN
unlink(tempFileName);
errorCnt++;
}
if ( !errorCnt ) {
bpc_hashtable_erase(&info->refCnt[compress].ht);
}
}
OutputFileCnt++;
if ( errorCnt ) {
/*
* Need to fsck this particular backup on this host
*/
bpc_poolRefRequestFsck(info->targetDir, getpid());
}
return errorCnt;
}
void bpc_poolRefDeltaUpdate(bpc_deltaCount_info *info, int compress, bpc_digest *digest, int32 count)
{
DigestInfo *digestInfo;
configure.sh view on Meta::CPAN
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h"
RSYNC_VERSION=0.62
{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring backuppc-xs $RSYNC_VERSION" >&5
$as_echo "$as_me: Configuring backuppc-xs $RSYNC_VERSION" >&6;}
cat >>confdefs.h <<_ACEOF
#define RSYNC_VERSION "$RSYNC_VERSION"
_ACEOF
LDFLAGS=${LDFLAGS-""}
ac_aux_dir=
configure.sh view on Meta::CPAN
$ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
$as_echo "" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: backuppc-xs ${RSYNC_VERSION} configuration successful" >&5
$as_echo " backuppc-xs ${RSYNC_VERSION} configuration successful" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
$as_echo "" >&6; }
lib/BackupPC/XS.pm view on Meta::CPAN
$numDirEntries = $a->count();
$a->read($dirPath, $attribFileName);
$a->write($dirPath, $attribFileName);
$textType = BackupPC::XS::Attrib::fileType2Text(BPC_FTYPE_....);
=head2 BackupPC::XS::AttribCache
Maintain a cache of directories, with full share/path semantics.
$ac = BackupPC::XS::AttribCache::new($host, $backupNum, $shareNameUM, $compress);
$attrHash = $ac->get($fileName, $allocateIfMissing, $dontReadInode);
$ac->set($fileName, $attrHash, $dontOverwriteInode);
$ac->delete($fileName);
$attrHash = $ac->getInode($inode, $allocateIfMissing);
$ac->setInode($inode, $attrHash);
$ac->deleteInode($inode);
$ac->getAll($path, $dontReadInode);
lib/BackupPC/XS.pm view on Meta::CPAN
$messageArrayRef = BackupPC::XS::Lib::logMsgGet();
$errorCnt = BackupPC::XS::Lib::logErrorCntGet;
BackupPC::XS::Lib::logLevelSet($level);
=head1 EXPORTS
If you specify :all (see SYNOPSIS), then the BPC_FTYPE_ values are exported.
=head1 SEE ALSO
BackupPC, backuppc.sourceforge.net.
rsync-bpc.
=head1 AUTHOR
Craig Barratt, E<lt>cbarratt@users.sourceforge.net<gt>
=head1 COPYRIGHT AND LICENSE
BackupPC code is copyright (C) 2013-2017 Craig Barratt