[Dovecot] Multiple quota roots with quota-fs backend
Today I've tried to configure multiple filesystem quotas, with some strange results.
These are my two filesystems; both using quotas:
/dev/mail mounted to /var/spool/mail using AIX quotas for all users. Mailbox format is 'mbox' and they are named '/var/spool/mail/<logname>'
filer0:/vol/home mounted to /home/f0 via nfs using netapp quotas for all users. Mailboxes are all 'mbox' and located in '~<logname>/Mail'
I've configured _two_ quota roots as described here: http://wiki.dovecot.org/Quota/FS?highlight=(two%20filesystems)
plugin { quota = fs:Home:mount=/home/f0 quota2 = fs:Spool:mount=/var/spool/mail }
This works like a charm, but when testing the configuration, the result was just surprising:
- OK [CAPABILITY IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN NAMESPACE LOGIN-REFERRALS UIDPLUS LIST-EXTENDED I18NLEVEL=1 QUOTA AUTH=PLAIN] Dovecot ready. . login rfttest XXX . OK Logged in. . getquotaroot "INBOX"
- QUOTAROOT "INBOX" "Home" "Spool"
- QUOTA "Home" (STORAGE 310360 1048576)
- QUOTA "Spool" (STORAGE 89708 1000000) . OK Getquotaroot completed. . getquotaroot "Trash"
- QUOTAROOT "Trash" "Home" "Spool"
- QUOTA "Home" (STORAGE 310360 1048576)
- QUOTA "Spool" (STORAGE 89708 1000000) . OK Getquotaroot completed. . logout
- BYE Logging out . OK Logout completed.
You see, that _always_ both quota roots are reported, whether the references mailbox is actually placed on this filesystem or not.
However reading RFC2087 confirms me in the idea, that just the _related_ quota roots should be listed:
-------------------------------8<----------------------------------------- 4.3. GETQUOTAROOT Command
Arguments: mailbox name
Data: untagged responses: QUOTAROOT, QUOTA
Result: OK - getquota completed
NO - getquota error: no such mailbox, permission denied
BAD - command unknown or arguments invalid
The GETQUOTAROOT command takes the name of a mailbox and returns the
list of quota roots for the mailbox in an untagged QUOTAROOT
response. For each listed quota root, it also returns the quota
root's resource usage and limits in an untagged QUOTA response.
Example: C: A003 GETQUOTAROOT INBOX
S: * QUOTAROOT INBOX ""
S: * QUOTA "" (STORAGE 10 512)
S: A003 OK Getquota completed
------------------------------->8-----------------------------------------
So in my opinion correctly reported quota roots should look like this:
- OK [CAPABILITY IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN NAMESPACE LOGIN-REFERRALS UIDPLUS LIST-EXTENDED I18NLEVEL=1 QUOTA AUTH=PLAIN] Dovecot ready. . login rfttest XXX . OK Logged in. . getquotaroot "INBOX"
- QUOTAROOT "INBOX" "Spool"
- QUOTA "Spool" (STORAGE 89708 1000000) . OK Getquotaroot completed. . getquotaroot "Trash"
- QUOTAROOT "Trash" "Home"
- QUOTA "Home" (STORAGE 310360 1048576) . OK Getquotaroot completed. . logout
- BYE Logging out . OK Logout completed.
Now I known what I want... but how to get it :-)
While I see no way to use namespaces and/or quota rules to configure this behavior, patching quota.c, quota-fs.c and quota-private.h seems to be an option.
A downside of this is, that I've to extend the quota plugin interface (quota_backend_vfuncs) defined in quota-private.h by adding an new callback function. Since all other quota backends don't have this new function, they have to initialize it with NULL. So there are side effects to other quota backends.
This is the reason why I want to discuss the above described problem (and solution) before posting my patch :-)
Regards, Ralf
--
Dipl.-Inform. (FH) Ralf Becker Rechenzentrum (r/ft) der FH Trier (Network|Mail|Web|Firewall) University of applied sciences Administrator Schneidershof, D-54293 Trier
Mail: beckerr@fh-trier.de Fon: +49 651 8103 499 WWW: http://www.fh-trier.de/~beckerr Fax: +49 651 8103 214
On Tue, 2008-07-08 at 16:49 +0200, Ralf Becker wrote:
You see, that _always_ both quota roots are reported, whether the references mailbox is actually placed on this filesystem or not.
However reading RFC2087 confirms me in the idea, that just the _related_ quota roots should be listed:
Right.
While I see no way to use namespaces and/or quota rules to configure this behavior, patching quota.c, quota-fs.c and quota-private.h seems to be an option.
A downside of this is, that I've to extend the quota plugin interface (quota_backend_vfuncs) defined in quota-private.h by adding an new callback function. Since all other quota backends don't have this new function, they have to initialize it with NULL. So there are side effects to other quota backends.
Right. If you'll write this code I can include it to v1.2 release.
Ok... here it is :-) BTW: The patch also includes another AIX specific code enhancement: On AIX the quota block size DEV_BSIZE should be 1024. This is easy to detect, because there is a macro DQBSIZE defined in jfs/quota.h. I've changed quota-fs.c to use DQBSIZE (if present) to initialize DEV_BSIZE. --- dovecot-1.1.1-orig/src/plugins/quota/quota-fs.c 2008-06-12 22:48:38.000000000 +0200 +++ dovecot-1.1.1/src/plugins/quota/quota-fs.c 2008-07-09 20:09:28.000000000 +0200 @@ -29,6 +29,10 @@ # define RQUOTA_GETQUOTA_TIMEOUT_SECS 10 #endif +#ifdef DQBSIZE +# define DEV_BSIZE DQBSIZE +#endif + #ifndef DEV_BSIZE # define DEV_BSIZE 512 #endif Timo Sirainen schrieb am 12.07.2008 15:14:
On Tue, 2008-07-08 at 16:49 +0200, Ralf Becker wrote:
You see, that _always_ both quota roots are reported, whether the references mailbox is actually placed on this filesystem or not.
However reading RFC2087 confirms me in the idea, that just the _related_ quota roots should be listed:
Right.
While I see no way to use namespaces and/or quota rules to configure this behavior, patching quota.c, quota-fs.c and quota-private.h seems to be an option.
A downside of this is, that I've to extend the quota plugin interface (quota_backend_vfuncs) defined in quota-private.h by adding an new callback function. Since all other quota backends don't have this new function, they have to initialize it with NULL. So there are side effects to other quota backends.
Right. If you'll write this code I can include it to v1.2 release.
-- ______________________________________________________________________ Dipl.-Inform. (FH) Ralf Becker Rechenzentrum (r/ft) der FH Trier (Network|Mail|Web|Firewall) University of applied sciences Administrator Schneidershof, D-54293 Trier Mail: beckerr@fh-trier.de Fon: +49 651 8103 499 Web: http://www.fh-trier.de/~beckerr Fax: +49 651 8103 214 PubKey: http://www.fh-trier.de/~beckerr Crypto: GnuPG, S/MIME ______________________________________________________________________ Wenn Gott gewollt haette, dass E-Mail in HTML geschrieben wuerden, endeten Gebete traditionell mit </amen>. (Tom Listen)
On Sat, 2008-07-12 at 15:54 +0200, Ralf Becker wrote:
Ok... here it is :-)
BTW: The patch also includes another AIX specific code enhancement:
On AIX the quota block size DEV_BSIZE should be 1024. This is easy to detect, because there is a macro DQBSIZE defined in jfs/quota.h. I've changed quota-fs.c to use DQBSIZE (if present) to initialize DEV_BSIZE.
Does it work if you instead use "root->mount->block_size" instead? I'm thinking about removing DEV_BSIZE from everywhere and using the looked up block_size instead.
mst.st_dev == rst.st_dev
Use CMP_DEV_T() macro instead (src/lib/compat.h).
+ if (getenv("DEBUG") != NULL)
root->quota->debug has the same value. Looks like I should fix some of my own code for that as well.
Timo Sirainen schrieb am 12.07.2008 16:29:
On Sat, 2008-07-12 at 15:54 +0200, Ralf Becker wrote:
Ok... here it is :-)
BTW: The patch also includes another AIX specific code enhancement:
On AIX the quota block size DEV_BSIZE should be 1024. This is easy to detect, because there is a macro DQBSIZE defined in jfs/quota.h. I've changed quota-fs.c to use DQBSIZE (if present) to initialize DEV_BSIZE.
Does it work if you instead use "root->mount->block_size" instead? I'm thinking about removing DEV_BSIZE from everywhere and using the looked up block_size instead.
no, it doesn't. DQBSIZE is 1024, but root->mount->block_size is 4096
mst.st_dev == rst.st_dev
Use CMP_DEV_T() macro instead (src/lib/compat.h).
done, I've changed it in src/lib/mountpoint.c too.
+ if (getenv("DEBUG") != NULL)
root->quota->debug has the same value. Looks like I should fix some of my own code for that as well.
It seems that root->quota->debug in not available in 1.1.1 release source code: "quota-fs.c", line 615.19: 1506-022 (S) "quota" is not a member of "struct fs_quota_root".
--
Dipl.-Inform. (FH) Ralf Becker Rechenzentrum (r/ft) der FH Trier (Network|Mail|Web|Firewall) University of applied sciences Administrator Schneidershof, D-54293 Trier
Mail: beckerr@fh-trier.de Fon: +49 651 8103 499
Web: http://www.fh-trier.de/~beckerr Fax: +49 651 8103 214
PubKey: http://www.fh-trier.de/~beckerr Crypto: GnuPG, S/MIME
Wenn Gott gewollt haette, dass E-Mail in HTML geschrieben wuerden, endeten Gebete traditionell mit </amen>. (Tom Listen)
On Sat, 2008-07-12 at 17:24 +0200, Ralf Becker wrote:
BTW: The patch also includes another AIX specific code enhancement:
On AIX the quota block size DEV_BSIZE should be 1024. This is easy to detect, because there is a macro DQBSIZE defined in jfs/quota.h. I've changed quota-fs.c to use DQBSIZE (if present) to initialize DEV_BSIZE.
Added to v1.1: http://hg.dovecot.org/dovecot-1.1/rev/3f903dfa8650
The rest I added only to v1.2, at least for now: http://hg.dovecot.org/dovecot-1.2/rev/796307638449
I also thought that the root checking usually isn't necessary if there's only a single quota root, so it skips it then.
+ if (getenv("DEBUG") != NULL)
root->quota->debug has the same value. Looks like I should fix some of my own code for that as well.
It seems that root->quota->debug in not available in 1.1.1 release source code: "quota-fs.c", line 615.19: 1506-022 (S) "quota" is not a member of "struct fs_quota_root".
Looks like it was root->root.quota->debug. I changed it everywhere now.
Timo Sirainen schrieb am 20.07.2008 20:40:
The rest I added only to v1.2, at least for now: http://hg.dovecot.org/dovecot-1.2/rev/796307638449
I also thought that the root checking usually isn't necessary if there's only a single quota root, so it skips it then.
I'm not sure with that, because even if there is just one quota root not all existing mailbox have to be located in it. Let's take Grandy Fu's configuration as example. It pictures a situtation where the checking is necessary:
dovecot.conf:
mail_location = mbox:~/mail:INBOX=/var/mail/%u plugin { quota = fs:INBOX:mount=/var/mail }
/var/mail
* has quotas
* for mailboxes hosted by this file system 'getrootquota' should
report used/total quota sizes, because it is covered by
quota = fs:INBOX:mount=/var/mail
/home/h1 (or any other fs where mailboxes may reside)
* has no quotas
* for mailboxes hosted by this file system 'getrootquota' should
report nothing, because it is _not_ covert by any quota root
--
Dipl.-Inform. (FH) Ralf Becker Rechenzentrum (r/ft) der FH Trier (Network|Mail|Web|Firewall) University of applied sciences Administrator Schneidershof, D-54293 Trier
Mail: beckerr@fh-trier.de Fon: +49 651 8103 499
Web: http://www.fh-trier.de/~beckerr Fax: +49 651 8103 214
PubKey: http://www.fh-trier.de/~beckerr Crypto: GnuPG, S/MIME
Wenn Gott gewollt haette, dass E-Mail in HTML geschrieben wuerden, endeten Gebete traditionell mit </amen>. (Tom Listen)
On Mon, 2008-07-21 at 01:34 +0200, Ralf Becker wrote:
Timo Sirainen schrieb am 20.07.2008 20:40:
The rest I added only to v1.2, at least for now: http://hg.dovecot.org/dovecot-1.2/rev/796307638449
I also thought that the root checking usually isn't necessary if there's only a single quota root, so it skips it then.
I'm not sure with that, because even if there is just one quota root not all existing mailbox have to be located in it. Let's take Grandy Fu's configuration as example. It pictures a situtation where the checking is necessary:
But most people haven't needed it, so it would be unnecessary extra checks for them. Wonder if it'd be better to just let them have the extra check or add a configuration option..
I'm also a bit worried that if this check was always done it would break some existing setup where the check doesn't work correctly for some reason.
Timo Sirainen schrieb am 21.07.2008 02:03:
But most people haven't needed it, so it would be unnecessary extra checks for them. Wonder if it'd be better to just let them have the extra check or add a configuration option..
I'm also a bit worried that if this check was always done it would break some existing setup where the check doesn't work correctly for some reason.
I see the point :-)
./src/plugins/quota/quota.c:
Looking over the new function 'quota_root_is_visible' let's me think, that Grandy Fu's original solution (*) should work then, because 'noenforcing' does cover not only quota checking but also quota root reporting. So 'noenforcing' is then just an alias for 'hidden'. Right?
So the meaning will change from dovecot-1.1.1: 'noenforcing' => report, but don't enforce to dovecot-1.1.2: 'noenforcing' => don't report and don't enforce
Or do I miss something?
(*) plugin { quota = fs:INBOX:mount=/var/mail quota2 = fs:home:noenforcing:mount=/home/h1 }
--
Dipl.-Inform. (FH) Ralf Becker Rechenzentrum (r/ft) der FH Trier (Network|Mail|Web|Firewall) University of applied sciences Administrator Schneidershof, D-54293 Trier
Mail: beckerr@fh-trier.de Fon: +49 651 8103 499
Web: http://www.fh-trier.de/~beckerr Fax: +49 651 8103 214
PubKey: http://www.fh-trier.de/~beckerr Crypto: GnuPG, S/MIME
Wenn Gott gewollt haette, dass E-Mail in HTML geschrieben wuerden, endeten Gebete traditionell mit </amen>. (Tom Listen)
On Mon, 2008-07-21 at 10:36 +0200, Ralf Becker wrote:
./src/plugins/quota/quota.c:
Looking over the new function 'quota_root_is_visible' let's me think, that Grandy Fu's original solution (*) should work then, because 'noenforcing' does cover not only quota checking but also quota root reporting. So 'noenforcing' is then just an alias for 'hidden'. Right?
So the meaning will change from dovecot-1.1.1: 'noenforcing' => report, but don't enforce to dovecot-1.1.2: 'noenforcing' => don't report and don't enforce
I suppose you mean with dovecot-1.2, since I didn't change this to v1.1.2..?
Anyway noenforcing still means the same. When reporting the enforce parameter is FALSE, so the no_enforcing check isn't done.
If it didn't report and didn't enfroce, there would be no point in having the quota specified at all. :)
participants (2)
-
Ralf Becker
-
Timo Sirainen