Inspect and Change Dovecot Storage with doveadm fs
Use doveadm fs to poke at Dovecot's abstract mail storage without guessing paths or deleting the wrong tenant. You will inspect first, then copy or add one object, and delete only after checking the exact path.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Confirm the installed command
- 2. Identify the driver and arguments
- 3. List directories and objects first
- 4. Inspect size and content
- 5. Copy an object without touching the source
- 6. Add data with put, then verify it
- 7. Delete only an identified object
- 8. Turn on diagnostics without changing the operation
Allow about fifteen minutes for a read-only look, longer if you have to dig out the driver settings.
- What you need: Dovecot's admin command and a configured filesystem driver.
- Placeholders:
fs-driver,fs-argsand object paths are deployment-specific, so the examples below use made-up values. - Privileges: read-only commands usually need the account that can read Dovecot's configuration and storage. Use elevated privileges only when your installation demands it, and do not add
sudoautomatically.
1. Confirm the installed command
Check the package version and the command's own usage. This does not change mail storage:
$ dovecot --version
2.3.21 (47349e2482)
$ dpkg-query -W -f='${Package} ${Version}\n' dovecot-core
dovecot-core 1:2.3.21+dfsg1-2ubuntu6.5
$ doveadm fs
usage: doveadm [-Dv] [-f <formatter>] fs <command> [<args>]
Version strings and help text vary by package build. The reference machine runs Dovecot 2.3.21, while its compressed manpage is labelled Dovecot v2.3. Treat the local manpage as the contract, and check the help output before copying a command into a script.
Checkpoint
If doveadm fs reports a configuration or socket permission error, stop here. Fix access to the Dovecot installation first. A permission workaround should not become an unexplained root-owned automation job.
2. Identify the driver and arguments
Every operation takes three storage-specific values. The manpage calls them fs-driver, fs-args and path.
- Driver. Which storage backend to use.
- Arguments. The driver's argument string.
- Path. The object you are working on.
Do not substitute a normal mail root unless your configuration explicitly defines it as the driver argument. Inspect the effective configuration with the Dovecot configuration tool and find the settings for the storage area you want. The names depend on the driver. For a POSIX driver, the shell shape looks like this:
$ FS_DRIVER='posix'
$ FS_ARGS='/srv/dovecot/objects'
$ ROOT_PATH='customer-a/'
$ printf 'driver=%s\nargs=%s\npath=%s\n' "$FS_DRIVER" "$FS_ARGS" "$ROOT_PATH"
driver=posix
args=/srv/dovecot/objects
path=customer-a/
Warning
Those values are examples, not defaults. Replace them with values from your own configuration. Keep the path separate from the driver arguments: joining them by hand can inspect a different object or expose data from the wrong tenant.
3. List directories and objects first
Use iter-dirs to list directories below a path and iter to list data files. Both are read-only:
$ doveadm fs iter-dirs "$FS_DRIVER" "$FS_ARGS" "$ROOT_PATH"
customer-a/index/
customer-a/messages/
$ doveadm fs iter "$FS_DRIVER" "$FS_ARGS" "$ROOT_PATH"
customer-a/messages/00000001
customer-a/messages/00000002
The returned paths are illustrative. Your driver may use different names or return nothing. An empty result is a finding, not permission to guess another path.
Tip
If the output is hard to scan, the global -f option can choose flow, pager, tab or the default table formatter, where the command produces structured records.
Checkpoint
Save the exact object path you intend to inspect. Do not turn a broad listing into a recursive delete. The path you give fs delete is the boundary of the operation.
4. Inspect size and content
Use stat to get an object's status. The local manpage documents the result as the total size in bytes:
$ OBJECT_PATH='customer-a/messages/00000001'
$ doveadm fs stat "$FS_DRIVER" "$FS_ARGS" "$OBJECT_PATH"
driver-specific status output, including the total size in bytes
Output and key spelling can vary with the build. The manpage guarantees the total size, not a particular display key, so check before parsing a label.
To retrieve the object itself, use get. Redirect it to a new, explicitly named file so an existing local file is not truncated:
$ OUTPUT='/tmp/dovecot-object-check.bin'
$ doveadm fs get "$FS_DRIVER" "$FS_ARGS" "$OBJECT_PATH" > "$OUTPUT"
$ test -s "$OUTPUT" && echo 'retrieved a non-empty object'
retrieved a non-empty object
Tip
The output may be binary, so do not dump it to a terminal. Keep it in a restricted temporary location, inspect it with a tool suited to its format, and remove it when finished. Retrieval does not modify the Dovecot object.
5. Copy an object without touching the source
copy takes one source path and one destination path. Pick a destination you know is unused, then verify it:
$ SOURCE_PATH='customer-a/messages/00000001'
$ DEST_PATH='customer-a/recovery/00000001'
$ doveadm fs copy "$FS_DRIVER" "$FS_ARGS" "$SOURCE_PATH" "$DEST_PATH"
$ doveadm fs stat "$FS_DRIVER" "$FS_ARGS" "$DEST_PATH"
driver-specific status output, including the total size in bytes
- Success is not verification. Compare the destination's status with the source, and use
getif you need to check content. - Copying creates storage state. Record the destination if you will need to remove this test later.
- There is no general undo. Recovery is another explicit copy or a restore from your storage backup.
6. Add data with put, then verify it
Prepare a local input file first, which does not touch the Dovecot object. The put command takes the input path followed by the destination object path:
$ INPUT_PATH='/srv/recovery/00000001.bin'
$ DEST_PATH='customer-a/recovery/00000001'
$ test -r "$INPUT_PATH" || { echo 'input is not readable' >&2; exit 1; }
$ doveadm fs put "$FS_DRIVER" "$FS_ARGS" "$INPUT_PATH" "$DEST_PATH"
$ doveadm fs stat "$FS_DRIVER" "$FS_ARGS" "$DEST_PATH"
total-size=18432
Warning
Do not assume put is append-only. An existing destination may be replaced, depending on the driver implementation. Use a new path for a first test and keep the source until you have checked the result.
Recovery
If put fails, leave the source in place and investigate the error before retrying.
7. Delete only an identified object
Warning
fs delete removes data associated with the supplied path. It is destructive and may be irreversible. Confirm the driver, arguments and path immediately before running it:
$ printf 'about to delete: driver=%s args=%s path=%s\n' "$FS_DRIVER" "$FS_ARGS" "$DEST_PATH"
about to delete: driver=posix args=/srv/dovecot/objects path=customer-a/recovery/00000001
$ doveadm fs delete "$FS_DRIVER" "$FS_ARGS" "$DEST_PATH"
$ doveadm fs stat "$FS_DRIVER" "$FS_ARGS" "$DEST_PATH"
object not found
The final error text is driver-specific. A non-zero status or a missing-object result is the check that matters.
- Default is not recursive. A plain delete removes only the path you name.
-Ris recursive. It explicitly enables recursive deletion.-n countlimits parallel operations.
Warning
Avoid -R and -n until you have a tested recovery plan, and never use -R on a path copied from an unvalidated variable.
8. Turn on diagnostics without changing the operation
Global -D enables debug messages and -v enables verbose output including a progress counter. Use them when a read or write fails:
$ doveadm -D -v fs stat "$FS_DRIVER" "$FS_ARGS" "$OBJECT_PATH"
$ printf 'exit status: %s\n' "$?"
exit status: 0
Warning
Review debug output for paths and other sensitive storage details before sharing it.
Global -o setting=value overrides configuration for that invocation and can be given more than once. Treat it as a configuration change for the command, not a harmless display option. Test overrides against a disposable object and record them with the command you used.
Done means
- Version checked. You confirmed the installed Dovecot package and read the local command usage.
- Values sourced. The driver and argument values came from your configuration.
- Listed first. You listed directories or objects before choosing a path.
- Verified read-only. You used
statand, where needed,getto check an object without modifying it. - Source kept. Any copy or put used a deliberately chosen destination and kept its source.
- Delete treated as destructive. Recursion stayed off unless you explicitly needed it.