Better than POSIX?
Autor original: Jonathan Corbet
Publicado originalmente no: lwn.net
Tradução: Roberto Bechtlufft
A essa altura, você já deve estar achando que não é mais necessário continuar discutindo sobre as decisões de design incorporadas ao recurso de “atraso de alocação” do ext4, bem como sobre as implicações em espaço de usuário dessas decisões. E talvez isso seja verdade, mas cai bem um resumo das questões relevantes. A questão mais importante não tem muito a ver com os detalhes do design de um sistema de arquivos, mas sim com o tipo de API que o kernel Linux deve apresentar aos seus processos em espaço de usuário.
Como já foi bem detalhado (e discutido) anteriormente, o recurso de atraso na alocação do sistema de arquivos ext4 – presente também na maioria dos outros sistemas de arquivos contemporâneos – traz alguns benefícios reais no desempenho do sistema. Em muitos casos, o atraso na alocação evita completamente a alocação de espaço na mídia física, bem como as operações de entrada e saída associadas. Para dados que serão mantidos por mais tempo, o atraso na alocação permite ao sistema de arquivos otimizar o posicionamento dos blocos de dados, agilizando os acessos subsequentes. Mas o atraso na alocação também pode, no caso de travamento do sistema, levar à perda de dados para os quais o espaço ainda não tenha sido alocado. Qualquer sistema de arquivos pode perder dados se o sistema operacional subitamente puxar o tapete dele, mas as mudanças no ext4 podem levar à perda de dados em situações que com o ext3 pareciam seguras. Para muitos usuários, a mudança mais parece uma regressão.
Muitos elétrons foram gastos para justificar o novo quadro de maior incerteza do ext4. A especificação POSIX diz que não dá para garantir a persistência de dados que não tenham sido enviados explicitamente para a mídia com a chamada do fsync(). Os aplicativos que perdem dados com o ext4 não estão usando o sistema de arquivos corretamente e precisam ser corrigidos. O verdadeiro problema são os usuários rodando módulos proprietários do kernel que podem fazer o sistema travar. E por aí vai. Todas essas declarações são verdadeiras, em algum nível.
Mas pode-se argumentar que sejam irrelevantes.
Fiquei sabendo recentemente que o Guia do Ódio ao Unix [PDF] de Simson Garfinkel está disponível online. Dizer que o guia é desagradável seria pegar leve: boa parte dele parece uma implicância infantil com o Unix, vinda de alguém que queria que o VMS (ou algum outro sistema proprietário) tivesse dominado o mundo. Ele está cheio de coisas do tipo:
Mas por trás da retórica tola, há alguns pontos válidos aos quais os que se preocupam com o valor dos sistemas da família Unix deveriam prestar atenção. Dentre eles, a noção de que “o pior é melhor” expressa por Richard Gabriel em 1991, o ano em que o kernel Linux nasceu. Trata-se da afirmação de que os desenvolvedores do Unix irão dar prioridade às soluções mais simples, e não às mais corretas, nos níveis mais baixos, mesmo que isso leve à complexidade (e à falta de robustez) nos aplicativos nos níveis mais altos. A capacidade da chamada de sistema write() de obter sucesso parcial é dada como exemplo; ela força todas as chamadas write() a serem incluídas em um loop no código, tentando a operação novamente até que o kernel conclua o trabalho. Os desenvolvedores que gostam de fazer as coisas do jeito mais fácil acabam fazendo aplicativos que funcionam na maior parte do tempo, mas que podem falhar silenciosamente nas circunstâncias mais inesperadas. Segundo essas pessoas argumentam, é bem melhor resolver o problema no nível do kernel para que os aplicativos possam sem mais simples e robustos.
A situação do ext4 pode ser vista de modo parecido: os desenvolvedores de aplicativos que queiram ter certeza de que os dados chegaram ao armazenamento permanente terão que tomar o cuidado adicional de informar ao kernel que, sim, os dados são importantes. Os desenvolvedores que pularem essa parte terão aplicativos que funcionam quase sempre. Pode-se argumentar, mais uma vez, que o kernel deveria assumir a responsabilidade de garantir o funcionamento correto, tirando essa preocupação dos desenvolvedores de aplicativos.
O sistema de arquivos ext3 não oferece essas garantias, mas devido à maneira como seus recursos interagem, oferece algo que se aproxima de uma garantia de persistência na maioria das situações. Um sistema de arquivos ext3 sendo executado com uma configuração padrão geralmente não perde mais de cinco segundos de trabalho em um travamento, e o que é importante, não é propenso à criação de arquivos de tamanho zero em cenários comuns. O sistema de arquivos ext4 suprimiu essa garantia implícita; seguiram-se surpresas desagradáveis para os usuários.
Chega o momento dos desenvolvedores do ext4 tomarem uma decisão. Eles poderiam defender as alterações, argumentando que um sistema menos robusto é justificado pelo aumento no desempenho e pela conformidade com o POSIX. Eles poderiam dizer que aplicativos bugados têm que ser corrigidos, mesmo que o número de aplicativos seja grande. Ou ao invés disso, eles poderiam concluir que o Linux deveria promover um nível mais alto de confiabilidade, independente da diligência dos desenvolvedores de aplicativos e do que os padrões digam.
Convém dizer que a primeira opção não está completamente desprovida de razão. O POSIX estabelece uma espécie de contrato entre o espaço de usuário e o kernel. Quando o kernel não é capaz de oferecer um comportamento especificado pelo POSIX, os desenvolvedores de aplicativos são os primeiros a reclamar. Por isso, talvez eles não devam fazer objeções quando o kernel insistir que eles também cumpram sua parte do trato. Pode-se argumentar que os aplicativos que tenham sido escritos de acordo com as regras não deveriam ter o desempenho comprometido para facilitar a vida de outros aplicativos. Além do mais, estamos falando de software livre; não deve levar tanto tempo para os maiores infratores entrarem na linha.
Mas lidar com esse tipo de problema é um daqueles casos clássicos em que você resolve um problema aqui e surge outro ali. Os desenvolvedores do kernel foram bem claros ao dizer que não se sentem presos ao POSIX nas ocasiões em que padrão seja visto como sem sentido. Logo, o POSIX certamente não os compele a oferecer uma robustez de dados no sistema de arquivos de baixo nível menor do que a que os desenvolvedores de aplicativos gostariam de ter. Pode-se defender que esta seja uma situação em que o kernel Linux, buscando aumentar a robustez em todo o sistema, deva ir além do POSIX.
A boa notícia é que, obviamente, isso já aconteceu. Há um conjunto de patches na fila para a versão 2.6.30 que oferecerão um comportamento semelhante ao do ext3 em muitas das situações que criaram problemas para os primeiros usuários do ext4. Além disso, os desenvolvedores do ext4 estão considerando uma opção de montagem “allocate-on-commit” (alocar ao submeter) que forçaria a realização das alocações atrasadas quando os metadados associados forem submetidos ao disco, restaurando a semântica do ext3 quase completamente. Há boas chances dos distribuidores ativarem essa opção por padrão. Haveria uma perda de desempenho, mas o ext4 ainda assim deve ter desempenho melhor do que o ext3, e não se deve subestimar os custos de desempenho associados à perda de dados.
Resumindo: os desenvolvedores do ext4, assim como os desenvolvedores do Linux de modo geral, se importam com os usuários. Eles podem reclamar um pouco dos desenvolvedores mais relaxados, da conformidade com os padrões, dos módulos proprietários do kernel, mas no fim das contas eles fazem a coisa certa.
Também é bom lembrar que o ext4 ainda é um sistema de arquivos muito jovem; não é de se surpreender que ele ainda tenha que aparar algumas arestas. É pouco provável que esta seja a última delas.
Também já foi sugerido que o verdadeiro problema seja a API do POSIX, que não apresenta a expressão de atomicidade e os requisitos de durabilidade de maneira fácil ou natural. Alguns dizem que chegou a hora de criar uma API estendida (ou totalmente nova) que lide melhor com essas questões. Isso pode ser verdade, mas falar é fácil, fazer é que é difícil. É claro que há dificuldades no design de uma nova API que vá durar mais algumas décadas; presume-se que nós estejamos à altura deste desafio. Mas será que alguém vai usá-la? Considere a resposta de Linus Torvalds a outra sugestão de extensão da API:
Os desenvolvedores de aplicativos naturalmente se sentirão apreensivos em desenvolver algo para interfaces exclusivamente Linux. Não está claro se o design de uma nova API que seja aceita fora do meio Linux é possível no momento.
Eu também quero destacar, embora hesitante, que Hans Reiser havia desenvolvido e implementado todo tipo de recurso que permitisse aos aplicativos fazer uso de arquivos pequenos de maneira robusta no sistema de arquivos reiser4. Já havia pouco interesse em se aceitar esses recursos mesmo antes de Hans sair de cena. Havia muitos motivos para isso, incluindo o nervosismo quanto à implementação de um único sistema de arquivos e também quanto a ter que lidar com Hans, mas a adição de extensões não-POSIX já era problemática por si só (veja este artigo para saber sobre a discussão de 2004).
A verdadeira resposta provavelmente não está em novas APIs. Provavelmente é uma questão de construir sistemas de arquivos que ofereçam uma robustez boa o suficiente por padrão, com garantias muito mais fortes aos desenvolvedores dispostos a ter mais trabalho no código. Essas mudanças podem ser complicadas para hackers de sistemas de arquivos que se empenharam em criar um sistema de arquivos que fosse o mais rápido possível. Mas elas acontecerão de uma maneira ou de outra. No fim das contas, o Linux é feito por seus usuários, e para seus usuários.
Créditos a Jonathan Corbet – lwn.net
Tradução por Roberto Bechtlufft <roberto at bechtranslations.com>
Deixe seu comentário