Linux
僅寫入 Delta 時使用圖像更新塊設備,這可能嗎?
我
dd
廣泛用作軟體配置控制的一種手段。映像通常部署在快閃記憶體盤上以更新設備。我發現我經常對圖像文件進行小的增量更新,然後必須將整個圖像重新復製到塊設備上。這是相當耗時的,因為圖像的大小通常為 8GB。為了使問題更加複雜,圖像(一旦組裝)不是一種易於安裝的格式。換句話說,直接在塊上進行更改是不可能的。我正在嘗試確定是否有一種方法可以將圖像文件與塊設備進行比較,並且只更新需要更新的塊。我懷疑這比寫入整個磁碟要快得多,因為這可能相當於圖像文件中的 10kb 增量。
下面是一個小型 C 程序的快速破解,它能夠逐塊比較兩個文件(file1、file2),如果塊不同,則將相應的塊從 file1 複製到 file2。也適用於文件和塊設備。隨心所欲地使用它,但風險自負!
/* Small program to blockwise compare two files and write different blocks from file1 to file2. Arguments: file1, file2, blocksize in bytes If blocksize is not given, it is set to 512 (minimum) No error checking, no intensive tests run - use at your own risk! */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> int main(argc, argv) int argc; char *argv[]; { char *fnamein; /* Input file name */ char *fnameout; /* Output file name */ char *bufin; /* Input buffer */ char *bufout; /* Output buffer */ int bufsize; /* Buffer size (blocksize) */ int fdin; /* Input file descriptor*/ int fdout; /* Output file descriptor*/ int cnt; /* Current block # */ /* Argument processing */ if (argc < 3 || argc > 4) { fprintf(stderr,"Usage: %s infile outfile [bufsize]\n", argv[0]); exit(1); } fnamein = argv[1]; fnameout = argv[2]; if (argc == 4) { bufsize = atoi(argv[3]); if (bufsize < 512) { fprintf(stderr,"Error: Illegal value for [bufsize]: %s\n", argv[3]); exit(1); } } else { bufsize = 512; } fprintf(stderr, "Copying differing blocks from '%s' to '%s', blocksize is %i\n", fnamein, fnameout, bufsize); if (! ((bufin = malloc(bufsize)) && (bufout = malloc(bufsize)))) { fprintf(stderr,"Error: Can't allocate buffers: %i\n", bufsize); exit(1); } fdin = open(fnamein, O_RDONLY); if (fdin < 0) { fprintf(stderr,"Error: Can't open input file: %s\n", fnamein); exit(1); } fdout = open(fnameout, O_RDWR | O_SYNC); if (fdout < 0) { fprintf(stderr,"Error: Can't open ouput file: %s\n", fnameout); exit(1); } cnt = 0; while (read(fdin, bufin, bufsize) == bufsize) { if (read(fdout, bufout, bufsize) == bufsize) { if (memcmp(bufin, bufout, bufsize) != 0) { fprintf(stderr, "Differing blocks at block # %i; writing block to %s\n", cnt, fnameout); if (lseek(fdout, -bufsize, SEEK_CUR) > -1) { if (write(fdout, bufin, bufsize) != bufsize) { fprintf(stderr,"Error: Unable to write to output file %s block # %i\n", fnameout, cnt); exit(1); } } else { fprintf(stderr,"Error: Unable to seek to output file %s block # %i\n", fnameout, cnt); exit(1); } } } else { fprintf(stderr,"Error: Unable to read from ouput file %s block # %i\n", fnameout, cnt); exit(1); } cnt++; } exit(0); }