From: Timo Sirainen Date: Sun, 24 Mar 2013 16:14:11 +0000 (+0200) Subject: doveadm replicator status: Without parameter show overview status. X-Git-Tag: 2.2.rc4~77 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5ca40db1f869421fc3798a304ad402834250ff50;p=thirdparty%2Fdovecot%2Fcore.git doveadm replicator status: Without parameter show overview status. --- diff --git a/src/doveadm/doveadm-replicator.c b/src/doveadm/doveadm-replicator.c index c17873d9ed..6c0038d710 100644 --- a/src/doveadm/doveadm-replicator.c +++ b/src/doveadm/doveadm-replicator.c @@ -105,6 +105,31 @@ static const char *time_ago(time_t t) return t_strdup_printf("%02d:%02d:%02d", diff/3600, diff/60, diff%60); } +static void cmd_replicator_status_overview(struct replicator_context *ctx) +{ + char *line, *value; + + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); + doveadm_print_header("field", "field", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); + doveadm_print_header("value", "value", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); + + replicator_send(ctx, "STATUS\n"); + while ((line = i_stream_read_next_line(ctx->input)) != NULL) { + if (*line == '\0') + break; + value = strchr(line, '\t'); + if (value != NULL) + *value++ = '\0'; + else + value = ""; + doveadm_print(line); + doveadm_print(value); + } + replicator_disconnect(ctx); +} + static void cmd_replicator_status(int argc, char *argv[]) { struct replicator_context *ctx; @@ -113,6 +138,11 @@ static void cmd_replicator_status(int argc, char *argv[]) ctx = cmd_replicator_init(argc, argv, "a:", cmd_replicator_status); + if (argv[1] == NULL) { + cmd_replicator_status_overview(ctx); + return; + } + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); doveadm_print_header("username", "username", DOVEADM_PRINT_HEADER_FLAG_EXPAND); @@ -121,12 +151,8 @@ static void cmd_replicator_status(int argc, char *argv[]) doveadm_print_header_simple("full sync"); doveadm_print_header_simple("failed"); - if (argv[1] == NULL) - replicator_send(ctx, "STATUS\n"); - else { - replicator_send(ctx, t_strdup_printf("STATUS\t%s\n", - str_tabescape(argv[1]))); - } + replicator_send(ctx, t_strdup_printf("STATUS\t%s\n", + str_tabescape(argv[1]))); while ((line = i_stream_read_next_line(ctx->input)) != NULL) { if (*line == '\0') break; diff --git a/src/replication/replicator/doveadm-connection.c b/src/replication/replicator/doveadm-connection.c index a54f743b4d..1884e7e715 100644 --- a/src/replication/replicator/doveadm-connection.c +++ b/src/replication/replicator/doveadm-connection.c @@ -21,6 +21,52 @@ struct doveadm_connection { }; static struct connection_list *doveadm_connections; +static int client_input_status_overview(struct doveadm_connection *client) +{ + struct replicator_user *const *users; + enum replication_priority priority; + unsigned int pending_counts[REPLICATION_PRIORITY_SYNC+1]; + unsigned int i, count, next_secs, pending_failed_count; + unsigned int pending_full_resync_count, waiting_failed_count; + string_t *str = t_str_new(256); + + memset(pending_counts, 0, sizeof(pending_counts)); + pending_failed_count = 0; waiting_failed_count = 0; + pending_full_resync_count = 0; + + users = replicator_queue_get_users(client->queue, &count); + for (i = 0; i < count; i++) { + if (users[i]->priority != REPLICATION_PRIORITY_NONE) + pending_counts[users[i]->priority]++; + else if (replicator_queue_want_sync_now(client->queue, + users[i], &next_secs)) { + if (users[i]->last_sync_failed) + pending_failed_count++; + else + pending_full_resync_count++; + } else { + if (users[i]->last_sync_failed) + waiting_failed_count++; + } + } + + for (priority = REPLICATION_PRIORITY_SYNC; priority > 0; priority--) { + str_printfa(str, "Queued '%s' requests\t%u\n", + replicator_priority_to_str(priority), + pending_counts[priority]); + } + str_printfa(str, "Queued 'failed' requests\t%u\n", + pending_failed_count); + str_printfa(str, "Queued 'full resync' requests\t%u\n", + pending_full_resync_count); + str_printfa(str, "Waiting 'failed' requests\t%u\n", + waiting_failed_count); + str_printfa(str, "Total number of known users\t%u\n", count); + str_append_c(str, '\n'); + o_stream_send(client->conn.output, str_data(str), str_len(str)); + return 0; +} + static int client_input_status(struct doveadm_connection *client, const char *const *args) { @@ -29,10 +75,13 @@ client_input_status(struct doveadm_connection *client, const char *const *args) const char *mask = args[0]; string_t *str = t_str_new(128); + if (mask == NULL) + return client_input_status_overview(client); + users = replicator_queue_get_users(client->queue, &count); for (i = 0; i < count; i++) { user = users[i]; - if (mask != NULL && !wildcard_match(user->username, mask)) + if (!wildcard_match(user->username, mask)) continue; str_truncate(str, 0); diff --git a/src/replication/replicator/replicator-queue.c b/src/replication/replicator/replicator-queue.c index c2d58fc645..5547abe5ce 100644 --- a/src/replication/replicator/replicator-queue.c +++ b/src/replication/replicator/replicator-queue.c @@ -198,10 +198,9 @@ void replicator_queue_remove(struct replicator_queue *queue, queue->change_callback(queue->change_context); } -static bool -replicator_queue_can_sync_now(struct replicator_queue *queue, - struct replicator_user *user, - unsigned int *next_secs_r) +bool replicator_queue_want_sync_now(struct replicator_queue *queue, + struct replicator_user *user, + unsigned int *next_secs_r) { time_t next_sync; @@ -235,7 +234,7 @@ replicator_queue_pop(struct replicator_queue *queue, return NULL; } user = (struct replicator_user *)item; - if (!replicator_queue_can_sync_now(queue, user, next_secs_r)) { + if (!replicator_queue_want_sync_now(queue, user, next_secs_r)) { /* we don't want to sync the user yet */ return NULL; } diff --git a/src/replication/replicator/replicator-queue.h b/src/replication/replicator/replicator-queue.h index e14df17533..a93114bc48 100644 --- a/src/replication/replicator/replicator-queue.h +++ b/src/replication/replicator/replicator-queue.h @@ -61,6 +61,11 @@ void replicator_queue_push(struct replicator_queue *queue, int replicator_queue_import(struct replicator_queue *queue, const char *path); int replicator_queue_export(struct replicator_queue *queue, const char *path); +/* Returns TRUE if user replication can be started now, FALSE if not. When + returning FALSE, next_secs_r is set to user's next replication time. */ +bool replicator_queue_want_sync_now(struct replicator_queue *queue, + struct replicator_user *user, + unsigned int *next_secs_r); /* Returns an (unsorted) array of all users in the queue. */ struct replicator_user *const * replicator_queue_get_users(struct replicator_queue *queue,