ZFS (Português)

Artigos relacionados
Sistema de arquivos
ZFS/Virtual disks
Installing Arch Linux on ZFS
Status de tradução:
Esse artigo é uma tradução de
ZFS
. Data da última tradução: 2020-01-10. Você pode ajudar a sincronizar a tradução, se houver
alterações
na versão em inglês.
ZFS
é um sistema de arquivos avançado criado pela
Sun Microsystems
(atualmente propriedade da Oracle) e lançado para OpenSolaris em novembro de 2005.
Características do ZFS incluem: armazenamento em "pools" (gerenciamento integrado de volumes - zpool),
cópia em gravação
,
snapshots
, verificação da integridade de dados e reparo automático (scrubbing - esfregar),
RAID-Z
, tamanho de arquivo máximo de
16 exabytes
, e um máximo de armazenamento de 256 quadrilhões de zettabytes sem limite de números de sistema de arquivos (datasets - conjuntos de dados) ou arquivos
[1]
. (Conteúdo em inglês). O ZFS está licenciado sob a
Common Development and Distribution License
(CDDL).
Descrito como
"A última palavra em sistemas de arquivos"
(Conteúdo em inglês), o ZFS é estável, rápido, seguro e à prova de futuro. Tendo a licença como CDDL, e, portanto, incompatível com a GPL, não é possível que o ZFS seja distribuído junto ao Kernel Linux. Esta necessidade, no entanto, não impede que um módulo do Kernel nativo de Linux seja distribuído por terceiros, como é o caso com o
zfsonlinux.org
(ZOL - ZFS no Linux/ZNL).
ZNL é um projeto fundado pelo
Lawrence Livermore National Laboratory
para desenvolver um módulo nativo do Kernel do Linux para a necessidade de armazenamento maciço de dados em supercomputadores.
Nota
Devido à incompatibilidade potencialmente ilegais entre CDDL do ZFS e GPL do Kernel Linux, o desenvolvimento do ZFS não é suportado pelo Kernel, como mostrado nas seguintes páginas: (
[2]
,
CDDL-GPL
,
ZFS no Linux
).
Como resultado:
O projeto ZFSonLinux deve acompanhar as versões do Kernel Linux. Após tornar um lançamento de uma versão estável do ZFSonLinux, os mantenedores do ZFS no Arch, fazem o lançamento junto à versão do Kernel.
Essa situação às vezes bloqueia o processo normal de atualização sem interrupção por dependências não satisfeitas, porque a nova versão do Kernel, proposta por atualização, não é suportada pelo ZFSonLinux
Instalação
Geral
Atenção
A não ser que você utilize as versões
DKMS
dos pacotes, os módulos do Kernel ZFS e SPL estarão amarrados a uma versão específica do Kernel. Não será possível aplicar nenhuma atualização do Kernel até que pacotes atualizados sejam subidos para o AUR ou o repositório não-oficial
archzfs
.
Dica
Você pode fazer o
downgrade
da sua versão do Linux para uma no repositório do
archzfs
se sua versão for mais nova.
Instale do repositório não-oficial
archzfs
ou, como alternativa, do
AUR
:
zfs-linux
AUR
: lançamento
estável
.
zfs-linux-git
AUR
: lançamento de
desenvolvimento
(com suporte às novas versões de Kernel).
zfs-linux-lts
AUR
: lançamento estável do Kernel LTS.
zfs-linux-lts-git
AUR
[
link quebrado
: package not found]
: lançamento de desenvolvimento para o Kernel LTS.
zfs-linux-hardened
AUR
: lançamento estável do Kernel hardened.
zfs-linux-hardened-git
AUR
[
link quebrado
: package not found]
: lançamento de desenvolvimento para o Kernel hardened.
zfs-linux-zen
AUR
[
link quebrado
: package not found]
: lançamento estável do Kernel zen.
zfs-linux-zen-git
AUR
[
link quebrado
: package not found]
: lançamento de desenvolvimento para o Kernel zen.
zfs-dkms
AUR
: lançamento com Dynamic Kernel Module Support (DKMS - Suporte a módulo de Kernel dinâmico).
zfs-dkms-git
AUR
: lançamento de desenvolvimento com DKMS.
Estas versões têm dependências do pacote
zfs-utils
.
Teste a instalação rodando
zpool status
na linha de comando. Se aparecer um erro com "insmod", tente
depmod -a
.
ZFS na raiz
Veja
Instalação
.
DKMS
Usuários podem utilizar o
DKMS
para reconstruir o módulo do ZFS automaticamente com cada atualização do Kernel.
Instale
zfs-dkms
AUR
ou
zfs-dkms-git
AUR
e aplique as instruções de pós-instalação dadas por estes pacotes.
Dica
Adicione uma entrada de
IgnorePkg
em
pacman.conf
para impedir que estes pacotes sejam atualizados em uma atualização regular.
Experimentos com ZFS
Usuários que tenham o desejo de realizar experimentos com ZFS em
dispositivos de blocos virtuais
(conhecidos no ZFS como VDEVs) que podem ser arquivos simples como
~/zfs0.img
,
~/zfs1.img
,
~/zfs2.img
, etc. sem a possibilidade de perda real de dados devem ver o artigo
ZFS/Virtual disks
. Tarefas comuns como construir um array (conjunto) em RAIDZ, propositalmente corromper dados e então recuperá-los, obter snapshots de datasets, etc. são cobertos nele.
Configuração
ZFS é considerado como um sitema de arquivos com "administração zero" pelos seus criadores; portanto, configurar o ZFS é um processo bem direto. A configuração é feita com 2 comandos:
zfs
e
zpool
.
Inicialização automática
Atualmente, por padrão, o módulo do Kernel não é carregado durante a inicialização (veja mais detalhes em
https://github.com/zfsonlinux/zfs/issues/6083
- conteúdo em inglês). Para carregar automaticamente o
zfs
, veja
Módulos de kernel#Carregamento automático de módulos com systemd
.
Para que o ZFS faça juz à "administração zero",o serviço
zfs-import-cache.service
deve ser habilitado para importar as pools e o
zfs-mount.service
deve ser habilitado para montar o sistema de arquivos disponível nas pools. Um benefício disto é que não é necessário montar os sistemas ZFS no
/etc/fstab
. O
zfs-import-cache.service
importa as pools lendo o arquivo
/etc/zfs/zpool.cache
.
Para cada
pool importada
, é desejável que o serviço
zfs-import-cache.service
que foi importado automaticamente, execute o seguinte comando:
# zpool set cachefile=/etc/zfs/zpool.cache <pool>
Nota
À partir da versão 0.6.5.8 do ZNL, os arquivos das unidades de serviço do ZFS foram mudadas para que você explicitamente habilite quaisquer serviços do ZFS que você queira executar. Veja o conteúdo em inglês
https://github.com/archzfs/archzfs/issues/72
para mais informações.
Habilite o serviço e o .target relevante para que as pools sejam automaticamente importadas durante a inicialização:
# systemctl enable zfs-import-cache
# systemctl enable zfs-import.target
Para montar os sistemas de arquivos ZFS, você possui 2 opções:
Habilite o
zfs-mount.service
Use o
zfs-mount-generator
Usando zfs-mount.service
Para montar os sistemas de arquivos ZFS automaticamente durante o boot, você precisa habilitar os seguintes serviços e alvos.
# systemctl enable zfs-mount
# systemctl enable zfs.target
Usando zfs-mount-generator
Você também pode usar o
zfs-mount-generator
para criar unidades de montagem do systemd para seus sistemas de arquivos ZFS durante a inicialização. O systemd irá automaticamente montar os sistemas de arquivos baseados nas unidades de montagem sem a necessidade de usar
zfs-mount.service
para fazer isto. Para isto, você precisa:
Criar o diretório
/etc/zfs/zfs-list.cache
.
Habilitar o script do ZFS Event Daemon (ZED - servidor de evento do ZFS, chamado de ZEDLET) necessário para criar uma lista de sistemas de arquivos montáveis do ZFS.
# ln -s /usr/lib/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d
Habilitar e iniciar o ZFS Event Daemon. Este serviço é responsável por executar o script do passo anterior.
# systemctl enable zfs-zed.service
# systemctl enable zfs.target
# systemctl start zfs-zed.service
Você precisa criar um arquivo vazio com o nome baseado no nome da sua pool em
/etc/zfs/zfs-list.cache
. O ZEDLET irá apenas atualizar a lista de sistema(s) de arquivos se o arquivo da pool já existir.
# touch /etc/zfs/zfs-list.cache/
nome-da-pool
Verifique o conteúdo de
/etc/zfs/zfs-list.cache/
nome-da-pool
. Se estiver vazio, assegure-se que o
zfs-zed.service
está executando e só mude a propriedade
canmount
de quaisquer sistemas de arquivos ZFS executando:
zfs set canmount=off zroot/fs1
Esta mudança faz com que o ZFS crie um evento que é capturado pelo ZED, que, então, roda o ZEDLET para atualizar o arquivo em
/etc/zfs/zfs-list.cache
. Se o arquivo em
/etc/zfs/zfs-list.cache
for atualizado, você pode definir a propriedade
canmount
do sistema de arquivos de volta executando:
zfs set canmount=on zroot/fs1
Você precisa acrescentar um arquivo em
/etc/zfs/zfs-list.cache
para cada pool ZFS no seu sistema. Assegure-se que as pools serão importadas habilitando
zfs-import-cache.service
e
zfs-import.target
conforme
explicado acima
.
Pools de Armazenamento
Não é necessário particionar os dispositivos antes de criar o sistema de arquivos ZFS. É recomendado apontar o ZFS para um disco inteiro (ex: `/dev/sdx` em vez de `/dev/sdx1`), que irá
automaticamente criar uma tabela de partições GPT
(conteúdo em inglês) e acrescentar uma partição reservada de 8 MB no final do disco para carregadores de inicialização legados. No entando, você pode especificar a partição ou um arquivo dentro do sistema de arquivos existente, se você deseja criar multiplos volumes com propriedades de redundância diferentes.
Nota
Se algum ou todos os dispositivos foram usados em um conjunto de RAID por software, é primordial
apagar quaisquer informações de configuração antigas de RAID
.
Atenção
Para
#Discos com formatação avançada
com tamanho de setor de 4KB, um
ashift
com valor 12 é recomendado para melhor desempenho. Discos com formatação avançada emulam um setor com tamanho de disco de 512 bytes para compatibilidade com sistemas legado. Uma vez que o pool foi criado, a única maneira de mudar a opção do
ashift
é recriar o pool. Usar um
ashift
de 12 também diminui a capacidade disponível. Veja
1.10 What’s going on with performance?
,
1.15 How does ZFS on Linux handle [Advanced
(Advanced) Format disks?], e
ZFS and Advanced Format disks
.
Identificando discos
ZFS no Linux
recomenda utilizar IDs do dispositivo quando for criar pools de armazenamento com menos de 10 dispositivos. Use
Nomeação persistente de dispositivo de bloco#by-id e by-path
para identificar a lista de dispositivos que serão utilizados no pool ZFS.
Os IDs dos discos serão similares ao seguinte:
$ ls -lh /dev/disk/by-id/
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0JKRR -> ../../sdc
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0JTM1 -> ../../sde
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0KBP8 -> ../../sdd
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0KDGY -> ../../sdb
Atenção
Se você criar zpools utilizando nomes dos dispositivos como
/dev/sda
,
/dev/sdb
, etc. o ZFS pode não ser capaz de detectar zpools intermitentemente na inicialização.
Utilizando rótulos GPT
Rótulos de disco e UUIDs podem ser utilizados por montagens de ZFS usando partições
GPT
. Dispositivos ZFS possuem rótulos mas o Linux não é capaz de lê-los durante a inicialização. Ao contrário de partições
MBR
, partições GPT diretamente suportam tanto UUID quanto rótulos, independente do formato dentro da partição. Particionar ao invés de utilizar o disco todo para o ZFS oferece duas vantagens adicionais. O SO não precisa gerar números de partição falsos à partir de quaisquer dados que o ZFS possa ter escrito no setor de particionamento, e, se desejado, é possível provisionar excessivamente dispositivos SSD, e provisionar ligeiramente mais discos de eixo para assegurar que diferentes modelos com contagem de setores diferentes possam substituir espelhos no seu zpool. Isto permite muita organização e controle sobre o ZFS utilizando ferramentas e técnicas prontamente disponíveis com custo quase nulo.
Utilize o
gdisk
para particionar todo ou apenas uma parte do disco como uma única partição. O gdisk não nomeia automaticamente as partições. Algumas razões para preferir rótulos ao invés de UUID são: rótulos são fáceis de controlar, podem indicar o propósito de cada disco, são mais curtos e mais simples de digitar. Estas são vantagens quando o servidor está inoperante e há pressão para restabelecimento. Rótulos de partições do GPT possuem amplo espaço disponível e podem suportar a maioria dos caracteres internacionais (
Entradas de Partição
) permitindo que grandes pools de dados sejam rotulados de uma maneira organizada.
Discos particionados com GPT possuem rótulos e UUIDs que parecem com o seguinte:
$ ls -l /dev/disk/by-partlabel
lrwxrwxrwx 1 root root 10 Apr 30 01:44 zfsdata1 -> ../../sdd1
lrwxrwxrwx 1 root root 10 Apr 30 01:44 zfsdata2 -> ../../sdc1
lrwxrwxrwx 1 root root 10 Apr 30 01:59 zfsl2arc -> ../../sda1
$ ls -l /dev/disk/by-partuuid
lrwxrwxrwx 1 root root 10 Apr 30 01:44 148c462c-7819-431a-9aba-5bf42bb5a34e -> ../../sdd1
lrwxrwxrwx 1 root root 10 Apr 30 01:59 4f95da30-b2fb-412b-9090-fc349993df56 -> ../../sda1
lrwxrwxrwx 1 root root 10 Apr 30 01:44 e5ccef58-5adf-4094-81a7-3bac846a885f -> ../../sdc1
Dica
Para minimizar digitar e erros ao copiar/colar, defina uma variável local com o PARTUUID de destino:
$ UUID=$(lsblk --noheadings --output PARTUUID /dev/sd
XY
)
Criando pools ZFS
Para criar uma pool com ZFS:
# zpool create -f -m <montagem> <pool> [raidz(2|3)|mirror] <ids>
Dica
É útil ler primeiro
#Discos com formatação avançada
para definir o valor correto de
ashift
durante a criação da pool
create
: subcomando para criar a pool.
-f
: força a criação da pool. Isto serve para ignorar o "EFI label error" (erro de rótulo EFI). Veja
#Não contém um rótulo EFI
.
-m
: O ponto de montagem da pool. Se não for especificado, então a pool será montada diretamente em
/<
pool
>
.
pool
: É o nome da pool.
raidz(2|3)|mirror
: Este é o tipo de dispositivo virtual que será criado à partir do conjunto de dispositivos de armazenamento, raidz possui um único disco de paridade, raidz2, 2 discos e raidz3 possui 3 discos de paridade, similares ao RAID5 e RAID6. Também há
mirror
, que é similar ao RAID1 ou RAID10, mas não é restrito à apenas 2 dispositivos. Se não especificado, cada dispositivo será acrescido como vdev, o que é similar ao RAID0. Após a criação, um dispositivo pode ser adicionado a cada vdev de dispositivo para transformar em um espelho (mirror), o que pode ser útil para migrar dados.
ids
: O
ID
dos dispositivos ou partições para incluir na pool.
Criar pool com um único vdev em raidz:
# zpool create -f -m /mnt/dados bigdata \
        raidz \
            ata-ST3000DM001-9YN166_S1F0KDGY \
            ata-ST3000DM001-9YN166_S1F0JKRR \
            ata-ST3000DM001-9YN166_S1F0KBP8 \
            ata-ST3000DM001-9YN166_S1F0JTM1
Criar pool com dois vdevs em espelhados:
# zpool create -f -m /mnt/dados bigdata \
        mirror \
            ata-ST3000DM001-9YN166_S1F0KDGY \
            ata-ST3000DM001-9YN166_S1F0JKRR \
        mirror \
            ata-ST3000DM001-9YN166_S1F0KBP8 \
            ata-ST3000DM001-9YN166_S1F0JTM1
Discos com formatação avançada
Durante a criação da pool,
ashift=12
deve sempre ser utilizado, exceto com SSDs que possuem setores com 8km onde
ashift=13
é o correto. Um disco com vdev de tamanho 512 bytes usando setores de 4k não irá experienciar problemas de desempenho, mas um disco de 4k usando 512 irá. Já que
ashift
não pode ser mudado após a criação da pool, até uma pool com apenas discos de 512 bytes deve usar 4k pois pode ser necessário a substituição destes discos com outros de 4k, ou ainda a pool pode ser expandida acrescentando um vdev composto por discos de 4k. Como a detecção correta de discos de 4k não é confiável
-o ashift=12
deve sempre ser utilizado durante a criação da pool, veja o conteúdo em inglês
ZFS on Linux FAQ
para mais detalhes.
Dica
Use
blockdev(8)
(parte do
util-linux
) como root para mostrar o tamanho do setor informado pelo ioctls do dispositivo:
blockdev --getpbsz /dev/sd
XY
.
Crie uma pool com ashift=12 e um único vdev em raidz:
# zpool create -f -o ashift=12 -m /mnt/dados bigdata \
               raidz \
                  ata-ST3000DM001-9YN166_S1F0KDGY \
                  ata-ST3000DM001-9YN166_S1F0JKRR \
                  ata-ST3000DM001-9YN166_S1F0KBP8 \
                  ata-ST3000DM001-9YN166_S1F0JTM1
Criação de pool compatível com GRUB
Nota
Esta seção frequentemente fica desatualizada com atualizações de GRUB e ZFS. Consulte as páginas de manual para informação mais atual.
Por padrão,
zpool create
permite todas as opções em uma pool. Se /boot reside em um ZFS quando usando o
GRUB
, você deve habilitar apenas as opções suportadas pelo GRUB, caso não faça isso, o GRUB não conseguirá ler a pool. O GRUB 2.02 suporta as opções de leitura e gravação
lz4_compress
,
hole_birth
,
embedded_data
,
extensible_dataset
, e
large_blocks
, isto não condiz com todas as opções no ZFSonLinux 0.8.0, e deve ter as opções não adequadas desabilitadas. Pode-se inserir explicitamente o nome das opções habilitadas com o argumento
-d
para o comando
zpool create
, que desabilita todas as opções por padrão.
Você pode criar a pool com apenas as opções permitidas habilitadas:
# zpool create -d -o feature@allocation_classes=enabled \
                  -o feature@async_destroy=enabled      \
                  -o feature@bookmarks=enabled          \
                  -o feature@embedded_data=enabled      \
                  -o feature@empty_bpobj=enabled        \
                  -o feature@enabled_txg=enabled        \
                  -o feature@extensible_dataset=enabled \
                  -o feature@filesystem_limits=enabled  \
                  -o feature@hole_birth=enabled         \
                  -o feature@large_blocks=enabled       \
                  -o feature@lz4_compress=enabled       \
                  -o feature@project_quota=enabled      \
                  -o feature@resilver_defer=enabled     \
                  -o feature@spacemap_histogram=enabled \
                  -o feature@spacemap_v2=enabled        \
                  -o feature@userobj_accounting=enabled \
                  -o feature@zpool_checkpoint=enabled   \
                  $
NOME_DA_POOL
$VDEVS
Verificando status da pool
Se o comando for executado com sucesso, não será mostrada saída. Usando o comando
mount
mostrará que a pool está montada. Usando
zpool status
mostrará que a pool foi criada:
# zpool status -v
pool: bigdata
 state: ONLINE
  scan: none requested
config:

        NAME                                       STATE     READ WRITE CKSUM
        bigdata                                    ONLINE       0     0     0
          -0                                       ONLINE       0     0     0
            ata-ST3000DM001-9YN166_S1F0KDGY-part1  ONLINE       0     0     0
            ata-ST3000DM001-9YN166_S1F0JKRR-part1  ONLINE       0     0     0
            ata-ST3000DM001-9YN166_S1F0KBP8-part1  ONLINE       0     0     0
            ata-ST3000DM001-9YN166_S1F0JTM1-part1  ONLINE       0     0     0

errors: No known data errors
Nesse momento, seria bom reiniciar a máquina para assegurar-se que a pool ZFS será montada durante a inicialização. É melhor lidar com todos os erros antes de transferir dados.
Importando por id uma pool criada
Eventualmente, uma pool pode falhar ao auto montar, então você precisará importar para trazer a pool de volta. Cuidado para evitar usar a solução óbvia.
Atenção
Não rode
zpool import
pool
! Isto irá importar seus pools utilizando
/dev/sd?
que irá causar problemas a próxima vez que rearranjar seus drives. Que pode ser algo simples como reiniciar com um USB conectado na máquina.
Adapte algum dos comandos seguintes para importar sua pool para que as importações dela retenham a persistência com que foram criadas.
# zpool import -d /dev/disk/by-id         bigdata
# zpool import -d /dev/disk/by-partlabel  bigdata
# zpool import -d /dev/disk/by-partuuid   bigdata
Nota
Use a opção
-l
ao importar a pool que contenha
chaves de conjuntos de dados criptografadas
:
# zpool import -l -d /dev/disk/by-id bigdata
Finalmente, verifique o estado da pool:
# zpool status -v bigdata
Destruir uma pool de armazenamento
ZFS torna fácil destruir uma pool de armazenamento montada, removendo todos os metadados sobre o dispositivo ZFS.
Atenção
Este comando destrói
qualquer dado
contido no pool e/ou dataset.
Para destruir a pool:
# zpool destroy <pool>
Para destruir o dataset:
# zfs destroy <pool>/<dataset>
E agora, ao verificar o status:
# zpool status
no pools available
Exportar uma pool de armazenamento
Se uma pool de armazenamento precisar ser utilizada em outro sistema, primeiro necessitará ser importada. Também faz-se necessário exportar uma pool se ela foi importada à partir da archiso pois o
hostid
será diferente entre a ISO e o sistema inicializado. O comando zpool se recusará a importar quaisquer pools de armazenamento que não foram exportadas. É possível forçar a importação com a opção
-f
mas esta prática é considerada ruim.
Quaisquer tentativas de importar uma pool de armazenamento não exportadas resultará em um erro ao iniciar a pool de armazenamento informando estar sendo utilizada em outro sistema. Este erro pode ser produzido durante a inicialização, abruptamente abandonando o sistema na console
busybox
, necessitando da archiso para fazer o conserto, seja via exportação da pool, seja acrescentando
zfs_force=1
aos parâmetros de inicialização do Kernel (o que não é ideal). Veja mais em
#Durante a inicialização, a pool do ZFS não monta afirmando: "pool may be in use from other system"
.
Para exportar uma pool:
# zpool export <pool>
Estendendo uma pool existente
Um dispositivo (uma partição ou um disco) pode ser acrescentado a uma zpool existente:
# zpool add <pool> <id-do-dispositivo>
Para importar uma pool que consiste de múltiplos dispositivos:
# zpool import -d <id-do-dispositivo-1> -d <id-do-dispositivo-2> <pool>
Ou simplesmente:
# zpool import -d /dev/disk-by-id/ <pool>
Renomear uma pool
Renomear uma pool que já foi criada é feito em 2 passos:
# zpool export nome-antigo
# zpool import nome-antigo nome-novo
Definir um ponto de montagem diferente
O ponto de montagem para uma determinada zpool pode ser movido conforme desejado com um comando:
# zfs set mountpoint=/foo/bar nome-da-pool
Criando datasets
Usuários possuem a opção de criar um dataset sob uma zpool, diferente de manualmente criar diretórios sob a zpool. Datasets permitem um nível maior de controle (por exemplo quotas), além de snapshots. Para conseguir criar e montar um dataset, um diretório homônimo não deve existir na zpool. Para criar um dataset, use:
# zfs create <
nome-da-zpool
>/<
nome-do-dataset
>
Então é possível aplicar atributos específicos do ZFS ao dataset. Por exemplo, limite de quota para um diretório específico dentro de um dataset:
# zfs set quota=20G <
nome-da-zpool
>/<
nome-do-dataset
>/<diretório>
Para ver todos os comandos disponíveis no ZFS, veja
zfs(8)
ou
zpool(8)
.
Criptografia nativa
ZFS oferece as seguintes opções suportadas de Criptografia:
aes-128-ccm
,
aes-192-ccm
,
aes-256-ccm
,
aes-128-gcm
,
aes-192-gcm
e
aes-256-gcm
. Quando a Criptografia é definida como
on
,
aes-256-gcm
será usada.
Os seguintes formatos de chave são suportados:
passphrase
,
raw
,
hex
.
É possível também especificar as iterações padrões do PBKDF2 quando usando
passphrase
com
-o pbkdf2iters <n>
, embora isto possa aumentar o tempo até terminar a descriptografia.
Nota
Criptografia nativa no ZFS tornou-se disponível à partir da versão estável 0.8.0 ou mais nova. Anteriormente estavam disponíveis apenas em versões de desenvolvimento fornecidas por pacotes como
zfs-linux-git
AUR
,
zfs-dkms-git
AUR
ou outras versões de desenvolvimento. Usuários que estavam utilizando as versões de desenvolvimento devido à criptografia podem agora trocar pela versão estável se assim desejarem.
A suite padrão de criptografia foi mudada de
aes-256-ccm
para
aes-256-gcm
na versão 0.8.4.
Para importar uma pool com chaves, é necessário especificar a opção
-l
, sem esta opção, datasets criptografados ficarão indisponíveis até que as chaves sejam carregadas. Veja
#Importando por id uma pool criada
.
Para criar um dataset, incluíndo criptografia por senha, use:
# zfs create -o encryption=on -o keyformat=passphrase <
nome-da-zpool
>/<
nome-do-dataset
>
Para utilizar chave ao invés de senha, use:
# dd if=/dev/random of=
/caminho/para/chave
bs=1 count=32
# zfs create -o encryption=on -o keyformat=raw -o keylocation=file://of=
/caminho/para/chave
<
nome-da-zpool
>/<
nome-do-dataset
>
Para verificar o local da chave:
# zfs get keylocation <
nome-da-zpool
>/<
nome-do-dataset
>
Para mudar o local da chave:
# zfs set keylocation=file://
/caminho/para/chave
<
nome-da-zpool
>/<
nome-do-dataset
>
Você também pode manualmente carregar as chaves utilizando um dos seguintes comandos:
# zfs load-key <
nome-da-zpool
>/<
nome-do-dataset
> # Carrega uma chave para um dataset específico
# zfs load-key -a                                # Carrega todas as chaves
# zfs load-key -r zpool/dataset                  # Carrega todas as chaves em um dataset
Para montar um dataset criptografado criado:
# zfs mount <
nome-da-zpool
>/<
nome-do-dataset
>
Desbloquear durante a inicialização
É possível automaticamente desbloquear um dataset de uma pool durante a inicialização usando uma unidade do
systemd
. Por exemplo, criar o seguinte serviço para desbloquear qualquer dataset específico.
/etc/systemd/system/zfs-load-key@.service
[Unit]
Description=Carregar chaves de criptografia %I
Before=systemd-user-sessions.service
After=zfs-import.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/bash -c 'until (systemd-ask-password "Senha criptografada do ZFS para %I" --no-tty | zfs load-key %I); do echo "Tente novamente!"; done'

[Install]
WantedBy=zfs-mount.service
Habilite e inicie
o serviço para cada dataset criptografado, e.g.
systemctl enable zfs-load-key@pool0-dataset0
como o usuário root. Note o uso do
-
, que é um
/
escapado nas definições de unidade do systemd. Veja
systemd-escape(1)
para mais informações.
Nota
O
Before=systemd-user-sessions.service
garante que o systemd-ask-password seja invocado antes que os dispositivos locais de E/S sejam entregues para o
ambiente de desktop
.
Uma alternativa é carregar todas as chaves possíveis:
/etc/systemd/system/zfs-load-key.service
[Unit]
Description=Carregar chaves de criptografia
DefaultDependencies=no
After=zfs-import.target
Before=zfs-mount.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/zfs load-key -a

[Install]
WantedBy=zfs-mount.service
Habilite e inicie
zfs-load-key.service
.
Volume de swap
Atenção
Em sistemas com pressão de memória extremamente alto, usar um zvol como swap pode resultar em em travamento, independente da quantidade de swap disponível. Este problema está atualmente sendo investigado
https://github.com/zfsonlinux/zfs/issues/7734
ZFS não permite o uso de arquivos de swap, mas usuários podem utilizar um volume de ZFS (ZVOL) como swap. É importante definir o tamanho de bloco do ZVOL para ser o mesmo do tamanho de página do sistema, que pode ser obtida com o comando
getconf PAGESIZE
(o padrão em x86_64 é 4KiB). Outra opção útil para manter o sistema rodando bem em situações de memória baixa é não fazer o cache dos dados do ZVOL.
Crie um volume ZFS de 8 GiB:
# zfs create -V 8G -b $(getconf PAGESIZE) \
              -o logbias=throughput -o sync=always\
              -o primarycache=metadata \
              -o com.sun:auto-snapshot=false <pool>/swap
Prepare-o como partição de swap:
# mkswap -f /dev/zvol/<pool>/swap
# swapon /dev/zvol/<pool>/swap
Para tornar permanente, edite o
/etc/fstab
. ZVOLs suportam "discard", que potencialmente pode ajudar o alocador de blocos do ZFS e reduzir a fragmentação para todos os outros datasets quando/se o swap não estiver cheio.
Acrescente uma linha no
/etc/fstab
:
/dev/zvol/<pool>/swap none swap discard 0 0
Listas de Controle de Acesso
Para utilizar
Listas de Controle de Acesso
(ACL) em um dataset:
# zfs set acltype=posixacl <
nome-da-zpool
>/<
nome-do-dataset
>
# zfs set xattr=sa         <
nome-da-zpool
>/<
nome-do-dataset
>
Definir
xattr
é recomendado por questões de desempenho, como é possível ver no conteúdo em inglês
[3]
.
Pode ser preferível habilitar o ACL na zpool pois os datasets irão herdar os parâmetros de ACL. Configurar
aclinherit=passthrough
Pode ser desejado pois o modo padrão é
restricted
, vide
[4]
(conteúdo em inglês):
# zfs set aclinherit=passthrough <
nome-da-zpool
>
# zfs set acltype=posixacl       <
nome-da-zpool
>
# zfs set xattr=sa               <
nome-da-zpool
>
Bancos de dados
ZFS, diferente da maioria dos outros sistemas de arquivos, tem u, tamanho de registro variável, ou o que é comumente chamado de tamanho de bloco. Por padrão, o tamanho de registro "recordsize" no ZFS é 128KiB, o que significa que irá alocar blocos dinamicamente de qualquer tamanho entre 512B e 128KiB, dependendo do tamanho do arquivo sendo escrito. Isto frequentemente pode ajudar com fragmentation e acesso a arquivos, com o custo que o ZFS teria ao alocar novos blocos de 128KiB cada vez que apenas alguns bytes são escritos.
A maioria dos SGBDRs trabalham com blocos com tamanho de 8KiB por padrão. Apesar do tamanho de bloco ser regulável para
MySQL/MariaDB
,
PostgreSQL
, e Oracle database, todos os 3 usam o tamanho de bloco de 8KiB
por padrão
. Tanto para preocupações com desempenho e manter diferença mínima em snapshots (em questão de backups, é útil), geralmente é desejável realizar configurações no ZFS para acomodar os banco de dados utilizando comandos como:
# zfs set recordsize=8K <pool>/postgres
Estes SGBDRs também tendem a implementar o próprio algoritmo de cache, geralmente similar ao próprio ARC do ZFS. Para economizar memória, é melhor simplemsnte desabilitar o cache do ZFS para o arquivo de banco de dados e deixar com que o banco faça o próprio gerenciamento:
# zfs set primarycache=metadata <pool>/postgres
Se sua pool não possui dispositivos de log, o ZFS reserva espaço dos discos de dados das pools para seu log (ZIL). O ZFS utiliza isso para recuperação em casos de "crash", mas bancos de dados geralmente sincronizam seus arquivos de dados para o sistema de arquivos dentro das confirmações de transações de qualquer forma. O resultado final é que o ZFS fará a gravação dos dados
duas vezes
, isto pode impactar severamente o desempenho. Você pode gerenciar para que o ZFS não use o ZIL, neste caso, os dados serão gravados no sistema de arquivos uma vez. Configurando isto para sistemas de arquivos não destinados à bancos de dados ou para pools com dispositivos com log configurados podem impactar
negativamente
o desempenho, então cuidado:
# zfs set logbias=throughput <pool>/postgres
Isto também pode ser feito durante a criação do sistema de arquvios, por exemplo:
# zfs create -o recordsize=8K \
             -o primarycache=metadata \
             -o mountpoint=/var/lib/postgres \
             -o logbias=throughput \
              <pool>/postgres
Por favor perceba: estes tipos de parâmetros de refinamento são ideais para aplicações especializadas como sistemas de bancos de dados relacionais. Você pode prejudicar o desempenho do ZFS ao configurar um sistema de arquivos de propósito generalizado como o seu diretório /home.
/tmp
Se você quiser usar o ZFS para armazenar seu diretório /tmp, o que pode ser útil para armazenar conjuntos de arquivos arbitrariamente grandes ou simplesmente manter sua RAM livre de dados, geralmente você pode melhorar o desempenho de certas aplicações que escrevem no /tmp desabilitando a sincronização do sistema de arquivos. Isto faz com que o ZFS ignore as requisições de sincronização das aplicações (e.g. com
fsync
ou
O_SYNC
) e retorne imediatamente.
Embora isso tenha sérias conseqüências de consistência de dados no lado de aplicações (nunca desative a sincronização para um banco de dados!), É menos provável que os arquivos em /tmp sejam importantes e afetados. Observe que isso
não
afeta a integridade do ZFS, apenas a possibilidade de que os dados esperados por um aplicativo no disco possam não ter sido gravados após um "crash".
# zfs set sync=disabled <pool>/tmp
Além disso, por motivos de segurança. você pode querer desabilitar
setuid
e
devices
no sistema de arquivos /tmp, o que impede alguns tipos de ataques de escalação de privilégios ou o uso de nós de dispositivos:
# zfs set setuid=off  <pool>/tmp
# zfs set devices=off <pool>/tmp
Combinar todos eles em um comando de criação é feito da seguinte forma:
# zfs create -o setuid=off -o devices=off -o sync=disabled -o mountpoint=/tmp <pool>/tmp
Por favor note, também. que se você deseja /tmp no ZFS, você precisará mascarar (desabilitar) o /tmp baseado em tmpfs automático do
systemd
, se não, o ZFS não será capaz de montar seu dataset durante a inicialização ou durante a etapa de importação:
# systemctl mask tmp.mount
Refinamento
Geral
Pools e datasets do ZFS podem ter ainda mais ajustes e refinamentos (tunings) utilizando parâmetros.
Nota
Todas as propriedades configuráveis, com exceção de quotas e reservas, herdam seu valor do dataset pai.
Para obter o status atual com os parâmetros da pool:
# zfs get all <pool>
Para obter o status atual com os parâmetros do dataset:
# zfs get all <pool>/<dataset>
Para desabilitar o tempo de acesso (atime), que é habilitado por padrão:
# zfs set atime=off <pool>
Para desabilitar o tempo de acesso (atime) em um dataset específico:
# zfs set atime=off <pool>/<dataset>
Uma alternativa a desabilitar o atime completamente, o
relatime
está disponível. Isto traz a semântica padrão do ext4/XFS ao ZFS, na qual o tempo de acesso somente é atualizado se o tempo de modificação ou tempo de criação é modificado, ou se o tempo existente de acesso não foi atualizado dentro das últimas 24 horas. É uma mistura entre
atime=off
e
atime=on
. Esta propriedade
só
tem efeito se
atime
estiver
on
.
# zfs set atime=on    <pool>
# zfs set relatime=on <pool>
Compression é apenas compressão transparente de dados. ZFS suporta poucos algoritmos, atualmente lz4 é o padrão,
gzip
também está disponível para dados raramente escrítos e ainda assim altamente compressível;  consulte mais detalhes na
Wiki do OpenZFS
(conteúdo em inglês) para mais detalhes.
Para habilitar compressão:
# zfs set compression=on <pool>
Para redefinir uma propriedade de uma pool ou dataset para o estado padrão, use
zfs inherit
:
# zfs inherit -rS atime <pool>
# zfs inherit -rS atime <pool>/<dataset>
Atenção
Usar a opção
-r
redefinirá recursivamente todos os datasets na zpool.
Esfregar
Quando dado é lido e o ZFS encontra erro, ele é silenciosamente reparado quando possível, reescrito de volta no disco e gera-se um log para que você possa obter uma visão geral de erros em suas pools. Não existe fsck ou ferramenta equivalenete para o ZFS. Ao invés disto, o ZFS suporta a opção de "esfregar". Isto percorre todos os dados na pool e verifica se todos os blocos podem ser lidos.
Para esfregar uma pool:
# zpool scrub <pool>
Para cancelar um esfregamento em execução:
# zpool scrub -s <pool>
Com que frequência devo fazer isto?
Da postagem no blog da Oracle
Disk Scrub - Why and When?
:
Esta pergunta é desafiadora até para o Supporte responder, porque como sempre a resposta correta é "Depende". Então antes que eu ofereça orientações gerais, aqui estão algumas dicas para lhe auxiliar a criar uma resposta mais apropriada para o seu padrão de uso.
Qual é a expiração do seu backup mais antigo? Você provavalmente deve esfregar seus dados pelo menos com a mesma frequência que as suas fitas mais antigas expiram para que você tenha um ponto de restauração que você saiba que é bom.
Com que frequência você experiencia falhas de disco? Embora o recrutamento de um disco hot-spare invoque um "resilver" -- um esfregamento direcionado apenas do VDEV que perdeu um disco -- você deve provavelmente esfregar pelo menos com a mesma frequência que você experiencia, em média, falhas de discos no seu ambiente.
Com que frequência o pedaço de dado mais antigo em seu disco é lido? Você deve esfregar ocasionalmente para que dados muito antigos e muito velhos não experienciem apodrecimento de bit "bit-rot" e morram sem que você perceba.
Se para qualquer uma das perguntas acima sua resposta seja "Não sei", a orientação geral é: você provavelmente deve esfregar sua zpool pelo menos uma vez por mês. É um agendamento que funciona bem para a maioria dos casos de uso, provê tempo suficiente para esfregamentos terminarem antes que outros sejam iniciados inclusive nos sistemas com maior carga, até mesmo deve concluir em zpools bem grandes (192 discos ou mais) antes que discos falhem.
No
ZFS Administration Guide
, de Aaron Toponce, ele aconselha esfregar discos de consumidores pelo menos uma vez por semana.
Iniciar com serviço ou timer
Usar um temporizador/serviço do
systemd
é possível para automaticamente esfregar pools.
Para realizar o esfregamento mensalmente de uma pool específica:
/etc/systemd/system/zfs-scrub@.timer
[Unit]
Description=Esfregar mensalmente a zpool em %i

[Timer]
OnCalendar=monthly
AccuracySec=1h
Persistent=true

[Install]
WantedBy=multi-user.target
/etc/systemd/system/zfs-scrub@.service
[Unit]
Description=Esfregar zpool em %i

[Service]
Nice=19
IOSchedulingClass=idle
KillSignal=SIGINT
ExecStart=/usr/bin/zpool scrub %i

[Install]
WantedBy=multi-user.target
Habilite e inicie
a unidade
zfs-scrub@
pool-pra-esfregar
.timer
para esfregar mensalmente a pool especificada.
Cache em SSD
Você pode adicionar dispositivos SSD com a inteção de gravar logs (ZIL ou SLOG externo) e também como um cache de substituição adaptável da camada 2 (L2ARC). O processo para adicioná-los é muito semelhante à adição de um novo VDEV.
Todas as referências abaixo à identificação do dispositivo são os IDs em
/dev/disk/by-id/*
.
SLOG
Para adicionar um SLOG espelhado:
# zpool add <pool> log mirror <identificação-do-dispositivo-1> <identificação-do-dispositivo-2>
Ou para acrescentar um único dispositivo SLOG (inseguro):
# zpool add <pool> log <identificação-do-dispositivo>
Como o dispositivo SLOG armazena dado que não foi escrito na pool, é importante usar dispositivos que podem finalizar escritas quando a energia é perdida. Também é importante utilizar redundância, já que a falha em um único dispositivo pode causar perda de dados. Além do mais, o SLOG é apenas utilizado para sincronizar escritas, então pode não auxiliar com melhorias de desempenho.
L2ARC
Para acrescentar L2ARC:
# zpool add <pool> cache <identificação-do-dispositivo>
Como cada bloco armazenado no L2ARC utiliza uma pequena quantidade de memória, geralmente só é útil em cargas onde o dado quente é *maior* que a quantidade total de memória que pode caber no computador, mas pequena suficiente para caber no L2ARC. O L2ARC também é limpo durante a reinicialização e é somente um cache de leitura, então a redundância é desnecessária. Não intuitivamente, L2ARC pode impactar no desempenho pois utiliza parte da memória que seria utilizada pelo ARC.
ZVOLs
Volumes de ZFS (ZVOLs) podem sofrer dos mesmos problemas relacionados à tamanho de blocos que SGBDRs, mas vale notar que o tamanho de registro padrão de ZVOLs já é 8KiB. Se possível, é melhor alinhar partições contidas em um ZVOL para o tamanho do seu recordsize (versões atuais de fdisk e gdisk por padrão automaticamente alinham segmentos de 1MiB, o que resolve), e tamanhos de blocos de sistema de arquivos para o mesmo tamanho. Mais do que isso, você pode ajustar o
recordsize
para acomodar os dados dentro do ZVOL conforme necessário (apesar que 8 KiB tende a ser um bom valor para a maioria dos sistemas de arquivos, mesmo ao utilizar blocos de 4 KiB naquele nível).
RAIDZ e discos físicos com Formatação Avançada
Cada bloco em um ZVOL possui seu próprio disco de paridade, e se você tiver mídias físicas com tamanhos de blocos de 4096B, 8192B ou assim por diante, a paridade precisa ser armazenada em blocos físicos inteiros, e isto pode drasticamente aumentar os requerimentos de espaço de um ZVOL, necessitando 2× ou mais capacidade de armazenamento do que a capacidade lógica do ZVOL. Definindo o
recordsize
como 16k ou 32k pode ajudar a reduzir drasticamente este efeito.
Veja
ZFS on Linux issue #1807 para detalhes
Escalonador de E/S
Quando a pool é importada, para vdevs que ocupam to o disco, o escalonador de E/S de dispositivos de bloco é definido através do
zfs_vdev_scheduler
[5]
(conteúdo em inglês). Os escalonadores mais comuns são
noop
,
cfq
,
bfq
, e
deadline
.
Em alguns casos, o escalonador não é mutável ao usar este método. Escalonadores que não podem ser mudados são:
scsi_mq
and
none
. Nestes casos, o escalonador permanece inalterado e uma mensagem de erro pode ser relatada nos logs.
Definindo manualmente
um dos escalonadores comuns através do
zfs_vdev_scheduler
pode resultar em desempenho mais consistente.
Solução de Problemas
Criação de uma zpool falha
Se o seguinte erro ocorrer, então é possível consertar.
# the Kernel failed to rescan the partition table: 16
# cannot label 'sdc': try using parted(8) and then provide a specific slice: -1
Uma razão para isto occorer é porque o
ZFS expera que a criação de uma pool leve menos que 1 segundo
(conteúdo em inglês). Esta é uma suposição razoável em condições normais, mas em muitas situações, pode levar mais tempo. Cada dispositivo precisará ser limpo novamente antes que alguma tentativa possa ser feita.
# parted /dev/sda rm 1
# parted /dev/sda rm 1
# dd if=/dev/zero of=/dev/sdb bs=512 count=1
# zpool labelclear /dev/sda
Uma criação com força bruta pode ser tentada repetidamente, e, com alguma sorte, a criação da ZPool levará menos que 1 segundo.
Uma causa para lentidão na criação pode ser picos de leitura e gravações lentos no dispositivo. Causando leitura no disco em paralelo à criação da ZPool, é possível acelerar a velocidade do pico.
# dd if=/dev/sda of=/dev/null
Isto pode ser feito com múltiplos dispositivos salvando o comando acima para cada dispositivo de armazenamento em uma linha diferente e executando
# cat $ARQUIVO | parallel
Então, rode a criação da ZPool ao mesmo tempo.
ZFS está utilizando muita RAM
Por padrão, o ZFS realiza o cache de operações nos arquivos (
ARC
- conteúdo em inglês), chegando a utilizar até ⅔ da memória disponível na máquina. Para ajustar o tamanho do ARC, acrescente o seguinte conteúdo à lista de
Parâmetros do kernel
:
zfs.zfs_arc_max=536870912 # (para 512MiB)
No caso em que o valor padrão de
zfs_arc_min
(1/32 da memória do sistema) seja maior do que o especificado
zfs_arc_max
, também é necessário acrescentar o seguinte na lista de
Parâmetros do kernel
:
zfs.zfs_arc_min=268435456 # (para 256MiB, precisa ser inferior ao do zfs.zfs_arc_max)
Para uma descrição mais detalhada, assim como outras opções de configuração, veja
gentoo-wiki:zfs#arc (Conteúdo em inglês)
.
Não contém um rótulo EFI
O seguinte erro irá ocorrer ao tentar criar o sistema de arquivos ZFS,
/dev/disk/by-id/<id> does not contain an EFI label but it may contain partition
Para supererar este erro, use
-f
junto ao comando zfs create.
Não encontrou hostid
Um erro que ocorre durante a inicialização com as seguintes linhas aparece antes da saída do scipt de inicialização:
ZFS: No hostid found on Kernel command line or /etc/hostid.
Este aviso ocorre pois o módulo do ZFS não tem acesso ao SPL hospedado. Existem duas soluções para isso. Ou insira a identificação do anfitrião (hostid) nos
Parâmetros do kernel
no gerenciador de inicialização, colocando
spl.spl_hostid=0x00bab10c
.
Ou garanta que existe um hostid em
/etc/hostid
, então
Gere novamente o initramfs
. Que irá copiar o hostid para a imagem do initramfs.
Pool não encontrada ao iniciar de dispositivos SAS/SCSI
Caso você esteja iniciando à partir de um SAS/SCSI, você pode ocasionalmente ter problemas de inicialização nos quais a pool que seu sistema está tentando utilizar para inicialização não pode ser encontrada. Uma possível razão para isto é que seus dispositivos foram inicializados tarde demais durante o processo. Isso significa que o ZFS não pode encontrar nenhum dispositivo no instante que tentou montar a pool.
Neste caso, você deve forçar o driver SCSI a aguardar para que os dispositivos estejam disponíveis antes de continuar. Você pode fazer isto inserindo o seguinte em
/etc/modprobe.d/zfs.conf
:
/etc/modprobe.d/zfs.conf
options scsi_mod scan=sync
Depois,
gere novamente o initramfs
.
Isto funciona pois o gancho do ZFS irá copiar o arquivo em
/etc/modprobe.d/zfs.conf
para o initcpio, que será então utilizado ao ser construído.
Durante a inicialização, a pool do ZFS não monta afirmando: "pool may be in use from other system"
Pool não exportada
Se a nova instalação não inicializa pois a zpool não pôde ser importada. Faça chroot para a instalação e exporte apropriadamente a zpool. Veja
#Conserto de emergência em chroot com archzfs
.
Uma vez dentro do ambiente chroot, carrege o módulo ZFS e force a importação da zpool:
# zpool import -a -f
Agora exporte a pool
# zpool export <pool>
Para ver as pools disponíveis:
# zpool status
É necessário exportar a pool devido à forma que o ZFS utiliza o hostid para descobrir o sistema no qual a zpool foi criada. O hostid é gerado parcialmente baseado na configuração da rede. Durante a instalação na archiso, a configuração de rede pode estar diferente, gerando um hostid diferente daquele contido na nova instalação. Uma vez que o sistema de arquivos ZFS é exportado e então reimportado na nova instalação, a hostid é redefinida. Veja o conteúdo em inglês
Re: Howto zpool import/export automatically? - msg#00227
.
Se o ZFS reclamar "a pool pode já estar em uso por outro sistema" mesmo após reinicializar, faça a exportação apropriadamente como descrito acima, então
gere novamente o initramfs
no sistema normalmente inicializado.
hostid incorreta
Verifique duas vezes se a pool foi exportada corretamente. Exportar a zpool limpa a hostid que marca a posse. Então durante a primeira inicialização, a zpool deve montar corretamente, caso não, exite outro problema.
Reinicie novamente, se a pool do zfs não for montada, significa que a hostid ainda não está propriamente definida durante o início da etapa de inicialização e isto confunde o ZFS. Manualmente informe ao zfs o número correto, uma vez que a hostid esteja coerente entre as reinicializações, a zpool montará corretamente.
Inicie utilizando zfs_force e escreva a hostid.
$ hostid
0a0af0f8
Este número deve ser acrescentado aos
Parâmetros do kernel
como
spl.spl_hostid=0x0a0af0f8
. Outra solução é escrever a hostid dentro da imagem de initramfs, veja a explicação no
guia de instalação
.
Usuários podem sempre ignorar a verificação e acrescentar
zfs_force=1
nos
Parâmetros do kernel
, mas não é aconselhável tornar esta a solução permanente.
Dispositivos possuem diferentes alinhamentos de setor
Uma vez que um dispositivo estiver com defeito, ele deve ser substituído o mais rapidamente possível, por um aparelho idêntico.
# zpool replace bigdata ata-ST3000DM001-9YN166_S1F0KDGY ata-ST3000DM001-1CH166_W1F478BD -f
Mas, neste exemplo, o seguinte erro ocorre:
cannot replace ata-ST3000DM001-9YN166_S1F0KDGY with ata-ST3000DM001-1CH166_W1F478BD: devices have different sector alignment
ZFS utiliza a opção ashift para se ajustar aos tamanhos de blocos físicos. Ao substituir o disco com defeito, ZFS tenta utilizar
ashift=12
, mas o discodefeituoso possivelmente utiliza outro valor de ashift (possivelmente
ashift=9
), e isto causa o erro acima.
Para Discos com Formatação Avançada com tamanho de bloco de 4KiB, um valor de ashift de 12 é recomendado para melhor desempenho. Veja os conteúdos em inglês
1.10 What’s going on with performance?
e
ZFS and Advanced Format disks
.
Use zdb para descobrir o valor de ashift para a ZPool -
zdb
- então use o argumento
-o
para definir o ashift no dispositivo que substituirá:
# zpool replace bigdata ata-ST3000DM001-9YN166_S1F0KDGY ata-ST3000DM001-1CH166_W1F478BD -o ashift=9 -f
Verifique o status da zpool para confirmar:
# zpool status -v
pool: bigdata
state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Mon Jun 16 11:16:28 2014
    10.3G scanned out of 5.90T at 81.7M/s, 20h59m to go
    2.57G resilvered, 0.17% done
config:

        NAME                                   STATE     READ WRITE CKSUM
        bigdata                                DEGRADED     0     0     0
        raidz1-0                               DEGRADED     0     0     0
            replacing-0                        OFFLINE      0     0     0
            ata-ST3000DM001-9YN166_S1F0KDGY    OFFLINE      0     0     0
            ata-ST3000DM001-1CH166_W1F478BD    ONLINE       0     0     0  (resilvering)
            ata-ST3000DM001-9YN166_S1F0JKRR    ONLINE       0     0     0
            ata-ST3000DM001-9YN166_S1F0KBP8    ONLINE       0     0     0
            ata-ST3000DM001-9YN166_S1F0JTM1    ONLINE       0     0     0

errors: No known data errors
Resilver de pool parado/preso/reiniciando/lento?
De acordo com o github do ZnL, este é um problema conhecido desde 2012 com ZFS-ZED, que faz com que o processo de resilver constantemente reinicie, as vezes fique parado/preso e geralmente lento em alguns hardwares. A mitigação mais simples é parar o zfs-zed.service até que o resilver complete.
Consertar inicialização lenta causada por falha na importação de pools indisponíveis no zpool.cache do initramfs
Seu tempo até inicializar pode ser significativamente impactado se a sua atualização do initramfs (ex: ao fazer a atualização do Kernel) quando você possui adicionais pools mas que não são permanentemente conectadas importadas porque estas pools serão acrescentadas ao zpool.cache e o ZFS tentará importar estas pools adicionais a cada inicialização, independentemente se você exportou e removeu do seu zpool.cache normal.
Se você perceber que o ZFS está tentando importar pools indisponíveis durante a inicialização, primeiro rode:
$ zdb -C
Para ver em seu zpool.cache pools que você não quer importadas durante a inicialização. Se este comando estiver mostrando pools adicionais, e não atualmente disponíveis, rode:
# zpool set cachefile=/etc/zfs/zpool.cache zroot
Para limpar o zpool.cache de quaisquer outras pools que não possuírem o nome zrool. Às vezes não é necessário redefinir o zpool.cache, mas simplesmente
gerar o initramfs novamente
Dicas e truques
Embutir os pacotes do archzfs na archiso
Siga os passos da
Archiso
para criar uma imagem live completamente funcional de CD/DVD/USB do Arch Linux.
Habilite o repositório do
archzfs
:
~/archlive/pacman.conf
...
[archzfs]
Server = http://archzfs.com/$repo/x86_64
SigLevel = Optional TrustAll
Acrescente o grupo
archzfs-linux
à lista de pacotes a serem instalados (o repositório do
archzfs
fornece os pacotes apenas para a arquitetura x86_64).
~/archlive/packages.x86_64
...
archzfs-linux
Complete a
compilação da ISO
para finalmente criar a ISO.
Nota
Se você posteriormente tiver problemas ao rodar modprobe zfs, você deve incluir linux-headers no packages.x86_64.
Snapshots automáticos
Serviço de snapshots automáticos do ZFS para o Linux
O pacote
zfs-auto-snapshot-git
AUR
AUR
fornece um script em shell para automatizar o gerenciamento de snapshots, com cada um recebendo o nome da data e rótulo (por hora, por dia, etc), fornecendo a obtenção rápida e conveniente de snapshots de todos os datasets do ZFS. O pacote também instala tarefas do cron para gerar snapshots a cada 15 minutos, hora, dia, semana e mês. Opcionalmente, ajuste o parâmetro
--keep
dos padrões dependendo da quantidade de tempo que você deseja que os snapshots existam (para o script mensal, a retenção é de até 1 ano).
Para impedir que um snapshots seja criado para um dataset específico, defina
com.sun:auto-snapshot=false
nele. Similarmente, tenha um controle mais refinado também definindo por rótulo, se, por exemplo, nenhum snapshot deva ser mantido para o período mensal definindo
com.sun:auto-snapshot:monthly=false
.
Nota
zfs-auto-snapshot-git não criará snapshots durante o
esfregamento
. É possível sobrescrever isto (
editando a unidade do systemd fornecida
) e removendo
--skip-scrub
na linha
ExecStart
.
Com o pacote já instalado,
habilite e inicie os temporizadores selecionados
(
zfs-auto-snapshot-{frequent,daily,weekly,monthly}.timer
).
zrepl
O pacote zrepl
zrepl
AUR
do
AUR
fornece um serviço de replicação automático, que pode ser também utilizado como um serviço para tirar snapshots, como o
snapper
.
Para detalhes em como configurar o daemon do zrepl, veja a
documentação
do zrepl. O arquivo de configuração deve estar em
/etc/zrepl/zrepl.yml
. Então, execute
zrepl configcheck
para ter certeza que a sintaxe do arquivo de configuração está correta. Finalmente, habilite
zrepl.service
.
Criando um compartilhamento
ZFS possui suporte para criares compartilhamentos (shares) por
NFS
ou
SMB
.
NFS
Assegure-se que
NFS
foi instalado/configurado, note que não há necessidade de editar o arquivo
/etc/exports
. Para compartilhar em cima de NFS, os serviços
nfs-server.service
e
zfs-share.service
deve ser
iniciado
.
Para tornar uma pool disponível na rede:
# zfs set sharenfs=on <nome-da-pool>
Para tornar um dataset disponível na rede:
# zfs set sharenfs=on <nome-da-pool>/<nome-do-dataset>
Para permitir acesso de leitura/escrita em um intervalo específico de IPs:
# zfs set sharenfs="rw=@192.168.1.100/24,rw=@10.0.0.0/24" <nome-da-pool>/<nome-do-dataset>
Para verificar se o dataset foi exportado com sucesso:
# showmount -e
hostname
Export list for hostname:
/path/of/dataset 192.168.1.100/24
Para ver as exportações atualmente carregadas com mais detalhes, use:
# exportfs -v
/path/of/dataset
    192.168.1.100/24(sync,wdelay,hide,no_subtree_check,mountpoint,sec=sys,rw,secure,no_root_squash,no_all_squash)
Para ver a lista atual de compartilhamentos em NFS do ZFS:
# zfs get sharenfs
SMB
Ao compartilhar através de SMB, usar
usershares
em
/etc/samba/smb.conf
permitirá ao ZFS configurar e criar os compartilhamentos.
# [global]
#    usershare path = /var/lib/samba/usershares
#    usershare max shares = 100
#    usershare allow guests = yes
#    usershare owner only = no
Crie e defina permissões no diretório do usuário como root.
# mkdir /var/lib/samba/usershares
# chmod +t /var/lib/samba/usershares
Para tornar disponível uma pool na rede:
# zfs set sharesmb=on <nome-da-zpool>
Para tornar disponível um dataset na rede:
# zfs set sharesmb=on <nome-da-zpool>/<nome-do-dataset>
Para verificar se o dataset foi exportado com sucesso:
# smbclient -L localhost -U%
Sharename       Type      Comment
        ---------       ----      -------
        IPC$            IPC       IPC Service (SMB Server Name)
        <nome-da-zpool>_<nome-do-dataset>        Disk      Comment: caminho/do/dataset
SMB1 disabled -- no workgroup available
Para ver a lista atual de compartilhamentos em SMB do ZFS:
# zfs get sharesmb
Criptografia no ZFS utilizando dm-crypt
A versão estável do ZFS no Linux não possuía suporte à criptografia (agora está disponível, veja
#Criptografia nativa
), mas zpools podem ser criados em dispositivos de bloco do dm-crypt. Já que a zpool é criada com a abstração plain-text (em texto simples, ou seja, não criptografado), é possível ter os dados criptografados e ainda aproveitar todas as vantagens do ZFS como deduplicação, compressão e robustez de dados.
dm-crypt, possivelmente através de LUKS, cria dispositivos em
/dev/mapper
e o nome é fixo. Então somente é necessário mudar o comando
zpool create
para apontar para aqueles nomes. A ideia é configurar o sistema para criar os dispositivos de bloco em
/dev/mapper
e importar as ZPools de lá. Como as ZPools podem ser criadas em múltiplos dispositivos (em RAID, espelhados, em faixas/striping, ...), é importante que todos os dispositivos estejam criptografados, caso não, a proteção poderá estar parcialmente perdida.
Por exemplo, uma ZPool criptografada pode ser criada usando somente dm-crypt (sem LUKS) com:
# cryptsetup --hash=sha512 --cipher=twofish-xts-plain64 --offset=0 \
             --key-file=/dev/sdZ --key-size=512 open --type=plain /dev/sdX enc
# zpool create zroot /dev/mapper/enc
No caso de uma pool para o sistema de arquivos do root, a linha dos HOOKS do
/etc/mkinitcpio.conf
precisa permitir o teclado para a senha, criar os dispositivos e carregar as pools, portanto, ficará similar ao seguinte:
HOOKS="... keyboard encrypt zfs ..."
Já que o nome
/dev/mapper/enc
é fixo, nenhum erro de importação ocorrerá.
Criar pools criptografadas funciona bem, no entanto, caso precise criptografar diretórios, por exemplo para proteger os diretórios pessoas dos usuários, o ZFS perde parte da funcionalidade.
ZFS enxergará o dado criptografado, não a abstração em texto simples, então a compressão e a deduplicação não funcionará. A razão é que o dado criptografado tem sempre alta entropia, fazendo com que a compressão seja ineficiente e até mesmo da mesma entrada, ocorrem saídas diferentes (graças ao
salt
), tornando a deduplicação impossível. Para reduzir sobrecarga desnecessária, é possível criar um subsistema de arquivos para cada diretório criptografado e usar
eCryptfs
nele.
Por exemplo, para ter o /home criptografado: (as duas senhas, de criptografia e login, devem ser a mesma).
# zfs create -o compression=off -o dedup=off -o mountpoint=/home/<nome-do-usuário> <zpool>/<nome-do-usuário>
# useradd -m <nome-do-usuário>
# passwd <nome-do-usuário>
# ecryptfs-migrate-home -u <nome-do-usuário>
<Faça o login e complete o procedimento com o ecryptfs-unwrap-passphrase>
Conserto de emergência em chroot com archzfs
Para entrar no sistema de arquivos ZFS à partir do sistema live para manutenção, existem duas opções:
Construa uma archiso personalizada com ZFS como descrito em
#Embutir os pacotes do archzfs na archiso
.
Inicialize na archiso oficial mais recente disponível, garanta acesso à rede, então habilite o repositório
archzfs
dentro do sistema live como de costume, sincronize o banco de dados de pacotes do pacman e instale o pacote
archzfs-archiso-linux
.
Para iniciar a recuperação, carregue o módulo do ZFS:
# modprobe zfs
Importe a pool:
# zpool import -a -R /mnt
Monte as partições de inicialização (se existir alguma):
# mount /dev/sda2 /mnt/boot
# mount /dev/sda1 /mnt/boot/efi
Faça o chroot para o sistema de arquivos ZFS:
# arch-chroot /mnt /bin/bash
Verifique a versão do Kernel:
# pacman -Qi linux
# uname -r
O comando uname mostrará a versão do Kernel na archiso. Se forem diferentes, execute depmod (no ambiente chroot) com a versão correta do Kernel da instalação do chroot:
# depmod -a 3.6.9-1-ARCH (versão obtida com pacman -Qi linux mas usando os módulos respectivos do Kernel dentro do /lib/modules no chroot)
Isto carregará os módulos corretos do Kernel para a versão do Kernel instalada durante a instalação do chroot.
Gere novamente o initramfs
. Não deve haver erros.
Montagem com bind
Aqui, uma montagem com bind do /mnt/zfspool para /srv/nfs4/musica é criada. A configuração garante que a pool de ZFS esteja pronta antes que a montagem com bind seja criada.
fstab
Veja
systemd.mount(5)
para mais informações em como o systemd converte fstab em unidades de montagem com o
systemd-fstab-generator(8)
, ambos os conteúdos são em inglês.
/etc/fstab
/mnt/zfspool		/srv/nfs4/musica		none	bind,defaults,nofail,x-systemd.requires=zfs-mount.service	0 0
Monitoração/envio de e-mails em eventos
Veja
ZED: The ZFS Event Daemon
para mais informações.
Um encaminhador de e-mail, como
S-nail
é necessário para conseguir isto. Teste para assegurar que está funcionando corretamente.
Descomente o seguinte no arquivo de configuração:
/etc/zfs/zed.d/zed.rc
ZED_EMAIL_ADDR="root"
 ZED_EMAIL_PROG="mailx"
 ZED_NOTIFY_VERBOSE=0
 ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
Mude 'root' em
ZED_EMAIL_ADDR="root"
para o endereço de e-mail no qual deseja receber as notificações.
Se você está mantendo o seu mailrc no seu diretório pessoal (home), você pode informar o mail para obter de lá configurando o
MAILRC
:
/etc/zfs/zed.d/zed.rc
export MAILRC=/home/<usuário>/.mailrc
Isto funciona pois o ZED lê este arquivo, então o
mailx
enxergara esta variável de ambiente.
Se você quer receber um e-mail, não importa o estado de sua pool, você deve definir
ZED_NOTIFY_VERBOSE=1
. Você precisa fazer isto temporariamente para testar.
Habilite e inicie
zfs-zed.service
.
Com
ZED_NOTIFY_VERBOSE=1
, você pode testar ao executar um esfregamento como root:
zpool scrub <nome-da-pool>
.
Utilizar comandos de shell antes e depois de snapshots
Já que é tão barato gerar um snapshot, podemos utilizar isto como medida de segurança para comandos sensíveis como atualização de pacotes e sistema. Se tirarmos um snapshot antes e um depois, é possível analisar as diferenças entre estes snapshots para descobrir o que foi modificado no sistema de arquivos depois que o comando foi executado. Além disso, podemos também voltar caso o resultado não tenha sido desejado.
E.g.:
# zfs snapshot -r zroot@pre
# pacman -Syu
# zfs snapshot -r zroot@post
# zfs diff zroot@pre zroot@post
# zfs rollback zroot@pre
Um utilitário que automatiza a criação anterior e posterior de snapshots envolvendo um comando do shell é
znp
.
E.g.:
# znp pacman -Syu
# znp find / -name "algo*" -delete
E você conseguirá snapshots antes e depois do comando fornecido, e também a saída do comando é inserida em logs de arquivos para referência futura, para que saibamos qual comando criou o diff visto em um par de snapshots pré/pós.
Desbloquear remotamente root ZFS criptografado
A partir do
PR #261
,
archzfs
suporta desbloqueio por SSH de datasets nativamente criptografados. Esta seção descreve como utilizar esta opção, e é amplamente baseada em
Dm-crypt/Specialties#Busybox based initramfs (built with mkinitcpio)
.
Instale
mkinitcpio-netconf
para fornecer os hooks (ganchos) para montar a rede inicial no espaço de usuário.
Escolha um servidor de SSH para usar no início do espaço do usuário. Opções mutualmente exclusivas são
mkinitcpio-tinyssh
ou
mkinitcpio-dropbear
.
Se utilizar
mkinitcpio-tinyssh
, também é recomendado instalar
tinyssh
ou
tinyssh-convert-git
AUR
. Esta ferramenta converte uma hostkey do OpenSSH existente para o formato de chave do TinySSH, preservando a impressão digital da chave e evitando avisos de conexão. Os scripts de instalação do mkinitcpio do TinySSH e Dropbear automaticamente converterão hostkeys existentes ao gerar uma imagem nova de initpcio.
Decida se irá utilizar uma chave de OpenSSH existente ou gerará uma nova (recomendado) para a máquina que se conectará e desbloqueará a máquina com ZFS criptografado. Copie a chave pública para
/etc/tinyssh/root_key
ou
/etc/dropbear/root_key
. Ao gerar a imagem de initcpio, este arquivo será adicionado às chaves autorizadas (
authorized_keys
) para o usuário root e somente é válida no ambiente initrd.
Decide whether to use an existing OpenSSH key or generate a new one (recommended) for the host that will be connecting to and unlocking the encrypted ZFS machine. Copy the public key into
/etc/tinyssh/root_key
or
/etc/dropbear/root_key
. When generating the initcpio image, this file will be added to
authorized_keys
for the root user and is only valid in the initrd environment.
Acrescente o
parâmetro do Kernel
ip=
à sua configuração do carregador de inicialização. A string
ip
é
altamente configurável (conteúdo em inglês)
. Um exemplo simples com DHCP é mostrado abaixo.
ip=:::::eth0:dhcp
Edite
/etc/mkinitcpio.conf
para incluir os ganchos
netconf
,
dropbear
ou
tinyssh
, e
zfsencryptssh
antes do gancho
zfs
:
HOOKS=(... netconf <tinyssh>|<dropbear> zfsencryptssh zfs ...)
Gere novamente o initramfs
.
Reinicie e teste!
Mudando a porta do servidor de SSH
Por padrão, ambos
mkinitcpio-tinyssh
e
mkinitcpio-dropbear
escutam na porta
22
. Para mudar isto.
Para
TinySSH
, copie
/usr/lib/initcpio/hooks/tinyssh
para
/etc/initcpio/hooks/tinyssh
, e encontre/modifique a seguinte linha na função
run_hook()
:
/etc/initcpio/hooks/tinyssh
/usr/bin/tcpserver -HRDl0 0.0.0.0 <nova-porta> /usr/sbin/tinysshd -v /etc/tinyssh/sshkeydir &
Para
Dropbear
, copie
/usr/lib/initcpio/hooks/dropbear
para
/etc/initcpio/hooks/dropbear
e encontre/modifique a seguinte linha na função
run_hook()
:
/etc/initcpio/hooks/tinyssh
/usr/sbin/dropbear -E -s -j -k -p <nova-porta>
Gere novamente o initramfs
.
Desbloquear à partir de uma máquina Windows usando PuTTY/Plink
Primeiro, precisamos usar
puttygen.exe
para importar e converter a chave de OpenSSH gerada mais cedo para o formato de chave privada do PuTTY
.ppk
. No exemplo abaixo chamado de
zfs_abrir.ppk
O processo acima do mkinitcpio-netconf não configura um shell (mas não é necessário). No entanto, como não existe um shell, o PuTTY fechará imediatamente após uma conexão bem sucedida. Isto pode ser desabilitado na configuração de SSH do PuTTY (
Connection -> SSH -> [X] Do not start a shell or command at all
), mas ainda não permite enxergar a saída padrão (stdout) ou entrar a frase de criptografia. Em vez disso, usaremos o
plink.exe
com os seguintes parâmetros:
plink.exe -ssh -l root -i C:\caminho\pro\zfs_abrir.ppk <hostname>
O comando do plink pode ser inserido em um script em lotes para simplificar o uso.
Veja também
Aaron Toponce's 17-part blog on ZFS
ZFS on Linux
ZFS on Linux FAQ
FreeBSD Handbook - O sistema de arquivos Z
Oracle Solaris ZFS Administration Guide
ZFS Best Practices Guide
ZFS Troubleshooting Guide
Tutorial on adding the modules to a custom Kernel
How to create cross platform ZFS disks under Linux
How-To: Using ZFS Encryption at Rest in OpenZFS (ZFS on Linux, ZFS on FreeBSD, …)