Linux

僅寫入 Delta 時使用圖像更新塊設備,這可能嗎?

  • February 13, 2017

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);
}

引用自:https://unix.stackexchange.com/questions/343762