am 43a4a8c7
: Fix redundant file backups
* commit '43a4a8c777fbb8f71540ac7fbe82674489ef557b': Fix redundant file backups
This commit is contained in:
@ -50,7 +50,6 @@ public class BackupHelperDispatcher {
|
|||||||
Header header = new Header();
|
Header header = new Header();
|
||||||
TreeMap<String,BackupHelper> helpers = (TreeMap<String,BackupHelper>)mHelpers.clone();
|
TreeMap<String,BackupHelper> helpers = (TreeMap<String,BackupHelper>)mHelpers.clone();
|
||||||
FileDescriptor oldStateFD = null;
|
FileDescriptor oldStateFD = null;
|
||||||
FileDescriptor newStateFD = newState.getFileDescriptor();
|
|
||||||
|
|
||||||
if (oldState != null) {
|
if (oldState != null) {
|
||||||
oldStateFD = oldState.getFileDescriptor();
|
oldStateFD = oldState.getFileDescriptor();
|
||||||
|
@ -152,7 +152,7 @@ private:
|
|||||||
KeyedVector<String8,FileRec> m_files;
|
KeyedVector<String8,FileRec> m_files;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEST_BACKUP_HELPERS 1
|
//#define TEST_BACKUP_HELPERS 1
|
||||||
|
|
||||||
#if TEST_BACKUP_HELPERS
|
#if TEST_BACKUP_HELPERS
|
||||||
int backup_helper_test_empty();
|
int backup_helper_test_empty();
|
||||||
|
@ -225,8 +225,6 @@ write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8&
|
|||||||
file_metadata_v1 metadata;
|
file_metadata_v1 metadata;
|
||||||
|
|
||||||
char* buf = (char*)malloc(bufsize);
|
char* buf = (char*)malloc(bufsize);
|
||||||
int crc = crc32(0L, Z_NULL, 0);
|
|
||||||
|
|
||||||
|
|
||||||
fileSize = lseek(fd, 0, SEEK_END);
|
fileSize = lseek(fd, 0, SEEK_END);
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
@ -310,8 +308,12 @@ write_update_file(BackupDataWriter* dataStream, const String8& key, char const*
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compute_crc32(int fd)
|
compute_crc32(const char* file, FileRec* out) {
|
||||||
{
|
int fd = open(file, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
const int bufsize = 4*1024;
|
const int bufsize = 4*1024;
|
||||||
int amt;
|
int amt;
|
||||||
|
|
||||||
@ -324,8 +326,11 @@ compute_crc32(int fd)
|
|||||||
crc = crc32(crc, (Bytef*)buf, amt);
|
crc = crc32(crc, (Bytef*)buf, amt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
free(buf);
|
free(buf);
|
||||||
return crc;
|
|
||||||
|
out->s.crc32 = crc;
|
||||||
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -353,7 +358,8 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
|
|||||||
|
|
||||||
err = stat(file, &st);
|
err = stat(file, &st);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
r.deleted = true;
|
// not found => treat as deleted
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
r.deleted = false;
|
r.deleted = false;
|
||||||
r.s.modTime_sec = st.st_mtime;
|
r.s.modTime_sec = st.st_mtime;
|
||||||
@ -361,12 +367,17 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
|
|||||||
//r.s.modTime_nsec = st.st_mtime_nsec;
|
//r.s.modTime_nsec = st.st_mtime_nsec;
|
||||||
r.s.mode = st.st_mode;
|
r.s.mode = st.st_mode;
|
||||||
r.s.size = st.st_size;
|
r.s.size = st.st_size;
|
||||||
// we compute the crc32 later down below, when we already have the file open.
|
|
||||||
|
|
||||||
if (newSnapshot.indexOfKey(key) >= 0) {
|
if (newSnapshot.indexOfKey(key) >= 0) {
|
||||||
LOGP("back_up_files key already in use '%s'", key.string());
|
LOGP("back_up_files key already in use '%s'", key.string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute the CRC
|
||||||
|
if (compute_crc32(file, &r) != NO_ERROR) {
|
||||||
|
ALOGW("Unable to open file %s", file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
newSnapshot.add(key, r);
|
newSnapshot.add(key, r);
|
||||||
}
|
}
|
||||||
@ -374,49 +385,41 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
int N = oldSnapshot.size();
|
int N = oldSnapshot.size();
|
||||||
int m = 0;
|
int m = 0;
|
||||||
|
int M = newSnapshot.size();
|
||||||
|
|
||||||
while (n<N && m<fileCount) {
|
while (n<N && m<M) {
|
||||||
const String8& p = oldSnapshot.keyAt(n);
|
const String8& p = oldSnapshot.keyAt(n);
|
||||||
const String8& q = newSnapshot.keyAt(m);
|
const String8& q = newSnapshot.keyAt(m);
|
||||||
FileRec& g = newSnapshot.editValueAt(m);
|
FileRec& g = newSnapshot.editValueAt(m);
|
||||||
int cmp = p.compare(q);
|
int cmp = p.compare(q);
|
||||||
if (g.deleted || cmp < 0) {
|
if (cmp < 0) {
|
||||||
// file removed
|
// file present in oldSnapshot, but not present in newSnapshot
|
||||||
LOGP("file removed: %s", p.string());
|
LOGP("file removed: %s", p.string());
|
||||||
g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
|
write_delete_file(dataStream, p);
|
||||||
dataStream->WriteEntityHeader(p, -1);
|
|
||||||
n++;
|
n++;
|
||||||
}
|
} else if (cmp > 0) {
|
||||||
else if (cmp > 0) {
|
|
||||||
// file added
|
// file added
|
||||||
LOGP("file added: %s", g.file.string());
|
LOGP("file added: %s crc=0x%08x", g.file.string(), g.s.crc32);
|
||||||
write_update_file(dataStream, q, g.file.string());
|
write_update_file(dataStream, q, g.file.string());
|
||||||
m++;
|
m++;
|
||||||
}
|
} else {
|
||||||
else {
|
// same file exists in both old and new; check whether to update
|
||||||
// both files exist, check them
|
|
||||||
const FileState& f = oldSnapshot.valueAt(n);
|
const FileState& f = oldSnapshot.valueAt(n);
|
||||||
|
|
||||||
int fd = open(g.file.string(), O_RDONLY);
|
LOGP("%s", q.string());
|
||||||
if (fd < 0) {
|
LOGP(" old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
|
||||||
// We can't open the file. Don't report it as a delete either. Let the
|
f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
|
||||||
// server keep the old version. Maybe they'll be able to deal with it
|
LOGP(" new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
|
||||||
// on restore.
|
g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
|
||||||
LOGP("Unable to open file %s - skipping", g.file.string());
|
if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
|
||||||
} else {
|
|| f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
|
||||||
g.s.crc32 = compute_crc32(fd);
|
int fd = open(g.file.string(), O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
LOGP("%s", q.string());
|
ALOGE("Unable to read file for backup: %s", g.file.string());
|
||||||
LOGP(" new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
|
} else {
|
||||||
f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
|
|
||||||
LOGP(" old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
|
|
||||||
g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
|
|
||||||
if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
|
|
||||||
|| f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
|
|
||||||
write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
|
write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
m++;
|
m++;
|
||||||
@ -425,12 +428,12 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
|
|||||||
|
|
||||||
// these were deleted
|
// these were deleted
|
||||||
while (n<N) {
|
while (n<N) {
|
||||||
dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
|
write_delete_file(dataStream, oldSnapshot.keyAt(n));
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// these were added
|
// these were added
|
||||||
while (m<fileCount) {
|
while (m<M) {
|
||||||
const String8& q = newSnapshot.keyAt(m);
|
const String8& q = newSnapshot.keyAt(m);
|
||||||
FileRec& g = newSnapshot.editValueAt(m);
|
FileRec& g = newSnapshot.editValueAt(m);
|
||||||
write_update_file(dataStream, q, g.file.string());
|
write_update_file(dataStream, q, g.file.string());
|
||||||
|
Reference in New Issue
Block a user