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: