Estou tentando limpar alguns arquivos de memória compartilhada de lixo deixados por um serviço após a falha. O serviço é executado como um usuário do sistema e um grupo específico. Sou membro desse grupo, mas não consigo excluir a memória compartilhada.
$ ls -la /dev/shm
drwxrwxrwt 2 root root 600 Jun 20 11:18 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 simbot simusers 500032 Jun 20 10:35 Sim_SharedMem_SLM__data_0
$ groups | grep simusers -q && echo member || echo not member
member
$ rm -f /dev/shm/Sim_SharedMem_SLM__data_0
rm: cannot remove '/dev/shm/Sim_SharedMem_SLM__data_0': Operation not permitted
Não tenho problemas para excluir os arquivos como root. Também não tenho problemas para excluir o arquivo se sou eu quem executa (e trava) o processo (sou o usuário que possui os arquivos).
Reprodução
Acho que a maneira mais fácil de exibir o problema é executar o processo como eu e alterar alguns dos arquivos de lixo como se fossem de propriedade do outro usuário.
$ /usr/local/bin/badProcess
^C
$ ls -la /dev/shm
drwxrwxrwt 2 root root 640 Jun 20 11:31 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_0
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_1
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_2
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_3
$ sudo chown simbot Sim_SharedMem_SLM__data_1
$ sudo chown :simusers Sim_SharedMem_SLM__data_2
$ sudo chown simbot:simusers Sim_SharedMem_SLM__data_3
$ ls -la /dev/shm
drwxrwxrwt 2 root root 640 Jun 20 11:31 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_0
-rw-rw-rw- 1 simbot stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_1
-rw-rw-rw- 1 stew simusers 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_2
-rw-rw-rw- 1 simbot simusers 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_3
$ rm /dev/shm/*
rm: cannot remove 'Sim_SharedMem_SLM__data_1`': Operation not permitted
rm: cannot remove 'Sim_SharedMem_SLM__data_3`': Operation not permitted
lsattr
Algumas soluções sugerem verificar os atributos +a ou +i com lsattr.
$ lsattr Sim_SharedMem_SLM__data_0
lsattr: Inappropriate ioctl for device While reading flags on Sim_SharedMem_SLM__data_0
Isso acontece porque esses atributos não são suportados pelo tmpfs (que é esse diretório)
$ mount | grep /dev/shm
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
ACLs
Dei uma olhada na ACL para ver se havia algo engraçado com o diretório pai ou o próprio arquivo. Não vejo que não aprendemos com ls
Eu tenho permissões de gravação no diretório pai
$ getfacl /dev/shm
getfacl: Removing leading '/' from absolute path names
# file: dev/shm
# owner: root
# group: root
# flags: --t
user::rwx
group::rwx
other::rwx
$ getfacl /dev/shm/Sim_SharedMem_SLM__data_0
getfacl: Removing leading '/' from absolute path names
# file: dev/shm/Sim_SharedMem_SLM__data_0
# owner: simbot
# group: simusers
user::rw-
group::rw-
other::rw-
Não são as permissões do arquivo que interessam ao excluir um arquivo, mas as permissões do diretório no qual o arquivo reside.
No seu caso, todos têm permissões de gravação no diretório, mas o diretório também possui o "sticky bit" definido (
t
no final da string de permissão).A exclusão de arquivos em tal diretório funciona de maneira diferente e você precisa ser o proprietário do arquivo, ou o proprietário do diretório fixo, ou ser root, para poder excluir o arquivo.
Isto é do
sticky(8)
manual em um sistema OpenBSD:No Ubuntu, o
chmod(1)
manual tem as informações equivalentes: