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 testu...@testdomain.com 
> <mailto:testu...@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;

_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org

Reply via email to