From: Karl Fleischmann Date: Fri, 7 Mar 2025 09:02:22 +0000 (+0100) Subject: lib-imap, imap: Load and restore logout statistics when creating a client X-Git-Tag: 2.4.1~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3d415cf2dd393e1b4ad6e2be1a06bb221406509f;p=thirdparty%2Fdovecot%2Fcore.git lib-imap, imap: Load and restore logout statistics when creating a client --- diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c index e79082329a..ade5d250ea 100644 --- a/src/imap/imap-client-hibernate.c +++ b/src/imap/imap-client-hibernate.c @@ -3,6 +3,7 @@ #include "imap-common.h" #include "fdpass.h" #include "net.h" +#include "istream.h" #include "ostream.h" #include "write-full.h" #include "base64.h" @@ -116,6 +117,27 @@ static void imap_hibernate_write_cmd(struct client *client, string_t *cmd, str_append(cmd, "\tnotify_fd"); str_append(cmd, "\tstate="); base64_encode(state->data, state->used, cmd); + + /* For imap_logout_format statistics: */ + str_printfa(cmd, + "\tfetch_hdr_count=%u\tfetch_hdr_bytes=%"PRIu64 + "\tfetch_body_count=%u\tfetch_body_bytes=%"PRIu64 + "\tdeleted_count=%u\texpunged_count=%u\ttrashed_count=%u" + "\tautoexpunged_count=%u\tappend_count=%u" + "\tinput_bytes_extra=%"PRIuUOFF_T + "\toutput_bytes_extra=%"PRIuUOFF_T, + client->logout_stats.fetch_hdr_count, + client->logout_stats.fetch_hdr_bytes, + client->logout_stats.fetch_body_count, + client->logout_stats.fetch_body_bytes, + client->logout_stats.deleted_count, + client->logout_stats.expunged_count, + client->logout_stats.trashed_count, + client->logout_stats.autoexpunged_count, + client->logout_stats.append_count, + i_stream_get_absolute_offset(client->input) + client->logout_stats.input_bytes_extra, + client->output->offset + client->logout_stats.output_bytes_extra); + str_append_c(cmd, '\n'); } diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index 1ec8400bc4..b21ede6cee 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -309,8 +309,8 @@ void client_command_cancel(struct client_command_context **_cmd) const char *client_stats(struct client *client) { const struct var_expand_table logout_tab[] = { - { .key = "input", .value = dec2str(i_stream_get_absolute_offset(client->input)) }, - { .key = "output", .value = dec2str(client->output->offset) }, + { .key = "input", .value = dec2str(i_stream_get_absolute_offset(client->input) + client->logout_stats.input_bytes_extra) }, + { .key = "output", .value = dec2str(client->output->offset + client->logout_stats.output_bytes_extra) }, { .key = "session", .value = client->user->session_id }, { .key = "fetch_hdr_count", .value = dec2str(client->logout_stats.fetch_hdr_count) }, { .key = "fetch_hdr_bytes", .value = dec2str(client->logout_stats.fetch_hdr_bytes) }, diff --git a/src/imap/imap-common.h b/src/imap/imap-common.h index 438616ded2..4cb236799b 100644 --- a/src/imap/imap-common.h +++ b/src/imap/imap-common.h @@ -34,6 +34,7 @@ void imap_refresh_proctitle(void); void imap_refresh_proctitle_delayed(void); int client_create_from_input(const struct mail_storage_service_input *input, + const struct imap_logout_stats *stats, int fd_in, int fd_out, enum client_create_flags flags, struct client **client_r, const char **error_r); diff --git a/src/imap/imap-master-client.c b/src/imap/imap-master-client.c index 6e98369733..b531d74f44 100644 --- a/src/imap/imap-master-client.c +++ b/src/imap/imap-master-client.c @@ -9,6 +9,7 @@ #include "str.h" #include "strescape.h" #include "str-sanitize.h" +#include "strnum.h" #include "time-util.h" #include "process-title.h" #include "master-service.h" @@ -58,6 +59,7 @@ static int imap_master_client_parse_input(const char *const *args, pool_t pool, enum client_create_flags *create_flags, struct mail_storage_service_input *input_r, + struct imap_logout_stats *stats_r, struct imap_master_input *master_input_r, const char **error_r) { @@ -65,6 +67,7 @@ imap_master_client_parse_input(const char *const *args, pool_t pool, unsigned int peer_dev_major = 0, peer_dev_minor = 0; i_zero(input_r); + i_zero(stats_r); i_zero(master_input_r); master_input_r->client_input = buffer_create_dynamic(pool, 64); master_input_r->client_output = buffer_create_dynamic(pool, 16); @@ -177,6 +180,72 @@ imap_master_client_parse_input(const char *const *args, pool_t pool, master_input_r->state_import_bad_idle_done = TRUE; } else if (strcmp(key, "idle-continue") == 0) { master_input_r->state_import_idle_continue = TRUE; + } else if (strcmp(key, "fetch_hdr_count") == 0) { + if (str_to_uint(value, &stats_r->fetch_hdr_count) < 0) { + *error_r = t_strdup_printf( + "Invalid fetch_hdr_count value: %s", value); + return -1; + } + } else if (strcmp(key, "fetch_hdr_bytes") == 0) { + if (str_to_uint64(value, &stats_r->fetch_hdr_bytes) < 0) { + *error_r = t_strdup_printf( + "Invalid fetch_hdr_bytes value: %s", value); + return -1; + } + } else if (strcmp(key, "fetch_body_count") == 0) { + if (str_to_uint(value, &stats_r->fetch_body_count) < 0) { + *error_r = t_strdup_printf( + "Invalid fetch_body_count value: %s", value); + return -1; + } + } else if (strcmp(key, "fetch_body_bytes") == 0) { + if (str_to_uint64(value, &stats_r->fetch_body_bytes) < 0) { + *error_r = t_strdup_printf( + "Invalid fetch_body_bytes value: %s", value); + return -1; + } + } else if (strcmp(key, "deleted_count") == 0) { + if (str_to_uint(value, &stats_r->deleted_count) < 0) { + *error_r = t_strdup_printf( + "Invalid deleted_count value: %s", value); + return -1; + } + } else if (strcmp(key, "expunged_count") == 0) { + if (str_to_uint(value, &stats_r->expunged_count) < 0) { + *error_r = t_strdup_printf( + "Invalid expunged_count value: %s", value); + return -1; + } + } else if (strcmp(key, "trashed_count") == 0) { + if (str_to_uint(value, &stats_r->trashed_count) < 0) { + *error_r = t_strdup_printf( + "Invalid trashed_count value: %s", value); + return -1; + } + } else if (strcmp(key, "autoexpunged_count") == 0) { + if (str_to_uint(value, &stats_r->autoexpunged_count) < 0) { + *error_r = t_strdup_printf( + "Invalid autoexpunged_count value: %s", value); + return -1; + } + } else if (strcmp(key, "append_count") == 0) { + if (str_to_uint(value, &stats_r->append_count) < 0) { + *error_r = t_strdup_printf( + "Invalid append_count value: %s", value); + return -1; + } + } else if (strcmp(key, "input_bytes_extra") == 0) { + if (str_to_uoff(value, &stats_r->input_bytes_extra) < 0) { + *error_r = t_strdup_printf( + "Invalid input_bytes_extra value: %s", value); + return -1; + } + } else if (strcmp(key, "output_bytes_extra") == 0) { + if (str_to_uoff(value, &stats_r->output_bytes_extra) < 0) { + *error_r = t_strdup_printf( + "Invalid output_bytes_extra value: %s", value); + return -1; + } } } if (peer_dev_major != 0 || peer_dev_minor != 0) { @@ -222,12 +291,13 @@ imap_master_client_input_args(struct connection *conn, const char *const *args, struct client *imap_client; enum client_create_flags create_flags = CLIENT_CREATE_FLAG_UNHIBERNATED; struct mail_storage_service_input input; + struct imap_logout_stats stats; struct imap_master_input master_input; const char *error = NULL, *reason; int ret; if (imap_master_client_parse_input(args, pool, &create_flags, - &input, &master_input, &error) < 0) { + &input, &stats, &master_input, &error) < 0) { e_error(conn->event, "imap-master: Failed to parse client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to parse client input: %s\n", error)); @@ -245,7 +315,7 @@ imap_master_client_input_args(struct connection *conn, const char *const *args, /* NOTE: before client_create_from_input() on failures we need to close fd_client, but afterward it gets closed by client_destroy() */ - ret = client_create_from_input(&input, fd_client, fd_client, + ret = client_create_from_input(&input, &stats, fd_client, fd_client, create_flags, &imap_client, &error); if (ret < 0) { e_error(conn->event, diff --git a/src/imap/main.c b/src/imap/main.c index fa2fbe309e..757b31e3b5 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -244,6 +244,7 @@ client_add_input_finalize(struct client *client) } int client_create_from_input(const struct mail_storage_service_input *input, + const struct imap_logout_stats *stats, int fd_in, int fd_out, enum client_create_flags flags, struct client **client_r, const char **error_r) @@ -299,6 +300,9 @@ int client_create_from_input(const struct mail_storage_service_input *input, event, mail_user, imap_set, smtp_set); client->userdb_fields = input->userdb_fields == NULL ? NULL : p_strarray_dup(client->pool, input->userdb_fields); + /* For imap_logout_format statistics: */ + if (stats != NULL) + client->logout_stats = *stats; event_unref(&event); *client_r = client; return 0; @@ -323,7 +327,7 @@ static void main_stdio_run(const char *username) if ((value = getenv("LOCAL_IP")) != NULL) (void)net_addr2ip(value, &input.local_ip); - if (client_create_from_input(&input, STDIN_FILENO, STDOUT_FILENO, + if (client_create_from_input(&input, NULL, STDIN_FILENO, STDOUT_FILENO, 0, &client, &error) < 0) i_fatal("%s", error); @@ -383,7 +387,7 @@ login_request_finished(const struct login_server_request *request, request->auth_req.data_size, &imap_request); - if (client_create_from_input(&input, request->fd, request->fd, + if (client_create_from_input(&input, NULL, request->fd, request->fd, create_flags, &client, &error) < 0) { int fd = request->fd; struct ostream *output = diff --git a/src/imap/test-imap-client-hibernate.c b/src/imap/test-imap-client-hibernate.c index 9f080ae595..9f9eacaa58 100644 --- a/src/imap/test-imap-client-hibernate.c +++ b/src/imap/test-imap-client-hibernate.c @@ -39,6 +39,7 @@ static struct mail_storage_service_ctx *storage_service; void imap_refresh_proctitle(void) { } void imap_refresh_proctitle_delayed(void) { } int client_create_from_input(const struct mail_storage_service_input *input ATTR_UNUSED, + const struct imap_logout_stats *stats ATTR_UNUSED, int fd_in ATTR_UNUSED, int fd_out ATTR_UNUSED, enum client_create_flags flags ATTR_UNUSED, struct client **client_r ATTR_UNUSED, diff --git a/src/lib-imap/imap-stats.h b/src/lib-imap/imap-stats.h index 9cda562efc..c70ba9860b 100644 --- a/src/lib-imap/imap-stats.h +++ b/src/lib-imap/imap-stats.h @@ -7,6 +7,7 @@ struct imap_logout_stats { uint64_t fetch_hdr_bytes, fetch_body_bytes; unsigned int deleted_count, expunged_count, trashed_count; unsigned int autoexpunged_count, append_count; + uoff_t input_bytes_extra, output_bytes_extra; }; #endif /* IMAP_STATS_H */