-
diff binário
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 +endifSalve 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.