[linux-lvm] How to use 'lvconvert --merge' to copy back data but keep snapshot

Tomas Dalebjork tomas.dalebjork at repostor.com
Mon Nov 24 12:18:04 UTC 2014


Hi,

I have a need to copy only changed block back to its origin from the
snapshot, but keep the snapshot device; similar to "lvconvert --merge".

Are there a way to do this?

Or can I use the below C code to perform this?

https://fbo.no-ip.org/svn/fbo/lvmsync+/lvmdiff.c
https://fbo.no-ip.org/svn/fbo/lvmsync+/lvmdiff.c

But instead of copying data from the /dev/mapper/vg-lv-real device to an
incremental file; by reading its <exception> data from the
/dev/mapper/vg-lv-cow; do this in like in reverse order.

Eg reading exception data from /dev/mapper/vg-lv-cow, read snapshot data
from /dev/mappper/vg-lv-cow and write its content to /dev/mapper/vg-lv or
/dev/mapper/vg-lv-real

..

	while ( progress ) {
		// process a single metadata chunk
		for(i=0;i<(chunksize/16);i++) {
			// Read a single chunk-pointer pair
			read(difffd,&ofs_origin,sizeof(ofs_origin));
			read(difffd,&ofs_snap,sizeof(ofs_snap));
			// this is the end of the chain
			if ( ofs_snap == 0 ) {
				progress=0;
				break;
			}
			ofs_realposition=ofs_origin * chunksize;

			// Read changed chunk from ref-device
			if ( lseek(reffd,ofs_realposition,SEEK_SET) != ofs_realposition ) {
				fprintf(stderr,"E: Seek on reference device '%s' at 0x%016llX
failed, aborting.\n",refdev,(long long)ofs_realposition);
				close(reffd);close(difffd);return 0;
			}
			if ( result=blockread(difffd,buffer,chunksize) != chunksize ) {
				fprintf(stderr,"E: Unable to read all the data of block '%016llX'
(got %i of %i), aborting.\n",(long
long)ofs_realposition,result,chunksize);
				close(difffd);close(reffd);return 0;
			}

			if ( result=blockwrite(refffd,buffer,chunksize) != chunksize ) {
				fprintf(stderr,"E: Unable to write all the data of block
'%016llX', aborting (wrote %i of %i).\n",(long
long)ofs_realposition,result,chunksize);
				close(difffd);close(reffd);return 0;
			}
		}
		stat_metadatachunks++;
	}
	if ( VERBOSE ) {
		fprintf(stderr,"I: Number of blocks: %li (%li
Bytes)\n",stat_chunks,stat_chunks*chunksize);
	}
	close(difffd);
	close(reffd);
	return 1;
}

int blockwrite(int fd,char *buffer,size_t size) {
	int done=0;
	int result;
	while ( done != size ) {
		result=write(fd,&buffer[done],size-done);
		if ( result <= 0 ) {
			return -1;
		} else {
			done += result;
		}
	}
	return size;
}

int blockread(int fd,char *buffer,size_t size) {
	int done=0;
	int result;
	while ( done != size ) {
		result=read(fd,&buffer[done],size-done);
		if ( result > 0 ) {
			done += result;
		} else {
			if ( done == 0 ) {
				return -1;
			} else {
				return done;
			}
		}
	}
	return size;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/linux-lvm/attachments/20141124/8334ba2d/attachment.htm>


More information about the linux-lvm mailing list