Mostrando postagens classificadas por relevância para a consulta btree. Ordenar por data Mostrar todas as postagens
Mostrando postagens classificadas por relevância para a consulta btree. Ordenar por data Mostrar todas as postagens

Rust no Linux: Um caso de amor e ódio

Rust e Linux: um caso de amor e ódio
Rust no Linux: um caso de amor e ódio

 É incrível como funciona o emocional do pessoal apaixonado por software livre. Se não estão 
decretando empresas como inimigas mortais, ou abominando o systemd ou criticando o btrfs, eles estão exaltando o projeto gnu como único e absoluto, o ZFS como sistema de arquivos indestrutível e insuperável, acreditando que o FreeBSD é superior a qualquer outro sistema operacional (eu já recebi vídeo assim hein, UFRS) e agora a bola da vez é dizer que a linguagem Rust irá substituir a linguagem C. E o argumento por traz de tudo isso é que a linguagem Rust trabalha melhor com gerenciamento de memória e... só... OK, está certo que isso não é pouca coisa; Em Setembro de 2024 foi publicado que o fato de o Google ter feito a transição do código do Android para Rust fez suas vulnerabilidades em memória caírem de 76% para 24% porém, por outro lado, portar o yash para rust não apresentou ganho nenhum.


 De lá para cá vimos noticias de que o Google anunciou em Abril de 2021 que está trabalhando para reescrever o user space do Android na linguagem RustNo dia 18 de Setembro de 2020, Rob Landley já havia escrito que "a empresa Google provavelmente vai reescrever por completo todas as coisas de baixo nível do Android em Rust nos próximos dez ou vinte anos". O que pode acarretar na completa substituição do toybox ou ter que portar o toybox para a linguagem Rust (algo que Rob não tem um grande interesse).

 Os desenvolvedores do kernel queriam adicionar suporte a linguagem Rust no kernel e, apesar de Linus ter sido resistente quanto a ideia e até mesmo ameaçar os desenvolvedores que fizessem isso, o kernel passou a ter suporte a Rust como segunda linguagem... O motivo é até simples, para atrair novos desenvolvedores para o kernel Linux (logo para essa geração que o forte deles não é estudar...).

 A Microsoft também  anunciou que planeja reescrever partes do kernel do Windows em Rusta equipe do projeto Tor passou a trabalhar na implementação do Arti (um Tor escrito na linguagem Rust) devido Rust trabalhar melhor com os protocolos tor do que a linguagem CPostgresML anunciou em Setembro de 2022 que estaria migrando para a linguagem Rust na versão 2.0 por apresentar melhor desempenho do que SQL, PLpgSQL, Python e Numpy em suas ferramentas (apesar que as rotinas BLAS (Basic Linear Algebra Subprograms, que geralmente são escritas em Fortran, apresentaram melhor desempenho do que Rust).


 O Zabbix Agent2 passou a ser escrito na linguagem Go. O motivo explicado pela comunidade é que fica melhor para integrar seus plugins e de forma mais modular mas vale a ressalva que partes do código do Zabbix Agent2 ainda é escrito em C. E assim vemos vários projetos fazendo adoção da linguagem Rust.

 O que eu me pergunto é, será que estamos no caminho certo? Será que isso não acabará solucionando um problema e causando vários outros ainda mais graves? Essas são as perguntas que devemos (ou ao menos deveríamos) nos fazer antes de começar o trabalho.

 E no meio de toda essa euforia, de muita gente que não entende de nada sobre linguagem de programação e outros tantos que também não leem nada sobre o assunto, vamos tratar de um assunto que quase ninguém prestou a atenção e que na verdade é o tema principal deste artigo.


O QUE NÃO TE CONTAM SOBRE A LINGUAGEM RUST

 Ao meu ver Rust solucionará certos problemas, mas outros não (muito menos solucionará todos como andam fantasiando). O problema é que todo mundo focou somente no prós da linguagem e esqueceram dos contras. É questão de saber quando, aonde e a que custo adotá-la.

 Um ótimo exemplo disso, o projeto Warp (um terminal escrito em Rust disponível para MacOS mas com planos para ser portado para Linux e Windows) que apresentou o tamanho da dificuldade de implementar UI (User Interface = Interface de Usuário) ou GUI (Grafical User Interface) utilizando a linguagem Rust:


 O segundo exemplo apresentando pelo projeto Warp foi utilizando o Timer da 7GUI e a dificuldade que é enfrentada para conseguir algo tão simples com Rust.


 A equipe desenhou um mapa explicando como todo o projeto ficaria e que essa abordagem de árvore não mapeia claramente para Rust. Uma série de erros iriam acontecer e tornariam o trabalho mais difícil para projetar um único componente e adicionar uma simples função em sua estrutura.




 Um outro bom exemplo de dificuldade GUI em Rust é o emulador Obliteration que a equipe do projeto reescreveu o seu núcleo de emulação em Rust enquanto que a interface gráfica é desenvolvida em C++ (utilizando o framework QT).

 Fora do contesto de GUIs, temos o gerenciador de pacotes da distribuição Glaucus que era escrito em Rust, mas a equipe o reescreveu na linguagem Nim no lançamento s6-x86-64-v3-28042023. Os motivos apresentados pela equipe na nota de lançamento foram:
  • O código e razoavelmente mais legível (mais do que a versão em Rust)
  • Muito menos LOC mesmo com mais recursos adicionados (comparado com a versão Rust)
  • O código foi escrito um montante de tempo razoável (muito menos do que a versão Rust, novamente a reescrita em si levou em torno de um mês, mas a velocidade que recursos mais novos foram adicionados é algo entre 4 a 8 vezes mais rápido do que o tempo que leva para implementa-los em Rust, provavelmente por conta que eu me aborreço com Rust mesmo depois de um ano de uso, mas quem sabe...)
  • menos uso de recursos do sistema (1/3 do que a versão em Rus utiliza)
  • Executável muito menor (200 a 300 KB. Comparado a versão em Rust que é de 3 MB)*
  • Pode ser construído utilizando toolchain existente no Glaucus porque Nim transpila para C; assim, tornando o uso de toolchain otimizada pelo Glaucus (diferente de Rust que é muito difícil de fazer bootstrap**, e não funciona tudo tão bem assim com musl compartilhada...)
  • Um pouco mais rápida (em analise, é por volta de 6 - 20% mais rápido no geral. Provavelmente porque eu odeio Rust mesmo depois de um ano utilizando, mas novamente eu estou escrevendo em Nim em apenas um mês ou dois...)


*Eu como administrador de sistemas utilizando programas escritos na linguagem Rust, sim eu constatei que executáveis em Rust são maiores e conseguiram apresentar problemas e menor desempenho. No artigo uutils: Um coreutils escrito na linguagem Rust eu acabei fazendo a observação que o uutils, com apenas 87 comandos e sendo linkado dinamicamente, ocupa mais de 12MB enquanto que o toybox 0.8.9 consegue ser 17 vezes menor ocupando apenas 724KB mesmo contendo 233 comandos (é mais de duas vezes e meia a quantidade de comandos do uutils) e ainda sendo linkado estaticamente (o que, pela lógica, o tornaria maior e foi ao contrário). Veja o resultado na imagem abaixo

uutils vs toybox
comparando o uutils e toybox

**Exatamente o motivo que Linus Torvalds não queria aceitar Rust no Linux e quase puniu quem tentou implementa-la (na verdade eu acho que deveria ter feito isso).

 Ainda podemos ressalta o PX5 RTOS, um sistema operacional Real Time que é novo, moderno e que vai atender as necessidades atuais do mercado. O PX5 é quase totalmente (99%) escrito em C. O motivo é que C o torna altamente portável para qualquer arquitetura de processador e por conta disso, o PX5 possui suporte a maioria das arquiteturas de embarcados MCU e MPU populares incluindo as famílias de arquiteturas ARM's Cortex-M, Cortex-R, Cortex-A e RISC-V.


 E aqui vai a minha pergunta, porque ninguém pensou em adotar a linguagem Nim como segunda linguagem no kernel ao invés de Rust? Drivers, sistemas operacionais (existe até mesmo um kernel escrito na linguagem Nim, o NimKernel e que ainda pretendem trabalhar em um Nim OS no futuro), embarcados e até Internet of Things (IoT) podem ser escritos em Nim. Nim possui a característica de memory safety ativa por padrão, faz o gerenciamento de memória através do suporte a diferentes tipos de garbage collectors com diferentes aplicações em mente além de lhe permitir trabalhar com gerenciamento de memória manualmente. Vocês puderam ver o projeto Glaucus se tornar muito mais eficiente com Nim do que com Rust. Por que ninguém pensou ou sugeriu isso?



Gerenciamento de memória na linguagem C?


 O que todos hoje temem a respeito de gerenciamento de memória em linguagens de programação como C e C++ na verdade é uma característica das duas linguagem e não uma falha; elas permitem que os programas tenham acesso direto a memória. O problema é que essa característica pode levar a certos desastres permitindo que programas que não foram atribuídos para esse uso acessarem memória. Já linguagens que recorrem ao recurso memory safe fazem isso ao custo de não permitir que programas acessem detalhes de baixo nível da memória que em alguns casos são necessário e também degrada o desempenho dos programas.

 Recentemente que foi adotado C11 no Linux. O que me leva a questionar se estamos no caminho correto. O que seria mais vantajoso? Reescrever códigos de uma linguagem para outra ou escrever patches usufruindo dos reais recursos da linguagem?

 Pode ser que de repente alguém ou um grupo de pesquisadores desenvolvam algoritmos ou simplesmente façam uso de algoritmos já existentes e solucionem esse "problema". Veja como exemplo a biblioteca Newlib; um desenvolvedor da empresa ARM desenvolveu um patch que melhora o desempenho da biblioteca baseando-se no algorítimo Horspool da universidade de Helsinki (o berço do Linux ;). Parte do algoritmo pode ser conferido na imagem abaixo; são algoritmos assim que acabam surgindo até de forma inesperada.


 Mais exemplos de algoritmos que solucionaram problemas e que quase ninguém imaginava que um dia seriam capazes, não nos faltam como é o caso do Btrfs pois sistemas de arquivos CopyonWrite são incompatíveis com Btree (o ZFS é incompatível com Btree; o HAMMER em sua primeira versão era Btree e não possuía suporte a CopyonWrite mas em sua segunda versão se tornou CopyonWrite e automaticamente não possui mais suporte a Btree; o Ext4 é Btree e também não possui suporte a CopyonWrite; o NTFS é Btree e faz uso shadow por conta desta incompatibilidade). Mas o que tornou o Btrfs Btree e CopyonWrite? Os algorítimos escritos por Ohad Rodeh da IBM de Haifa que permitiu que essa fosse uma das características do Btrfs e hoje herdado pelo BcacheFS.

 Outro exemplo é o algoritmo malloc (abreviação de memory allocator). O artigo da Etalabs chamado O que é Overcommit? E por que ele é ruim? descreve que "existem mal entendimentos a respeito de gerenciamento de memória no Linux que acabam levando a muitos programas ruins falhar em lidar de forma robusta com condições de pouca memóriaGrande parte dessa falha de gerenciamento de memória na linguagem C está relacionada a forma como os programas são escritos (vale lembrar que bibliotecas como dietlibc e musl possuem recursos para auxiliar desenvolvedores a escrever códigos melhores. Na bibliotec musl surgiu o conceito de Quality Safe Code e a própria musl possui recursos de debug).

 Rich Felker começou a desenvolver sua própria implementação do algoritmo malloc para a musl chamada de mallocng que a proporciona ganhos de desempenho. A microsoft mantem um fork do jemalloc chamado mimalloc que é utilizado nas imagens Apline do Docker, Azure, no Bing, no jogo Death Stranging, no Unreal Engine, na assembly toolkit SPAdes e em muitos outros projetos oferecendo desempenho muito melhor do que os dois anteriormente mencionados.

glibc vs musl
Comparação de desempenho entre glibc e musl sem malloc

glibc vs musl vs malloc-ng
Comparação de desempenho entre glibc, musl e malloc-ng

glibc vs musl vs malloc-ng vs musl+mimalloc
Comparação de desempenho entre glibc, musl, malloc-ng e musl+mimalloc

 Todos os detalhes sobre o desempenho do algoritmo malloc podem ser conferido no linkedin do Emerson Gomes. Vale acrescentar que no elinux de 2022 descreve que Rust no kernel é um problema difícil de solucionar pois, programas escritos em Rust normalmente não lidam com falhas de alocação de memória (estranho a maior propaganda da linguagem Rust ser segurança de memória e não tratar do ponto de alocação de memória) e sofre também com muitos recursos que ainda são INSTÁVEIS.


 E o terceiro exemplo é o novo recurso _FORTIFY_SOURCE que foi adicionado no GCC e no LLVM/Clang. Esse recurso é uma macro de pré-processamento que garante um nível extra de segurança para as linguagens C e C++ detectando erros durante o processo de compilação e de execução já que, como descrito no link da Red Hat, programas escritos na linguagem C rotineiramente sofrem com problemas de gerenciamento de memória. O _FORTIFY_SOURCE detecta mais buffer overflows e bugs que mitigam problemas de segurança na aplicações em tempo de execução. Além do mais, existe Garbage Collector para as linguagens C e C++ desenvolvido por Hans-J. Boehm. Ou SEJA! sim, existe o recurso de segurança de memória para a linguagem C ;)

# Boehm-Demers-Weiser Garbage Collector
Garbage Collector para as linguagens C e C++ de autoria de Boehm-Demers-Weiser

CONCLUSÃO


 Se levou tanto tempo para adotar C11 no Linux, acredito que adotar Rust está sendo uma ideia de certa forma prematura e um tanto precipitada. Um erro que pode custar muito caro no futuro. Lembrando que quando eu iniciei este artigo, estamos na C17 (ISO/IEC 9899:2018e agora já estamos na C23 (ISO/IEC 9899:202x). A própria biblioteca musl já está recebendo suporte a C23 dentro do padrão WG14 (musl patch for c2x %b printf/scanf). Esse mesmo recurso (macros %b/%B PRI* e SCN*) foi adicionado à Bionic do Android no dia 7 de Março de 2023 (leia Add the %b/%B PRI* and SCN* macros).


 Pode ser que a versão C25 ou C26 surja com as exatas características da linguagem Rust que todos enaltecendo. Eu acredito que Rust irá substituir C? Não! Eu acredito que cada linguagem será adotada em campos que cada uma possui melhor atuação.

 Diziam que o o kernel monolítico era obsoleto e que o microkernel iria substituí-lo; já se passaram quase 40 anos e ainda nada. Diziam que php estava morrendo, diziam até que php estava sendo substituído por Java (uma linguagem que não tem nada a ver com a outra), contudo php está bem forte no mercado e Java declinando.

 O que temos que entender é que em cada linguagem existem suas vantagens e desvantagens. Cabe a nós saber quando desfrutar de cada uma nos momentos exatos.


Btrfs: Uma breve comparação com o ZFS

    Ontem eu publiquei o vídeo de aniversário do Btrfs (que espero terem gostado. Já deixo-os ciente de que a festa ainda não acabou hehehe).

    Quando o ZFS foi iniciado, a perspectiva para o file systems no Solaris também era escura. Logging UFS já estava aproximando do fim fim da linha em termos de tamanho de file system size e desempenho. UFS estava de longe atrás que clientes do Solaris pagaram somas substanciais em dinheiro para a Veritas rodar o VxFS.

    O Solaris precisava de um novo file system, e precisava em breve. Jeff Bonwick decidiu resolver o problema e iniciar o projeto ZFS dentro Sun. Sua metáfora de se organizar era aquela do subsistema da memória virtual:
"Por que o disco não pode ser fácil de administrar e utilizar quando a memória? "
    A estrutura central de dado ondisk era a laje, um naco de dispositivo de disco divididos em blocos do mesmo tamanho, como aquele no alocador de memória do kernel SLAB, que ele também criou.  Ao invés de extents, ZFS utilizaria um block pointer por bloco, mas cada objeto utilizaria um tamanho de bloco diferente. E.g., 512 bytes, ou 128KB dependendo do tamanho do objeto. Endereços de blocos seriam traduzidos através de um tipo de meconismo de memória virtual, assim os blocos poderiam ser realocados sem o conhecimento das camadas mais alta. Todos os dados e metadados do file system seria armazenados em objetos. E todas as mudanças no file system seriam descritas em termos de mudanças para objetos, que seriam escritas em um estilo copyonwrite.


    Em resumo, btrfs organiza tudo no disco dentro de uma btree de extents contendo itess e dados. ZFS organiza tudo no disco dentro de uma árvore de apontadores de bloco, com tamanhos diferentes de bloco dependendo no tamanho do objeto. Btrfs realiza checksums e re-confere os extents; o ZFS realiza checksums e re-confere tamanhos variáveis de blocos. Ambos os file systems escrevem as alterações no disco utilizando CopyonWrite extents ou blocos em uso não são sobre escritos no lugar, eles são sempre copiados em algum outro lugar primeiro.

    Então, enquanto a lista de recurso dos dois file systems parecem bastante similares, as implementações são completamente diferentes. É um pouco de evolução convergente entre marsupiais e mamíferos placentários. Um rato marsupial e um rato placental parecem bem idênticos por fora, mas suas implementações internas são um bocado diferentes!

    Na minha opinião, a arquitetura básica do btrfs é mais adequada do que a do ZFS. Um dos maiores problemas com a abordagem do ZFS "slabs" de blocos de um tamanho particular é fragmentado. Cada objeto pode conter blocos de somente um tamanho, e cada slab pode somente conter blocos de um tamanho. Você pode facilmente acabar com, por exemplo, um arquivo de blocos do tamanho de 64K que precisam crescer um blocos ou mais, mas nenhum bloco to tamanho de 64K estão disponíveis, mesmo que o file system esteja cheio de bem perto de slabs vazios com blocos do tamanho de 512 byte, 4K, 128K e etc. Para solucionar esse problema, nós (os desenvolvedores do ZFS) inventamos meios de criar grandes blocos fora de pequenos blocos ("gang blocks") e outros trabalhos desagradáveis. Em nossa defesa, no tempo que btrees e extents aparentavam fundamentalmente incompatíveis com copyonwrite, e a metáfora da memória virtual metaphor nos serviram bem em muitos outros respeitos.

    Em contraste, os itens em uma abordagem btree são extremamente eficientes e flexíveis em espaço. Desfragmentação é um processo em curso reempacotando os itens eficientemente é parte do caminho do código normal preparando extents para serem escritos no disco. Fazer checksums, reference counting e outros metadados variados em uma base por extent reduz a sobrecarga e torna novos recursos (tal como reverso de mapiamento rápido de um extent tudo que refere-se) possível.

    Agora, para algumas predições pessoais (baseada puramente em informações publicas, eu não tenho nenhum conhecimento de informante). Btrfs será o file system padrão no Linux dentro de dois anos. Btrfs como um projeto não será (e não pode, a esse ponto) ser cancelado pela Oracle. Se todas as propriedades intelectuais estão funcionando (um grande se), ZFS será portado para Linux, mas ele terá menos de um pouco percentual da base instalada do btrfs.

    Verifiquem daqui a dois anos e vejam se eu eu estou certo dessa predições!*

*Este artigo foi escrito em 22 de Julho de 2009

Lançado xfsprogs-5.0.0

xfsprogs-5.0.0
xfsprogs-5.0.0
 xfsprogs-5.0.0 foi lançado antes do lançamento do kernel kernel 5.1! Já havíamos tratado de correções e melhorias que essa versão iria receber e agora é oficial. xfsprogs é o conjunto de ferramentas do sistema de arquivos xfs.
CLIQUE AQUI E VENHA APRENDER LINUX COMIGO E TORNE-SE UM PROFISSIONAL MACHO DE VERDADE.
Essa versão recebeu várias correções (que não me me dispus a traduzir)

xfsprogs-5.0.0-rc1 (26 Apr 2019)

  1.   mkfs: validate extent size hint parameters (Darrick Wong)
  2.   xfs_repair: bump on-disk nlink when adding lost+found (Darrick Wong)
  3.   xfs_repair: reinitialize root directory nlink correctly (Darrick Wong)
  4.   xfs_repair: use lenient verifiers for half-fixed inodes (Darrick Wong)
  5.   xfs_repair: acct for btree shrinks when fixing freelist (Darrick Wong)
  6.   xfs_repair: better cli option parameter checking (Darrick Wong)
  7.   xfs_repair: fix deadlock due to failed inode flushes (Dave Chinner)
  8.   xfs_info: handle devices, mountpoints, and loop files (Darrick Wong)
  9.   xfs_metadump: fix symlink handling (Darrick Wong)
  10.   xfs_io: fix label parsing and validation (Darrick Wong)
  11.   xfs_io: print attributes_mask in statx (Darrick Wong)
  12.   xfs_scrub: fix Make targets which depend on builddefs (Darrick Wong)
  13.   xfs_scrub: check label for misleading characters (Darrick Wong)
  14.   xfs_scrub: parallelize based on storage not CPUS (Darrick Wong)
  15.   xfs_scrub: activate timer only after system is up (Darrick Wong)
  16.   libxfs: fix buffer & inode lifetimes (Darrick Wong)
  17.   misc: fix strncpy length complaints from gcc (Darrick Wong)
  18.   debian build & packaging fixes (Darrick Wong)
  19.   Merge libxfs from kernel 5.0

xfsprogs-5.0.0 (03 May 2019)

  1. xfs_db: scan all sparse inodes when using 'frag' (Jorge Guerra)
  2. Fix build with newer statx headers (Eric Sandeen)
E pode ser baixada ou clicando nos links abaixo ou diretamente no repositório git:

Marcadores

A pior história sobre Linux que já ouvi (6) A.I (2) ambiente gráfico (19) AMD (14) analise (10) Andriod (17) android (8) Apple (1) arm (5) artigo (5) aws (1) bc (23) benchmark (6) BetrFS (1) blackhat (1) BSDs (35) btrfs (32) bugs (2) Caixa de Ferramentas do UNIX (18) canonical (1) canto do Diego Lins (2) certificações Linux (7) Código Fonte (53) comandos (34) comp (1) compressores (9) consoles (1) container (8) CPU (19) cracker (1) criptografia (5) crowdfunding (9) cursos (24) daemons (14) Debian (31) desempenho (2) desenvolvimento (104) desktop (19) DevOps (3) DevSecOps (4) dic (1) Dica de leitura (91) dica DLins (2) dicas do Flávio (27) Dicas TechWarn (1) diet libc (4) diocast (1) dioliunx (3) distribuições Linux (14) Docker (13) DragonflyBSD (24) driver (2) dropbear (3) ead Diolinux (2) edição de vídeo (5) embarcados (1) EMMI Linux (4) emuladores (9) endless (5) English interview (3) Enless OS (2) entrevista (17) espaço aberto (82) evento (6) facebook (1) Fedora (11) filesystem (82) financiamento coletivo (2) fork (4) fox n forests (4) FreeBSD (22) Funtoo Linux (13) games (95) garbage collector (1) gerenciadores de pacotes (4) glaucus (8) GOG (3) google (9) gpu (3) hacker (2) hardware (104) hash (1) helenos (3) I.A (1) init system (13) Intel (15) inteligencia artificial (2) IoT (1) ispconfig (1) jogos (39) kde (1) kernel (142) lançamento (64) leis (1) LFCS (1) libs (2) licenças (10) Linus (16) linus torvalds (2) Linux (194) linux foundation (3) linux para leigos (1) live (4) lkgr (1) LPI (8) LTS (1) Mac (1) machine learning (1) matemática (9) mesa redonda (27) microcontroladores (1) microsoft (6) microst (1) muito além do GNU (182) musl (3) não viva de boatos (9) navegadores (5) NetBSD (7) newlib (1) nim (12) nimlang (4) nintendo (1) novatec (17) novidades (1) nuvem (1) o meu ambiente de trabalho (3) off-topic (12) ONLYOFFICE (5) open source (85) OpenBSD (8) OpenShift (1) oracle (1) os vários sabores de Linux (46) padrim (2) palestras e eventos (5) partições (6) pentest (8) performance (1) pipewire (1) plan9 (3) playstation (1) processadores (30) professor Augusto Manzano (11) Programação (72) promoção (1) propagandas com Linux (8) ps4 (1) real-time. (1) Red Hat (23) redes (4) resenha nerd (4) Resumo da Semana do Dlins (2) resumo do Tux (19) retrospectiva Linux (1) risc-V (14) RISCV (13) rtos (2) runlevel (2) rust (16) Sega (1) Sega Saturn (1) segurança digital (28) servidor web (2) servidores (3) shell (12) shell script (9) sistema operacional (25) skarnet (2) smartphones (3) Software livre e de código aberto (150) sorteio (3) Steam (10) Steam no Linux (8) supercomputadores (4) suse (7) systemd (9) terminal (90) terminal de comandos (21) toca do tux (1) toybox (31) tutorial (6) Tux (3) ubuntu (1) unboxing (7) UNIX (17) UNIX Toolbox (13) vartroy (1) vga (1) virtualização (3) vulnerabilidade (7) wayland (5) web (1) whatsapp (1) whitehat (1) Windows Subsystem for Linux (2) wine (14) WoT (1) yash (1) ZFS (16) zsh (3)