Quem administra servidores com cPanel frequentemente se depara com discrepâncias que, à primeira vista, parecem bugs incompreensíveis do painel: o cliente recebe alertas de que sua conta estourou a cota contratada (marcando mais de 60 GB ocupados), mas ao checar a pasta do usuário via terminal com o comando du -sh, o consumo real no disco não passa de 25 ou 30 GB.
Para complicar ainda mais, ao tentar forçar a recalibração das caixas de e-mail com os scripts nativos do sistema, o terminal entra em um loop sem fim de erros de execução.
Abaixo está o raio-x completo dessa investigação: desde o destravamento do loop do erro 67 causado por contas zumbis até o comportamento interno do plugin Zlib do Dovecot, explicando por que a camada de sistema de arquivos (física) e a camada de aplicação (lógica) medem grandezas completamente diferentes.
Fase 1: O loop do erro 67 e o estado órfão no sistema de arquivos#
Tudo começou com a tentativa de forçar a regeneração das cotas de e-mail de uma conta com o utilitário do cPanel:
/scripts/generate_maildirsize --confirm usuario
O comando travou o terminal, disparando processos contínuos e cuspindo centenas de linhas idênticas:
The “/usr/bin/doveadm quota recalc -u orfao@meudominio.com.br” command (process 2311259) reported error number 67 when it ended.: doveadm(orfao@meudominio.com.br): Error: cmd quota recalc: User doesn't exist
O que acontece por baixo do capô:#
O script /scripts/generate_maildirsize é um wrapper em Perl que executa as seguintes etapas:
- O interpretador Perl faz uma chamada de sistema (syscall)
getdents()para varrer a pasta/home/usuario/mail/meudominio.com.br/. - Para cada subdiretório físico encontrado, ele invoca o binário do Dovecot:
doveadm quota recalc -u conta@meudominio.com.br. - O
doveadm, escrito em C, consulta seu mecanismo de autenticação (passdb, mapeado pelo cPanel no arquivo/home/usuario/etc/meudominio.com.br/passwd).
O Erro 67 (que no padrão POSIX/C mapeia para EX_NOUSER no arquivo de cabeçalho sysexits.h) ocorre quando há um desencontro: o diretório físico existe no disco, mas a conta não existe mais no arquivo de senhas e metadados.
Para confirmar o desalinhamento:
# 1. Conferindo o banco de senhas virtual:
grep "orfao" /home/usuario/etc/meudominio.com.br/passwd
# Retorno vazio: o usuário não existe logicamente.
# 2. Conferindo o sistema de arquivos:
ls -lad /home/usuario/mail/meudominio.com.br/orfao
# Retorno: drwxr-x--x 5 usuario usuario 118 Jun 5 16:26 /home/usuario/mail/meudominio.com.br/orfao
Trata-se de uma pasta órfã: algum processo antigo deletou o e-mail no painel, mas deixou a pasta no disco. Como o Perl itera o que está no disco e o Dovecot valida o que está no banco, o script entrava em loop.
Como destravar o loop:#
Para alinhar o sistema de arquivos com o banco de contas do cPanel:
# 1. Atualiza os mapeamentos de domínios do usuário
/scripts/updateuserdomains
# 2. Ajusta permissões estruturais
/scripts/mailperm usuario
# 3. Mova a pasta órfã para uma área de backup (ou delete se não houver dados relevantes)
mv /home/usuario/mail/meudominio.com.br/orfao /root/backup-orfao/
# 4. Remova os caches maildirsize corrompidos para forçar reconstrução limpa
rm -f /home/usuario/mail/meudominio.com.br/*/maildirsize
# 5. Execute novamente o gerador de cotas
/scripts/generate_maildirsize --confirm usuario
Com a pasta órfã removida, o comando finalizou em segundos sem nenhum erro.
Fase 2: O paradoxo de 14 GB entre o terminal e o painel#
Com o script rodando perfeitamente, surgiu o verdadeiro mistério: o painel do cPanel continuava reportando que a conta consumia mais de 60 GB de disco. No entanto, ao medir o espaço diretamente pelo terminal:
du -sh /home/usuario
# Retorno: 59G
du -sh /home/usuario/mail/meudominio.com.br/* | sort -hr | head -n 5
# 11G /home/usuario/mail/meudominio.com.br/admin
# 9.9G /home/usuario/mail/meudominio.com.br/geral
# 9.6G /home/usuario/mail/meudominio.com.br/financeiro
A pasta física da conta geral ocupava exatos 9.9 GB no disco.
Porém, ao consultar a API do cPanel (que alimenta os gráficos do painel web):
uapi --user=usuario Email list_pops_with_disk | awk '/email:/ {email=$2} /diskused:/ {printf "%-40s %s MB\n", email, $2}' | sort -k2 -nr
A saída era alarmante:
geral@meudominio.com.br 24995.54 MB (Aprox. 24.41 GB)
Uma discrepância de quase 15 GB em uma única caixa postal! Como isso é possível se os arquivos estão na mesma partição?
Testando as hipóteses técnicas#
Antes de entender o mecanismo subjacente, foram eliminadas eventuais corrupções de cache:
Hipótese 1: Cache corrompido do datastore ou permissões do maildirsize#
Se o arquivo maildirsize foi gerado por root sem permissão de leitura para o usuário cPanel, a interface poderia exibir lixo de memória.
- Teste: Foi executado
chown usuario:usuario /home/usuario/mail/meudominio.com.br//maildirsizee o cache do painel foi limpo comrm -rf /home/usuario/.cpanel/datastore/. - Resultado: O valor de 24.4 GB persistiu inalterado.
Hipótese 2: Inconsistência na árvore de índices b-tree do Dovecot#
Se deleções antigas de mensagens não atualizaram o índice dovecot.index.cache, o Dovecot poderia estar somando mensagens inexistentes.
- Ação: Foi forçada a destruição dos índices e o recálculo:
find /home/usuario/mail/meudominio.com.br/geral -name "dovecot.index*" -type f -delete
find /home/usuario/mail/meudominio.com.br/geral -name "dovecot.list.index.log" -type f -delete
doveadm force-resync -u geral@meudominio.com.br '*'
doveadm quota recalc -u geral@meudominio.com.br
Ao inspecionar o arquivo bruto de cota recém-gerado:
head -n 2 /home/usuario/mail/meudominio.com.br/geral/maildirsize
A saída foi taxativa:
0S
26209724197 311650
O Dovecot continuava gravando o número exato de 26.209.724.197 bytes (24.41 GB) para um conjunto de 311.650 mensagens. O daemon não estava em dúvida: para ele, a caixa tinha 24.4 GB.
Fase 3: A explicação arquitetural: zlib e cotas lógicas vs. físicas#
A resposta reside no formato Maildir++ e no uso do plugin de compressão Zlib ativado no Dovecot (mail_plugins = $mail_plugins zlib).
1. O que o comando du -sh mede (camada do kernel / VFS):#
O utilitário du faz uma chamada lstat() em cada arquivo da pasta e lê o campo st_blocks retornado pelo inode no sistema de arquivos (ext4 ou XFS). Esse campo reflete o espaço físico real ocupado pelos blocos magnéticos ou semicondutores no SSD após a compressão transparente do Zlib. Como o Zlib compacta e-mails e anexos de texto com alta taxa de eficiência, o tamanho físico encolheu para densos 9.9 GB.
2. O que o Dovecot mede (camada de aplicação):#
Para manter alta performance, o Dovecot implementa a especificação Maildir++. Se o Dovecot precisasse abrir e descompactar cada um dos 311 mil e-mails via read() a cada consulta de cota, o servidor entraria em colapso de I/O e CPU.
Em vez disso, ao receber e compactar uma mensagem de 10 MB, o Dovecot grava o arquivo no disco com o seguinte formato de nome:
1717618293.M491294P2839.servidor,S=10485760:2,S
A tag S=10485760 indica o tamanho original descompactado (lógico) da mensagem em bytes. Quando o plugin Zlib grava o arquivo no disco, ele passa a ocupar fisicamente apenas 2 MB no SSD. Contudo, o módulo de cotas do Dovecot (src/plugins/quota/quota-maildir.c) lê puramente o valor da flag S= no nome do arquivo.
Por que o cPanel adota essa política?#
O cPanel projeta suas cotas com base no espaço lógico descompactado. A razão é de governança de recursos: se a cota fosse cobrada pelo espaço comprimido físico, clientes poderiam armazenar quantidades infinitas de dados compactados, sobrecarregando o processador do servidor a cada tentativa de leitura, busca IMAP ou descompactação massiva.
Portanto, não havia bug nem corrupção. A conta de e-mail continha legitimamente 24.4 GB de mensagens originais. A compressão do Zlib economizava espaço físico no array de discos do servidor, mas a política de uso do plano de hospedagem considerava o volume de dados de origem.
Depuração avançada com strace#
Se você quiser ver o doveadm lendo esses metadados diretamente no nível das chamadas de sistema, execute o comando monitorando as syscalls de I/O:
strace -f -e trace=open,read,write,stat dovecot quota recalc -u geral@meudominio.com.br 2>&1 | grep "maildirsize"
No output do strace, você verá o binário abrindo o arquivo maildirsize, percorrendo o nome de cada mensagem para extrair a flag S= e, finalmente, gravando o total consolidado de bytes no cabeçalho antes de fechar a chamada.
Para ativar logs detalhados de autenticação e manipulação de caixas no arquivo de configuração do Dovecot (/etc/dovecot/dovecot.conf):
mail_debug = yes
auth_debug = yes
Os eventos podem ser acompanhados em tempo real no arquivo /var/log/maillog.
Como agir ao se deparar com essa discrepância#
Quando atender um usuário intrigado com a diferença entre o du -sh e a barra de espaço do cPanel:
- Elimine contas órfãs primeiro: Se o comando de cota travar no erro 67, verifique pastas em
/home/usuario/mail/dominio/que não constam em/etc/dominio/passwd. - Apresente a diferença entre tamanho lógico e físico: Explique com clareza que o servidor utiliza compressão para economizar disco físico, mas o plano de hospedagem contabiliza o volume descompactado das mensagens.
- Identifique as pastas vilãs: Utilize scripts simples para mostrar onde está o acúmulo real (geralmente nas subpastas
.Sente.Trash):
du -sh /home/usuario/mail/dominio/conta/.* 2>/dev/null | grep -v "\.$" | sort -hr
- Oriente a decisão: O usuário pode optar por aplicar regras de expurgo de e-mails antigos ou fazer o upgrade do pacote no painel para acompanhar o crescimento da caixa postal.
Entender como o kernel, o sistema de arquivos e os daemons de e-mail interagem transforma o que parecia um erro inexplicável em uma explicação técnica sólida e transparente.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários