AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 421163
Accepted
hiro protagonist
hiro protagonist
Asked: 2018-02-02 01:28:36 +0800 CST2018-02-02 01:28:36 +0800 CST 2018-02-02 01:28:36 +0800 CST

instantâneos incrementais btrfs: encontre UUID nos dados enviados

  • 772

estou fazendo instantâneos incrementais btrfsusando btrfs sendebtrfs receive

supondo que eu comece de um instantâneo inicial snapshot_0e sendos dados para um arquivo

$ sudo btrfs send snapshot_0 -f snapshot_0.data

em seguida, faça algumas alterações, crie um novo instantâneo snapshot_1e tire um instantâneo diferencial ao longo das linhas de

$ sudo btrfs send -p snapshot_0 snapshot_1 -f snapshot_0-1.data

agora eu tenho os dois arquivos snapshot_0.datae snapshot_0-1.data. eu sei que posso usar

$ sudo btrfs subvolume show snapshot_0
$ sudo btrfs subvolume show snapshot_1

para obter o UUIDe o Parent UUID(ou Received UUID) dos instantâneos reais.

minha pergunta é: existe uma maneira de obter esses UUIDs de meus arquivos de dados snapshot_0.datae snapshot_0-1.data?

atualização: acabei de encontrar Design Notes em Send/Receive .

2ª atualização: btrfs-snapshots-diff.py[github.com] pode fornecer exatamente isso; investigando...

(eu também postei a pergunta em askubuntu.com )

btrfs
  • 1 1 respostas
  • 335 Views

