A anatomia de um troubleshooting: cotas fantasmas, Dovecot e a ilusão do espaço físico em servidores cPanel
Voltar para blog

A anatomia de um troubleshooting: cotas fantasmas, Dovecot e a ilusão do espaço físico em servidores cPanel

02/10/2026 · 6 min · E-mail

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:

  1. O interpretador Perl faz uma chamada de sistema (syscall) getdents() para varrer a pasta /home/usuario/mail/meudominio.com.br/.
  2. Para cada subdiretório físico encontrado, ele invoca o binário do Dovecot: doveadm quota recalc -u conta@meudominio.com.br.
  3. 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.

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.

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:

  1. 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.
  2. 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.
  3. Identifique as pastas vilãs: Utilize scripts simples para mostrar onde está o acúmulo real (geralmente nas subpastas .Sent e .Trash):
   du -sh /home/usuario/mail/dominio/conta/.* 2>/dev/null | grep -v "\.$" | sort -hr
  1. 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:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários