MYSQL TMPDIR em TMPFS com SELINUX ativado

Eu sou daqueles caras teimosos que insiste em usar o SELINUX ao invés de desligar ele após a instalação do servidor :)

Eis que estava montando um servidor MYSQL para o Zabbix no CentOS 6.5 e resolvi criar um diretório temporário para o MYSQL em um TMPFS para obter uma melhor performance do Zabbix.

Basicamente fiz o seguinte

service mysqld stop

Criei o diretório

mkdir /mytmp

No my.cnf coloquei o seguinte

tmpdir=/mytmp

No fstab coloquei o seguinte

tmpfs			/mytmp			tmpfs  rw,uid=mysql,gid=mysql,size=1g,nr_inodes=10k,mode=0775 0 0

Montei o tmpfs

mount /mytmp

Iniciei o mysql

service mysqld start

Porém, quando eu iniciava o MYSQL, os seguintes erros apareciam no LOG

/usr/libexec/mysqld: Can't create/write to file '/tmpfs/ibbBLVnW' (Errcode: 13)
140829 12:23:42  InnoDB: Error: unable to create temporary file; errno: 13
140829 12:23:42 [ERROR] Plugin 'InnoDB' init function returned error.
140829 12:23:42 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.

O sintoma do lado da aplicação era um access denied na conexão com o banco, os desavisados podem perder muito tempo tentando acertar permissões mas não é esse o problema, isto ocorria pois o MySQL não conseguia escrever no ponto de montagem TMPFS, veja o erro no detalhe

/usr/libexec/mysqld: Can't create/write to file '/tmpfs/ibbBLVnW' (Errcode: 13)

Sabendo que o SELINUX estava ligado fui olhar no /var/log/audit/audit.log

cat /var/log/audit/*.log |grep mysql|grep -v zabbix|grep tmpfs

Encontrei então a seguinte informação

type=AVC msg=audit(1408993827.194:10192): avc:  denied  { write } for  pid=28603 comm="mysqld" name="/" dev=tmpfs ino=708243 scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir

No log acima é possível ver que o MYSQL tentou escrever em um diretorio da raiz que montava um TMPFS e não conseguiu devido ao contexto do diretório, tive então que checar o contexto do diretório, para isto eu rodei o comando abaixo

ls -Z /|grep mytmp

A saída recebida foi esta

drwxr-xr-x. root  root  unconfined_u:object_r:default_t:s0 mytmp

Veja que o conexto acima está com o tipo default_t, e neste caso, quando o SELINUX está ativo, o mysql não consegue escrever no diretório.

Para resolver a questão foi necessário ajustar o contexto do diretório para mysqld_db_t, só assim o mysql terá condições de escrever dentro dele.

Usei o semanage para definir o contexto default do diretório

semanage fcontext -a -t mysqld_db_t "/mytmp(/.*)?"

E depois rodei um restorecon para corrigir o contexto do diretório

restorecon -Rv /mytmp/

Acompanhe a saída do restorecon

restorecon reset /mytmp context unconfined_u:object_r:tmp_t:s0->unconfined_u:object_r:mysqld_db_t:s0

Feito isto, iniciei o MYSQL sem erros no log.

Os erros na aplicação também foram solucionados.

O processo é o mesmo se deseja colocar o diretório DATA do MYSQL em outro local em um servidor com SELINUX ativado.

[s]
Guto