Обновить блок-устройство с изображением при записи только Delta, возможно ли это?

Я использую dd в качестве средства управления конфигурацией программного обеспечения. Изображения, как правило, развертываются на флэш-диске для обновления устройств. Я нахожу, что я часто делаю небольшие инкрементные обновления для файлов изображений и должен затем повторно скопировать все изображение на блок-устройство. Это занимает довольно много времени, поскольку изображения обычно составляют 8 ГБ. Чтобы усугубить проблему, изображения (после сборки) не находятся в легко монтируемом формате. Другими словами, сделать изменение непосредственно на блоке невозможно.

Я пытаюсь определить, есть ли способ сравнить файл изображения с блочным устройством и обновлять только блоки, требующие обновления. Я подозреваю, что это будет намного быстрее, чем запись всего диска, что, вероятно, приравнивается к дельтам 10kb в файле изображения.

  • Есть ли whoami, чтобы найти текущую группу, в которую я вошел?
  • Iptables для маскирования одного узла подсети для разных сетевых адаптеров
  • Искусственно первичный буферный кеш?
  • Debian не загружается: udevd не может загрузить устройство sda и sdb
  • Изображение SquashFS как rootfs в LXC
  • Как получить фактическое использование памяти процесса (включая данные в swap)
  • Как настроить Linux для надежной работы с флеш-памятью?
  • linux: Class10 SD-карта различного устройства и размер блока устройства
  • Подключить текущий MAC-адрес к известному адресу, чтобы обмануть маршрутизатор и устройство регистрации
  • Живое изменение размера файла ext3 на CentOS6.5
  • установить раздел секций freebsd под linux
  • Создайте устройство петли записи-записи для гораздо большего блочного устройства
  • 3 Solutions collect form web for “Обновить блок-устройство с изображением при записи только Delta, возможно ли это?”

    Ниже приведен быстрый взлом для небольшой программы на C, способной сравнивать два файла (файл1, файл2) по блоку и, если блоки разные, копирует соответствующий блок из файла1 в файл2. Работает также с файлами и блочными устройствами. Делай с ним то, что хочешь, но на свой страх и риск!

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

    Посмотрите на qemu-img, используя оригинал в качестве файла резервной копии и создайте разностный диск в формате qcow2.

    Получите доступ к нему как к блочному устройству с помощью qemu-nbd (чтобы преобразовать его в устройство nbd).

    Это запишет дельта в диск разности qcow2 и оставит оригинал в покое. Разностный диск увеличивается на небольшие значения для каждого измененного блока.

    Чтобы затем применить эти дельта к одному или нескольким «оригиналам», используйте операцию «совершить» qemu-img.

    Ну, как упоминалось в комментарии к вашему вопросу, параметры dd bs , seek , skip и count ваши друзья. Кроме того, я бы логически разделил ваши изображения на список кусочков подходящего размера (скажем, 10 Мб каждый) и поддерживал md5sum каждого фрагмента (или более длинный хеш, если вы боитесь столкновений, чего я не буду). Когда появляется новое изображение, вам нужно только проверить новое изображение против хэшей (практически половину времени сравнения) и скопировать на диск только измененные куски. Вы даже можете обнаружить, что некоторые ваши куски идентичны (все нули, вероятно), и выполняют дальнейшие оптимизации соответственно.

    Linux и Unix - лучшая ОС в мире.