Timo Sirainen [Mon, 25 Dec 2017 16:24:35 +0000 (18:24 +0200)]
lib-storage: mail_storage_set_index_error() - handle NULL index error
This avoids assert-crashing later on in mail*_get_last_internal_error().
This could potentially be an assert instead of setting it as "BUG", but
it looks like there are various code paths in lib-index that return -1
without setting an error. (That's to avoid duplicate error logging,
although it could now be fixed with mail_index_set_error_nolog().)
Timo Sirainen [Mon, 25 Dec 2017 16:18:14 +0000 (18:18 +0200)]
lib-storage: Set index error on transaction commit() callback
The commit callback is setting errors to storage. However, it's being
called from mail_index_transaction_commit() whose callers are expecting
the error to be in index. If that index error was attempted to be used,
it could have been wrong or NULL. Fix this by setting the same storage
error also to the index.
Including it in lib.h allows all of the Dovecot code (as well as any
external plugins) to just use these macros without worrying about what
system headers to include.
Timo Sirainen [Thu, 19 Oct 2017 10:26:27 +0000 (13:26 +0300)]
lib: printf_format_fix*() - Use the same 4 digits as maximum precision length
I forgot the precision can also be used to truncate strings, not just
specify the precision for floating point numbers. So it makes more sense
that the limit is the same as for minimum field width.
Timo Sirainen [Tue, 17 Oct 2017 14:39:32 +0000 (17:39 +0300)]
lib: printf_format_fix*() - Be over-strict in what format strings are allowed
The checks could have been bypassed by some invalid format strings that were
handled differently by the printf_format_fix*() code and libc. For example
"%**%n" was passed through as ok, but glibc handled the %n in it.
Timo Sirainen [Thu, 28 Dec 2017 12:10:23 +0000 (14:10 +0200)]
dsync: Add per-mailbox sync lock that is always used.
Both importing and exporting gets the lock before they even sync the
mailbox. The lock is kept until the import/export finishes. This guarantees
that no matter how dsync is run, two dsyncs can't be working on the same
mailbox at the same time.
This lock is in addition to the optional per-user lock enabled by the -l
parameter. If the -l parameter is used, the same lock timeout is used for
the per-mailbox lock. Otherwise 30s timeout is used.
This should help to avoid email duplication when replication is enabled for
public namespaces, and maybe in some other rare situations as well.
Timo Sirainen [Wed, 13 Dec 2017 23:36:50 +0000 (01:36 +0200)]
LAYOUT=fs: Fix listing prefix/INBOX
Removed some confusing special case code that didn't seem to work very well.
Implemented this now properly so that prefix/INBOX is listed as \NoSelect
mailbox whenever it has children.
It's not actually possible to differentiate between INBOX and prefix/INBOX
in the storage for a inbox=yes namespace, because they both are converted
into the same storage_name=INBOX.
Timo Sirainen [Tue, 28 Nov 2017 17:01:19 +0000 (19:01 +0200)]
director: Fix logging disconnection error reasons
The previous commit set errno=0, which weren't logged. If error string is
provided, it doesn't matter what the errno is set (as long as it's not 0),
so we'll just use EINVAL.
Timo Sirainen [Fri, 24 Nov 2017 10:31:22 +0000 (12:31 +0200)]
lib-storage: Fix sorting mails with the same primary sort key
The sorting order may have been wrong when there was a combination of:
* Messages were sorted by a string (e.g. Subject)
* Some messages had the same sort key (e.g. same base subject)
* Within the messages with the same sort key, some of the messages already
had the "sort-*" index number in Dovecot indexes, but some of them
didn't.
The result was that Dovecot found that the two messages had exactly the same
sort key. It should have continued with the secondary sort key (e.g.
message sequence number), but it didn't.
Timo Sirainen [Sat, 25 Nov 2017 08:01:31 +0000 (10:01 +0200)]
director: Don't send USERs in handshake that were already sent between handshake
If the user was refreshed since the handshake was started, it means that
the same user was already sent to the other side (added to the stream
immediately after it was received/handled). There's no need to send it
again.
This fixes a potentally infinite handshake when users are rapidly changing
and the handshake iterator never sees the end of the list. (Each refreshed
user is moved to the end of the list, so handshaking can keep sending the
same user over and over again.)
Timo Sirainen [Sat, 25 Nov 2017 08:05:27 +0000 (10:05 +0200)]
director: Delay sorting users until there are no more user iterators
This shouldn't have normally happened. Only when an outgoing handshake was
going on at the same time as a) another outgoing handshake was going on, or
b) doveadm was doing HOST-RESET-USERS
Timo Sirainen [Sat, 25 Nov 2017 23:31:08 +0000 (01:31 +0200)]
director: Avoid USER loops with >1s ring latency also with old directors
Do this by ignoring USER refreshes that were already updated recently.
The "recently" is calculated by director_user_expire/4 seconds ago, but
with an upper limit of 15 secs. This means that the USER loops can now
only exist if the director ring latency is above 15 seconds. (Once all
directors in the ring are running the new version, there's no looping
at any latency.)
Timo Sirainen [Sat, 25 Nov 2017 23:19:35 +0000 (01:19 +0200)]
director: Avoid USER loops when ring latency is over 1 second
Do this by adding a timestamp parameter to USER events. This way if it
takes over 1 second for the USER event to traverse the ring, it won't get
into an infinite loop getting the user updated over and over again.
Timo Sirainen [Fri, 17 Nov 2017 11:24:59 +0000 (13:24 +0200)]
director: Keep users unsorted during handshake and sort them at the end
This is simpler and sometimes more efficient than the current way of
immediately inserting the users to the correct place in the linked list.
This is especially useful if handshaking is mixed with regular USER updates,
because each switch between them required walking the linked list backwards
to find the proper insert position.
It's not a big problem if the users list is temporarily unordered. It mainly
means that some of the users won't be expired as early as they should have.
Timo Sirainen [Fri, 17 Nov 2017 16:53:18 +0000 (18:53 +0200)]
director: Make sure users are sorted after unfinished handshake
The users were sorted after the handshake was finished, but if the
connection was closed before that hapepned, the users were left
unsorted. This could have caused the users to not expire early
enough.
Timo Sirainen [Wed, 15 Nov 2017 22:44:17 +0000 (00:44 +0200)]
director: Reconnect after detecting a write failure to director
If disconnection is detected during write failure, or "Output buffer full"
occurs, the connection is disconnected. However, if this was the right side
connection, it wasn't automatically reconnected to. This left the ring
nonworking.
Stephan Bosch [Wed, 20 Sep 2017 22:38:33 +0000 (00:38 +0200)]
lib-http: client: Send empty payload (Content-Length: 0) for requests that normally expect a payload.
This includes the standard POST and PUT methods.
Others need to use the new http_client_request_set_payload_empty() function to force sending an empty payload.
Timo Sirainen [Mon, 6 Nov 2017 16:59:34 +0000 (18:59 +0200)]
lib-storage: When copying mails, copy also empty cache fields
This mainly means that it copies cache fields for nonexistent message
headers. Those are still important, because otherwise Dovecot doesn't know
whether they exist or not.
The director_max_parallel_moves setting controls the default limit, which
can still be increased by explicitly using the doveadm director flush
--max-parallel" parameter.
Timo Sirainen [Sun, 5 Nov 2017 20:38:27 +0000 (22:38 +0200)]
director: Include used CPU secs in director connection log messages
It's counting the process's full CPU seconds used since the handshake
started, so it's not specific to the connection itself. Still, this is
likely to be very useful in debugging whether a slow handshake was due
to CPU usage or something else.