]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm replicator status: Without <usermask> parameter show overview status.
authorTimo Sirainen <tss@iki.fi>
Sun, 24 Mar 2013 16:14:11 +0000 (18:14 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 24 Mar 2013 16:14:11 +0000 (18:14 +0200)
src/doveadm/doveadm-replicator.c
src/replication/replicator/doveadm-connection.c
src/replication/replicator/replicator-queue.c
src/replication/replicator/replicator-queue.h

index c17873d9ed69dd91747cc407c7abd2b7162c3af7..6c0038d710726ab4bc89784712fc01a8684ff039 100644 (file)
@@ -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;
index a54f743b4d787961654368d9df0f4f9547932bea..1884e7e715070c2d6e4e38c55b5798a9c4a6ea4c 100644 (file)
@@ -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);
index c2d58fc6455c0cea96da13cb7a78ac9ebce088de..5547abe5ce37424c37ce4d0324b94456eba9004d 100644 (file)
@@ -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;
        }
index e14df1753395fc2c57e799fe014b4ad7c44186a8..a93114bc4882154f26a153ff74b14e7a2a966f9b 100644 (file)
@@ -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,