Обновить блочное устройство с изображением при записи только дельты, возможно ли?

Из справочной страницы sudo :

-i, --login
             Run the shell specified by the target user's password data-
             base entry as a login shell. 

Ваш userB имеет / bin / false в качестве оболочки, поэтому эта команда запущен.

% /bin/false ; echo $? 
1

Чтобы исправить это, вам нужно изменить оболочку пользователя B на / bin / bash (или / bin / sh или как вам больше нравится) или не используйте флаг -i для sudo. Вам нужна оболочка входа?

2
09.02.2017, 18:28
3 ответа

Ниже приводится быстрый способ взлома небольшой программы на 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);
}
5
27.01.2020, 21:52

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

0
27.01.2020, 21:52

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

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

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

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

2
27.01.2020, 21:52

Теги

Похожие вопросы