From: Timo Sirainen Date: Sun, 29 Apr 2018 10:45:05 +0000 (+0300) Subject: doveadm: Add mailbox cache compress X-Git-Tag: 2.3.4~146 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ab895423914eaa4830061ae4294c19cf0a065739;p=thirdparty%2Fdovecot%2Fcore.git doveadm: Add mailbox cache compress --- diff --git a/doc/man/doveadm-mailbox.1.in b/doc/man/doveadm-mailbox.1.in index f0cb19750b..275cfdbbed 100644 --- a/doc/man/doveadm-mailbox.1.in +++ b/doc/man/doveadm-mailbox.1.in @@ -302,6 +302,17 @@ This command is used to set UID validity, next UID, first recent UID and modific Usually this is only ever to be used during migration, or restoring mailbox after disaster. Settings these values is highly discouraged, and is not supported for all mail backends. .\"------------------------------------------------------------------------ +.SS mailbox cache compress +.B doveadm mailbox cache compress +[\fB\-A\fP|\fB\-u\fP \fIuser\fP|\fB\-F\fP \fIfile\fP] +[\fB\-S\fP \fIsocket_path\fP] +.IR mailbox\ ... +.PP +Perform "compression" to the dovecot.index.cache file. Most importantly this +frees up disk space from mails that were already deleted. Normally there is +no need to run this command manually, because the compression is also run +automatically. +.\"------------------------------------------------------------------------ .SS mailbox cache decision .B doveadm mailbox cache decision [\fB\-A\fP|\fB\-u\fP \fIuser\fP|\fB\-F\fP \fIfile\fP] diff --git a/src/doveadm/doveadm-mail-mailbox-cache.c b/src/doveadm/doveadm-mail-mailbox-cache.c index 12d6454e0e..cc36962f97 100644 --- a/src/doveadm/doveadm-mail-mailbox-cache.c +++ b/src/doveadm/doveadm-mail-mailbox-cache.c @@ -321,6 +321,73 @@ static void cmd_mailbox_cache_remove_init(struct doveadm_mail_cmd_context *_ctx, ctx->ctx.search_args = doveadm_mail_build_search_args(args); } +static int cmd_mailbox_cache_compress_run_box(struct mailbox_cache_cmd_context *ctx, + struct mailbox *box) +{ + struct mailbox_transaction_context *t = + mailbox_transaction_begin(box, + MAILBOX_TRANSACTION_FLAG_EXTERNAL, + "mailbox cache compress"); + struct mail_cache *cache = t->box->cache; + struct mail_cache_compress_lock *lock; + int ret = 0; + + if (mail_cache_open_and_verify(cache) < 0 || + MAIL_CACHE_IS_UNUSABLE(cache)) { + mailbox_transaction_rollback(&t); + i_error("Cache is unusable"); + ctx->ctx.exit_code = EX_TEMPFAIL; + return -1; + } + + cache->need_compress_file_seq = UINT_MAX; + if (mail_cache_compress_forced(cache, t->itrans, &lock) < 0) { + mailbox_set_index_error(t->box); + doveadm_mail_failed_mailbox(&ctx->ctx, box); + ret = -1; + } + + if (mailbox_transaction_commit(&t) < 0) { + i_error("mailbox_transaction_commit() failed: %s", + mailbox_get_last_internal_error(box, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, box); + ret = -1; + } + mail_cache_compress_unlock(&lock); + return ret; +} + +static int cmd_mailbox_cache_compress_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct mailbox_cache_cmd_context *ctx = + container_of(_ctx, struct mailbox_cache_cmd_context, ctx); + const char *const *boxname; + int ret = 0; + + if (_ctx->exit_code != 0) + return -1; + + for(boxname = ctx->boxes; ret == 0 && *boxname != NULL; boxname++) { + struct mailbox *box; + if ((ret = cmd_mailbox_cache_open_box(_ctx, user, *boxname, &box)) < 0) + break; + ret = cmd_mailbox_cache_compress_run_box(ctx, box); + mailbox_free(&box); + } + + return ret; +} + +static void cmd_mailbox_cache_compress_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct mailbox_cache_cmd_context *ctx = + container_of(_ctx, struct mailbox_cache_cmd_context, ctx); + + ctx->boxes = args; +} + static struct doveadm_mail_cmd_context *cmd_mailbox_cache_decision_alloc(void) { struct mailbox_cache_cmd_context *ctx = @@ -345,6 +412,17 @@ static struct doveadm_mail_cmd_context *cmd_mailbox_cache_remove_alloc(void) return &ctx->ctx; } +static struct doveadm_mail_cmd_context *cmd_mailbox_cache_compress_alloc(void) +{ + struct mailbox_cache_cmd_context *ctx = + doveadm_mail_cmd_alloc(struct mailbox_cache_cmd_context); + ctx->ctx.v.init = cmd_mailbox_cache_compress_init; + ctx->ctx.v.run = cmd_mailbox_cache_compress_run; + ctx->ctx.getopt_args = ""; + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); + return &ctx->ctx; +} + struct doveadm_cmd_ver2 doveadm_cmd_mailbox_cache_decision = { .name = "mailbox cache decision", .mail_cmd = cmd_mailbox_cache_decision_alloc, @@ -370,3 +448,13 @@ DOVEADM_CMD_MAIL_COMMON DOVEADM_CMD_PARAM('\0', "query", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL) DOVEADM_CMD_PARAMS_END }; + +struct doveadm_cmd_ver2 doveadm_cmd_mailbox_cache_compress = { + .name = "mailbox cache compress", + .mail_cmd = cmd_mailbox_cache_compress_alloc, + .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX" [...]", +DOVEADM_CMD_PARAMS_START +DOVEADM_CMD_MAIL_COMMON +DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL) +DOVEADM_CMD_PARAMS_END +}; diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index 2fccccb3a9..c73c7f61b6 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -923,6 +923,7 @@ static struct doveadm_cmd_ver2 *mail_commands_ver2[] = { &doveadm_cmd_move_ver2, &doveadm_cmd_mailbox_cache_decision, &doveadm_cmd_mailbox_cache_remove, + &doveadm_cmd_mailbox_cache_compress, &doveadm_cmd_rebuild_attachments, }; diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h index 16ebcc8828..cbf533b532 100644 --- a/src/doveadm/doveadm-mail.h +++ b/src/doveadm/doveadm-mail.h @@ -197,6 +197,7 @@ extern struct doveadm_cmd_ver2 doveadm_cmd_mailbox_update_ver2; extern struct doveadm_cmd_ver2 doveadm_cmd_mailbox_path_ver2; extern struct doveadm_cmd_ver2 doveadm_cmd_mailbox_cache_decision; extern struct doveadm_cmd_ver2 doveadm_cmd_mailbox_cache_remove; +extern struct doveadm_cmd_ver2 doveadm_cmd_mailbox_cache_compress; extern struct doveadm_cmd_ver2 doveadm_cmd_rebuild_attachments; #define DOVEADM_CMD_MAIL_COMMON \