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: 

Reply via email to