exmdb_provider(4gx)
π Name: exmdb_provider π
okay bestie, this is exmdb_provider β the Gromox Information Store, and it is literally giving mailbox-engine main character energy. π
β¨ Description β¨
exmdb_provider is the mailbox engine. It offers a whole plethora β literally 124 β of stateless low-level functions for operating on mailbox stores. The engineβs functionality is exposed by way of a Gromox-specific network protocol on port 5000. π
exmdb_provider is built as a shared library and can run in either the http(8gx) or istore(8gx) processes, depending on the gromox.cfg:istore_standalone config directive.
The shared library contributes an exmdb_client API, and that API will transparently pick either a local or a remote procedure call depending on whether the mailbox is served by the same process or not. no cap. π«Ά
π Configuration directives (gromox.cfg) π
These are the directives that get recognized when they show up in /etc/gromox/gromox.cfg β periodt. β¨
exmdb_force_write_txnβ (Developer option.) Perform all SQLite transactions as write transactions (i.e. with exclusive locking). Default:no.exmdb_deep_backtraceβ (Developer option.) Record and report transaction problems with a multi-level backtrace instead of a single-level location indicator. Default:no.exmdb_ics_log_fileβ Log ICS/synchronization requests (and their results) to this file. Default:(empty).exmdb_optimize_stmβ A debug knob to turn on/off a specific subset of the SQLite prepared statements with extended lifetimes used in the vicinity of property retrieval in conjunction with Content Table querying (e.g.exmdb_server::query_table, orMAPI ropQueryRows), Content Table matching (exmdb_server::match_table, orMAPI ropFindRow), and non-instanced full message retrieval (exmdb_server::read_message, often used by our exporters). Default:on.outgoing_smtp_urlβ Seegromox.cfg(5):outgoing_smtp_url. iykyk. π«
π¦ Configuration directives (exmdb_provider.cfg) π¦
The usual config file location is /etc/gromox/exmdb_provider.cfg β thatβs where this batch of knobs lives. π
cache_intervalβ The inactivity timer after which a mailboxβs sqlite files are closed. Default:15min. Lower limit:1s.dbg_synthesize_contentβ When this directive is set to1, missing content files will not be regarded as an error, and the respective attachment or property is delivered with a replacement string. If set to2, a replacement string is always delivered; mode2is useful for reducing the amount of data downloaded when debugging ICS. Default:0.enable_damβ When set toon, inbox rule processing is allowed to create Deferred Action Messages (DAM). Furthermore, the "Deferred Actions" folder will have its contents shown. Conversely, if this directive isoff, no DAMs will be created, and the DAM folder in inboxes is presented as empty to clients (even if it has content from earlier). Outlookβs DAM handling is poor, and if you experience a crash with a primary mailbox that is in non-cached/online mode a few seconds after Outlook has opened it, turn this option off for mitigation. Default:on.exmdb_body_autosynthesisβ When a client requests eitherPR_BODY,PR_HTMLorPR_RTF_COMPRESSED, but that property does not exist on a particular message, automatically synthesize the data on-the-fly from another of the available formats. Default:on.exmdb_file_compressionβ Compress content files (bodytexts and attachments). Possible values:no,yes(zstd-6),zstd-level(level=1..19). Default:zstd-6.exmdb_hosts_allowβ A space-separated list of individual host addresses that are allowed to converse with the exmdb service. The addresses must conform togromox(7)Β§ "Host addresses". No networks and no CIDR notations are permitted. This option deprecates the/etc/gromox/exmdb_acl.txtfile used before Gromox2.8. Default:::1.exmdb_listen_portβ The TCP port number for exposing the timer service on. Default:5000.exmdb_pf_read_per_userβ Keep public folder read states per user (1) or keep one state for all users (0). Default:1.exmdb_pf_read_statesβ When set to0, messages in public stores/folders will always be shown as read and the folder summary will reflect that. When set to1, messages will have new/read markings butPR_CONTENT_UNREADwill indicate0new messages at all times. When set to2,PR_CONTENT_UNREADindicates the number of new messages for the particular user. (Outlook does not show this number; in Folder Properties, the radiobox is even greyed out.) Default:2.exmdb_private_folder_softdeleteβ Enables soft-delete support for folders in private stores. (This feature is experimental.) Public folders always have this on. Default:yes.exmdb_schema_upgradesβ This directive controls whether database schemas are automatically upgraded when a mailbox is loaded. During this time, the mailbox is unavailable and operations on it will be delayed. Connection aborts, if any, would be due to timeouts in clients rather than servers. (The procedure takes roughly36secper gigabyte ofexchange.sqlite3worth of data, or36secper about110kmessages, on a3700XCPU, single-thread. The file can also temporarily grow to double its size, so ample disk space may be required.) Default:yes.exmdb_eph_prefixβ A path for where variadic data files that are process-temporary can be stored. This may be used to keep thetables.sqlite3file off an NFS-backed homedir. Required disk space scales linearly with open table handles and linearly with messages in the opened folders, at about80bytes per messages. (In other words, donβt lump molasses of messages into a single folder in a shared mailbox read by multiple people.) When you create the directory, set its ownership togromox:gromoxand mode to0770. Default:(empty).exmdb_search_pacingβ When initially populating a search folder (static or dynamic), yield the lock on the sqlite database (file descriptor) after so many messages to give other clients a chance to perform an action. Default:250.exmdb_search_pacing_timeβ When initially populating a search folder (static or dynamic), yield the lock on the sqlite database (file descriptor) after this much time has passed to give other clients a chance to perform an action. Default:2s.exmdb_search_niceβ Run the search folder population thread with adjusted niceness, which affects process scheduling. This is not an absolute priority as thenice(1)command would use, but a relative one, as per thenice(2)syscall. The allowed range in Gromox is0..19; negative values are not supported (and not meaningful, because Gromox will usually be running in an unprivileged setting where it is not possible to raise the priority). Default:0.exmdb_search_yieldβ Make the search folder population thread not only give up the lock on the sqlite database temporarily, but also invokepthread_yield(3)after every work block (cf.exmdb_search_pacing). Default:no.exrpc_debugβ Log every incoming exmdb network RPC and the return code of the operation in a minimal fashion tostderr. Level1emits RPCs with a failure return code, level2emits all RPCs. Note that direct function calls from within the process image are not logged this way, so this will not showexmdb_providerinvocations fromexchange_emsmdb(4gx). Note the daemon log level needs to be "debug" (6), too. Default:0.listen_ipβ The IPv6 socket address for exposing the exmdb service on. The address must conform togromox(7)Β§ "Host addresses". Default:::1.max_ext_rule_numberβ Default:20.max_router_connectionsβ As an exmdb server, permit at most this many inbound connections for the purpose of sending notifications on these channels. Note that every incoming TCP connection starts as a data connection and only becomes re-classified as "notification" once theLISTEN_NOTIFICATIONRPC has been issued by the client. Default:unlimited(only limited by ulimits).max_rpc_stub_threadsβ As an exmdb server, permit at most this many inbound connections for commands. Default:unlimited(only limited by ulimits).max_rule_numberβ Default:1000.max_store_message_countβ The maximum number of messages any one particular message store is allowed to keep. The technical limit is somewhere around2^47. Default:0(no limit).populating_threads_numβ The number of threads to spawn that will work on asynchronous search folder population. Default:4.rpc_proxy_connection_numβ For every remote exmdb server that needs to be contacted because of rule processing anOP_FOWARD(or similar) rule, keep this many number of outbound connections for sending commands. Default:10.sqlite_debugβ If set to1, every query given to SQLite prepare/execute is logged. If set to0, only failed queries are logged. (It cannot be made completely silent, since our queries ought to never fail.) Default:0.table_sizeβ Maximum number of concurrently active mailboxes. Default:5000.x500_org_nameβ Default:(unspecified).
π Sharding / Multiple Home Server Cluster π
Okay so picture this: every exmdb_provider (server) instance is doing a vibe check on SQL columns. For private stores it checks users.homeserver / servers.hostname; for public stores it checks domains.homeserver / servers.hostname. It compares that against the host_id directive to figure out whether it should be serving that thing. And the exmdb_client component β the one used by zcore, imapd, etc., plus a whole plethora of command-line utilities β does the same SQL-column evaluating to decide which server to contact. iykyk.
The magic value 0 in the homeserver column is like the βeveryone is invitedβ of server authority: any and all server instances consider themselves authoritative. This has serious implications (concurrent writes by multiple hosts), so for accounts with an actual maildir, avoid homeserver=0 in multiserver setups. Using 0 for Contact Objects is tolerable, and using 0 for single-server setups is tolerable too. (Keep that distinction: βtolerableβ, not βa slayβ.)
For a decidedly single-server cluster, this circumstance requires attention too. Example: imagine the server.hostname SQL column contains "server01.example.com", which resolves to "2001:db8::1" β this conflicts with the ::1 bind address, making connection attempts fail. Yeah. Thatβs the tea.
Also: the file /etc/gromox/exmdb_list.txt became obsolete in the development phase that followed the Gromox 3.4 release. So donβt come for it, itβs retired.
π Network protocol π
The transmissions on the socket are simple concatenations of protocol data units built using the NDR format. The PDU length is present within the PDU itself near the start.
{
leuint32_t length;
char pdu[];
}
pdu := {
uint8_t call_id;
string directory;
switch (call_id) {
...
}
}
π Files π
data_file_path/mail_bounce/
config_file_path and data_file_path are determined by the configuration of the program that loaded the exmdb_provider component.
π¦ Signals π¦
Upon receipt of SIGHUP, configuration files are re-read β but only a few select directives can be changed this way, because many parts do not implement reload. So donβt assume a full glow-up reload for everything.
π See also π
And thatβs the page, bestie. Footer vibe: this is from Gromox, page exmdb_provider(4gx), and weβre closing it out with a little sparkle. πβ¨
π¦ where this page comes from
- alpine 3.24: grommunio-gromox-doc 3.6-r0 Β· AGPL-3.0-or-later
- π the page's license: CC-BY-SA-4.0 or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms