Loading include/utils/BackupHelpers.h +1 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ int backup_helper_test_empty(); int backup_helper_test_four(); int backup_helper_test_files(); int backup_helper_test_null_base(); int backup_helper_test_missing_file(); int backup_helper_test_data_writer(); int backup_helper_test_data_reader(); #endif Loading libs/utils/BackupHelpers.cpp +108 −45 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ struct FileState { struct FileRec { char const* file; // this object does not own this string bool deleted; FileState s; }; Loading Loading @@ -135,18 +136,23 @@ read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot) static int write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot) { int fileCount = 0; int bytesWritten = sizeof(SnapshotHeader); // preflight size const int N = snapshot.size(); for (int i=0; i<N; i++) { const FileRec& g = snapshot.valueAt(i); if (!g.deleted) { const String8& name = snapshot.keyAt(i); bytesWritten += sizeof(FileState) + round_up(name.length()); fileCount++; } } LOGP("write_snapshot_file fd=%d\n", fd); int amt; SnapshotHeader header = { MAGIC0, N, MAGIC1, bytesWritten }; SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten }; amt = write(fd, &header, sizeof(header)); if (amt != sizeof(header)) { Loading @@ -154,9 +160,10 @@ write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot) return errno; } for (int i=0; i<header.fileCount; i++) { const String8& name = snapshot.keyAt(i); for (int i=0; i<N; i++) { FileRec r = snapshot.valueAt(i); if (!r.deleted) { const String8& name = snapshot.keyAt(i); int nameLen = r.s.nameLen = name.length(); amt = write(fd, &r.s, sizeof(FileState)); Loading @@ -182,6 +189,7 @@ write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot) } } } } return 0; } Loading Loading @@ -308,9 +316,9 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD err = stat(file, &st); if (err != 0) { LOGW("Error stating file %s", file); continue; } r.deleted = true; } else { r.deleted = false; r.s.modTime_sec = st.st_mtime; r.s.modTime_nsec = 0; // workaround sim breakage //r.s.modTime_nsec = st.st_mtime_nsec; Loading @@ -321,6 +329,7 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD LOGP("back_up_files key already in use '%s'", key.string()); return -1; } } newSnapshot.add(key, r); } Loading @@ -331,24 +340,24 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD while (n<N && m<fileCount) { const String8& p = oldSnapshot.keyAt(n); const String8& q = newSnapshot.keyAt(m); FileRec& g = newSnapshot.editValueAt(m); int cmp = p.compare(q); if (cmp > 0) { // file added const FileRec& g = newSnapshot.valueAt(m); LOGP("file added: %s", g.file); write_update_file(dataStream, q, g.file); m++; } else if (cmp < 0) { if (g.deleted || cmp < 0) { // file removed LOGP("file removed: %s", p.string()); g.deleted = true; // They didn't mention the file, but we noticed that it's gone. dataStream->WriteEntityHeader(p, -1); n++; } else if (cmp > 0) { // file added LOGP("file added: %s", g.file); write_update_file(dataStream, q, g.file); m++; } else { // both files exist, check them const FileState& f = oldSnapshot.valueAt(n); FileRec& g = newSnapshot.editValueAt(m); int fd = open(g.file, O_RDONLY); if (fd < 0) { Loading Loading @@ -550,6 +559,7 @@ backup_helper_test_four() String8 filenames[4]; FileState states[4]; FileRec r; r.deleted = false; r.file = NULL; states[0].modTime_sec = 0xfedcba98; Loading Loading @@ -1149,6 +1159,59 @@ backup_helper_test_null_base() return 0; } int backup_helper_test_missing_file() { int err; int oldSnapshotFD; int dataStreamFD; int newSnapshotFD; system("rm -r " SCRATCH_DIR); mkdir(SCRATCH_DIR, 0777); mkdir(SCRATCH_DIR "data", 0777); write_text_file(SCRATCH_DIR "data/b", "b\nbb\n"); char const* files[] = { SCRATCH_DIR "data/a", SCRATCH_DIR "data/b", SCRATCH_DIR "data/c", }; char const* keys[] = { "a", "b", "c", }; dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666); if (dataStreamFD == -1) { fprintf(stderr, "error creating: %s\n", strerror(errno)); return errno; } newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666); if (newSnapshotFD == -1) { fprintf(stderr, "error creating: %s\n", strerror(errno)); return errno; } { BackupDataWriter dataStream(dataStreamFD); err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1); if (err != 0) { return err; } } close(dataStreamFD); close(newSnapshotFD); return 0; } #endif // TEST_BACKUP_HELPERS Loading Loading
include/utils/BackupHelpers.h +1 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ int backup_helper_test_empty(); int backup_helper_test_four(); int backup_helper_test_files(); int backup_helper_test_null_base(); int backup_helper_test_missing_file(); int backup_helper_test_data_writer(); int backup_helper_test_data_reader(); #endif Loading
libs/utils/BackupHelpers.cpp +108 −45 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ struct FileState { struct FileRec { char const* file; // this object does not own this string bool deleted; FileState s; }; Loading Loading @@ -135,18 +136,23 @@ read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot) static int write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot) { int fileCount = 0; int bytesWritten = sizeof(SnapshotHeader); // preflight size const int N = snapshot.size(); for (int i=0; i<N; i++) { const FileRec& g = snapshot.valueAt(i); if (!g.deleted) { const String8& name = snapshot.keyAt(i); bytesWritten += sizeof(FileState) + round_up(name.length()); fileCount++; } } LOGP("write_snapshot_file fd=%d\n", fd); int amt; SnapshotHeader header = { MAGIC0, N, MAGIC1, bytesWritten }; SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten }; amt = write(fd, &header, sizeof(header)); if (amt != sizeof(header)) { Loading @@ -154,9 +160,10 @@ write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot) return errno; } for (int i=0; i<header.fileCount; i++) { const String8& name = snapshot.keyAt(i); for (int i=0; i<N; i++) { FileRec r = snapshot.valueAt(i); if (!r.deleted) { const String8& name = snapshot.keyAt(i); int nameLen = r.s.nameLen = name.length(); amt = write(fd, &r.s, sizeof(FileState)); Loading @@ -182,6 +189,7 @@ write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot) } } } } return 0; } Loading Loading @@ -308,9 +316,9 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD err = stat(file, &st); if (err != 0) { LOGW("Error stating file %s", file); continue; } r.deleted = true; } else { r.deleted = false; r.s.modTime_sec = st.st_mtime; r.s.modTime_nsec = 0; // workaround sim breakage //r.s.modTime_nsec = st.st_mtime_nsec; Loading @@ -321,6 +329,7 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD LOGP("back_up_files key already in use '%s'", key.string()); return -1; } } newSnapshot.add(key, r); } Loading @@ -331,24 +340,24 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD while (n<N && m<fileCount) { const String8& p = oldSnapshot.keyAt(n); const String8& q = newSnapshot.keyAt(m); FileRec& g = newSnapshot.editValueAt(m); int cmp = p.compare(q); if (cmp > 0) { // file added const FileRec& g = newSnapshot.valueAt(m); LOGP("file added: %s", g.file); write_update_file(dataStream, q, g.file); m++; } else if (cmp < 0) { if (g.deleted || cmp < 0) { // file removed LOGP("file removed: %s", p.string()); g.deleted = true; // They didn't mention the file, but we noticed that it's gone. dataStream->WriteEntityHeader(p, -1); n++; } else if (cmp > 0) { // file added LOGP("file added: %s", g.file); write_update_file(dataStream, q, g.file); m++; } else { // both files exist, check them const FileState& f = oldSnapshot.valueAt(n); FileRec& g = newSnapshot.editValueAt(m); int fd = open(g.file, O_RDONLY); if (fd < 0) { Loading Loading @@ -550,6 +559,7 @@ backup_helper_test_four() String8 filenames[4]; FileState states[4]; FileRec r; r.deleted = false; r.file = NULL; states[0].modTime_sec = 0xfedcba98; Loading Loading @@ -1149,6 +1159,59 @@ backup_helper_test_null_base() return 0; } int backup_helper_test_missing_file() { int err; int oldSnapshotFD; int dataStreamFD; int newSnapshotFD; system("rm -r " SCRATCH_DIR); mkdir(SCRATCH_DIR, 0777); mkdir(SCRATCH_DIR "data", 0777); write_text_file(SCRATCH_DIR "data/b", "b\nbb\n"); char const* files[] = { SCRATCH_DIR "data/a", SCRATCH_DIR "data/b", SCRATCH_DIR "data/c", }; char const* keys[] = { "a", "b", "c", }; dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666); if (dataStreamFD == -1) { fprintf(stderr, "error creating: %s\n", strerror(errno)); return errno; } newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666); if (newSnapshotFD == -1) { fprintf(stderr, "error creating: %s\n", strerror(errno)); return errno; } { BackupDataWriter dataStream(dataStreamFD); err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1); if (err != 0) { return err; } } close(dataStreamFD); close(newSnapshotFD); return 0; } #endif // TEST_BACKUP_HELPERS Loading