mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
A handful of late-arriving changes, most of which were ready ahead of the
merge window:
- More Portuguese translation updates
- Some docs-build and self-test fixes
- Bring documentation for the user-space access primitives in
include/linux/uaccess.h into the docs build. This revealed a number of
malformed kerneldoc comments, which are fixed in a subsequent tweak to
uaccess.h.
-----BEGIN PGP SIGNATURE-----
iQFDBAABCgAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAmriEykPHGNvcmJldEBs
d24ubmV0AAoJEBdDWhNsDH5YC9IH/ikTCYIK+3Nz8odNLbEh505Ug0KDaAK6Cux5
Wb6eKpMaLfwxMojV80V8/lZMMmKzkeGWRO60TgF4V6MNdziOuj2UoFNIx/M+9jkw
5kPsc/vwGdtt2bR7FN1GKbchH9sh22Baw0aCTk+ymMMTFqDHDJ7qXrCfvm8MNAXg
8+xPr9acR4hYy9Bd8HOKx+noym8qmRvLqeznM5hvOBlQtYk5ZJWwIfuiiH61pzyv
89BrR9fMhObO/5ObSv9OpxFR+28SeB2986zXw1HTyskCrFes9s0Dd6EQfVvL6NxV
ldCt1odfoyAa5KJurvJ3piILJANrcID5PBDlqN/T8jG9oO6gxRc=
=xUko
-----END PGP SIGNATURE-----
Merge tag 'docs-7.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/docs/linux
Pull more documentation updates from Jonathan Corbet:
"A handful of late-arriving changes, most of which were ready ahead of
the merge window:
- More Portuguese translation updates
- Some docs-build and self-test fixes
- Bring documentation for the user-space access primitives
in include/linux/uaccess.h into the docs build.
This revealed a number of malformed kerneldoc comments,
which are fixed in a subsequent tweak to uaccess.h"
* tag 'docs-7.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/docs/linux:
uaccess: fix some erroneous kerneldoc comments
docs/translations/pt_BR: admin-guide: add efi-stub.rst
docs/translations/pt_BR: admin-guide: add kernel-parameters.rst
docs/translations/pt_BR: admin-guide: add bootconfig.rst
docs/translations/pt_BR: admin-guide: add perf-security.rst
docs/translations/pt_BR: admin-guide: add LSM/index.rst
docs/translations/pt_BR: admin-guide: add hw-vuln/index.rst
docs/translations/pt_BR: admin-guide: add cputopology.rst
docs/translations/pt_BR: admin-guide: add sysctl/index.rst
docs/translations/pt_BR: admin-guide: add sysfs-rules.rst
docs/translations/pt_BR: admin-guide: add features.rst
docs: pt_BR: process: translate userspace debugging guide
docs: kerneldoc.py: preserve headings in kernel-doc output
docs: xforms_lists: Handle DECLARE_KHOSER_PTR() struct members
docs: test_doc_build: don't select urllib3 yanked version
docs: test_doc_build: address pylint warnings
docs: test_doc_build: update it to support newer Sphinx versions
docs: test_doc_build: better handle python version
docs: admin-guide: Fix typo in kernel-parameters.txt
docs: core-api: include documentation from linux/uaccess.h
This commit is contained in:
commit
cb01c6914e
|
|
@ -6242,7 +6242,7 @@ Kernel parameters
|
|||
rcutorture.stall_only= [KNL]
|
||||
Shut off all rcutorture kthreads other than the
|
||||
RCU CPU stall-warning test kthreads. The purpose
|
||||
of this is to test production applictions'
|
||||
of this is to test production applications'
|
||||
reactions to CPU stalls, and with minimal
|
||||
additional overhead. Or you can omit the
|
||||
stall-warning tests as well and get a heavy
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ User Space Memory Access
|
|||
.. kernel-doc:: arch/x86/include/asm/uaccess.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: include/linux/uaccess.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: arch/x86/lib/usercopy_32.c
|
||||
:export:
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ from docutils.statemachine import ViewList
|
|||
from docutils.parsers.rst import directives, Directive
|
||||
import sphinx
|
||||
from sphinx.util.docutils import switch_source_input
|
||||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
from sphinx.util import logging
|
||||
from pprint import pformat
|
||||
|
||||
|
|
@ -252,7 +253,7 @@ class KernelDocDirective(Directive):
|
|||
|
||||
def do_parse(self, result, node):
|
||||
with switch_source_input(self.state, result):
|
||||
self.state.nested_parse(result, 0, node, match_titles=1)
|
||||
nested_parse_with_titles(self.state, result, node)
|
||||
|
||||
def setup_kfiles(app):
|
||||
global kfiles
|
||||
|
|
|
|||
53
Documentation/translations/pt_BR/admin-guide/LSM/index.rst
Normal file
53
Documentation/translations/pt_BR/admin-guide/LSM/index.rst
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===========================================
|
||||
Uso dos Módulos de Segurança do Linux (LSM)
|
||||
===========================================
|
||||
|
||||
O framework dos Módulos de Segurança do Linux (LSM - Linux Security Module)
|
||||
fornece um mecanismo para que várias verificações de segurança sejam interceptadas
|
||||
por novas extensões do kernel. O nome "módulo" é um pouco impróprio, já que essas
|
||||
extensões não são, na verdade, módulos carregáveis do kernel. Em vez disso, elas
|
||||
são selecionáveis em tempo de compilação via CONFIG_DEFAULT_SECURITY e podem ser
|
||||
substituídas em tempo de inicialização pelo argumento de linha de comando do
|
||||
kernel ``"security=..."``, no caso em que múltiplos LSMs foram compilados em um
|
||||
determinado kernel.
|
||||
|
||||
Os principais usuários da interface LSM são as extensões de Controle de Acesso
|
||||
Obrigatório (MAC - Mandatory Access Control), que fornecem uma política de
|
||||
segurança abrangente. Os exemplos incluem SELinux, Smack, Tomoyo e AppArmor. Além
|
||||
das extensões MAC maiores, outras extensões podem ser construídas usando o LSM
|
||||
para fornecer alterações específicas na operação do sistema quando esses ajustes
|
||||
não estão disponíveis na funcionalidade principal do próprio Linux.
|
||||
|
||||
Os módulos de capacidades do Linux sempre serão incluídos. Isso pode ser seguido
|
||||
por qualquer número de módulos "menores" (minor) e no máximo um módulo "maior"
|
||||
(major). Para obter mais detalhes sobre capacidades, consulte ``capabilities(7)``
|
||||
no projeto Linux man-pages.
|
||||
|
||||
Uma lista dos módulos de segurança ativos pode ser encontrada lendo
|
||||
``/sys/kernel/security/lsm``. Esta é uma lista separada por vírgulas e sempre
|
||||
incluirá o módulo de capacidade. A lista reflete a ordem na qual as verificações
|
||||
são feitas. O módulo de capacidade sempre será o primeiro, seguido por quaisquer
|
||||
módulos "menores" (por exemplo, Yama) e depois pelo módulo "maior" (por exemplo,
|
||||
SELinux), se houver um configurado.
|
||||
|
||||
Os atributos de processo associados aos módulos de segurança "maiores" devem ser
|
||||
acessados e mantidos usando os arquivos especiais em ``/proc/.../attr``. Um módulo
|
||||
de segurança pode manter um subdiretório específico do módulo lá, nomeado após o
|
||||
módulo. ``/proc/.../attr/smack`` é fornecido pelo módulo de segurança Smack e
|
||||
contém todos os seus arquivos especiais. Os arquivos diretamente em
|
||||
``/proc/.../attr`` permanecem como interfaces legadas para módulos que fornecem
|
||||
subdiretórios.
|
||||
|
||||
Todolist:
|
||||
|
||||
* apparmor
|
||||
* LoadPin
|
||||
* SELinux
|
||||
* Smack
|
||||
* tomoyo
|
||||
* Yama
|
||||
* SafeSetID
|
||||
* ipe
|
||||
* landlock
|
||||
425
Documentation/translations/pt_BR/admin-guide/bootconfig.rst
Normal file
425
Documentation/translations/pt_BR/admin-guide/bootconfig.rst
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================
|
||||
Configuração de boot
|
||||
====================
|
||||
|
||||
:Autor: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
|
||||
Visão geral
|
||||
===========
|
||||
|
||||
A configuração de boot expande a linha de comando atual do kernel para suportar
|
||||
dados adicionais de chave-valor ao inicializar o kernel de forma eficiente.
|
||||
Isso permite que os administradores passem um arquivo de configuração estruturado
|
||||
por chaves.
|
||||
|
||||
Sintaxe do arquivo de configuração
|
||||
==================================
|
||||
|
||||
A sintaxe de configuração de boot é uma estrutura simples de chave-valor. Cada
|
||||
chave consiste em palavras conectadas por pontos, e a chave e o valor são
|
||||
conectados por ``=``. A string de valor deve ser terminada pelos seguintes
|
||||
delimitadores descritos abaixo.
|
||||
|
||||
Cada palavra-chave deve conter apenas letras do alfabeto, números, traço (``-``)
|
||||
ou sublinhado (``_``). E cada valor contém apenas caracteres imprimíveis ou espaços,
|
||||
exceto delimitadores como ponto e vírgula (``;``), quebra de linha (``\n``),
|
||||
vírgula (``,``), cerquilha (``#``) e chave de fechamento (``}``).
|
||||
|
||||
Se o ``=`` for seguido por espaços em branco até um desses delimitadores, a chave
|
||||
será atribuída a um valor vazio.
|
||||
|
||||
Para arrays, os valores do array são separados por vírgula (``,``), e comentários
|
||||
e quebras de linha com nova linha (``\n``) são permitidos entre os valores do array
|
||||
para facilitar a legibilidade. Assim, a primeira entrada do array deve estar na
|
||||
mesma linha da chave.::
|
||||
|
||||
CHAVE[.PALAVRA[...]] = VALOR[, VALOR2[...]][;]
|
||||
|
||||
Diferente da sintaxe de linha de comando do kernel, espaços em branco (incluindo
|
||||
tabs) são ignorados ao redor da vírgula e do ``=``.
|
||||
|
||||
Se você quiser usar esses delimitadores em um valor, pode usar aspas duplas
|
||||
(``"VALOR"``) ou aspas simples (``'VALOR'``) para colocá-lo entre aspas. Observe
|
||||
que você não pode escapar essas aspas.
|
||||
|
||||
Pode haver uma chave que não tenha valor ou tenha um valor vazio. Essas chaves
|
||||
são usadas para verificar se a chave existe ou não (como um booleano).
|
||||
|
||||
Sintaxe de chave-valor
|
||||
----------------------
|
||||
|
||||
A sintaxe do arquivo de configuração de boot permite que o usuário mescle chaves
|
||||
com palavras parcialmente iguais usando chaves (braces). Por exemplo::
|
||||
|
||||
foo.bar.baz = value1
|
||||
foo.bar.qux.quux = value2
|
||||
|
||||
Elas também podem ser escritas assim::
|
||||
|
||||
foo.bar {
|
||||
baz = value1
|
||||
qux.quux = value2
|
||||
}
|
||||
|
||||
Ou de forma mais concisa, escrita da seguinte maneira::
|
||||
|
||||
foo.bar { baz = value1; qux.quux = value2 }
|
||||
|
||||
Em ambos os estilos, as mesmas palavras-chave são mescladas automaticamente ao
|
||||
serem analisadas no momento da inicialização. Assim, você pode anexar árvores ou
|
||||
pares de chave-valor semelhantes.
|
||||
|
||||
Valores com a mesma chave
|
||||
-------------------------
|
||||
|
||||
É proibido que dois ou mais valores ou arrays compartilhem a mesma chave.
|
||||
Por exemplo::
|
||||
|
||||
foo = bar, baz
|
||||
foo = qux # !ERRO! não podemos redefinir a mesma chave
|
||||
|
||||
Se você quiser atualizar o valor, deve usar o operador de substituição (override)
|
||||
``:=`` explicitamente. Por exemplo::
|
||||
|
||||
foo = bar, baz
|
||||
foo := qux
|
||||
|
||||
então, ``qux`` é atribuído à chave ``foo``. Isso é útil para sobrescrever o
|
||||
valor padrão adicionando bootconfigs personalizados (parciais) sem precisar
|
||||
analisar o bootconfig padrão.
|
||||
|
||||
Se você quiser anexar o valor a uma chave existente como membro de um array,
|
||||
pode usar o operador ``+=``. Por exemplo::
|
||||
|
||||
foo = bar, baz
|
||||
foo += qux
|
||||
|
||||
Neste caso, a chave ``foo`` conterá ``bar``, ``baz`` e ``qux``.
|
||||
|
||||
Além disso, subchaves e um valor podem coexistir sob uma chave pai.
|
||||
Por exemplo, a seguinte configuração é permitida::
|
||||
|
||||
foo = value1
|
||||
foo.bar = value2
|
||||
foo := value3 # Isto atualizará o valor de foo.
|
||||
|
||||
Observe que, como não há sintaxe para colocar um valor puro diretamente sob uma
|
||||
chave estruturada, você deve defini-lo fora das chaves. Por exemplo::
|
||||
|
||||
foo {
|
||||
bar = value1
|
||||
bar {
|
||||
baz = value2
|
||||
qux = value3
|
||||
}
|
||||
}
|
||||
|
||||
Além disso, a ordem do nó de valor sob uma chave é fixa. Se houver um valor e
|
||||
subchaves, o valor será sempre o primeiro nó filho da chave. Portanto, se o
|
||||
usuário especificar subchaves primeiro, por exemplo::
|
||||
|
||||
foo.bar = value1
|
||||
foo = value2
|
||||
|
||||
No programa (e em /proc/bootconfig), ele será exibido conforme abaixo::
|
||||
|
||||
foo = value2
|
||||
foo.bar = value1
|
||||
|
||||
Comentários
|
||||
-----------
|
||||
|
||||
A sintaxe de configuração aceita comentários no estilo shell-script. Os comentários
|
||||
iniciados com cerquilha ("#") até a quebra de linha ("\n") serão ignorados.
|
||||
|
||||
::
|
||||
|
||||
# linha de comentário
|
||||
foo = value # valor atribuído a foo.
|
||||
bar = 1, # 1º elemento
|
||||
2, # 2º elemento
|
||||
3 # 3º elemento
|
||||
|
||||
Isto é analisado como abaixo::
|
||||
|
||||
foo = value
|
||||
bar = 1, 2, 3
|
||||
|
||||
Observe que você NÃO pode colocar um comentário ou uma quebra de linha entre o
|
||||
valor e o delimitador (``,`` ou ``;``). Isso significa que a seguinte configuração
|
||||
possui um erro de sintaxe::
|
||||
|
||||
key = 1 # comentário
|
||||
,2
|
||||
|
||||
|
||||
/proc/bootconfig
|
||||
================
|
||||
|
||||
/proc/bootconfig é uma interface de espaço de usuário da configuração de boot.
|
||||
Diferente de /proc/cmdline, este arquivo exibe a lista no estilo chave-valor.
|
||||
Cada par chave-valor é mostrado em cada linha no seguinte formato::
|
||||
|
||||
CHAVE[.PALAVRAS...] = "[VALOR]"[,"VALOR2"...]
|
||||
|
||||
|
||||
Inicializando o kernel com um Boot Config
|
||||
=========================================
|
||||
|
||||
Existem duas opções para inicializar o kernel com bootconfig: anexar o bootconfig
|
||||
à imagem initrd ou embuti-lo no próprio kernel.
|
||||
|
||||
Anexando um Boot Config ao Initrd
|
||||
---------------------------------
|
||||
|
||||
Como o arquivo de configuração de boot é carregado com o initrd por padrão, ele
|
||||
será adicionado ao final do arquivo de imagem do initrd (initramfs) com
|
||||
preenchimento (padding), tamanho, checksum e palavra mágica de 12 bytes conforme
|
||||
abaixo.
|
||||
|
||||
[initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
|
||||
|
||||
Os campos de tamanho (size) e checksum são valores de 32 bits sem sinal em little endian.
|
||||
|
||||
Quando a configuração de boot é adicionada à imagem do initrd, o tamanho total
|
||||
do arquivo é alinhado a 4 bytes. Para preencher a lacuna, caracteres nulos
|
||||
(``\0``) serão adicionados. Assim, ``size`` é o comprimento do arquivo bootconfig
|
||||
+ bytes de preenchimento.
|
||||
|
||||
O kernel Linux decodifica a última parte da imagem do initrd na memória para
|
||||
obter os dados de configuração de boot.
|
||||
Por causa desse método "piggyback", não há necessidade de alterar ou atualizar o
|
||||
carregador de inicialização (boot loader) e a própria imagem do kernel, desde que
|
||||
o boot loader passe o tamanho correto do arquivo initrd. Se, por qualquer motivo,
|
||||
o boot loader passar um tamanho maior, o kernel não conseguirá encontrar os
|
||||
dados do bootconfig.
|
||||
|
||||
Para realizar esta operação, o kernel Linux fornece o comando ``bootconfig`` sob
|
||||
tools/bootconfig, que permite ao administrador aplicar ou excluir o arquivo de
|
||||
configuração na/da imagem do initrd. Você pode compilá-lo com o seguinte comando::
|
||||
|
||||
# make -C tools/bootconfig
|
||||
|
||||
Para adicionar seu arquivo de configuração de boot à imagem do initrd, execute o
|
||||
bootconfig conforme abaixo (dados antigos são removidos automaticamente se existirem)::
|
||||
|
||||
# tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z
|
||||
|
||||
Para remover a configuração da imagem, você pode usar a opção -d como abaixo::
|
||||
|
||||
# tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z
|
||||
|
||||
Em seguida, adicione "bootconfig" na linha de comando normal do kernel para instruir
|
||||
o kernel a procurar pelo bootconfig no final do arquivo initrd.
|
||||
Como alternativa, compile seu kernel com a opção Kconfig ``CONFIG_BOOT_CONFIG_FORCE``
|
||||
selecionada.
|
||||
|
||||
Embutindo um Boot Config no kernel
|
||||
----------------------------------
|
||||
|
||||
Se você não puder usar initrd, também poderá embutir o arquivo bootconfig no
|
||||
kernel através de opções do Kconfig. Nesse caso, você precisa recompilar o
|
||||
kernel com as seguintes configurações::
|
||||
|
||||
CONFIG_BOOT_CONFIG_EMBED=y
|
||||
CONFIG_BOOT_CONFIG_EMBED_FILE="/CAMINHO/PARA/ARQUIVO/BOOTCONFIG"
|
||||
|
||||
``CONFIG_BOOT_CONFIG_EMBED_FILE`` requer um caminho absoluto ou um caminho
|
||||
relativo para o arquivo bootconfig a partir da árvore de código-fonte ou da
|
||||
árvore de objetos. O kernel o embutirá como o bootconfig padrão.
|
||||
|
||||
Assim como ao anexar o bootconfig ao initrd, você precisa da opção ``bootconfig``
|
||||
na linha de comando do kernel para habilitar o bootconfig embutido ou,
|
||||
alternativamente, compilar seu kernel com a opção Kconfig
|
||||
``CONFIG_BOOT_CONFIG_FORCE`` selecionada.
|
||||
|
||||
Observe que, mesmo se você definir esta opção, poderá sobrescrever o bootconfig
|
||||
embutido por outro bootconfig anexado ao initrd.
|
||||
|
||||
Renderizando chaves kernel.* embutidas em tempo de compilação
|
||||
-------------------------------------------------------------
|
||||
|
||||
Por padrão, o bootconfig embutido (``CONFIG_BOOT_CONFIG_EMBED=y``) é analisado
|
||||
em tempo de execução, após ``parse_early_param()`` já ter sido executado. Os
|
||||
tratadores de parâmetros iniciais (early parameters) (``mem=``, ``earlycon=``,
|
||||
``loglevel=``, ...) não conseguem, portanto, ver valores fornecidos através da
|
||||
subárvore ``kernel`` embutida.
|
||||
|
||||
A opção ``CONFIG_CMDLINE_FROM_BOOTCONFIG`` resolve isso renderizando a subárvore
|
||||
``kernel`` de ``CONFIG_BOOT_CONFIG_EMBED_FILE`` em uma string de cmdline plana em
|
||||
tempo de compilação do kernel (via ``tools/bootconfig -C``) e prefixando-a a
|
||||
``boot_command_line`` durante a configuração arquitetural inicial, de modo que
|
||||
as chaves fiquem visíveis para ``parse_early_param()``.
|
||||
|
||||
A opção requer ``CONFIG_BOOT_CONFIG_EMBED=y``, um ``CONFIG_BOOT_CONFIG_EMBED_FILE``
|
||||
não vazio, ``CONFIG_CMDLINE`` vazio e uma arquitetura que selecione
|
||||
``CONFIG_ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG``. Atualmente apenas x86 a seleciona;
|
||||
em outras arquiteturas, o bootconfig embutido ainda funciona, mas apenas por meio
|
||||
do analisador tardio em tempo de execução.
|
||||
|
||||
A mesma ativação explícita de ``bootconfig`` se aplica como em outros lugares:
|
||||
as chaves renderizadas são prefixadas apenas quando ``bootconfig`` (em qualquer
|
||||
forma) aparece na linha de comando do kernel, ou quando ``CONFIG_BOOT_CONFIG_FORCE``
|
||||
está definido, cujo padrão é ``y`` quando ``CONFIG_BOOT_CONFIG_EMBED`` está definido.
|
||||
|
||||
Por exemplo, dado::
|
||||
|
||||
kernel {
|
||||
loglevel = 7
|
||||
mem = 4G
|
||||
}
|
||||
|
||||
o kernel inicializa como se ``loglevel=7 mem=4G`` tivesse sido prefixado à linha
|
||||
de comando do carregador de inicialização, com os valores visíveis para os
|
||||
tratadores analisados precocemente. Valores separados por vírgula ainda são
|
||||
expandidos em múltiplas entradas de linha de comando de acordo com a convenção
|
||||
de array do bootconfig -- o ``kernel.earlycon = "uart8250,io,0x3f8"`` embutido
|
||||
deve estar entre aspas para resultar em uma única entrada ``earlycon=``, exatamente
|
||||
como no analisador em tempo de execução.
|
||||
|
||||
Se a string renderizada não couber em ``COMMAND_LINE_SIZE`` juntamente com a
|
||||
linha de comando existente, o prefixo será ignorado e um erro será registrado,
|
||||
de modo que um bootconfig embutido superdimensionado não possa travar a inicialização.
|
||||
|
||||
Interação com outras fontes de linha de comando e bootconfig
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Com ``CONFIG_CMDLINE_FROM_BOOTCONFIG=y``, a subárvore ``kernel`` renderizada
|
||||
comporta-se como uma linha de comando em tempo de compilação (semelhante a
|
||||
``CONFIG_CMDLINE``), e não como uma fonte de bootconfig. Ela é prefixada a
|
||||
``boot_command_line`` em ``setup_arch()``, antes de ``parse_early_param()`` e
|
||||
muito antes de o analisador em tempo de execução inspecionar um initrd. As opções
|
||||
podem chegar ao kernel a partir de até quatro locais:
|
||||
|
||||
- Linha de comando do carregador de inicialização (bootloader): os argumentos
|
||||
que o carregador de inicialização passa. A linha de comando embutida é
|
||||
prefixada na frente deles, portanto, para parâmetros onde o último vence
|
||||
(last-one-wins), uma opção do bootloader ainda sobrescreve o valor embutido.
|
||||
Visível em /proc/cmdline.
|
||||
- Linha de comando embutida (esta opção): a subárvore ``kernel`` renderizada,
|
||||
prefixada precocemente para ser vista por ``parse_early_param()``. Visível em
|
||||
/proc/cmdline.
|
||||
- Bootconfig do initrd: analisado tardiamente em ``setup_boot_config()``; suas
|
||||
chaves ``kernel`` são colocadas antes de ``boot_command_line``, ou seja, antes
|
||||
da linha de comando embutida, portanto, a regra do último vencedor favorece os
|
||||
valores embutidos. Como uma fonte de bootconfig, um bootconfig do initrd ainda
|
||||
substitui o bootconfig embutido. Visível em /proc/cmdline e /proc/bootconfig.
|
||||
- Bootconfig embutido (tempo de execução): analisado tardiamente, apenas quando
|
||||
nenhum bootconfig do initrd estiver presente. Visível em /proc/cmdline e
|
||||
/proc/bootconfig.
|
||||
|
||||
Assim, com esta opção, os valores ``kernel.*`` embutidos têm precedência sobre os
|
||||
valores ``kernel.*`` de um bootconfig do initrd: para parâmetros iniciais, o initrd
|
||||
ainda não foi analisado e, para parâmetros comuns, as chaves embutidas chegam mais
|
||||
tarde na linha de comando. Se você precisa que um bootconfig do initrd sobrescreva
|
||||
as chaves ``kernel.*`` embutidas, deixe esta opção desativada e confie no analisador
|
||||
em tempo de execução.
|
||||
|
||||
A string renderizada faz parte da linha de comando, portanto aparece em
|
||||
/proc/cmdline. Ela deliberadamente não é mostrada em /proc/bootconfig: esse
|
||||
arquivo continua relatando a árvore de bootconfig analisada -- o bootconfig do
|
||||
initrd se presente, caso contrário o bootconfig embutido -- independentemente de a
|
||||
renderização da linha de comando em tempo de compilação estar ativada.
|
||||
|
||||
Parâmetros do kernel via Boot Config
|
||||
====================================
|
||||
|
||||
Além da linha de comando do kernel, a configuração de boot pode ser usada para
|
||||
passar os parâmetros do kernel. Todos os pares chave-valor sob a chave ``kernel``
|
||||
serão passados diretamente para a linha de comando do kernel. Além disso, os pares
|
||||
chave-valor sob ``init`` serão passados para o processo init via linha de comando.
|
||||
Os parâmetros são concatenados com a string de linha de comando do kernel fornecida
|
||||
pelo usuário na seguinte ordem, de modo que o parâmetro de linha de comando possa
|
||||
sobrescrever os parâmetros de bootconfig (isso depende de como o subsistema lida com
|
||||
parâmetros, mas em geral, o parâmetro anterior será sobrescrito pelo posterior)::
|
||||
|
||||
[bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params]
|
||||
|
||||
Aqui está um exemplo de arquivo bootconfig para parâmetros de kernel/init::
|
||||
|
||||
kernel {
|
||||
root = 01234567-89ab-cdef-0123-456789abcd
|
||||
}
|
||||
init {
|
||||
splash
|
||||
}
|
||||
|
||||
Isto será copiado na string de linha de comando do kernel da seguinte forma::
|
||||
|
||||
root="01234567-89ab-cdef-0123-456789abcd" -- splash
|
||||
|
||||
Se o usuário fornecer alguma outra linha de comando como::
|
||||
|
||||
ro bootconfig -- quiet
|
||||
|
||||
A linha de comando final do kernel será a seguinte::
|
||||
|
||||
root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet
|
||||
|
||||
|
||||
Limitações do arquivo de configuração
|
||||
=====================================
|
||||
|
||||
Atualmente, o tamanho máximo da configuração é de 32 KB e o total de palavras-chave
|
||||
(não entradas de chave-valor) deve ser inferior a 1024 nós.
|
||||
Nota: este não é o número de entradas, mas de nós; uma entrada deve consumir mais
|
||||
de 2 nós (uma palavra-chave e um valor). Portanto, teoricamente, haverá até 512
|
||||
pares chave-valor. Se as chaves contiverem 3 palavras em média, poderá conter 256
|
||||
pares chave-valor. Na maioria dos casos, o número de itens de configuração estará
|
||||
abaixo de 100 entradas e será menor que 8 KB, o que seria suficiente.
|
||||
Se o número de nós exceder 1024, o analisador retornará um erro mesmo se o tamanho
|
||||
do arquivo for menor que 32 KB. (Observe que esse tamanho máximo não inclui os
|
||||
caracteres nulos de preenchimento.)
|
||||
De qualquer forma, como o comando bootconfig verifica isso ao anexar uma configuração
|
||||
de boot à imagem initrd, o usuário pode perceber antes da inicialização.
|
||||
|
||||
|
||||
APIs do Bootconfig
|
||||
==================
|
||||
|
||||
O usuário pode consultar ou iterar sobre pares chave-valor; também é possível
|
||||
encontrar um nó de chave raiz (prefixo) e encontrar chaves-valores sob esse nó.
|
||||
|
||||
Se você tiver uma string de chave, poderá consultar o valor diretamente com a chave
|
||||
usando xbc_find_value(). Se quiser saber quais chaves existem no bootconfig, pode
|
||||
usar xbc_for_each_key_value() para iterar sobre os pares chave-valor.
|
||||
Observe que você precisa usar xbc_array_for_each_value() para acessar o valor de
|
||||
cada array, por exemplo::
|
||||
|
||||
vnode = NULL;
|
||||
xbc_find_value("key.word", &vnode);
|
||||
if (vnode && xbc_node_is_array(vnode))
|
||||
xbc_array_for_each_value(vnode, value) {
|
||||
printk("%s ", value);
|
||||
}
|
||||
|
||||
Se você quiser focar em chaves que tenham uma string de prefixo, pode usar
|
||||
xbc_find_node() para encontrar um nó pela string de prefixo e iterar pelas chaves
|
||||
sob o nó de prefixo com xbc_node_for_each_key_value().
|
||||
|
||||
Mas o uso mais típico é obter o valor nomeado sob o prefixo ou obter o array
|
||||
nomeado sob o prefixo, como abaixo::
|
||||
|
||||
root = xbc_find_node("key.prefix");
|
||||
value = xbc_node_find_value(root, "option", &vnode);
|
||||
...
|
||||
xbc_node_for_each_array_value(root, "array-option", value, anode) {
|
||||
...
|
||||
}
|
||||
|
||||
Isso acessa um valor de "key.prefix.option" e um array de "key.prefix.array-option".
|
||||
|
||||
O bloqueio (locking) não é necessário, pois após a inicialização, a configuração
|
||||
torna-se somente leitura. Todos os dados e chaves devem ser copiados se você
|
||||
precisar modificá-los.
|
||||
|
||||
|
||||
Funções e estruturas
|
||||
====================
|
||||
|
||||
Para a documentação kernel-doc das definições, consulte:
|
||||
|
||||
- include/linux/bootconfig.h
|
||||
- lib/bootconfig.c
|
||||
105
Documentation/translations/pt_BR/admin-guide/cputopology.rst
Normal file
105
Documentation/translations/pt_BR/admin-guide/cputopology.rst
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
================================================================
|
||||
Como as informações de topologia de CPU são exportadas via sysfs
|
||||
================================================================
|
||||
|
||||
As informações de topologia de CPU são exportadas via sysfs. Os itens
|
||||
(atributos) são semelhantes à saída de /proc/cpuinfo em algumas arquiteturas.
|
||||
Eles residem em /sys/devices/system/cpu/cpuX/topology/. Por favor, consulte o
|
||||
arquivo de ABI: Documentation/ABI/stable/sysfs-devices-system-cpu.
|
||||
|
||||
O arquivo independente de arquitetura, drivers/base/topology.c, exporta esses
|
||||
atributos. No entanto, os arquivos do sysfs relacionados à hierarquia de die,
|
||||
cluster, book e drawer só serão criados se uma arquitetura fornecer as macros
|
||||
relacionadas, conforme descrito abaixo.
|
||||
|
||||
Para que uma arquitetura ofereça suporte a esse recurso, ela deve definir
|
||||
algumas dessas macros em include/asm-XXX/topology.h::
|
||||
|
||||
#define topology_physical_package_id(cpu)
|
||||
#define topology_die_id(cpu)
|
||||
#define topology_cluster_id(cpu)
|
||||
#define topology_core_id(cpu)
|
||||
#define topology_book_id(cpu)
|
||||
#define topology_drawer_id(cpu)
|
||||
#define topology_sibling_cpumask(cpu)
|
||||
#define topology_core_cpumask(cpu)
|
||||
#define topology_cluster_cpumask(cpu)
|
||||
#define topology_die_cpumask(cpu)
|
||||
#define topology_book_cpumask(cpu)
|
||||
#define topology_drawer_cpumask(cpu)
|
||||
|
||||
O tipo das ``macros **_id`` é int.
|
||||
O tipo das ``macros **_cpumask`` é ``(const) struct cpumask *``. Estas últimas
|
||||
correspondem aos atributos apropriados ``**_siblings`` do sysfs (exceto por
|
||||
topology_sibling_cpumask(), que corresponde a thread_siblings).
|
||||
|
||||
Para manter a consistência em todas as arquiteturas, include/linux/topology.h
|
||||
fornece definições padrão para qualquer uma das macros acima que não estejam
|
||||
definidas em include/asm-XXX/topology.h:
|
||||
|
||||
1) topology_physical_package_id: -1
|
||||
2) topology_die_id: -1
|
||||
3) topology_cluster_id: -1
|
||||
4) topology_core_id: 0
|
||||
5) topology_book_id: -1
|
||||
6) topology_drawer_id: -1
|
||||
7) topology_sibling_cpumask: apenas a CPU fornecida
|
||||
8) topology_core_cpumask: apenas a CPU fornecida
|
||||
9) topology_cluster_cpumask: apenas a CPU fornecida
|
||||
10) topology_die_cpumask: apenas a CPU fornecida
|
||||
11) topology_book_cpumask: apenas a CPU fornecida
|
||||
12) topology_drawer_cpumask: apenas a CPU fornecida
|
||||
|
||||
Além disso, as informações de topologia de CPU são fornecidas sob
|
||||
/sys/devices/system/cpu e incluem estes arquivos. A fonte interna para a saída
|
||||
está entre colchetes ("[]").
|
||||
|
||||
=========== ==========================================================
|
||||
kernel_max: o índice máximo de CPU permitido pela configuração do kernel.
|
||||
[NR_CPUS-1]
|
||||
|
||||
offline: CPUs que não estão online porque foram desligadas via
|
||||
HOTPLUG ou excedem o limite de CPUs permitido pela
|
||||
configuração do kernel (kernel_max acima).
|
||||
[~cpu_online_mask + cpus >= NR_CPUS]
|
||||
|
||||
online: CPUs que estão online e sendo escalonadas [cpu_online_mask]
|
||||
|
||||
possible: CPUs para as quais foram alocados recursos e que podem ser
|
||||
colocadas online se estiverem presentes. [cpu_possible_mask]
|
||||
|
||||
present: CPUs que foram identificadas como presentes no
|
||||
sistema. [cpu_present_mask]
|
||||
=========== ==========================================================
|
||||
|
||||
O formato para a saída acima é compatível com cpulist_parse()
|
||||
[veja <linux/cpumask.h>]. Alguns exemplos a seguir.
|
||||
|
||||
Neste exemplo, existem 64 CPUs no sistema, mas as cpus 32-63 excedem
|
||||
o máximo do kernel, que está limitado a 0..31 devido à opção de
|
||||
configuração NR_CPUS ser 32. Observe também que as CPUs 2 e 4-31 não estão
|
||||
online, mas poderiam ser colocadas online, pois estão tanto presentes
|
||||
quanto possíveis::
|
||||
|
||||
kernel_max: 31
|
||||
offline: 2,4-31,32-63
|
||||
online: 0-1,3
|
||||
possible: 0-31
|
||||
present: 0-31
|
||||
|
||||
Neste exemplo, a opção de configuração NR_CPUS é 128, mas o kernel foi
|
||||
iniciado com possible_cpus=144. Existem 4 CPUs no sistema e a cpu2
|
||||
foi colocada offline manualmente (e é a única CPU que pode ser colocada
|
||||
online.)::
|
||||
|
||||
kernel_max: 127
|
||||
offline: 2,4-127,128-143
|
||||
online: 0-1,3
|
||||
possible: 0-127
|
||||
present: 0-3
|
||||
|
||||
Consulte Documentation/core-api/cpu_hotplug.rst para o parâmetro de inicialização
|
||||
do kernel possible_cpus=NUM, bem como para obter mais informações sobre as
|
||||
várias cpumasks.
|
||||
102
Documentation/translations/pt_BR/admin-guide/efi-stub.rst
Normal file
102
Documentation/translations/pt_BR/admin-guide/efi-stub.rst
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================
|
||||
O EFI Boot Stub
|
||||
=================
|
||||
|
||||
Nas plataformas x86 e ARM, uma zImage/bzImage do kernel pode se passar por
|
||||
uma imagem PE/COFF, convencendo assim os carregadores de firmware EFI a
|
||||
carregá-la como um executável EFI. O código que modifica o cabeçalho da bzImage,
|
||||
juntamente com o ponto de entrada específico do EFI para o qual o carregador de
|
||||
firmware salta, são conhecidos coletivamente como o "EFI boot stub", e residem
|
||||
em arch/x86/boot/header.S e drivers/firmware/efi/libstub/x86-stub.c, respectivamente.
|
||||
Para ARM, o stub EFI é implementado em arch/arm/boot/compressed/efi-header.S e
|
||||
drivers/firmware/efi/libstub/arm32-stub.c. O código do stub EFI compartilhado
|
||||
entre arquiteturas está em drivers/firmware/efi/libstub.
|
||||
|
||||
Para arm64, não há suporte a kernel compactado, portanto a própria Imagem se
|
||||
passa por uma imagem PE/COFF e o stub EFI é vinculado diretamente ao kernel. O
|
||||
stub EFI para arm64 reside em drivers/firmware/efi/libstub/arm64.c e
|
||||
drivers/firmware/efi/libstub/arm64-stub.c.
|
||||
|
||||
Ao usar o EFI boot stub, é possível inicializar um kernel Linux sem o uso de um
|
||||
carregador de boot EFI convencional, como o grub ou elilo. Como o EFI boot stub
|
||||
desempenha as tarefas de um carregador de inicialização, em certo sentido ele *É*
|
||||
o carregador de inicialização.
|
||||
|
||||
O EFI boot stub é ativado com a opção de kernel CONFIG_EFI_STUB.
|
||||
|
||||
|
||||
Como instalar bzImage.efi
|
||||
-------------------------
|
||||
|
||||
A bzImage localizada em arch/x86/boot/bzImage deve ser copiada para a Partição
|
||||
de Sistema EFI (ESP - EFI System Partition) e renomeada com a extensão ".efi".
|
||||
Sem a extensão, o carregador de firmware EFI se recusará a executá-la. Não é
|
||||
possível executar bzImage.efi a partir dos sistemas de arquivos normais do Linux
|
||||
porque o firmware EFI não possui suporte para eles. Para ARM, a
|
||||
arch/arm/boot/zImage deve ser copiada para a partição de sistema e pode não
|
||||
precisar ser renomeada. Da mesma forma, para arm64, arch/arm64/boot/Image deve
|
||||
ser copiada, mas não necessariamente renomeada.
|
||||
|
||||
|
||||
Passando parâmetros do kernel a partir do shell EFI
|
||||
---------------------------------------------------
|
||||
|
||||
Argumentos para o kernel podem ser passados após bzImage.efi, por exemplo::
|
||||
|
||||
fs0:> bzImage.efi console=ttyS0 root=/dev/sda4
|
||||
|
||||
A opção "initrd="
|
||||
-----------------
|
||||
|
||||
Como a maioria dos carregadores de inicialização, o stub EFI permite que o
|
||||
usuário especifique múltiplos arquivos initrd usando a opção "initrd=". Este é
|
||||
o único parâmetro de linha de comando específico do stub EFI; tudo o mais é
|
||||
passado para o kernel quando ele inicializa.
|
||||
|
||||
O caminho para o arquivo initrd deve ser um caminho absoluto a partir do início
|
||||
da ESP; nomes de caminhos relativos não funcionam. Além disso, o caminho é no
|
||||
estilo EFI e os elementos de diretório devem ser separados com barras invertidas
|
||||
(\). Por exemplo, dada a seguinte estrutura de diretórios::
|
||||
|
||||
fs0:>
|
||||
Kernels\
|
||||
bzImage.efi
|
||||
initrd-large.img
|
||||
|
||||
Ramdisks\
|
||||
initrd-small.img
|
||||
initrd-medium.img
|
||||
|
||||
para inicializar com o arquivo initrd-large.img se o diretório de trabalho atual
|
||||
for fs0:\Kernels, o seguinte comando deve ser usado::
|
||||
|
||||
fs0:\Kernels> bzImage.efi initrd=\Kernels\initrd-large.img
|
||||
|
||||
Observe como bzImage.efi pode ser especificado com um caminho relativo. Isso ocorre
|
||||
porque a imagem que estamos executando é interpretada pelo shell EFI, que entende
|
||||
caminhos relativos, enquanto o restante da linha de comando é passado para bzImage.efi.
|
||||
|
||||
.. hint::
|
||||
Também é possível fornecer um initrd usando um protocolo UEFI específico do
|
||||
Linux no momento da inicialização. Consulte :ref:`pe-coff-entry-point` para
|
||||
obter detalhes.
|
||||
|
||||
A opção "dtb="
|
||||
--------------
|
||||
|
||||
Para as arquiteturas ARM e arm64, uma árvore de dispositivos (device tree) deve ser
|
||||
fornecida ao kernel. Normalmente, o firmware deve fornecer a árvore de dispositivos
|
||||
através da EFI CONFIGURATION TABLE. No entanto, a opção de linha de comando "dtb="
|
||||
pode ser usada para sobrescrever a árvore de dispositivos fornecida pelo firmware
|
||||
ou para fornecer uma quando o firmware não puder fazê-lo.
|
||||
|
||||
Observe: O firmware adiciona informações de configuração em tempo de execução à
|
||||
árvore de dispositivos antes de inicializar o kernel. Se dtb= for usado para
|
||||
sobrescrever a árvore de dispositivos, quaisquer dados em tempo de execução
|
||||
fornecidos pelo firmware serão perdidos. A opção dtb= deve ser usada apenas como
|
||||
uma ferramenta de depuração ou como último recurso quando uma árvore de dispositivos
|
||||
não for fornecida na EFI CONFIGURATION TABLE.
|
||||
|
||||
"dtb=" é processado da mesma maneira que a opção "initrd=" descrita acima.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. kernel-feat:: features
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
============================
|
||||
Vulnerabilidades de hardware
|
||||
============================
|
||||
|
||||
Esta seção descreve vulnerabilidades de CPU e fornece uma visão geral das
|
||||
possíveis mitigações, juntamente com orientações para a seleção de mitigações,
|
||||
caso sejam configuráveis em tempo de compilação, inicialização ou execução.
|
||||
|
||||
Todolist:
|
||||
|
||||
* attack_vector_controls
|
||||
* spectre
|
||||
* l1tf
|
||||
* mds
|
||||
* tsx_async_abort
|
||||
* multihit
|
||||
* special-register-buffer-data-sampling
|
||||
* core-scheduling
|
||||
* l1d_flush
|
||||
* processor_mmio_stale_data
|
||||
* cross-thread-rsb
|
||||
* srso
|
||||
* gather_data_sampling
|
||||
* reg-file-data-sampling
|
||||
* rsb
|
||||
* old_microcode
|
||||
* indirect-target-selection
|
||||
* vmscape
|
||||
|
|
@ -26,38 +26,44 @@ etc.
|
|||
|
||||
README
|
||||
devices
|
||||
|
||||
Todolist:
|
||||
|
||||
* features
|
||||
features
|
||||
|
||||
Uma grande parte da interface administrativa do kernel são os sistemas de
|
||||
arquivos virtuais /proc e sysfs; estes documentos descrevem como interagir
|
||||
com eles.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
sysfs-rules
|
||||
sysctl/index
|
||||
cputopology
|
||||
|
||||
Todolist:
|
||||
|
||||
* sysfs-rules
|
||||
* sysctl/index
|
||||
* cputopology
|
||||
* abi
|
||||
|
||||
Documentação relacionada à segurança:
|
||||
|
||||
Todolist:
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
* hw-vuln/index
|
||||
* LSM/index
|
||||
* perf-security
|
||||
hw-vuln/index
|
||||
LSM/index
|
||||
perf-security
|
||||
|
||||
Inicializando o kernel
|
||||
----------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
bootconfig
|
||||
kernel-parameters
|
||||
efi-stub
|
||||
|
||||
Todolist:
|
||||
|
||||
* bootconfig
|
||||
* kernel-parameters
|
||||
* efi-stub
|
||||
* initrd
|
||||
|
||||
Rastreando e identificando problemas
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Os parâmetros de linha de comando do kernel
|
||||
===========================================
|
||||
|
||||
A seguir está uma lista consolidada dos parâmetros do kernel conforme
|
||||
implementados pelas macros __setup(), early_param(), core_param() e
|
||||
module_param(), ordenados na ordem do dicionário inglês (definida como ignorar
|
||||
toda a pontuação e ordenar dígitos antes de letras sem distinção entre
|
||||
maiúsculas e minúsculas), e com descrições onde conhecidas.
|
||||
|
||||
O kernel analisa os parâmetros da linha de comando do kernel até "``--``";
|
||||
se ele não reconhecer um parâmetro e este não contiver um '.', o parâmetro
|
||||
será passado para o init: parâmetros com '=' vão para o ambiente do init,
|
||||
outros são passados como argumentos de linha de comando para o init.
|
||||
Tudo após "``--``" é passado como argumento para o init.
|
||||
|
||||
Os parâmetros de módulo podem ser especificados de duas maneiras: através da
|
||||
linha de comando do kernel com um prefixo de nome de módulo, ou via modprobe,
|
||||
por exemplo::
|
||||
|
||||
(linha de comando do kernel) usbcore.blinkenlights=1
|
||||
(linha de comando do modprobe) modprobe usbcore blinkenlights=1
|
||||
|
||||
Os parâmetros para módulos compilados embutidos no kernel precisam ser
|
||||
especificados na linha de comando do kernel. O modprobe examina a linha de
|
||||
comando do kernel (/proc/cmdline) e coleta parâmetros de módulo ao carregar um
|
||||
módulo, de modo que a linha de comando do kernel também pode ser usada para
|
||||
módulos carregáveis.
|
||||
|
||||
Este documento pode não estar totalmente atualizado e abrangente. O comando
|
||||
"modinfo -p ${nomedomodulo}" exibe uma lista atual de todos os parâmetros de um
|
||||
módulo carregável. Módulos carregáveis, após serem carregados no kernel em
|
||||
execução, também revelam seus parâmetros em /sys/module/${nomedomodulo}/parameters/.
|
||||
Alguns desses parâmetros podem ser alterados em tempo de execução pelo comando
|
||||
``echo -n ${valor} > /sys/module/${nomedomodulo}/parameters/${param}``.
|
||||
|
||||
Tratamento especial
|
||||
-------------------
|
||||
|
||||
Hífens (traços) e sublinhados são equivalentes em nomes de parâmetros, portanto::
|
||||
|
||||
log_buf_len=1M print-fatal-signals=1
|
||||
|
||||
também pode ser inserido como::
|
||||
|
||||
log-buf-len=1M print_fatal_signals=1
|
||||
|
||||
Aspas duplas podem ser usadas para proteger espaços nos valores, por exemplo::
|
||||
|
||||
param="spaces in here"
|
||||
|
||||
Listas de CPUs
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Alguns parâmetros do kernel recebem uma lista de CPUs como valor, por exemplo:
|
||||
isolcpus, nohz_full, irqaffinity, rcu_nocbs. O formato desta lista é:
|
||||
|
||||
<número da cpu>,...,<número da cpu>
|
||||
|
||||
ou
|
||||
|
||||
<número da cpu>-<número da cpu>
|
||||
(deve ser um intervalo positivo em ordem crescente)
|
||||
|
||||
ou uma mistura
|
||||
|
||||
<número da cpu>,...,<número da cpu>-<número da cpu>
|
||||
|
||||
Observe que, para o caso especial de um intervalo, é possível dividir o intervalo em
|
||||
grupos de tamanhos iguais e, para cada grupo, usar uma determinada quantidade a
|
||||
partir do início desse grupo:
|
||||
|
||||
<número da cpu>-<número da cpu>:<tamanho usado>/<tamanho do grupo>
|
||||
|
||||
Por exemplo, pode-se adicionar à linha de comando o seguinte parâmetro:
|
||||
|
||||
isolcpus=1,2,10-20,100-2000:2/25
|
||||
|
||||
onde o item final representa as CPUs 100,101,125,126,150,151,...
|
||||
|
||||
O valor "N" pode ser usado para representar a última CPU numericamente no sistema,
|
||||
ou seja, "foo_cpus=16-N" seria equivalente a "16-31" em um sistema de 32 núcleos.
|
||||
|
||||
Tenha em mente que "N" é dinâmico; portanto, se alterações no sistema fizerem com
|
||||
que a largura do bitmap mude, como menos núcleos na lista de CPUs, N e quaisquer
|
||||
intervalos que usem N também mudarão. Use o mesmo em um sistema pequeno de 4 núcleos,
|
||||
e "16-N" se tornará "16-3", e agora a mesma entrada de boot será sinalizada como
|
||||
inválida (início > fim).
|
||||
|
||||
O nome de grupo especial tolerante a maiúsculas/minúsculas "all" tem o significado
|
||||
de selecionar todas as CPUs, de modo que "nohz_full=all" seja o equivalente a
|
||||
"nohz_full=0-N".
|
||||
|
||||
A semântica de "N" e "all" é suportada em nível de bitmaps e é válida para todos
|
||||
os usuários de bitmap_parselist().
|
||||
|
||||
Sufixos métricos
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
O sufixo [KMG] é comumente descrito após vários valores de parâmetros do kernel.
|
||||
Os sufixos 'K', 'M', 'G', 'T', 'P' e 'E' são permitidos. Essas letras representam
|
||||
os multiplicadores _binários_ 'Quilo', 'Mega', 'Giga', 'Tera', 'Peta' e 'Exa',
|
||||
equivalendo a 2^10, 2^20, 2^30, 2^40, 2^50 e 2^60 bytes, respectivamente. Esses
|
||||
sufixos de letras também podem ser totalmente omitidos.
|
||||
|
||||
Opções de compilação do kernel
|
||||
------------------------------
|
||||
|
||||
Os parâmetros listados abaixo só são válidos se certas opções de compilação do
|
||||
kernel foram ativadas e se o respectivo hardware estiver presente. Esta lista deve
|
||||
ser mantida em ordem alfabética. O texto entre colchetes no início de cada descrição
|
||||
informa as restrições sob as quais um parâmetro é aplicável.
|
||||
|
||||
Os parâmetros indicados com BOOT são, na verdade, interpretados pelo carregador
|
||||
de inicialização e não têm significado diretamente para o kernel.
|
||||
Não modifique a sintaxe dos parâmetros do carregador de inicialização sem extrema
|
||||
necessidade ou coordenação com <Documentation/arch/x86/boot.rst>.
|
||||
|
||||
Existem também parâmetros do kernel específicos de arquitetura não documentados aqui.
|
||||
|
||||
Observe que TODOS os parâmetros do kernel listados abaixo DISTINGUEM MAIÚSCULAS DE
|
||||
MINÚSCULAS, e que um = final no nome de qualquer parâmetro indica que o parâmetro
|
||||
será inserido como uma variável de ambiente, enquanto sua ausência indica que ele
|
||||
aparecerá como um argumento do kernel legível via /proc/cmdline por programas em
|
||||
execução assim que o sistema estiver ativo.
|
||||
|
||||
O número de parâmetros do kernel não é limitado, mas o comprimento da linha de
|
||||
comando completa (parâmetros incluindo espaços, etc.) é limitado a um número fixo
|
||||
de caracteres. Este limite depende da arquitetura e varia entre 256 e 4096 caracteres.
|
||||
Ele é definido no arquivo ./include/uapi/asm-generic/setup.h como COMMAND_LINE_SIZE.
|
||||
|
||||
.. include:: ../../../admin-guide/kernel-parameters.txt
|
||||
:literal:
|
||||
328
Documentation/translations/pt_BR/admin-guide/perf-security.rst
Normal file
328
Documentation/translations/pt_BR/admin-guide/perf-security.rst
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Segurança das ferramentas e eventos Perf
|
||||
========================================
|
||||
|
||||
Visão geral
|
||||
-----------
|
||||
|
||||
O uso dos Contadores de Desempenho para Linux (perf_events) [1]_ , [2]_ , [3]_
|
||||
pode impor um risco considerável de vazamento de dados confidenciais acessados
|
||||
por processos monitorados. O vazamento de dados é possível tanto em cenários de
|
||||
uso direto da API de chamadas de sistema perf_events [2]_ quanto por meio de
|
||||
arquivos de dados gerados pelo utilitário em modo de usuário da ferramenta
|
||||
Perf (Perf) [3]_ , [4]_ . O risco depende da natureza dos dados que as unidades
|
||||
de monitoramento de desempenho (PMU - Performance Monitoring Units) do
|
||||
perf_events [2]_ e o Perf coletam e expõem para análise de desempenho.
|
||||
Os dados de sistema e de desempenho coletados podem ser divididos em várias
|
||||
categorias:
|
||||
|
||||
1. Dados de configuração de hardware e software do sistema, por exemplo: um
|
||||
modelo de CPU e sua configuração de cache, a quantidade de memória disponível
|
||||
e sua topologia, versões do kernel e do Perf utilizadas, configuração de
|
||||
monitoramento de desempenho incluindo tempo de experimento, configuração de
|
||||
eventos, parâmetros de linha de comando do Perf, etc.
|
||||
|
||||
2. Caminhos de módulos de usuário e de kernel e seus endereços de carregamento com
|
||||
tamanhos, nomes de processos e threads com seus PIDs e TIDs, registros de data
|
||||
e hora (timestamps) para eventos capturados de hardware e software.
|
||||
|
||||
3. Conteúdo de contadores de software do kernel (por exemplo, para trocas de contexto,
|
||||
falhas de página, migrações de CPU), contadores arquiteturais de desempenho de
|
||||
hardware (PMC) [8]_ e registradores específicos de modelo (MSR) [9]_ que fornecem
|
||||
métricas de execução para várias partes monitoradas do sistema (por exemplo,
|
||||
controlador de memória (IMC), interconexão (QPI/UPI) ou contadores uncore
|
||||
periféricos (PCIe)) sem atribuição direta a qualquer estado de contexto de execução.
|
||||
|
||||
4. Conteúdo de registradores de contexto de execução arquiteturais (por exemplo,
|
||||
RIP, RSP, RBP em x86_64), endereços de memória e dados de espaço de usuário
|
||||
e de kernel de processos, conteúdo de vários MSRs arquiteturais que capturam
|
||||
dados desta categoria.
|
||||
|
||||
Dados que pertencem à quarta categoria podem conter potencialmente dados confidenciais
|
||||
do processo. Se as PMUs em alguns modos de monitoramento capturam valores de registradores
|
||||
de contexto de execução ou dados da memória do processo, o acesso a esses modos de
|
||||
monitoramento precisa ser ordenado e protegido adequadamente. Portanto, as operações de
|
||||
monitoramento de desempenho e observabilidade do perf_events são objeto de gerenciamento
|
||||
de controle de acesso de segurança [5]_ .
|
||||
|
||||
Controle de acesso do perf_events
|
||||
---------------------------------
|
||||
|
||||
Para realizar verificações de segurança, a implementação do Linux divide os
|
||||
processos em duas categorias [6]_ : a) processos privilegiados (cujo ID de
|
||||
usuário efetivo é 0, chamados de superusuário ou root) e b) processos não
|
||||
privilegiados (cujo UID efetivo é diferente de zero). Processos privilegiados
|
||||
ignoram todas as verificações de permissão de segurança do kernel, de modo que
|
||||
o monitoramento de desempenho do perf_events está totalmente disponível para
|
||||
processos privilegiados sem restrições de acesso, escopo e recursos.
|
||||
|
||||
Processos não privilegiados estão sujeitos a uma verificação completa de permissão
|
||||
de segurança com base nas credenciais do processo [5]_ (geralmente: UID efetivo,
|
||||
GID efetivo e lista de grupos suplementares).
|
||||
|
||||
O Linux divide os privilégios tradicionalmente associados ao superusuário em
|
||||
unidades distintas, conhecidas como capacidades (capabilities) [6]_ , que podem
|
||||
ser habilitadas e desabilitadas independentemente por thread para processos e
|
||||
arquivos de usuários não privilegiados.
|
||||
|
||||
Processos não privilegiados com a capacidade CAP_PERFMON habilitada são tratados
|
||||
como processos privilegiados em relação às operações de monitoramento de
|
||||
desempenho e observabilidade do perf_events, contornando, assim, as verificações
|
||||
de permissões de *escopo* no kernel. A CAP_PERFMON implementa o princípio do menor
|
||||
privilégio [13]_ (POSIX 1003.1e: 2.2.2.39) para operações de monitoramento de
|
||||
desempenho e observabilidade no kernel e fornece uma abordagem segura para o
|
||||
monitoramento de desempenho e observabilidade no sistema.
|
||||
|
||||
Por motivos de compatibilidade retroativa, o acesso às operações de monitoramento
|
||||
e observabilidade do perf_events também é aberto para processos privilegiados com
|
||||
CAP_SYS_ADMIN, mas o uso de CAP_SYS_ADMIN para casos de uso de monitoramento e
|
||||
observabilidade seguros é desencorajado em relação à capacidade CAP_PERFMON.
|
||||
Se os registros de auditoria do sistema [14]_ para um processo usando a API de
|
||||
chamada de sistema perf_events contiverem registros de negação para a obtenção de
|
||||
ambas as capacidades CAP_PERFMON e CAP_SYS_ADMIN, fornecer ao processo apenas a
|
||||
capacidade CAP_PERFMON é recomendado como a abordagem segura preferida para resolver
|
||||
o log duplo de negação de acesso relacionado ao uso de monitoramento de desempenho
|
||||
e observabilidade.
|
||||
|
||||
Antes do Linux v5.9, processos não privilegiados que usavam a chamada de sistema
|
||||
perf_events também estavam sujeitos à verificação do modo de acesso ptrace
|
||||
PTRACE_MODE_READ_REALCREDS [7]_ , cujo resultado determina se o monitoramento é
|
||||
permitido. Portanto, processos não privilegiados com a capacidade CAP_SYS_PTRACE
|
||||
recebiam permissão efetiva para passar na verificação. A partir do Linux v5.9, a
|
||||
capacidade CAP_SYS_PTRACE não é necessária e a CAP_PERFMON é suficiente para que
|
||||
processos executem operações de monitoramento de desempenho e observabilidade.
|
||||
|
||||
Outras capacidades concedidas a processos não privilegiados podem efetivamente
|
||||
permitir a captura de dados adicionais necessários para análises posteriores de
|
||||
desempenho de processos monitorados ou do sistema. Por exemplo, a capacidade
|
||||
CAP_SYSLOG permite a leitura de endereços de memória do espaço de kernel a partir
|
||||
do arquivo /proc/kallsyms.
|
||||
|
||||
Grupos de usuários privilegiados do Perf
|
||||
----------------------------------------
|
||||
|
||||
Mecanismos de capacidades, arquivos privilegiados desprovidos de capacidade
|
||||
(capability-dumb) [6]_, ACLs de sistema de arquivos [10]_ e o utilitário
|
||||
sudo [15]_ podem ser usados para criar grupos dedicados de usuários privilegiados
|
||||
do Perf com permissão para executar monitoramento de desempenho e observabilidade
|
||||
sem limites. As etapas a seguir podem ser seguidas para criar esses grupos de
|
||||
usuários privilegiados do Perf.
|
||||
|
||||
1. Crie o grupo perf_users de usuários privilegiados do Perf, atribua o grupo
|
||||
perf_users ao executável da ferramenta Perf e restrinja o acesso ao executável
|
||||
para outros usuários no sistema que não estejam no grupo perf_users:
|
||||
|
||||
::
|
||||
|
||||
# groupadd perf_users
|
||||
# ls -alhF
|
||||
-rwxr-xr-x 2 root root 11M Oct 19 15:12 perf
|
||||
# chgrp perf_users perf
|
||||
# ls -alhF
|
||||
-rwxr-xr-x 2 root perf_users 11M Oct 19 15:12 perf
|
||||
# chmod o-rwx perf
|
||||
# ls -alhF
|
||||
-rwxr-x--- 2 root perf_users 11M Oct 19 15:12 perf
|
||||
|
||||
2. Atribua as capacidades necessárias ao arquivo executável da ferramenta Perf e
|
||||
habilite os membros do grupo perf_users com privilégios de monitoramento e
|
||||
observabilidade [6]_ :
|
||||
|
||||
::
|
||||
|
||||
# setcap "cap_perfmon,cap_sys_ptrace,cap_syslog=ep" perf
|
||||
# setcap -v "cap_perfmon,cap_sys_ptrace,cap_syslog=ep" perf
|
||||
perf: OK
|
||||
# getcap perf
|
||||
perf = cap_sys_ptrace,cap_syslog,cap_perfmon+ep
|
||||
|
||||
Se a libcap [16]_ instalada ainda não oferecer suporte a "cap_perfmon", use "38",
|
||||
ou seja:
|
||||
|
||||
::
|
||||
|
||||
# setcap "38,cap_ipc_lock,cap_sys_ptrace,cap_syslog=ep" perf
|
||||
|
||||
Observe que você pode precisar incluir 'cap_ipc_lock' na combinação para
|
||||
ferramentas como 'perf top'; alternativamente, use 'perf top -m N' para reduzir a
|
||||
memória que ele usa para o buffer de anel (ring buffer) do perf; consulte a seção
|
||||
de alocação de memória abaixo.
|
||||
|
||||
O uso de uma libcap sem suporte a CAP_PERFMON fará com que cap_get_flag(caps, 38,
|
||||
CAP_EFFECTIVE, &val) falhe, o que fará com que o evento padrão seja 'cycles:u',
|
||||
portanto, como solução alternativa, solicite explicitamente o evento 'cycles', ou seja:
|
||||
|
||||
::
|
||||
|
||||
# perf top -e cycles
|
||||
|
||||
Para obter amostras do kernel e do usuário com um binário do perf com apenas CAP_PERFMON.
|
||||
|
||||
Como resultado, os membros do grupo perf_users são capazes de conduzir
|
||||
monitoramento de desempenho e observabilidade utilizando a funcionalidade do
|
||||
executável da ferramenta Perf configurado que, ao ser executado, passa nas
|
||||
verificações de escopo do subsistema perf_events.
|
||||
|
||||
Caso não seja possível atribuir as capacidades necessárias ao executável da
|
||||
ferramenta Perf (por exemplo, o sistema de arquivos está montado com a opção
|
||||
nosuid ou atributos estendidos não são suportados pelo sistema de arquivos), a
|
||||
criação de um ambiente privilegiado por capacidades, naturalmente um shell, é
|
||||
possível. O shell fornece aos processos herdados a CAP_PERFMON e outras
|
||||
capacidades necessárias para que operações de monitoramento de desempenho e
|
||||
observabilidade estejam disponíveis no ambiente sem limites. O acesso ao ambiente
|
||||
pode ser aberto via utilitário sudo apenas para membros do grupo perf_users. Para
|
||||
criar tal ambiente:
|
||||
|
||||
1. Crie um script shell que utilize o utilitário capsh [16]_ para atribuir a
|
||||
CAP_PERFMON e outras capacidades necessárias no conjunto de capacidades
|
||||
ambiente (ambient capability set) do processo do shell, travar os bits de
|
||||
segurança do processo após habilitar os bits SECBIT_NO_SETUID_FIXUP,
|
||||
SECBIT_NOROOT e SECBIT_NO_CAP_AMBIENT_RAISE e, em seguida, alterar a
|
||||
identidade do processo para o chamador do script via sudo, que deve ser
|
||||
essencialmente um membro do grupo perf_users:
|
||||
|
||||
::
|
||||
|
||||
# ls -alh /usr/local/bin/perf.shell
|
||||
-rwxr-xr-x. 1 root root 83 Oct 13 23:57 /usr/local/bin/perf.shell
|
||||
# cat /usr/local/bin/perf.shell
|
||||
exec /usr/sbin/capsh --iab=^cap_perfmon --secbits=239 --user=$SUDO_USER -- -l
|
||||
|
||||
2. Estenda a política do sudo no arquivo /etc/sudoers com uma regra para o grupo
|
||||
perf_users:
|
||||
|
||||
::
|
||||
|
||||
# grep perf_users /etc/sudoers
|
||||
%perf_users ALL=/usr/local/bin/perf.shell
|
||||
|
||||
3. Verifique se os membros do grupo perf_users têm acesso ao shell privilegiado
|
||||
e têm a CAP_PERFMON e outras capacidades necessárias habilitadas nos conjuntos
|
||||
de capacidades permitidas (permitted), efetivas (effective) e ambiente (ambient)
|
||||
de um processo herdado:
|
||||
|
||||
::
|
||||
|
||||
$ id
|
||||
uid=1003(capsh_test) gid=1004(capsh_test) groups=1004(capsh_test),1000(perf_users) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
|
||||
$ sudo perf.shell
|
||||
[sudo] password for capsh_test:
|
||||
$ grep Cap /proc/self/status
|
||||
CapInh: 0000004000000000
|
||||
CapPrm: 0000004000000000
|
||||
CapEff: 0000004000000000
|
||||
CapBnd: 000000ffffffffff
|
||||
CapAmb: 0000004000000000
|
||||
$ capsh --decode=0000004000000000
|
||||
0x0000004000000000=cap_perfmon
|
||||
|
||||
Como resultado, os membros do grupo perf_users têm acesso ao ambiente
|
||||
privilegiado onde podem usar ferramentas que empregam APIs de monitoramento
|
||||
de desempenho governadas pela capacidade Linux CAP_PERFMON.
|
||||
|
||||
Este gerenciamento específico de controle de acesso está disponível apenas para
|
||||
processos em execução pelo superusuário ou root com as capacidades CAP_SETPCAP,
|
||||
CAP_SETFCAP [6]_ .
|
||||
|
||||
Usuários não privilegiados
|
||||
--------------------------
|
||||
|
||||
O controle de *escopo* e *acesso* do perf_events para processos não
|
||||
privilegiados é governado pela configuração perf_event_paranoid [2]_ :
|
||||
|
||||
-1:
|
||||
Não impõe restrições de *escopo* e *acesso* ao uso do monitoramento de
|
||||
desempenho do perf_events. O limite de travamento perf_event_mlock_kb [2]_
|
||||
por usuário e por CPU é ignorado ao alocar buffers de memória para armazenar
|
||||
dados de desempenho. Este é o modo menos seguro, pois o *escopo* monitorado
|
||||
permitido é maximizado e nenhum limite específico do perf_events é imposto
|
||||
aos *recursos* alocados para o monitoramento de desempenho.
|
||||
|
||||
>=0:
|
||||
O *escopo* inclui o monitoramento de desempenho por processo e em todo o
|
||||
sistema, mas exclui o monitoramento de tracepoints brutos e tracepoints de
|
||||
funções do ftrace. Eventos de CPU e do sistema ocorridos durante a execução
|
||||
no espaço de usuário ou no espaço de kernel podem ser monitorados e capturados
|
||||
para análise posterior. O limite de travamento perf_event_mlock_kb por usuário
|
||||
e por CPU é imposto, mas ignorado para processos não privilegiados com a
|
||||
capacidade CAP_IPC_LOCK [6]_ .
|
||||
|
||||
>=1:
|
||||
O *escopo* inclui apenas o monitoramento de desempenho por processo e exclui
|
||||
o monitoramento de desempenho em todo o sistema. Eventos de CPU e do sistema
|
||||
ocorridos durante a execução no espaço de usuário ou no espaço de kernel podem
|
||||
ser monitorados e capturados para análise posterior. O limite de travamento
|
||||
perf_event_mlock_kb por usuário e por CPU é imposto, mas ignorado para
|
||||
processos não privilegiados com a capacidade CAP_IPC_LOCK.
|
||||
|
||||
>=2:
|
||||
O *escopo* inclui apenas o monitoramento de desempenho por processo. Eventos
|
||||
de CPU e do sistema ocorridos durante a execução apenas no espaço de usuário
|
||||
podem ser monitorados e capturados para análise posterior. O limite de
|
||||
travamento perf_event_mlock_kb por usuário e por CPU é imposto, mas ignorado
|
||||
para processos não privilegiados com a capacidade CAP_IPC_LOCK.
|
||||
|
||||
Controle de recursos
|
||||
--------------------
|
||||
|
||||
Descritores de arquivo abertos
|
||||
++++++++++++++++++++++++++++++
|
||||
|
||||
A API de chamada de sistema perf_events [2]_ aloca descritores de arquivo para cada
|
||||
evento de PMU configurado. Descritores de arquivos abertos são um recurso contabilizado
|
||||
por processo e governado pelo limite RLIMIT_NOFILE [11]_ (ulimit -n), que geralmente é
|
||||
derivado do processo do shell de login. Ao configurar a coleta do Perf para uma longa
|
||||
lista de eventos em um sistema de servidor grande, esse limite pode ser facilmente
|
||||
atingido, impedindo a configuração de monitoramento necessária. O limite RLIMIT_NOFILE
|
||||
pode ser aumentado por usuário modificando o conteúdo do arquivo limits.conf [12]_ .
|
||||
Normalmente, uma sessão de amostragem do Perf (perf record) requer uma quantidade de
|
||||
descritores de arquivos perf_event abertos que não seja inferior ao número de eventos
|
||||
monitorados multiplicado pelo número de CPUs monitoradas.
|
||||
|
||||
Alocação de memória
|
||||
+++++++++++++++++++
|
||||
|
||||
A quantidade de memória disponível para processos de usuário para captura de dados
|
||||
de monitoramento de desempenho é governada pela configuração perf_event_mlock_kb [2]_ .
|
||||
Esta configuração de recurso específica do perf_event define os limites gerais de
|
||||
memória por CPU permitidos para mapeamento pelos processos de usuário para executar
|
||||
o monitoramento de desempenho. A configuração essencialmente estende o limite
|
||||
RLIMIT_MEMLOCK [11]_ , mas apenas para regiões de memória mapeadas especificamente
|
||||
para a captura de eventos de desempenho monitorados e dados relacionados.
|
||||
|
||||
Por exemplo, se uma máquina tiver oito núcleos e o limite perf_event_mlock_kb estiver
|
||||
definido como 516 KiB, então um processo de usuário receberá 516 KiB * 8 = 4128 KiB
|
||||
de memória acima do limite RLIMIT_MEMLOCK (ulimit -l) para buffers mmap do perf_event.
|
||||
Em particular, isso significa que, se o usuário desejar iniciar dois ou mais processos
|
||||
de monitoramento de desempenho, ele deverá distribuir manualmente os 4128 KiB disponíveis
|
||||
entre os processos de monitoramento, por exemplo, usando a opção do modo de gravação
|
||||
--mmap-pages do Perf. Caso contrário, o primeiro processo de monitoramento de desempenho
|
||||
iniciado alocará todos os 4128 KiB disponíveis e os outros processos falharão em prosseguir
|
||||
devido à falta de memória.
|
||||
|
||||
As restrições de recursos RLIMIT_MEMLOCK e perf_event_mlock_kb são ignoradas para
|
||||
processos com a capacidade CAP_IPC_LOCK. Assim, usuários privilegiados de
|
||||
perf_events/Perf podem receber memória acima das restrições para fins de monitoramento
|
||||
de desempenho de perf_events/Perf fornecendo a capacidade CAP_IPC_LOCK ao executável
|
||||
do Perf.
|
||||
|
||||
Bibliografia
|
||||
------------
|
||||
|
||||
.. [1] `<https://lwn.net/Articles/337493/>`_
|
||||
.. [2] `<http://man7.org/linux/man-pages/man2/perf_event_open.2.html>`_
|
||||
.. [3] `<http://web.eece.maine.edu/~vweaver/projects/perf_events/>`_
|
||||
.. [4] `<https://perf.wiki.kernel.org/index.php/Main_Page>`_
|
||||
.. [5] `<https://www.kernel.org/doc/html/latest/security/credentials.html>`_
|
||||
.. [6] `<http://man7.org/linux/man-pages/man7/capabilities.7.html>`_
|
||||
.. [7] `<http://man7.org/linux/man-pages/man2/ptrace.2.html>`_
|
||||
.. [8] `<https://en.wikipedia.org/wiki/Hardware_performance_counter>`_
|
||||
.. [9] `<https://en.wikipedia.org/wiki/Model-specific_register>`_
|
||||
.. [10] `<http://man7.org/linux/man-pages/man5/acl.5.html>`_
|
||||
.. [11] `<http://man7.org/linux/man-pages/man2/getrlimit.2.html>`_
|
||||
.. [12] `<http://man7.org/linux/man-pages/man5/limits.conf.5.html>`_
|
||||
.. [13] `<https://sites.google.com/site/fullycapable>`_
|
||||
.. [14] `<http://man7.org/linux/man-pages/man8/auditd.8.html>`_
|
||||
.. [15] `<https://man7.org/linux/man-pages/man8/sudo.8.html>`_
|
||||
.. [16] `<https://git.kernel.org/pub/scm/libs/libcap/libcap.git/>`_
|
||||
108
Documentation/translations/pt_BR/admin-guide/sysctl/index.rst
Normal file
108
Documentation/translations/pt_BR/admin-guide/sysctl/index.rst
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===========================
|
||||
Documentação para /proc/sys
|
||||
===========================
|
||||
|
||||
Copyright (c) 1998, 1999, Rik van Riel <riel@nl.linux.org>
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
'Por que', ouço você perguntar, 'alguém iria sequer _querer_ documentação
|
||||
para esses arquivos sysctl? Se alguém realmente precisa, está tudo no
|
||||
código-fonte...'
|
||||
|
||||
Bem, esta documentação foi escrita porque algumas pessoas ou não sabem
|
||||
que precisam ajustar algo, ou porque não têm tempo ou conhecimento
|
||||
para ler o código-fonte.
|
||||
|
||||
Além disso, os programadores que construíram o sysctl o fizeram para
|
||||
ser realmente utilizado, e não apenas pela diversão de programá-lo :-)
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Aviso legal:
|
||||
|
||||
Como de costume, há duas coisas principais a se considerar:
|
||||
|
||||
1. você recebe pelo que paga
|
||||
2. é de graça
|
||||
|
||||
As consequências são que eu não garanto a exatidão deste
|
||||
documento e, se você vier reclamar comigo sobre como você bagunçou seu
|
||||
sistema por causa de uma documentação incorreta, não sentirei pena de você.
|
||||
Eu posso até rir de você...
|
||||
|
||||
Mas é claro, se você _realmente_ conseguir bagunçar seu sistema usando
|
||||
apenas as opções de sysctl utilizadas neste arquivo, eu gostaria de saber
|
||||
disso. Não apenas para dar boas risadas, mas também para ter certeza de que
|
||||
você é a última pessoa lendo o manual (RTFM) a fazer essa besteira.
|
||||
|
||||
Em resumo, envie suas sugestões, correções e/ou histórias de terror
|
||||
por e-mail para: <riel@nl.linux.org>
|
||||
|
||||
Rik van Riel.
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Introdução
|
||||
==========
|
||||
|
||||
O sysctl é um meio de configurar determinados aspectos do kernel
|
||||
em tempo de execução, e o diretório /proc/sys/ existe para que você
|
||||
nem precise de ferramentas especiais para fazer isso!
|
||||
Na verdade, são necessárias apenas quatro coisas para usar esses recursos
|
||||
de configuração:
|
||||
|
||||
- um sistema Linux em execução
|
||||
- acesso root
|
||||
- bom senso (isso é especialmente difícil de encontrar hoje em dia)
|
||||
- conhecimento sobre o que todos esses valores significam
|
||||
|
||||
Como um rápido 'ls /proc/sys' mostrará, o diretório consiste em
|
||||
vários subdiretórios (dependentes de arquitetura?). Cada subdiretório
|
||||
trata principalmente de uma parte do kernel, permitindo que você faça
|
||||
a configuração parte por parte, ou apenas algumas 'modificações temáticas'.
|
||||
|
||||
Esta documentação é sobre:
|
||||
|
||||
=============== ===============================================================
|
||||
abi/ domínios de execução e personalidades
|
||||
<$ARCH> controles de ajuste para várias arquiteturas de CPU (ex.: csky, s390)
|
||||
crypto/ subsistema criptográfico
|
||||
debug/ recursos de depuração
|
||||
dev/ informações específicas de dispositivos (ex.: dev/cdrom/info)
|
||||
fs/ sistemas de arquivos específicos
|
||||
ajustes de manipuladores de arquivos (filehandle), inode, dentry e cotas
|
||||
binfmt_misc <Documentation/admin-guide/binfmt-misc.rst>
|
||||
kernel/ informações globais / ajustes do kernel
|
||||
coisas diversas
|
||||
alguns controles específicos de arquitetura
|
||||
coisas de segurança (LSM)
|
||||
net/ coisas de rede; para documentação consulte:
|
||||
<Documentation/networking/>
|
||||
proc/ <vazio>
|
||||
sunrpc/ SUN Remote Procedure Call (NFS)
|
||||
user/ limites por namespace de usuário
|
||||
vm/ ajustes de gerenciamento de memória
|
||||
gerenciamento de buffers e cache
|
||||
xen/ controles do hipervisor Xen
|
||||
=============== ===============================================================
|
||||
|
||||
Estes são os subdiretórios que tenho no meu sistema ou que foram descobertos
|
||||
pesquisando pelo código-fonte. Pode haver mais ou outros subdiretórios em
|
||||
outra configuração. Se você encontrar outro diretório, eu realmente gostaria de
|
||||
saber sobre ele :-)
|
||||
|
||||
Todolist:
|
||||
|
||||
* abi
|
||||
* crypto
|
||||
* debug
|
||||
* fs
|
||||
* kernel
|
||||
* net
|
||||
* sunrpc
|
||||
* user
|
||||
* vm
|
||||
* xen
|
||||
195
Documentation/translations/pt_BR/admin-guide/sysfs-rules.rst
Normal file
195
Documentation/translations/pt_BR/admin-guide/sysfs-rules.rst
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Regras sobre como acessar informações no sysfs
|
||||
==============================================
|
||||
|
||||
O sysfs exportado pelo kernel expõe detalhes internos de implementação do
|
||||
kernel e depende de estruturas e do leiaute internos do kernel. Há um consenso
|
||||
entre os desenvolvedores do kernel de que o kernel Linux não fornece uma API
|
||||
interna estável. Portanto, existem aspectos da interface do sysfs que podem
|
||||
não ser estáveis entre lançamentos do kernel.
|
||||
|
||||
Para minimizar o risco de quebrar os usuários do sysfs — que, na maioria dos
|
||||
casos, são aplicações de espaço de usuário de baixo nível — a cada novo
|
||||
lançamento do kernel, os usuários do sysfs devem seguir algumas regras para usar
|
||||
uma forma o mais abstrata possível de acessar esse sistema de arquivos. Os
|
||||
programas udev e HAL atuais já implementam isso, e os usuários são incentivados
|
||||
a se conectar, se possível, às abstrações que esses programas fornecem em vez de
|
||||
acessar o sysfs diretamente.
|
||||
|
||||
Mas, se você realmente quer ou precisa acessar o sysfs diretamente, siga as
|
||||
seguintes regras e, assim, seus programas deverão funcionar com versões
|
||||
futuras da interface do sysfs.
|
||||
|
||||
- Não use a libsysfs
|
||||
Ela faz suposições sobre o sysfs que não são verdadeiras. Sua API não
|
||||
oferece nenhuma abstração; ela expõe todos os detalhes de implementação do
|
||||
driver-core do kernel em sua própria API. Portanto, ela não é melhor do que
|
||||
ler diretórios e abrir os próprios arquivos.
|
||||
Além disso, ela não é mantida ativamente no sentido de refletir o
|
||||
desenvolvimento atual do kernel. O objetivo de fornecer uma interface
|
||||
estável para o sysfs falhou; ela causa mais problemas do que resolve. Ela
|
||||
viola muitas das regras deste documento.
|
||||
|
||||
- sysfs está sempre em ``/sys``
|
||||
Analisar ``/proc/mounts`` é perda de tempo. Outros pontos de montagem são um
|
||||
bug de configuração do sistema que você não deve tentar contornar. Para
|
||||
casos de teste, talvez ofereça suporte a uma variável de ambiente
|
||||
``SYSFS_PATH`` para sobrescrever o comportamento da aplicação, mas nunca
|
||||
tente procurar pelo sysfs. Nunca tente montá-lo, a menos que você seja um
|
||||
script de inicialização inicial (early boot).
|
||||
|
||||
- Dispositivos são apenas "dispositivos"
|
||||
Não existe algo como dispositivos de classe, de barramento, físicos,
|
||||
interfaces e afins com os quais você possa contar no espaço de usuário.
|
||||
Tudo é simplesmente um "dispositivo". Tipos como classe, barramento,
|
||||
físico... são apenas detalhes de implementação do kernel que não devem ser
|
||||
esperados por aplicações que procuram dispositivos no sysfs.
|
||||
|
||||
As propriedades de um dispositivo são:
|
||||
|
||||
- devpath (``/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0``)
|
||||
|
||||
- idêntico ao valor de DEVPATH no evento enviado pelo kernel na criação e
|
||||
remoção do dispositivo
|
||||
- a chave única para o dispositivo naquele momento
|
||||
- o caminho do kernel para o diretório do dispositivo sem o ``/sys`` inicial,
|
||||
e sempre começando com uma barra
|
||||
- todos os elementos de um devpath devem ser diretórios reais. Links
|
||||
simbólicos apontando para /sys/devices devem ser sempre resolvidos para o
|
||||
seu alvo real e o caminho do alvo deve ser usado para acessar o dispositivo.
|
||||
Dessa forma, o devpath para o dispositivo corresponde ao devpath do kernel
|
||||
usado no momento do evento.
|
||||
- usar ou expor valores de symlinks como elementos em uma string de devpath
|
||||
é um bug na aplicação
|
||||
|
||||
- nome do kernel (``sda``, ``tty``, ``0000:00:1f.2``, ...)
|
||||
|
||||
- um nome de diretório, idêntico ao último elemento do devpath
|
||||
- as aplicações precisam lidar com espaços e caracteres como ``!`` no
|
||||
nome
|
||||
|
||||
- subsistema (``block``, ``tty``, ``pci``, ...)
|
||||
|
||||
- string simples, nunca um caminho ou um link
|
||||
- recuperado através da leitura do link "subsystem" e usando apenas o
|
||||
último elemento do caminho de destino
|
||||
|
||||
- driver (``tg3``, ``ata_piix``, ``uhci_hcd``)
|
||||
|
||||
- uma string simples, que pode conter espaços, nunca um caminho ou um
|
||||
link
|
||||
- é recuperado pela leitura do link "driver" e usando apenas o último
|
||||
elemento do caminho de destino
|
||||
- dispositivos que não possuem o link "driver" simplesmente não possuem um
|
||||
driver; copiar o valor do driver no contexto de um dispositivo filho é
|
||||
um bug na aplicação
|
||||
|
||||
- atributos
|
||||
|
||||
- os arquivos no diretório do dispositivo ou arquivos abaixo de subdiretórios
|
||||
do mesmo diretório de dispositivo
|
||||
- acessar atributos alcançados por um symlink apontando para outro dispositivo,
|
||||
como o link "device", é um bug na aplicação
|
||||
|
||||
Tudo o mais é apenas um detalhe de implementação do driver-core do kernel
|
||||
que não deve ser presumido como estável entre lançamentos do kernel.
|
||||
|
||||
- Propriedades de dispositivos pais nunca pertencem a um dispositivo filho.
|
||||
Sempre olhe para os próprios dispositivos pais para determinar as propriedades
|
||||
de contexto do dispositivo. Se o dispositivo ``eth0`` ou ``sda`` não tiver
|
||||
um link "driver", então esse dispositivo não possui um driver. Seu valor é vazio.
|
||||
Nunca copie nenhuma propriedade do dispositivo pai para um dispositivo filho.
|
||||
As propriedades do dispositivo pai podem mudar dinamicamente sem qualquer aviso
|
||||
para o dispositivo filho.
|
||||
|
||||
- Hierarquia em uma única árvore de dispositivos
|
||||
Há apenas um lugar válido no sysfs onde a hierarquia pode ser examinada
|
||||
e este é abaixo de: ``/sys/devices.``
|
||||
Está planejado que todos os diretórios de dispositivos terminarão na árvore
|
||||
abaixo deste diretório.
|
||||
|
||||
- Classificação por subsistema
|
||||
Atualmente, existem três locais para classificação de dispositivos:
|
||||
``/sys/block,`` ``/sys/class`` e ``/sys/bus.`` Está planejado que estes não
|
||||
conterão diretórios de dispositivos em si, mas apenas listas planas de
|
||||
symlinks apontando para a árvore unificada ``/sys/devices``.
|
||||
Todos os três locais têm regras completamente diferentes sobre como acessar
|
||||
informações de dispositivos. Está planejado fundir todos os três diretórios de
|
||||
classificação em um único local em ``/sys/subsystem``, seguindo o leiaute dos
|
||||
diretórios de barramentos. Todos os barramentos e classes, incluindo o
|
||||
subsistema de blocos convertido, aparecerão lá.
|
||||
Os dispositivos pertencentes a um subsistema criarão um symlink no diretório
|
||||
"devices" em ``/sys/subsystem/<name>/devices``,
|
||||
|
||||
Se ``/sys/subsystem`` existir, ``/sys/bus``, ``/sys/class`` e ``/sys/block``
|
||||
podem ser ignorados. Se ele não existir, você sempre terá que varrer todos os
|
||||
três locais, já que o kernel é livre para mover um subsistema de um local para
|
||||
o outro, desde que os dispositivos ainda sejam acessíveis pelo mesmo nome de
|
||||
subsistema.
|
||||
|
||||
Presumir que ``/sys/class/<subsystem>`` e ``/sys/bus/<subsystem>``, ou
|
||||
``/sys/block`` e ``/sys/class/block`` não são intercambiáveis é um bug na
|
||||
aplicação.
|
||||
|
||||
- Bloco
|
||||
O subsistema de blocos convertido em ``/sys/class/block`` ou
|
||||
``/sys/subsystem/block`` conterá os links para discos e partições no mesmo
|
||||
nível, nunca em uma hierarquia. Presumir que o subsistema de blocos contém
|
||||
apenas discos e não dispositivos de partição na mesma lista plana é um bug
|
||||
na aplicação.
|
||||
|
||||
- Link "device" e links <subsystem>:<kernel name>
|
||||
Nunca dependa do link "device". O link "device" é uma solução alternativa
|
||||
para o leiaute antigo, onde dispositivos de classe não são criados em
|
||||
``/sys/devices/`` como os dispositivos de barramento. Se a resolução de links
|
||||
de um diretório de dispositivo não terminar em ``/sys/devices/``, você pode
|
||||
usar o link "device" para encontrar os dispositivos pais em ``/sys/devices/``;
|
||||
esse é o único uso válido do link "device"; ele nunca deve aparecer em nenhum
|
||||
caminho como um elemento. Presumir a existência do link "device" para um
|
||||
dispositivo em ``/sys/devices/`` é um bug na aplicação.
|
||||
Acessar ``/sys/class/net/eth0/device`` é um bug na aplicação.
|
||||
|
||||
Nunca dependa dos links específicos de classe de volta para o diretório
|
||||
``/sys/class``. Esses links também são uma solução paliativa para o erro de
|
||||
projeto no qual dispositivos de classe não são criados em ``/sys/devices.``
|
||||
Se um diretório de dispositivo não contiver diretórios para dispositivos
|
||||
filhos, esses links podem ser usados para encontrar os dispositivos filhos em
|
||||
``/sys/class.`` Esse é o único uso válido desses links; eles nunca devem
|
||||
aparecer em nenhum caminho como um elemento. Presumir a existência desses links
|
||||
para dispositivos que são diretórios reais de dispositivos filhos na árvore
|
||||
``/sys/devices`` é um bug na aplicação.
|
||||
|
||||
Está planejado remover todos esses links quando todos os diretórios de
|
||||
dispositivos de classe residirem em ``/sys/devices.``
|
||||
|
||||
- A posição dos dispositivos ao longo da cadeia de dispositivos pode mudar.
|
||||
Nunca dependa de uma posição específica do dispositivo pai no devpath,
|
||||
ou da cadeia de dispositivos pais. O kernel é livre para inserir dispositivos
|
||||
na cadeia. Você deve sempre requisitar o dispositivo pai que procura pelo
|
||||
valor do seu subsistema. Você precisa percorrer a cadeia para cima até
|
||||
encontrar o dispositivo correspondente ao subsistema esperado. Depender de
|
||||
uma posição específica de um dispositivo pai ou expor caminhos relativos
|
||||
usando ``../`` para acessar a cadeia de pais é um bug na aplicação.
|
||||
|
||||
- Ao ler e gravar arquivos de atributos de dispositivo do sysfs, evite a dependência
|
||||
de códigos de erro específicos sempre que possível. Isso minimiza o acoplamento
|
||||
com a implementação do tratamento de erros dentro do kernel.
|
||||
|
||||
Em geral, falhas ao ler ou gravar atributos de dispositivos no sysfs devem
|
||||
propagar erros sempre que possível. Erros comuns incluem, mas não estão
|
||||
limitados a:
|
||||
|
||||
``-EIO``: A operação de leitura ou gravação não é suportada, tipicamente
|
||||
retornada pelo próprio sistema sysfs se o ponteiro de leitura ou gravação
|
||||
for ``NULL``.
|
||||
|
||||
``-ENXIO``: A operação de leitura ou gravação falhou
|
||||
|
||||
Os códigos de erro não serão alterados sem um bom motivo, e caso uma alteração
|
||||
nos códigos de erro resulte em quebra no espaço de usuário, ela será corrigida,
|
||||
ou a alteração causadora será revertida.
|
||||
|
||||
As aplicações do espaço de usuário podem, no entanto, esperar que o formato e
|
||||
o conteúdo dos arquivos de atributos permaneçam consistentes na ausência de uma
|
||||
mudança no atributo de versão no contexto de um determinado atributo.
|
||||
|
|
@ -7,12 +7,16 @@ Dicas de depuração para desenvolvedores do Kernel Linux
|
|||
Guias gerais
|
||||
------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
userspace_debugging_guide
|
||||
|
||||
Todolist:
|
||||
|
||||
* driver_development_debugging_guide
|
||||
* gdb-kernel-debugging
|
||||
* kgdb
|
||||
* userspace_debugging_guide
|
||||
|
||||
Guias específicos de subsistemas
|
||||
--------------------------------
|
||||
|
|
@ -40,8 +44,8 @@ andamento?
|
|||
|
||||
Nesse caso, sua capacidade de depuração depende do suporte de depuração
|
||||
embutido no kernel fornecido pela distribuição.
|
||||
O :doc:`/process/debugging/userspace_debugging_guide` fornece uma breve visão
|
||||
geral sobre uma variedade de ferramentas de depuração possíveis nessa situação.
|
||||
O :doc:`userspace_debugging_guide` fornece uma breve visão geral sobre uma
|
||||
variedade de ferramentas de depuração possíveis nessa situação.
|
||||
Você pode verificar a capacidade do seu kernel, na maioria dos casos, olhando o
|
||||
arquivo de configuração dentro do diretório /boot.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,297 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================================================
|
||||
Conselhos de depuração a partir do espaço de usuário
|
||||
====================================================
|
||||
|
||||
Este documento fornece uma breve visão geral das ferramentas mais comuns
|
||||
para depurar o kernel Linux a partir do espaço de usuário.
|
||||
Para conselhos de depuração voltados a desenvolvedores de drivers, veja
|
||||
:doc:`aqui </process/debugging/driver_development_debugging_guide>`.
|
||||
Para conselhos gerais de depuração, veja o :doc:`documento de conselhos
|
||||
gerais <index>`.
|
||||
|
||||
.. contents::
|
||||
:depth: 3
|
||||
|
||||
As seções a seguir apresentam as ferramentas disponíveis.
|
||||
|
||||
Dynamic debug
|
||||
-------------
|
||||
|
||||
Mecanismo para filtrar o que chega ao log do kernel, desabilitando ou
|
||||
habilitando mensagens de log.
|
||||
|
||||
Pré-requisito: ``CONFIG_DYNAMIC_DEBUG``
|
||||
|
||||
O dynamic debug só consegue atuar sobre:
|
||||
|
||||
- pr_debug()
|
||||
- dev_dbg()
|
||||
- print_hex_dump_debug()
|
||||
- print_hex_dump_bytes()
|
||||
|
||||
Por isso a utilidade dessa ferramenta é, até o momento, bastante limitada,
|
||||
já que não há uma regra uniforme para adicionar prints de depuração ao
|
||||
código-fonte, o que resulta em uma variedade de formas de implementar
|
||||
esses prints.
|
||||
|
||||
Note também que a maioria das instruções de depuração é implementada como
|
||||
uma variação de dprintk(), que precisa ser ativada por um parâmetro no
|
||||
módulo correspondente; o dynamic debug não é capaz de fazer essa etapa por
|
||||
você.
|
||||
|
||||
Eis um exemplo que habilita todos os pr_debug() disponíveis no arquivo::
|
||||
|
||||
$ alias ddcmd='echo $* > /proc/dynamic_debug/control'
|
||||
$ ddcmd '-p; file v4l2-h264.c +p'
|
||||
$ grep =p /proc/dynamic_debug/control
|
||||
drivers/media/v4l2-core/v4l2-h264.c:372 [v4l2_h264]print_ref_list_b =p
|
||||
"ref_pic_list_b%u (cur_poc %u%c) %s"
|
||||
drivers/media/v4l2-core/v4l2-h264.c:333 [v4l2_h264]print_ref_list_p =p
|
||||
"ref_pic_list_p (cur_poc %u%c) %s\n"
|
||||
|
||||
**Quando usar isto em vez do Ftrace?**
|
||||
|
||||
- Quando o código contém uma das instruções de print válidas (veja acima)
|
||||
ou quando você adicionou várias instruções pr_debug() durante o
|
||||
desenvolvimento
|
||||
- Quando o tempo não é um problema, ou seja, se várias instruções
|
||||
pr_debug() no código não causarem atrasos
|
||||
- Quando você se importa mais em receber mensagens de log específicas do
|
||||
que em rastrear o padrão de chamadas de uma função
|
||||
|
||||
Para a documentação completa, veja
|
||||
:doc:`/admin-guide/dynamic-debug-howto`
|
||||
|
||||
Ftrace
|
||||
------
|
||||
|
||||
Pré-requisito: ``CONFIG_DYNAMIC_FTRACE``
|
||||
|
||||
Esta ferramenta usa o sistema de arquivos tracefs para os arquivos de
|
||||
controle e de saída. Esse sistema de arquivos é montado como um diretório
|
||||
``tracing``, que pode ser encontrado em ``/sys/kernel/`` ou em
|
||||
``/sys/debug/kernel/``.
|
||||
|
||||
Algumas das operações mais importantes para depuração são:
|
||||
|
||||
- Você pode fazer um rastreamento de função adicionando o nome da função
|
||||
ao arquivo ``set_ftrace_filter`` (que aceita qualquer nome de função
|
||||
encontrado no arquivo ``available_filter_functions``) ou pode
|
||||
desabilitar funções específicas adicionando seus nomes ao arquivo
|
||||
``set_ftrace_notrace`` (mais informações em:
|
||||
:ref:`trace/ftrace:dynamic ftrace`).
|
||||
- Para descobrir de onde partem as chamadas, você pode ativar a opção
|
||||
``func_stack_trace`` em ``options/func_stack_trace``.
|
||||
- Rastrear as funções filhas de uma chamada e exibir os valores de retorno
|
||||
é possível adicionando a função desejada ao arquivo
|
||||
``set_graph_function`` (requer a configuração ``FUNCTION_GRAPH_RETVAL``);
|
||||
mais informações em
|
||||
:ref:`trace/ftrace:dynamic ftrace with the function graph tracer`.
|
||||
|
||||
Para a documentação completa do Ftrace, veja :doc:`/trace/ftrace`
|
||||
|
||||
Você também pode rastrear eventos específicos :ref:`usando o rastreamento
|
||||
de eventos <trace/events:2. using event tracing>`, que pode ser definido
|
||||
conforme descrito aqui: :ref:`Criando um tracepoint customizado do Ftrace
|
||||
<process/debugging/driver_development_debugging_guide:ftrace>`.
|
||||
|
||||
Para a documentação completa do rastreamento de eventos do Ftrace, veja
|
||||
:doc:`/trace/events`
|
||||
|
||||
.. _pt_BR_read_ftrace_log:
|
||||
|
||||
Lendo o log do ftrace
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
O arquivo ``trace`` pode ser lido como qualquer outro arquivo (``cat``,
|
||||
``tail``, ``head``, ``vim``, etc.); o tamanho do arquivo é limitado pelo
|
||||
``buffer_size_kb`` (``echo 1000 > buffer_size_kb``). O
|
||||
:ref:`trace/ftrace:trace_pipe` se comporta de forma semelhante ao arquivo
|
||||
``trace``, mas sempre que você lê o arquivo o conteúdo é consumido.
|
||||
|
||||
Kernelshark
|
||||
~~~~~~~~~~~
|
||||
|
||||
Uma interface gráfica para visualizar os rastreamentos em forma de gráfico
|
||||
e de lista, a partir da saída da aplicação `trace-cmd
|
||||
<https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/>`__.
|
||||
|
||||
Para a documentação completa, veja
|
||||
`<https://kernelshark.org/Documentation.html>`__
|
||||
|
||||
Perf e alternativas
|
||||
-------------------
|
||||
|
||||
As ferramentas mencionadas acima oferecem maneiras de inspecionar o código
|
||||
do kernel, resultados, valores de variáveis, etc. Às vezes você precisa
|
||||
primeiro descobrir onde olhar e, para esses casos, um conjunto de
|
||||
ferramentas de acompanhamento de desempenho pode ajudar a delimitar o
|
||||
problema.
|
||||
|
||||
Por que fazer uma análise de desempenho?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Uma análise de desempenho é um bom primeiro passo quando, entre outros
|
||||
motivos:
|
||||
|
||||
- você não consegue definir o problema
|
||||
- você não sabe onde ele ocorre
|
||||
- o sistema em execução não deve ser interrompido, ou é um sistema remoto
|
||||
no qual você não pode instalar um novo módulo/kernel
|
||||
|
||||
Como fazer uma análise simples com ferramentas do Linux?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Para iniciar uma análise de desempenho, você pode começar com as
|
||||
ferramentas usuais, como:
|
||||
|
||||
- ``top`` / ``htop`` / ``atop`` (*obtenha uma visão geral da carga do
|
||||
sistema, veja picos em processos específicos*)
|
||||
- ``mpstat -P ALL`` (*observe a distribuição de carga entre as CPUs*)
|
||||
- ``iostat -x`` (*observe a utilização e o desempenho dos dispositivos de
|
||||
entrada e saída*)
|
||||
- ``vmstat`` (*visão geral do uso de memória no sistema*)
|
||||
- ``pidstat`` (*semelhante ao* ``vmstat`` *, mas por processo, para
|
||||
restringir ao alvo*)
|
||||
- ``strace -tp $PID`` (*uma vez que você conhece o processo, pode descobrir
|
||||
como ele se comunica com o kernel*)
|
||||
|
||||
Isso deve ajudar a reduzir suficientemente as áreas a serem investigadas.
|
||||
|
||||
Indo mais fundo com o perf
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A ferramenta **perf** fornece uma série de métricas e eventos para
|
||||
aprofundar a investigação dos problemas.
|
||||
|
||||
Pré-requisito: compilar ou instalar o perf no seu sistema
|
||||
|
||||
Coletar dados estatísticos ao procurar todos os arquivos que começam com
|
||||
``gcc`` em ``/usr``::
|
||||
|
||||
# perf stat -d find /usr -name 'gcc*' | wc -l
|
||||
|
||||
Performance counter stats for 'find /usr -name gcc*':
|
||||
|
||||
1277.81 msec task-clock # 0.997 CPUs utilized
|
||||
9 context-switches # 7.043 /sec
|
||||
1 cpu-migrations # 0.783 /sec
|
||||
704 page-faults # 550.943 /sec
|
||||
766548897 cycles # 0.600 GHz (97.15%)
|
||||
798285467 instructions # 1.04 insn per cycle (97.15%)
|
||||
57582731 branches # 45.064 M/sec (2.85%)
|
||||
3842573 branch-misses # 6.67% of all branches (97.15%)
|
||||
281616097 L1-dcache-loads # 220.390 M/sec (97.15%)
|
||||
4220975 L1-dcache-load-misses # 1.50% of all L1-dcache accesses (97.15%)
|
||||
<not supported> LLC-loads
|
||||
<not supported> LLC-load-misses
|
||||
|
||||
1.281746009 seconds time elapsed
|
||||
|
||||
0.508796000 seconds user
|
||||
0.773209000 seconds sys
|
||||
|
||||
|
||||
52
|
||||
|
||||
A disponibilidade de eventos e métricas depende do sistema em que você está
|
||||
executando.
|
||||
|
||||
Para a documentação completa, veja
|
||||
`<https://perf.wiki.kernel.org/index.php/Main_Page>`__
|
||||
|
||||
Perfetto
|
||||
~~~~~~~~
|
||||
|
||||
Um conjunto de ferramentas para medir e analisar o desempenho de
|
||||
aplicações e sistemas. Você pode usá-lo para:
|
||||
|
||||
* identificar gargalos
|
||||
* otimizar código
|
||||
* fazer o software rodar mais rápido e de forma mais eficiente.
|
||||
|
||||
**Qual é a diferença entre o perfetto e o perf?**
|
||||
|
||||
* o perf é uma ferramenta que faz parte do kernel Linux e é especializada
|
||||
nele, com interface de linha de comando.
|
||||
* o Perfetto é um conjunto multiplataforma de ferramentas para análise de
|
||||
desempenho, estende suas funcionalidades ao espaço de usuário e oferece
|
||||
uma interface web.
|
||||
|
||||
Para a documentação completa, veja `<https://perfetto.dev/docs/>`__
|
||||
|
||||
Ferramentas de análise de kernel panic
|
||||
--------------------------------------
|
||||
|
||||
Para capturar o crash dump, use ``Kdump`` e ``Kexec``. Abaixo você
|
||||
encontra alguns conselhos para analisar os dados.
|
||||
|
||||
Para a documentação completa, veja :doc:`/admin-guide/kdump/kdump`
|
||||
|
||||
Para encontrar a linha correspondente no código, você pode usar o
|
||||
`faddr2line
|
||||
<https://elixir.bootlin.com/linux/v6.11.6/source/scripts/faddr2line>`__;
|
||||
note que é preciso habilitar ``CONFIG_DEBUG_INFO`` para que isso
|
||||
funcione.
|
||||
|
||||
Uma alternativa ao ``faddr2line`` é o uso do ``objdump`` (e de suas
|
||||
variantes para as diferentes plataformas, como
|
||||
``aarch64-linux-gnu-objdump``). Tome esta linha como exemplo:
|
||||
|
||||
``[ +0.000240] rkvdec_device_run+0x50/0x138 [rockchip_vdec]``.
|
||||
|
||||
Podemos encontrar a linha de código correspondente executando::
|
||||
|
||||
aarch64-linux-gnu-objdump -dS drivers/staging/media/rkvdec/rockchip-vdec.ko | grep rkvdec_device_run\>: -A 40
|
||||
0000000000000ac8 <rkvdec_device_run>:
|
||||
ac8: d503201f nop
|
||||
acc: d503201f nop
|
||||
{
|
||||
ad0: d503233f paciasp
|
||||
ad4: a9bd7bfd stp x29, x30, [sp, #-48]!
|
||||
ad8: 910003fd mov x29, sp
|
||||
adc: a90153f3 stp x19, x20, [sp, #16]
|
||||
ae0: a9025bf5 stp x21, x22, [sp, #32]
|
||||
const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
|
||||
ae4: f9411814 ldr x20, [x0, #560]
|
||||
struct rkvdec_dev *rkvdec = ctx->dev;
|
||||
ae8: f9418015 ldr x21, [x0, #768]
|
||||
if (WARN_ON(!desc))
|
||||
aec: b4000654 cbz x20, bb4 <rkvdec_device_run+0xec>
|
||||
ret = pm_runtime_resume_and_get(rkvdec->dev);
|
||||
af0: f943d2b6 ldr x22, [x21, #1952]
|
||||
ret = __pm_runtime_resume(dev, RPM_GET_PUT);
|
||||
af4: aa0003f3 mov x19, x0
|
||||
af8: 52800081 mov w1, #0x4 // #4
|
||||
afc: aa1603e0 mov x0, x22
|
||||
b00: 94000000 bl 0 <__pm_runtime_resume>
|
||||
if (ret < 0) {
|
||||
b04: 37f80340 tbnz w0, #31, b6c <rkvdec_device_run+0xa4>
|
||||
dev_warn(rkvdec->dev, "Not good\n");
|
||||
b08: f943d2a0 ldr x0, [x21, #1952]
|
||||
b0c: 90000001 adrp x1, 0 <rkvdec_try_ctrl-0x8>
|
||||
b10: 91000021 add x1, x1, #0x0
|
||||
b14: 94000000 bl 0 <_dev_warn>
|
||||
*bad = 1;
|
||||
b18: d2800001 mov x1, #0x0 // #0
|
||||
...
|
||||
|
||||
Ou seja, nesta linha do crash dump::
|
||||
|
||||
[ +0.000240] rkvdec_device_run+0x50/0x138 [rockchip_vdec]
|
||||
|
||||
Posso tomar ``0x50`` como deslocamento, que devo somar ao endereço base
|
||||
da função correspondente, que encontro nesta linha::
|
||||
|
||||
0000000000000ac8 <rkvdec_device_run>:
|
||||
|
||||
O resultado de ``0xac8 + 0x50 = 0xb18``
|
||||
E quando procuro por esse endereço dentro da função, obtenho a seguinte
|
||||
linha::
|
||||
|
||||
*bad = 1;
|
||||
b18: d2800001 mov x1, #0x0
|
||||
|
||||
**Copyright** ©2024 : Collabora
|
||||
|
|
@ -357,7 +357,7 @@ extern __must_check int check_zeroed_user(const void __user *from, size_t size);
|
|||
* struct).
|
||||
*
|
||||
* @ksize is just sizeof(*dst), and @usize should've been passed by userspace.
|
||||
* The recommended usage is something like the following:
|
||||
* The recommended usage is something like the following::
|
||||
*
|
||||
* SYSCALL_DEFINE2(foobar, const struct foo __user *, uarg, size_t, usize)
|
||||
* {
|
||||
|
|
@ -447,7 +447,7 @@ copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
|
|||
* about data it does not.
|
||||
*
|
||||
* @ksize is just sizeof(*src), and @usize should've been passed by userspace.
|
||||
* The recommended usage is something like the following:
|
||||
* The recommended usage is something like the following::
|
||||
*
|
||||
* SYSCALL_DEFINE2(foobar, struct foo __user *, uarg, size_t, usize)
|
||||
* {
|
||||
|
|
@ -529,7 +529,7 @@ __copy_struct_generic_bounce_buffer(void *dst, size_t dstsize,
|
|||
memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* This is like copy_struct_from_user(), but the
|
||||
* src buffer was already copied into a kernel
|
||||
* bounce buffer, so it will never return -EFAULT.
|
||||
|
|
@ -553,7 +553,7 @@ copy_struct_from_bounce_buffer(void *dst, size_t dstsize,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* This is like copy_struct_to_user(), but the
|
||||
* dst buffer is a kernel bounce buffer instead
|
||||
* of a direct userspace buffer, so it will never return -EFAULT.
|
||||
|
|
@ -770,7 +770,7 @@ static __always_inline void __scoped_user_rw_access_end(const void *p)
|
|||
* If the user access function inside the scope requires a fault label, it
|
||||
* can use @elbl or a different label outside the scope, which requires
|
||||
* that user access which is implemented with ASM GOTO has been properly
|
||||
* wrapped. See unsafe_get_user() for reference.
|
||||
* wrapped. See unsafe_get_user() for reference::
|
||||
*
|
||||
* scoped_user_rw_access(ptr, efault) {
|
||||
* unsafe_get_user(rval, &ptr->rval, efault);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright(c) 2025: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
|
||||
#
|
||||
# pylint: disable=R0903,R0912,R0913,R0914,R0917,C0301
|
||||
# pylint: disable=R0903,R0912,R0913,R0914,R0915,R0917,C0301
|
||||
|
||||
"""
|
||||
Install minimal supported requirements for different Sphinx versions
|
||||
|
|
@ -11,40 +11,64 @@ and optionally test the build.
|
|||
|
||||
import argparse
|
||||
import asyncio
|
||||
import glob
|
||||
import os.path
|
||||
import shutil
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
# Minimal python version supported by the building system.
|
||||
from textwrap import indent
|
||||
|
||||
PYTHON = os.path.basename(sys.executable)
|
||||
MIN_PYTHON_SUBVER = 9 # Currently, Python 3.9 is the minimal supported version
|
||||
|
||||
min_python_bin = None
|
||||
RE_VERSION = re.compile(r"python3\.\d+$")
|
||||
|
||||
for i in range(9, 13):
|
||||
p = f"python3.{i}"
|
||||
if shutil.which(p):
|
||||
min_python_bin = p
|
||||
break
|
||||
|
||||
if not min_python_bin:
|
||||
min_python_bin = PYTHON
|
||||
def get_min_python_bin(min_subver):
|
||||
"""Get minimal python binary since 3.MIN_PYTHON_SUBVER"""
|
||||
bins = set()
|
||||
|
||||
# Starting from 8.0, Python 3.9 is not supported anymore.
|
||||
PYTHON_VER_CHANGES = {(8, 0, 0): PYTHON}
|
||||
paths = os.environ.get("PATH", "").split(os.pathsep)
|
||||
for d in paths:
|
||||
for p in glob.glob(os.path.join(d, "python3.[0-9]*")):
|
||||
if not RE_VERSION.search(p):
|
||||
continue
|
||||
|
||||
ver = int(p.split(".")[1])
|
||||
if ver < min_subver:
|
||||
continue
|
||||
|
||||
if os.path.isfile(p) and os.access(p, os.X_OK):
|
||||
bins.add(p)
|
||||
|
||||
if not bins:
|
||||
return None
|
||||
|
||||
return sorted(bins, key=lambda x: (3, int(x.split(".")[1])))[0]
|
||||
|
||||
|
||||
# Minimal python versions. Please notice that for 3.4.3, older python
|
||||
# versions would work with Sphinx, but kernel doc build is not compatible
|
||||
# with them anymore, due to Sphinx extensions and kernel-doc.
|
||||
PYTHON_VER_CHANGES = {
|
||||
(3, 4, 3): (3, MIN_PYTHON_SUBVER),
|
||||
(8, 0, 0): (3, 10),
|
||||
(8, 1, 0): (3, 11),
|
||||
(9, 1, 0): (3, 12),
|
||||
}
|
||||
|
||||
DEFAULT_VERSIONS_TO_TEST = [
|
||||
(3, 4, 3), # Minimal supported version
|
||||
(5, 3, 0), # CentOS Stream 9 / AlmaLinux 9
|
||||
(6, 1, 1), # Debian 12
|
||||
(7, 2, 1), # openSUSE Leap 15.6
|
||||
(7, 2, 6), # Ubuntu 24.04 LTS
|
||||
(7, 4, 7), # Ubuntu 24.10
|
||||
(7, 3, 0), # openSUSE Tumbleweed
|
||||
(8, 1, 3), # Fedora 42
|
||||
(8, 2, 3) # Latest version - covers rolling distros
|
||||
(3, 4, 3), # Minimal supported version
|
||||
(5, 3, 0), # CentOS Stream 9 / AlmaLinux 9
|
||||
(6, 1, 1), # Debian 12
|
||||
(7, 2, 1), # openSUSE Leap 15.6
|
||||
(7, 2, 6), # Ubuntu 24.04 LTS
|
||||
(7, 4, 7), # Ubuntu 24.10
|
||||
(7, 3, 0), # openSUSE Tumbleweed
|
||||
(8, 1, 3), # Debian 13
|
||||
(8, 2, 3), # Ubuntu 26.04 LTS / Fedora 44
|
||||
(9, 1, 0), # Latest version
|
||||
]
|
||||
|
||||
# Sphinx versions to be installed and their incremental requirements
|
||||
|
|
@ -55,7 +79,6 @@ SPHINX_REQUIREMENTS = {
|
|||
"alabaster": "0.7.12",
|
||||
"babel": "2.8.0",
|
||||
"certifi": "2020.6.20",
|
||||
"docutils": "0.16",
|
||||
"idna": "2.10",
|
||||
"imagesize": "1.2.0",
|
||||
"Jinja2": "2.11.2",
|
||||
|
|
@ -89,7 +112,7 @@ SPHINX_REQUIREMENTS = {
|
|||
"sphinxcontrib-applehelp": "1.0.4",
|
||||
"sphinxcontrib-htmlhelp": "2.0.1",
|
||||
"sphinxcontrib-serializinghtml": "1.1.5",
|
||||
"urllib3": "2.0.0",
|
||||
"urllib3": "2.0.2",
|
||||
},
|
||||
|
||||
# Starting from here, ensure all docutils versions are covered with
|
||||
|
|
@ -160,6 +183,10 @@ SPHINX_REQUIREMENTS = {
|
|||
"PyYAML": "6.0.1",
|
||||
"sphinxcontrib-serializinghtml": "1.1.9",
|
||||
},
|
||||
# from https://raw.githubusercontent.com/sphinx-doc/sphinx/v9.0.0/pyproject.toml
|
||||
(9, 0, 0): {
|
||||
"roman-numerals": "1.0.0",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -173,7 +200,8 @@ class AsyncCommands:
|
|||
self.output = None
|
||||
self.fp = fp
|
||||
|
||||
def log(self, out, verbose, is_info=True):
|
||||
def log(self, out, verbose=True, is_info=True):
|
||||
"""Ancillary routine to output a message"""
|
||||
out = out.removesuffix('\n')
|
||||
|
||||
if verbose:
|
||||
|
|
@ -202,7 +230,6 @@ class AsyncCommands:
|
|||
|
||||
async def run(self, cmd, capture_output=False, check=False,
|
||||
env=None, verbose=True):
|
||||
|
||||
"""
|
||||
Execute an arbitrary command, handling errors.
|
||||
|
||||
|
|
@ -301,8 +328,8 @@ class SphinxVenv:
|
|||
|
||||
# Pip install succeeded. Write requirements file
|
||||
if args.req_file:
|
||||
with open(req_file, "w", encoding="utf-8") as fp:
|
||||
fp.write(result.stdout)
|
||||
with open(req_file, "w", encoding="utf-8") as fout:
|
||||
fout.write(result.stdout)
|
||||
|
||||
if args.build:
|
||||
start_time = time.time()
|
||||
|
|
@ -354,7 +381,7 @@ class SphinxVenv:
|
|||
"""
|
||||
|
||||
if args.log:
|
||||
fp = open(args.log, "w", encoding="utf-8")
|
||||
fp = open(args.log, "w", encoding="utf-8") # pylint: disable=R1732
|
||||
if not args.verbose:
|
||||
args.verbose = False
|
||||
else:
|
||||
|
|
@ -362,8 +389,19 @@ class SphinxVenv:
|
|||
if not args.verbose:
|
||||
args.verbose = True
|
||||
|
||||
cmd = AsyncCommands(fp)
|
||||
|
||||
cur_requirements = {}
|
||||
python_bin = min_python_bin
|
||||
python_bin = get_min_python_bin(MIN_PYTHON_SUBVER)
|
||||
if not python_bin:
|
||||
python_bin = os.path.basename(sys.executable)
|
||||
python_ver = tuple(sys.version_info[:2])
|
||||
|
||||
if python_ver < (3, MIN_PYTHON_SUBVER):
|
||||
sys.exit(f"Python {python_ver[0]}.{python_ver[1]} is too old.")
|
||||
else:
|
||||
ver = int(python_bin.split(".")[1])
|
||||
python_ver = tuple([3, ver])
|
||||
|
||||
vers = set(SPHINX_REQUIREMENTS.keys()) | set(args.versions)
|
||||
|
||||
|
|
@ -372,8 +410,14 @@ class SphinxVenv:
|
|||
new_reqs = SPHINX_REQUIREMENTS[cur_ver]
|
||||
cur_requirements.update(new_reqs)
|
||||
|
||||
if cur_ver in PYTHON_VER_CHANGES: # pylint: disable=R1715
|
||||
python_bin = PYTHON_VER_CHANGES[cur_ver]
|
||||
if cur_ver in PYTHON_VER_CHANGES:
|
||||
new_ver = PYTHON_VER_CHANGES[cur_ver]
|
||||
if python_ver < new_ver:
|
||||
python_bin = get_min_python_bin(new_ver[1])
|
||||
|
||||
if not python_bin:
|
||||
cmd.log(f"Can't check {cur_ver}: {python_bin} not found.")
|
||||
break
|
||||
|
||||
if cur_ver not in args.versions:
|
||||
continue
|
||||
|
|
@ -390,7 +434,6 @@ class SphinxVenv:
|
|||
python_bin)
|
||||
|
||||
if args.build:
|
||||
cmd = AsyncCommands(fp)
|
||||
cmd.log("\nSummary:", verbose=True)
|
||||
for ver, elapsed_time in sorted(self.built_time.items()):
|
||||
cmd.log(f"\tSphinx {ver} elapsed time: {elapsed_time}",
|
||||
|
|
@ -399,15 +442,15 @@ class SphinxVenv:
|
|||
if fp:
|
||||
fp.close()
|
||||
|
||||
|
||||
def parse_version(ver_str):
|
||||
"""Convert a version string into a tuple."""
|
||||
|
||||
return tuple(map(int, ver_str.split(".")))
|
||||
|
||||
|
||||
DEFAULT_VERS = " - "
|
||||
DEFAULT_VERS += "\n - ".join(map(lambda v: f"{v[0]}.{v[1]}.{v[2]}",
|
||||
DEFAULT_VERSIONS_TO_TEST))
|
||||
DEFAULT_VERS = indent("\n".join(map(lambda v: f"{v[0]}.{v[1]}.{v[2]}",
|
||||
DEFAULT_VERSIONS_TO_TEST)), " - ")
|
||||
|
||||
SCRIPT = os.path.relpath(__file__)
|
||||
|
||||
|
|
@ -452,6 +495,7 @@ MAKE_TARGETS = [
|
|||
"xmldocs",
|
||||
]
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main program"""
|
||||
|
||||
|
|
@ -499,8 +543,6 @@ async def main():
|
|||
if not args.make_args:
|
||||
args.make_args = []
|
||||
|
||||
sphinx_versions = sorted(list(SPHINX_REQUIREMENTS.keys()))
|
||||
|
||||
if args.full:
|
||||
args.versions += list(SPHINX_REQUIREMENTS.keys())
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class CTransforms:
|
|||
(CMatch("DECLARE_HASHTABLE"), r"unsigned long \1[1 << ((\2) - 1)]"),
|
||||
(CMatch("DECLARE_KFIFO"), r"\2 *\1"),
|
||||
(CMatch("DECLARE_KFIFO_PTR"), r"\2 *\1"),
|
||||
(CMatch("DECLARE_KHOSER_PTR"), r"\2 \1"),
|
||||
(CMatch("DECLARE_PIDS"), r"struct pid *\1[(\2) + 1]"),
|
||||
(CMatch("(?:__)?DECLARE_FLEX_ARRAY"), r"\1 \2[]"),
|
||||
(CMatch("DEFINE_DMA_UNMAP_ADDR"), r"dma_addr_t \1"),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user