On Friday 23 December 2005 20:48, Blaisorblade wrote: > On Wednesday 21 December 2005 17:31, Ian Smith-Heisters wrote:
> ./makeEqualDev /dev/ubdA /dev/ubdB Forgot the program - here it is. I renamed it meanwhile... -- Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!". Paolo Giarrusso, aka Blaisorblade (Skype ID "PaoloGiarrusso", ICQ 215621894) http://www.user-mode-linux.org/~blaisorblade
/* * Copyright(C) 2005 Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]> * Licensed under the GPL v2 or any later version. */ /* * Smart-resync program for COW files * * Do a block-by-block comparison of file1 and file2, where block is 512-byte * wide; whenever a difference is found the content of file1 block is written * onto file2 to replace the original content. * * This is useful, for instance, when file2 is setup as a COW device (for UML * or for the host), and file1 has some changes from it, to resync the contents. * * Rewriting all the content would make the COW become as large as its backing * file. */ /* For LFS support - some of this is maybe redundant */ #define _FILE_OFFSET_BITS 64 #define _LARGEFILE64_SOURCE #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <assert.h> #define SECTSIZE (512LL) void usage(const char * name) { printf("Usage: %s src dest\n", name); printf( "\tThe content of dest is made equal to the one of src,\n" "\twith as few writes as possible.\n"); } int readBlock(int fd, char * buf, off64_t i, int *atEof) { // Read a SECTSIZE block {{{ int n; assert(lseek64(fd, 0, SEEK_CUR) == i * SECTSIZE); n = read(fd, buf, SECTSIZE); if (n < 0) { perror("read output"); exit(1); } else if (n != SECTSIZE && atEof != NULL) { *atEof = 1; } return n; // }}} } int main(int argc, char* argv[]) { // Declarations {{{ char inBuf[SECTSIZE]; char outBuf[SECTSIZE]; char * inPath, * outPath; int in, out; int atEof = 0; off64_t i; // }}} // Argument parsing {{{ if (argc < 2) { fprintf(stderr,"Not enough args\n"); usage(argv[0]); exit(1); } else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { usage(argv[0]); exit(0); } inPath = argv[1]; outPath = argv[2]; // }}} // File open {{{ in = open(inPath, O_RDONLY|O_LARGEFILE); if (in < 0) { perror("open input file"); exit(1); } out = open(outPath, O_RDWR|O_LARGEFILE); if (out < 0) { perror("open output file"); exit(1); } // }}} // Main loop - compare and make equal {{{ for (i = 0; !atEof; i++) { int n; readBlock(out, outBuf, i, NULL); n = readBlock(in, inBuf, i, &atEof); if (memcmp(inBuf, outBuf, SECTSIZE)) { lseek64(out, i * SECTSIZE, SEEK_SET); write(out, inBuf, n); } } // }}} return 0; } // vim: set fdm=marker: