Apêndice A. O Mapeador de Dispositivo
O Mapeador de Dispositivo é um driver do kernel que fornece uma estrutura para gerenciamento de volume. Ele fornece uma forma genérica de criar dispositivos mapeados, que podem ser usados como volumes lógicos. Isto não trata especificamente sobre grupos de volumes ou formatos de metadados.
O Mapeador de Dispositivos fornece a base para uma série de tecnologias de alto nível. Além do LVM, o Mapeador de Dispositivos multipath e o comando
dmraid
usam o Mapeador de Dispositivos. A interface de aplicação para o Mapeador de Dispositivos é a ioctl
system call. A interface de usuário é o comando dmsetup
.
Volumes lógicos LVM são ativados usando o Mapeador de Dispositivos. Cada volume lógico é convertido em um dipositivo mapeado. Cada segmento converte em uma linha na tabela de mapeamento que descreve o dispositivo. O Mapeador de Dispositivo suporta uma variedade de alvos de mapeamento, incluindo mapeamento linear, mapeamento distribuído e mapeamento de erro. Então, por exemplo, dois discos podem estar concatenados em um volume lógico com um par de mapeamentos lineares, uma para cada disco. Quando o LVM cria um volume, cria um dispositivo mapeado que pode ser consultado com o comando
dmsetup
. Para informações sobre o formato dos dispositivos em uma tabela mapeada, veja a Seção A.1, “Mapeamentos da Tabela de Dispositivo”. Para informações sobre o uso do comando dmsetup
para consultar um dispositivo, veja a Seção A.2, “O Comando dmsetup”.
A.1. Mapeamentos da Tabela de Dispositivo
Um dispositivo mapeado é definido por uma tabela que especifica como mapear cada classe de setores lógicos do dispositivo usando um mapeamento de Tabela de Dispositivo suportado. A tabela para um dispositivo mapeado é construída a partir de uma lista de linhas na forma:
start length mapping
[mapping_parameters...
]
Na primeira linha da tabela de um Dispositivo Mapeado, o parâmetro
start
deve ser igual a 0. Os parâmetros start
+ length
em uma linha devem ser iguais ao start
na próxima linha. Os parâmetros que são especificados em uma linha da tabela de mapeamento dependem de qual tipo mapping
é especificado na linha.
Tamanhos no Mapeador de Dispositivo são sempre especificados em setores (512 bytes).
Quando um dispositivo é especificado como um parâmetro de mapeamento no Mapeador de Dispositivos, ele pode ser referenciado pelo nome de dispositivo no sistema de arquivos (por exemplo,
/dev/hda
) ou pelos números maiores e menores no formato major
:minor
. O formato maior:menor é preferido por que evita pesquisas no caminho de nomes.
Segue um exemplo de tabela de mapeamento para um dispositivo. Nesta tabela existem quatro alvos lineares:
0 35258368 linear 8:48 65920 35258368 35258368 linear 8:32 65920 70516736 17694720 linear 8:16 17694976 88211456 17694720 linear 8:16 256
Os 2 primeiros parâmetros de cada linha são o início do bloco de segmento e a extensão do segmento. A próxima palavra é o alvo de mapeamento, no qual em todos os casos deste exemplo são
linear
. O resto de cada linha consiste de parâmetros para um alvo linear
.
As subseções a seguir descrevem o formato dos seguintes mapeamentos:
- linear
- distribuído
- espelho
- snapshot e origem de snapshot
- erro
- zero
- multipath
- crypt
A.1.1. O Alvo do Mapeamento Linear
O alvo do mapeamento linear mapeia uma variação contínua de blocos em outro dispositivo de bloco. O formato de um alvo linear é o seguinte:
start length
lineardevice offset
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
device
- dispositivo de bloco, referenciado pelo nome do dispositivo no sistema de arquivo ou pelos números maiores ou menores no formato
major
:minor
offset
- offset inicial do mapeamento no dispositivo
O seguinte exemplo exibe um alvo linear com um início de bloco no dispositivo virtual de 0, um comprimento de segmento de 1638400, um par de números maior:menor de 8:2 e um offset inicial de dispositivo de 41146992.
0 16384000 linear 8:2 41156992
O exemplo a seguir exibe um alvo linear com o parâmetro de dispositivo especificado como o dispositivo
/dev/hda
.
0 20971520 linear /dev/hda 384
A.1.2. O Alvo de Mapeamento distribuído
O alvo de mapeamento distribuído suporta distribuições em dispositivos físicos. Ele toma como argumentos o número de distribuições e os tamanhos das partes distribuídas seguido de uma lista de pares de nomes de dispositivos e setores. O formato do alvo distribuído é o seguinte:
start length
striped#stripes chunk_size device1 offset1 ... deviceN offsetN
Existe um conjunto de parâmetros de
device
e offset
para cada distribuição.
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
#stripes
- número de distribuições para o dispositivo virtual
chunk_size
- número de setores gravados em cada distribuição antes de mudar para a próxima, deve ser potência de 2 pelo menos e tão grande quanto o tamanho de página do kernel.
device
- dispositivo de bloco, referenciado pelo nome do dispositivo no sistema de arquivos ou pelos números maiores e menores no formato
major
:minor
. offset
- offset inicial do mapeamento no dispositivo
O exemplo a seguir demonstra um alvo distribuído com três distribuições e uma parte de tamanho 128:
0 73728 striped 3 128 8:9 384 8:8 384 8:7 9789824
- 0
- bloco inicial em um dispositivo virtual
- 73728
- comprimento deste segmento
- striped 3 128
- distribuição em três dispositivos com tamanho em partes de 128 blocos
- 8:9
- números major:minor do primeiro dispositivo
- 384
- offset inicial de mapeamento no primeiro dispositivo
- 8:8
- números major:minor do segundo dispositivo
- 384
- offset inicial de mapeamento no segundo dispositivo
- 8:7
- números major: minor do terceiro dispositivo
- 9789824
- offset inicial do mapeamento no terceiro dispositivo
O exemplo seguinte mostra um alvo distribuído para 2 distribuições com partes de 256 KiB, com os parâmetros de dispositivo especificados pelos nomes de dispositivos no sistema de arquivo ao invés dos números maiores e menores.
0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0
A.1.3. O Alvo de Mapeamento do espelho
O alvo de mapeamento de espelho suporta o mapeamento de um dispositivo lógico espelhado. O formato de um alvo espelhado é como se segue:
start length
mirrorlog_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
log_type
- Os tipos de log possíveis e seus argumentos são como se segue:
core
- O espelho é local e o log do espelho é mantido na memória do núcleo. Este tipo de log leva 1 - 3 argumentos:regionsize [[
no
]sync
] [block_on_error
] disk
- O espelho é local e o log do espelho é mantido no disco. Este tipo de log leva de 2 - 4 argumentos:logdevice regionsize [[
no
]sync
] [block_on_error
] clustered_core
- O espelho é clusterizado e o log do espelho é mantido na memória do núcleo. Este tipo de log leva de 2 - 4 argumentos:regionsize UUID [[
no
]sync
] [block_on_error
] clustered_disk
- O espelho é clusterizado e o log do espelho é mantido no disco. Este tipo de log leva de 3 - 5 argumentos:logdevice regionsize UUID [[
no
]sync
] [block_on_error
]
O LVM mantém um log pequeno que é usado para manter o controle de quais regiões estão em sync com o espelho ou espelhos. O argumento regionsize especifica o tamanho dessas regiões.Em um ambiente clusterizado, o argumento UUID é um único indentificador associado com o log do dispositivo espelho para que o estado do log possa ser mantido através de todo o cluster.O argumento opcional[no]sync
pode ser usado para especificar o espelho como "in-sync" ou "out-of-sync". O argumentoblock_on_error
é usado para dizer ao espelho para responder aos erros e não ignora-los. #log_args
- número de argumentos de log que serão especificados no mapeamento
logargs
- os argumentos de logs para o espelho; o número de argumentos de logs fornecido é especificado pelo parâmetro
#log-args
e os argumentos de logs válidos são determinados pelo parâmetrolog_type
. #devs
- o número de pernas no espelho; um dispositivo e um offset são especificados para cada perna.
device
- dispositivo de bloco para cada perna do espelho, referenciados pelo nome do dispositivo no sistema de arquivos ou pelos números maiores e menores no formato
major
:minor
. Um dispositivo de bloco e offset são especificados para cada perna do espelho, como indicado pelo parâmetro#devs
. offset
- offset inicial do mapeador no dispositivo. Um dispositivo de bloco e offset são específicados para cada perna do espelho, como indicado pelo parâmetro
#devs
.
O exemplo a seguir demonstra um alvo de mapeamento de espelho para um espelho clusterizado com um log de espelho mantido no disco.
0 52428800 mirror clustered_disk 4 253:2 1024 UUID block_on_error 3 253:3 0 253:4 0 253:5 0
- 0
- bloco inicial em um dispositivo virtual
- 52428800
- comprimento deste segmento
- mirror clustered_disk
- o alvo do espelho com o tipo de log especificando que aquele espelho está clusterizado e o log do espelho é mantido no disco.
- 4
- 4 argumentos de log de espelho seguirão
- 253:2
- números de dispositivo de log major: minor
- 1024
- tamanho da região que o log do espelho usa para manter registro do que está em sincronia
UUID
- UUID do dispositivo do log de espelho para manter a informação do log em todo o cluster
block_on_error
- espelho deve responder a erros
- 3
- número de pernas no espelho
- 253:3 0 253:4 0 253:5 0
- números major:minor e offset para dispositivos que constituem cada perna de um espelho
A.1.4. O Alvo de Mapeamento Snapshot e snapshot-origem
Quando você criar o primeiro snapshot LVM de um volume, quatro dispositivos do Mapeador de Dispositivo serão usados:
- Um dispositivo com um mapeamento
linear
contendo a tabela de mapeamento original do volume fonte. - Um dispositivo com um mapeamento
linear
usado como dispositivo copy-on-write (COW) para o volume de origem; para cada escrita, os dados originais são salvos no dispositivo COW de cada snapshot para manter seu conteúdo visível inalterado (até o dispositivo COW encher). - Um dispositivo com um mapeamento
snapshot
combinando o #1 e #2, os quais são volumes snapshot visíveis. - O volume "original" (que usa o número de dispositivo usado pelo volume fonte original), o qual a tabela é substituida por um mapeador "snapshot-origin" do dispositivo #1.
Um esquema de nomeação fixo é usado para criar dispositivos. Por exemplo, você poderá usar os seguintes comandos para criar um volume LVM chamado
base
e um volume snapshot chamado snap
baseado nesse volume.
#lvcreate -L 1G -n base volumeGroup
#lvcreate -L 100M --snapshot -n snap volumeGroup/base
Isso produz quatro dispositivos, que você pode ver com os seguintes comandos:
#dmsetup table|grep volumeGroup
volumeGroup-base-real: 0 2097152 linear 8:19 384 volumeGroup-snap-cow: 0 204800 linear 8:19 2097536 volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16 volumeGroup-base: 0 2097152 snapshot-origin 254:11 #ls -lL /dev/mapper/volumeGroup-*
brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
O formato para o alvo
snapshot-origin
se segue:
start length
snapshot-originorigin
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
origin
- volume base do snapshot
O
snapshot-origin
terá normalmente um ou mais snapshots baseados nele. Leituras serão mapeadas diretamente para o dispositivo de suporte. Para cada gravação, os dados originais serão salvos no dispositivo COW de cada snapshot para manter inalterados o seu conteúdo visível até que o dispositivo COW encha.
O formato para o alvo
snapshot
é como se segue:
start length
snapshotorigin COW-device
P|Nchunksize
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
origin
- volume base do snapshot
COW-device
- Dispositivo no qual as partes modificadas de dados são armazenadas
- P|N
- P (Persistente) ou N (Não persistente); indica se o snapshot sobreviverá após o reboot. Para snapshots transientes (N), menos metadados devem ser salvos no disco; eles podem ser mantidos na memória pelo kernel.
chunksize
- Tamanho em setores de partes modificadas de dados que serão armazenados no dispositivo COW.
O exemplo a seguir mostra um alvo
snapshot-origin
com um dispositivo original de 254:11.
0 2097152 snapshot-origin 254:11
O seguinte exemplo exibe um alvo
snapshot
com um dispositivo de origem de 254:11 e um dispositivo COW de 254:12. Este dispositivo snapshot é persistente em reboots e os tamanhos das partes para os dados armazenados no dispositivo COW é de 16 setores.
0 2097152 snapshot 254:11 254:12 P 16
A.1.5. O Alvo de Mapeamento de erro
Com um alvo de mapeamento de erro, qualquer operação de E/S no setor mapeado irá falhar.
Um alvo de mapeamento de erro pode ser usado para testes. Para testar como o dispositivo se comportará durante uma falha, você pode criar um mapeador de dispositivo com um setor defeituoso no meio de um dispositivo ou você pode trocar a perna de um espelho e substituir a perna com um alvo errado.
Um alvo de erro pode ser usado no lugar de um dispositivo com falha, como uma maneira de evitar tempos de espera e tentativas no dispositivo em questão. Ele pode servir como um alvo intermediário enquanto você re-organiza os metadados LVM durantes falhas.
O alvo de mapeamento
error
não leva parâmetros adicionais além dos parâmetros start e length.
O exemplo a seguir mostra um alvo
error
.
0 65536 error
A.1.6. O Alvo de Mapeamento zero
O alvo de mapeamento zero é um dispositivo de bloco equivalente a
/dev/zero
. A operação de leitura para este mapeamento retorna blocos de zeros. Dados escritos para este mapeamento são descartados, mas a escrita é bem sucedida. O alvo de mapeamento zero
não leva parâmetros adicionais além do parâmetros start e length.
O seguinte exemplo mostra um alvo
zero
para o Dispositivo 16Tb.
0 65536 zero
A.1.7. O Alvo de Mapeamento multipath
O alvo de mapeamento multipath suporta o mapeamento de um dispositivo multipath. O formato para o alvo
multipath
é como segue:
start length
multipath
#features [feature1 ... featureN] #handlerargs [handlerarg1 ... handlerargN] #pathgroups pathgroup pathgroupargs1 ... pathgroupargsN
Existe um conjunto de parâmetros de
pathgroupargs
para cada grupo de path.
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
#features
- A quantidade de características de multipath, seguidos pelas características. Se este parâmetro for zero, então não há parâmetro
feature
e o próximo parâmetro do dispositivo de mapeamento é#handlerargs
. Atualmente há uma característica multipath suportada,queue_if_no_path
. Esta indica que o dispositivo multipath está atualmente configurado para enfileirar operações de E/S se não houver um path disponível.Por exemplo, se a opçãono_path_retry
no arquivomultipath.conf
foi configurado para enfileirar operações de E/S somente até que todos os paths tenham sido marcados como reprovados após que um certo número de tentativas foram feitas para usar os paths, o mapeamento apareceria como a seguir até que todos os controladores de paths falhem o número de vezes especificadas.0 71014400 multipath 1 queue_if_no_path 0 2 1 round-robin 0 2 1 66:128 \ 1000 65:64 1000 round-robin 0 2 1 8:0 1000 67:192 1000
Após todos os controladores de paths falharem o número de vezes especificadas, o mapeamento aparece como a seguir:0 71014400 multipath 0 0 2 1 round-robin 0 2 1 66:128 1000 65:64 1000 \ round-robin 0 2 1 8:0 1000 67:192 1000
#handlerargs
- A quantidade de argumentos do manipulador de hardware, seguido por estes argumentos. Um manipulador de hardware especifica um módulo que será usado para executar ações específicas de hardware quando trocando grupos de paths ou manipulando erros de E/S. Se este é configurado como 0, então o próximo parâmetro é
#pathgroups
. #pathgroups
- O número de grupos paths. Um grupo paths é o conjunto de caminhos em que um dispositivo multipath irá carregar equilíbrio. Há uma configuração de parâmetro
pathgroupargs
para cada grupo de path. pathgroup
- O próximo grupo de caminho a ser tentado
pathgroupsargs
- Cada grupo de caminho consiste dos seguintes argumentos:
pathselector #selectorargs #paths #pathargs device1 ioreqs1 ... deviceN ioreqsN
Existe um conjunto de argumentos de path para cada caminho no grupo.pathselector
- Especifica o algorítmo em uso para determinar qual path neste grupo de caminho usar para a próxima operação de E/S.
#selectorargs
- O número de argumentos seletores de path que seguem este argumento no mapeador multipath. Atualmente, o valor deste argumento é sempre 0.
#paths
- O número de paths neste grupo de caminho
#pathargs
- O número de argumentos path especificados para cada caminho neste grupo. Atualmente este número é sempre 1, o argumento
ioreqs
. device
- O número do dispositivo de bloco de path, referenciado pelos números maiores e menores no formato
major
:minor
ioreqs
- O número de requisições de E/S para rotear neste caminho antes de mudar para o caminho seguinte no grupo atual.
A Figura A.1, “Alvo de Mapeamento Multipath” mostra o formato de um alvo multipath com dois grupos de caminho.
Figura A.1. Alvo de Mapeamento Multipath
O exemplo seguinte mostra uma pura definição de alvo failover no mesmo dispositivo multipath. Neste alvo existem 4 grupos de caminho, com somente um caminho aberto por grupo de caminho, então o dispositivo multpath usará somente um caminho por vez.
0 71014400 multipath 0 0 4 1 round-robin 0 1 1 66:112 1000 \ round-robin 0 1 1 67:176 1000 round-robin 0 1 1 68:240 1000 \ round-robin 0 1 1 65:48 1000
O exemplo seguinte mostra uma definição de propagação (multibus) de alvo para o mesmo dispositivo multipathed. Neste alvo há somente um grupo de caminho, que inclui todos os paths. Nesta configuração, multipath distribui a carga uniformemente a todos os caminhos.
0 71014400 multipath 0 0 1 1 round-robin 0 4 1 66:112 1000 \ 67:176 1000 68:240 1000 65:48 1000
Para mais informações sobre multipathing, veja o documento Utilizando o Mapeador de Dispositivo Multipath
A.1.8. O Alvo de Mapeamento crypt.
O alvo
crypt
criptografa os dados passando pelo dispositivo especificado. Ele utiliza o kernelCrypto API.
O formato para o alvo
crypt
é como a seguir:
start length
cryptcipher key IV-offset device offset
start
- bloco inicial em um dispositivo virtual
length
- comprimento deste segmento
cipher
- O cipher consiste de
cipher[-chainmode]-ivmode[:iv options]
.cipher
- Ciphers disponíveis estão listados em
/proc/crypto
(por exemplo,aes
). chainmode
- Sempre use o
cbc
. Não use oebc
; pois este não utiliza um vetor inicial (IV). ivmode[:iv options]
- IV é um setor inicial usado para variar a criptografia. O modo IV é
plain
ouessiv:hash
. Umivmode
do-plain
usa o número de setor (mais offset IV) como o IV. Umivmode
do-essiv
é um aprimoramento para evitar a fraqueza de marca d'agua.
key
- A chave de criptografia, fornecida em hex
IV-offset
- Vetor inicial (IV) offset
device
- dispositivo de bloco, referenciado pelo nome do dispositivo no sistema de arquivo ou pelos números maiores ou menores no formato
major
:minor
offset
- offset inicial do mapeamento no dispositivo
Segue um exemplo de um alvo
crypt
0 2097152 crypt aes-plain 0123456789abcdef0123456789abcdef 0 /dev/hda 0