quarta-feira, 22 de junho de 2016

Apple File System

APFS in Detail: Overview (Adam Leventhal's blog)
Introducing Apple File System (WWDC16, PDF)

Boa notícia. Já estava mais do que na hora de um substituto para o HFS+ aparecer. A Apple pretende colocá-lo em produção em 2017. Será tempo recorde, levando com conta que é um sistema de arquivos desenvolvido do zero a partir de 2014. Sistemas de arquivos precisam de pelo menos dez anos para amadurecerem, diz o provérbio.

quarta-feira, 15 de junho de 2016

Assinaturas

Quando formatamos um dispositivo de armazenamento, colocamos um sistema arquivos numa região delimitada. Às ferramentas que os criam, precisamos dizer qual área compreenderá essa região. Tradicionalmente, especificamos um dispositivo de bloco como /dev/sdc1.

Imagine um disco de 2 MiB (2097152 bytes) com setores de 512 bytes (4096 setores), particionamento MBR (MS-DOS) e uma única partição primária.

    Disco
    /dev/sdc
    +----------------------------------------------------------------------------+
    |                   Espaço não                                               |
    |                   particionado                                             |
    |   +--------------+  /      \  +----------------------------------------+   |
    |   | MBR, tabela  |            | Partição 1                             |   |
    |   | de partições |            | /dev/sdc1                              |   |
    |   |              |            |                                        |   |
    |   +--------------+            +----------------------------------------+   |
LBA |   0              1           / 2048                               4095 /   |
    |                             /                                         /    |
    +----------------------------/-----------------------------------------/-----+
                                /                                         /
                                +----------------------------------------+
                                |                                        |
                                |                                        |
                                |                                        |
                                +----------------------------------------+
                                0                                      2047

(fora de escala)

O kernel interpreta a tabela de partições do disco /dev/sdc e cria o dispositivo /dev/sdc1 [1], que corresponde à área entre os setores 2048 e 4095 neste exemplo. Quando um programa acessar o setor 0 de /dev/sdc1, estará na verdade acessando o setor 2048 do disco. Da mesma forma, o último setor de /dev/sdc1 (2047) equivale ao setor 4095 do disco. Essa tradução é feita automaticamente pelo kernel.

Portanto, ao rodarmos mkfs.ext4 /dev/sdc1, dizemos ao programa para criar um sistema de arquivos EXT4 entre os setores 2048 e 4095 do disco. O resto fica intocado.

Cada sistema de arquivos possui alguns bytes em posições específicas (assinaturas) que os identificam. À medida que sobre uma mesma área criamos diferentes sistemas de arquivos, é prudente, a cada formatação, apagar assinaturas anteriores eventualmente presentes. Ter mais de uma assinatura numa mesma área é roleta russa, pois o volume pode, se por azar o offset conferir, ser montado com o driver de outro sistema de arquivos (colisão), que por sua vez pode considerá-lo inconsistente e na pior das hipóteses tentar consertá-lo sobrescrevendo setores e causando perda de dados no sistema arquivos verdadeiro. Idem com as ferramentas de verificação (fsck).

Na libblkid, parte da suíte util-linux, há funções de detecção e apagamento de assinaturas, e um extenso banco de dados contendo várias delas, que podem ser usadas por outros programas. O wipefs, da própria suíte, é um consumidor dessas interfaces. Idealmente, todos os mkfs deveriam linkar a libblkid e usá-la com essa finalidade, mas nem todos o fazem.

Áreas não particionadas podem ter qualquer coisa gravada. E ferramentas de particionamento que não automatizem a criação de sistemas de arquivos em partições recém criadas também não importam-se com o que está presente entre início e fim das mesmas. Sua obrigação é entregar a estrutura que as delimita. Consequentemente, é recomendável, antes de criar o sistema de arquivos, rodar wipefs -af <partição>. Talvez o mkfs em questão faça isso por nós, porém não custa prevenir.

O mesmo aplica-se ao disco em si, pois é perfeitamente possível criar um sistema de arquivos diretamente em /dev/sdc no nosso exemplo. Vamos supor que /dev/sdc nunca tenha sido particionado e tenha um sistema de arquivos EXT4 em toda sua área (entre os setores 0 e 4095). Ao decidir particioná-lo em MBR, não basta apenas criar a tabela de partições no setor 0. Precisamos garantir que a assinatura EXT4 anterior, gravada no terceiro setor (o superbloco dos EXT começa a partir de 1 KiB [2] — estaria em LBA 2), seja apagada. Ou seja, apagar assinaturas considerando a área total do dispositivo, entre LBA 0 e 4095 no esquema acima. Abstraia por um momento que o disco inteiro passou a ser uma partição de outro disco imaginário. A libblkid é capaz de apagar não só assinaturas de sistema de arquivos: as que identificam particionamento também desaparecerão.

Minha recomendação é fazer assim ao começar um particionamento do zero num disco usado anteriormente [3]:

          wipefs -a <dispositivo>
                    |
                    v
               particionar
                    |
                    v
        wipefs -af /dev/<partição 1>
        wipefs -af /dev/<partição 2>
                   etc.
                    |
                    v
         criar sistema de arquivos

As ferramentas fdisk e sfdisk ganharam na versão 2.28 da suíte util-linux habilidade de limpar automaticamente as assinaturas do disco (opção --wipe):

fdisk: add --wipe
sfdisk: add --wipe

Assim a primeira invocação de wipefs torna-se desnecessária.

Na versão 2.29, poderemos instruí-las a fazer o mesmo nas áreas que englobam partições (opção --wipe-partitions) [4]:

fdisk: add --wipe-partitions=auto|never|default
sfdisk: add --wipe-partitions=auto|never|default

O que nos permite remover a segunda invocação de wipefs.

Já o cfdisk permite apagar assinaturas presentes no disco, porém não faz o mesmo com partições por enquanto:

cfdisk: wipe device if create a new label

Bugs graves foram corrigidos na versão 2.30, que é requerida para as funcionalidades de --wipe e --wipe-partitions. Ver Usando o sfdisk.

Outra alternativa é escrever zeros do início ao fim do disco. Em SSDs é um processo fácil e rápido via secure erase.


[1] Antigamente, era tarefa do udevd. Hoje, o daemon apenas ajusta permissões e cria links simbólicos de conveniência. O kernel é responsável por manter os nós de dispositivos no diretório /dev (devtmpfs).
[2] A posição em relação ao início (e ao fim em alguns casos) do dispositivo varia de acordo com o sistema de arquivos, volume RAID, etc. Identificá-la fica por conta da libblkid. O Btrfs, por exemplo, tem até três superblocos (64 KiB, 64 MiB e 256 GiB), cada um com sua assinatura.
[3] O GParted tem tudo isso automatizado. Infelizmente, por precisar manter-se compatível com distribuições obsoletas, que carregam pacotes util-linux ultrapassados demais, precisa reinventar a roda implementando as rotinas de apagamento por conta, sem usar a libblkid.
[4] Petr Uzel da SUSE implementou funcionalidade equivalente no Parted. Patch ainda não tornado upstream, provavelmente porque depende de uma recente correção na libblkid.

quarta-feira, 8 de junho de 2016

Firefox 49 requererá SSE2

Snif, snif, não poderei mais rodar o Firefox no Windows ☹

Espantoso assombrações como Athlon XP, Duron e afins ainda terem influência em softwares atuais. SSE2 é suportado desde o Athlon 64 (K8, 2003) e Pentium 4 (Willamette, 2000).

O Visual C++ 2015 (compilador C/C++ do Visual Studio, vulgo MSVC) tem um bug que, em x86-32, emite instruções SSE mesmo quando configurado para não fazê-lo (/arch:IA32). Esse bug acendeu a discussão sobre o assunto. Para o Firefox 48, voltarão ao VS2013 temporariamente, cujos binários produzidos, devido à configuração da Mozilla, continuarão rodando em máquinas sem nem mesmo SSE!

No ciclo do Firefox 49, colocarão o VS2015 de volta e nas compilações x86-32 trocarão /arch:IA32 por /arch:SSE2 (que, a propósito, é padrão a partir do VS2012). O instalador do Firefox 49 será modificado para não prosseguir ao detectar processador sem SSE2. A infraestrutura de atualização funcionará assim: instalações anteriores precisarão atualizar obrigatoriamente para a versão 48 primeiro, que estará apta a detectar quais instruções adicionais são suportadas, de forma a oferecer ou não versões posteriores. Máquinas sem SSE2 ficarão na versão 48 para sempre. Restará para esse pessoal rodar a versão 45 ESR enquanto for suportada (idem com o Thunderbird).

Em x86-64, SSE2 é sempre presente pois faz parte do conjunto base de instruções da arquitetura. /arch:SSE2 não tem efeito na versão x86-64 do MSVC. Nela, é possível apenas habilitar geração de código com instruções AVX (/arch:AVX) ou AVX2 (/arch:AVX2).

Ganho de desempenho do navegador em x86-32 com /arch:SSE2 é de até 18%.

No Linux a situação está indefinida. As distribuições possuem política que define globalmente o conjunto de instruções requerido por todos os pacotes do repositório. Será improvável aceitarem o Firefox x86-32 requerendo SSE2, a menos que uma cirurgia downstream para isso seja complexa e torne a manutenção do pacote um inferno, como aconteceu com o Chromium no Debian.

quinta-feira, 2 de junho de 2016

Flatpak

Este é um projeto absolutamente fundamental:

Flatpak - the future of application distribution

É o antigo xdg-app (antes GNOME Apps), sobre o qual comentei anos atrás. Não existe a mais mínima chance do GNU/Linux vingar em dispositivos que não sejam embarcados ou servidores sem algo assim, que facilite a distribuição de programas e seja independente da estrutura de empacotamento convencional (DEB, RPM, etc.). É similar ao Snappy da Canonical, com a vantagem de não requerer assinatura de contributor licence agreement nas contribuições de código. Não recomendo a ninguém doar código para qualquer empresa/entidade que seja. No fim, quem perde é quem exige-o.