1 respostas

  • Voted
  1. Best Answer
    hiro protagonist
    2018-02-02T07:13:42+08:002018-02-02T07:13:42+08:00

    a partir do código de btrfs-snapshots-diff.py [github.com] consegui fazer um script adaptado às minhas necessidades. eu posso usá-lo desta forma para obter o uuids:

    with BtrfsStream('snapshot_0-1.data') as btrfs_stream:
        print(btrfs_stream.get_send_command())
    # ('BTRFS_SEND_C_SNAPSHOT', 
    #      (UUID('01234567-89ab-cdef-0123-456789abcdef'), 
    #       UUID('fedcba98-7654-3210-fedc-ba9876543210')))
    

    com a classe BtrfsStreamabaixo.

    Fiz algumas modificações no código original:

    • python 3 (em vez de python 2)
    • iterando sobre o arquivo em vez de ler tudo na memória
    • recursos adicionados contextmanagerpara usá-lo em um withsatement

    o código usado é então:

    from struct import unpack
    import io
    from uuid import UUID
    
    class BtrfsStream:
    
        # From btrfs/send.h
        send_cmds = (
            'BTRFS_SEND_C_UNSPEC BTRFS_SEND_C_SUBVOL BTRFS_SEND_C_SNAPSHOT '
            'BTRFS_SEND_C_MKFILE BTRFS_SEND_C_MKDIR BTRFS_SEND_C_MKNOD '
            'BTRFS_SEND_C_MKFIFO BTRFS_SEND_C_MKSOCK BTRFS_SEND_C_SYMLINK '
            'BTRFS_SEND_C_RENAME BTRFS_SEND_C_LINK BTRFS_SEND_C_UNLINK '
            'BTRFS_SEND_C_RMDIR BTRFS_SEND_C_SET_XATTR BTRFS_SEND_C_REMOVE_XATTR '
            'BTRFS_SEND_C_WRITE BTRFS_SEND_C_CLONE BTRFS_SEND_C_TRUNCATE '
            'BTRFS_SEND_C_CHMOD BTRFS_SEND_C_CHOWN BTRFS_SEND_C_UTIMES '
            'BTRFS_SEND_C_END BTRFS_SEND_C_UPDATE_EXTENT').split()
    
        send_attrs = (
            'BTRFS_SEND_A_UNSPEC BTRFS_SEND_A_UUID BTRFS_SEND_A_CTRANSID '
            'BTRFS_SEND_A_INO BTRFS_SEND_A_SIZE BTRFS_SEND_A_MODE '
            'BTRFS_SEND_A_UID BTRFS_SEND_A_GID BTRFS_SEND_A_RDEV '
            'BTRFS_SEND_A_CTIME BTRFS_SEND_A_MTIME BTRFS_SEND_A_ATIME '
            'BTRFS_SEND_A_OTIME BTRFS_SEND_A_XATTR_NAME '
            'BTRFS_SEND_A_XATTR_DATA BTRFS_SEND_A_PATH BTRFS_SEND_A_PATH_TO '
            'BTRFS_SEND_A_PATH_LINK BTRFS_SEND_A_FILE_OFFSET BTRFS_SEND_A_DATA '
            'BTRFS_SEND_A_CLONE_UUID BTRFS_SEND_A_CLONE_CTRANSID '
            'BTRFS_SEND_A_CLONE_PATH BTRFS_SEND_A_CLONE_OFFSET '
            'BTRFS_SEND_A_CLONE_LEN').split()
    
        # From btrfs/ioctl.h:#define BTRFS_UUID_SIZE 16
        BTRFS_UUID_SIZE = 16
        HEADER_SIZE = 17
    
        # Headers length
        l_head = 10
        l_tlv = 4
    
        def __init__(self, path):
            '''
            '''
    
            self.path = path
            self._stream = None
    
        def __enter__(self):
            '''
            enter for context manager
            '''
    
            self._stream = open(self.path, 'rb')
            self._read_header()
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            '''
            exit for context manager
            '''
    
            self._stream.close()
    
        def _read_header(self):
            '''
            read the header
            '''
    
            header = self.read(BtrfsStream.HEADER_SIZE, assert_lengh=False)
    
            if len(header) < BtrfsStream.HEADER_SIZE:
                raise IOError('Invalid stream length\n')
    
            magic, null, self.version = unpack('<12scI', header)
            if magic != b'btrfs-stream':
                raise IOError('Not a Btrfs stream!')
    
        def seek(self, offset, whence=io.SEEK_SET):
            '''
            seek to a given point
            '''
    
            self._stream.seek(offset)
    
        def tell(self):
            '''
            tell where we are
            '''
    
            return self._stream.tell()
    
        def read(self, n_bytes, assert_lengh=True):
            '''
            try to read n_bytes
            '''
    
            tell_before = self.tell()
            btes = self._stream.read(n_bytes)
    
            if assert_lengh is True and len(btes) != n_bytes:
                msg = ('could only read {} instead of {} at offset {}'
                       ).format(len(btes), n_bytes, tell_before)
                raise IOError(msg)
            return btes
    
        def tlv_get(self, attr_type):
            attr, l_attr = unpack('<HH', self.read(BtrfsStream.l_tlv))
            if self.send_attrs[attr] != attr_type:
                raise ValueError('Unexpected attribute %s' % self.send_attrs[attr])
            ret, = unpack('<H', self.read(2))
            return ret
    
        def _tlv_get_string(self, attr_type):
            attr, l_attr = unpack('<HH', self.read(BtrfsStream.l_tlv))
            if self.send_attrs[attr] != attr_type:
                raise ValueError('Unexpected attribute %s' % self.send_attrs[attr])
            ret, = unpack('<%ds' % l_attr, self.read(l_attr))
            return ret
    
        def _tlv_get_u64(self, attr_type):
            attr, l_attr = unpack('<HH', self.read(BtrfsStream.l_tlv))
            if self.send_attrs[attr] != attr_type:
                raise ValueError('Unexpected attribute %s' % self.send_attrs[attr])
            ret, = unpack('<Q', self.read(l_attr))
            return ret
    
        def _tlv_get_uuid(self, attr_type):
            attr, l_attr = unpack('<HH', self.read(BtrfsStream.l_tlv))
            if self.send_attrs[attr] != attr_type:
                raise ValueError('Unexpected attribute %s' % self.send_attrs[attr])
            return UUID(bytes=self.read(l_attr))
    
        def get_send_command(self):
            '''
            search uuids only.
            '''
            # start at the right point in the file
            self.seek(BtrfsStream.HEADER_SIZE)
    
            while True:
    
                l_cmd, cmd, crc = unpack('<IHI', self.read(BtrfsStream.l_head))
                tell_before_cmd = self.tell()
    
                try:
                    command = self.send_cmds[cmd]
                except:
                    raise ValueError('Unkown command %d' % cmd)
    
                if command == 'BTRFS_SEND_C_SNAPSHOT':
                    self._tlv_get_string('BTRFS_SEND_A_PATH')
                    uuid = self._tlv_get_uuid('BTRFS_SEND_A_UUID')
                    self._tlv_get_u64('BTRFS_SEND_A_CTRANSID')
                    clone_uuid = self._tlv_get_uuid('BTRFS_SEND_A_CLONE_UUID')
                    return 'BTRFS_SEND_C_SNAPSHOT', (uuid, clone_uuid)
    
                elif command == 'BTRFS_SEND_C_SUBVOL':
                    self._tlv_get_string('BTRFS_SEND_A_PATH')
                    uuid = self._tlv_get_uuid('BTRFS_SEND_A_UUID')
                    return 'BTRFS_SEND_C_SUBVOL', (uuid, )
    
                elif command == 'BTRFS_SEND_C_CLONE':
                    self._tlv_get_string('BTRFS_SEND_A_PATH')
                    self._tlv_get_u64('BTRFS_SEND_A_FILE_OFFSET')
                    self._tlv_get_u64('BTRFS_SEND_A_CLONE_LEN')
                    clone_uuid = self._tlv_get_uuid('BTRFS_SEND_A_CLONE_UUID')
                    return 'BTRFS_SEND_C_CLONE', (clone_uuid, )
    
                elif command == 'BTRFS_SEND_C_END':
                    return
    
                self.seek(tell_before_cmd + l_cmd)
    
    • 0

relate perguntas

  • sincronização incremental de instantâneo btrfs: inicialização com rsync

  • Como criptografar os dados apenas uma vez pelo RAID no nível do sistema de arquivos?

  • Como definir um nível de compactação zstd não padrão na desfragmentação do sistema de arquivos btrfs?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve