ZFS (Portuguê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.
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
Instale do repositório não-oficial archzfs ou, como alternativa, do AUR:
- zfs-linuxAUR: lançamento estável.
- zfs-linux-gitAUR: lançamento de desenvolvimento (com suporte às novas versões de Kernel).
- zfs-linux-ltsAUR: lançamento estável do Kernel LTS.
- zfs-linux-lts-gitAUR[link quebrado: package not found]: lançamento de desenvolvimento para o Kernel LTS.
- zfs-linux-hardenedAUR: lançamento estável do Kernel hardened.
- zfs-linux-hardened-gitAUR[link quebrado: package not found]: lançamento de desenvolvimento para o Kernel hardened.
- zfs-linux-zenAUR: lançamento estável do Kernel zen.
- zfs-linux-zen-gitAUR[link quebrado: package not found]: lançamento de desenvolvimento para o Kernel zen.
- zfs-dkmsAUR: lançamento com Dynamic Kernel Module Support (DKMS - Suporte a módulo de Kernel dinâmico).
- zfs-dkms-gitAUR: 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-dkmsAUR ou zfs-dkms-gitAUR e aplique as instruções de pós-instalação dadas por estes pacotes.
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 Experimenting with ZFS. 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>
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 ozfs-zed.service
está executando e só mude a propriedadecanmount
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 propriedadecanmount
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.
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
/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
$ UUID=$(lsblk --noheadings --output PARTUUID /dev/sdXY)
Criando pools ZFS
Para criar uma pool com ZFS:
# zpool create -f -m <montagem> <pool> [raidz(2|3)|mirror] <ids>
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.
blockdev --getpbsz /dev/sdXY
.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
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.
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
-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.
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.
- 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-gitAUR, zfs-dkms-gitAUR 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
paraaes-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.
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
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.
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>
-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.
Snapshots automáticos
Serviço de snapshots automáticos do ZFS para o Linux
O pacote zfs-auto-snapshot-gitAUR 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
.
--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 zreplAUR 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-gitAUR. 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 stringip
é 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 ganchosnetconf
,dropbear
outinyssh
, ezfsencryptssh
antes do ganchozfs
: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>
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, …)