On 26. Nov 2024, at 15.34, Кирилл Шигапов via dovecot <dovecot@dovecot.org> wrote:
We are using virtiofs share mounted to /var/vmail When dovecot tries to make a directory structure, it fails with error - fchown: Invalid argument
strace doveadm mailbox create -u testuser@testdomain.com <mailto:testuser@testdomain.com> Trash ... mkdir("/var/vmail/vmail1/ testdomain.com/t/e/s/testuser-2024.11.25.12.58.50//Maildir/.Trash <http://testdomain.com/t/e/s/testuser-2024.11.25.12.58.50//Maildir/.Trash>", 0700) = 0 umask(077) = 000 openat(AT_FDCWD, "/var/vmail/vmail1/ testdomain.com/t/e/s/testuser-2024.11.25.12.58.50//Maildir/.Trash <http://testdomain.com/t/e/s/testuser-2024.11.25.12.58.50//Maildir/.Trash>", O_RDONLY) = 11 fchown(11, -1, -1) = -1 EINVAL (Invalid argument) close(11) = 0 rmdir("/var/vmail/vmail1/ testdomain.com/t/e/s/testuser-2024.11.25.12.58.50//Maildir/.Trash <http://testdomain.com/t/e/s/testuser-2024.11.25.12.58.50//Maildir/.Trash>") = 0 ... So there is no permission issue, directory successfully created. It seems that virtiofs not allowing uid=-1 and gid=-1
I write a small C program for testing. And when using fchown($FileDescriptor, 2000, 2000) there is no error.
Did you try to fchown() a directory file descriptor or a regular file? I've a feeling it doesn't work for directory fds.
I can't find a way to tell dovecot to use uid & gid 2000 when he tries to do fchown.
If I create a directory structure manually, everything works well.
Maybe we can make some parameter in config, telling that we are using virtiofs and skip EINVAL when doing fchown...
It's completely unnecessary to do fchown(fd, -1, -1). It doesn't do anything. This patch perhaps helps? : diff --git a/src/lib/mkdir-parents.c b/src/lib/mkdir-parents.c index 64f660df3e..f2de0ccd09 100644 --- a/src/lib/mkdir-parents.c +++ b/src/lib/mkdir-parents.c @@ -34,6 +34,11 @@ mkdir_chown_full(const char *path, mode_t mode, uid_t uid, umask(old_mask); if (ret < 0) break; + if (uid == (uid_t)-1 && gid == (gid_t)-1) { + /* no changes to owner/group */ + return 0; + } + fd = open(path, O_RDONLY); if (fd != -1) break;