• diff binário

    Data:2010.06.28 | Categoriacuriosidade, linux, utilidades | Tags: ,,

    Estava eu procurando por uma solução de patch binário para compor uma parte do meu sistema de backups. Pois bem, embora não seja o cerne de tudo, vou explicar meu cenário para que seja melhor entendido.

    Eu estou trabalhando com máquinas virtuais com imagens de discos em volumes lógicos (LVM). Usando o recurso de snapshot do LVM, que é assunto para outro post, eu estava copiando inteiramente a imagem para um backup, através do comando dd. O problema é ter que fazer uma cópia full da  imagem a cada backup. Minha máquina de teste tem 10GB, mas imagina um servidor em produção, que pode ter várias dezenas de GBs… Fica inviável o backup deste jeito. Assim começou a busca por uma solução de calcular a diferença entre os dois binários, imagem de produção e a backup, para assim gerar um patch com somente o necessário para transferir ao servidor de backup. Após, eu precisaria aplicar este patch e assim atualizar a iamgem.

    Pesquisando no oráculo Google, encontrei este site. Lá pude baixar dois fontes, bsdiff e bspatch. Esses são versões ‘binárias’ do GNU diff e patch. Depois de baixar, compilei usando o Makefile do próprio pacote. Como ele foi feito para os *BSD, o formato do Makefile é um pouco diferente. Para compilar direitinho, crie um arquivo chamado Makefile.patch no mesmo diretório do fonte. Dentro dele, coloque o seguinte conteúdo:

    --- Makefile    2010-06-28 14:52:42.351369894 -0300
    +++ Makefile.gnu        2010-06-28 14:53:29.883369968 -0300
    @@ -1,4 +1,5 @@
     CFLAGS         +=      -O3 -lbz2
    +INSTALL                ?=      /bin/install
    
     PREFIX         ?=      /usr/local
     INSTALL_PROGRAM        ?=      ${INSTALL} -c -s -m 555
    @@ -10,6 +11,6 @@
    
     install:
            ${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin
    -.ifndef WITHOUT_MAN
    +ifndef WITHOUT_MAN
            ${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1
    -.endif
    +endif
    

    Salve o arquivo e aplique o patch da seguinte forma:

    patch -p0 < Makefile.patch

    Depois disso, é só instalar:

    make install

    Para testar, fiz o seguinte: copiei para uma pasta os binários /bin/ls e /bin/bash. Lá, calculei a diferença usando o bsdiff:

    /usr/local/bin/bsdiff ls bash teste

    Assim, foi criado o arquivo binário teste, que é a diferença entre ls e bash, ou seja, um patch. Depois, eu resolvi aplicar este patch no próprio ls. Assim, eu faria este ls se transformar no bash.

    /usr/local/bin/bspatch ls ls_patched teste

    Realmente, aconteceu como eu esperava. O comand bspatch gerou um binário ls_patched, que é o resultado do ls + teste. E adivinha, ele é exatamente o bash. Executa  direitinho.