]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added "doveadm process status"
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 20 Oct 2016 10:30:36 +0000 (13:30 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 20 Oct 2016 20:04:41 +0000 (23:04 +0300)
This allows asking for processes' current status in master process.

src/doveadm/doveadm-cmd.c
src/doveadm/doveadm-cmd.h
src/doveadm/doveadm-master.c
src/master/master-client.c

index 7d50bcf141dcf0a4179fa53748b879f1c8b61067..b21d4322f7620dfdb034663515d1c0668254694b 100644 (file)
@@ -21,6 +21,7 @@ static struct doveadm_cmd *doveadm_commands[] = {
 static struct doveadm_cmd_ver2 *doveadm_commands_ver2[] = {
        &doveadm_cmd_service_stop_ver2,
        &doveadm_cmd_service_status_ver2,
+       &doveadm_cmd_process_status_ver2,
        &doveadm_cmd_stop_ver2,
        &doveadm_cmd_reload_ver2,
        &doveadm_cmd_stats_dump_ver2,
index f3c7796c3e3294bfc5651c443e5f27c6b61be83f..9f226ef8c3609688ed4750a3e3c145b4be6442d4 100644 (file)
@@ -150,6 +150,7 @@ void doveadm_cmd_params_null_terminate_arrays(ARRAY_TYPE(doveadm_cmd_param_arr_t
 
 extern struct doveadm_cmd_ver2 doveadm_cmd_service_stop_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_service_status_ver2;
+extern struct doveadm_cmd_ver2 doveadm_cmd_process_status_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_stop_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_reload_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_stats_reset_ver2;
index ecf3ed3261e90ed405f8ece8432956b318de61aa..1ff76f381abed2a5c984a50043f828143a53db79 100644 (file)
@@ -194,6 +194,46 @@ static void cmd_service_status(struct doveadm_cmd_context *cctx)
        i_stream_destroy(&input);
 }
 
+static void cmd_process_status(struct doveadm_cmd_context *cctx)
+{
+       const char *line, *const *services;
+
+       if (!doveadm_cmd_param_array(cctx, "service", &services))
+               services = NULL;
+
+       struct istream *input =
+               master_service_send_cmd_with_args("PROCESS-STATUS", services);
+
+       doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
+       doveadm_print_header_simple("name");
+       doveadm_print_header_simple("pid");
+       doveadm_print_header_simple("available_count");
+       doveadm_print_header_simple("total_count");
+       doveadm_print_header_simple("idle_start");
+       doveadm_print_header_simple("last_status_update");
+       doveadm_print_header_simple("last_kill_sent");
+
+       alarm(5);
+       while ((line = i_stream_read_next_line(input)) != NULL) {
+               if (line[0] == '\0')
+                       break;
+               T_BEGIN {
+                       const char *const *args = t_strsplit_tabescaped(line);
+                       if (str_array_length(args) >= 7) {
+                               for (unsigned int i = 0; i < 7; i++)
+                                       doveadm_print(args[i]);
+                       }
+               } T_END;
+       }
+       if (line == NULL) {
+               i_error("read(%s) failed: %s", i_stream_get_name(input),
+                       i_stream_get_error(input));
+               doveadm_exit_code = EX_TEMPFAIL;
+       }
+       alarm(0);
+       i_stream_destroy(&input);
+}
+
 struct doveadm_cmd_ver2 doveadm_cmd_stop_ver2 = {
        .old_cmd = cmd_stop,
        .name = "stop",
@@ -227,3 +267,12 @@ DOVEADM_CMD_PARAMS_START
 DOVEADM_CMD_PARAM('\0', "service", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAMS_END
 };
+
+struct doveadm_cmd_ver2 doveadm_cmd_process_status_ver2 = {
+       .cmd = cmd_process_status,
+       .name = "process status",
+       .usage = "[<service> [...]]",
+DOVEADM_CMD_PARAMS_START
+DOVEADM_CMD_PARAM('\0', "service", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
+DOVEADM_CMD_PARAMS_END
+};
index 64d9872229374a4f0a85792ea8864f43dd71b70c..3b1eb0199bfbd01f806818be51c3609e58bc99e6 100644 (file)
@@ -7,6 +7,7 @@
 #include "ostream.h"
 #include "connection.h"
 #include "service.h"
+#include "service-process.h"
 #include "service-monitor.h"
 #include "master-client.h"
 
@@ -45,6 +46,40 @@ master_client_service_status(struct master_client *client)
        return 1;
 }
 
+static void
+master_client_process_output(string_t *str,
+                            const struct service_process *process)
+{
+       str_append_tabescaped(str, process->service->set->name);
+       str_printfa(str, "\t%ld\t%u\t%u\t%ld\t%ld\t%ld\n",
+                   (long)process->pid, process->available_count,
+                   process->total_count, (long)process->idle_start,
+                   (long)process->last_status_update,
+                   (long)process->last_kill_sent);
+}
+
+static int
+master_client_process_status(struct master_client *client,
+                            const char *const *args)
+{
+       struct service *const *servicep;
+       struct service_process *p;
+       string_t *str = t_str_new(128);
+
+       array_foreach(&services->services, servicep) {
+               if (args[0] != NULL && !str_array_find(args, (*servicep)->set->name))
+                       continue;
+               str_truncate(str, 0);
+               for (p = (*servicep)->processes; p != NULL; p = p->next) {
+                       master_client_process_output(str, p);
+                       o_stream_nsend(client->conn.output,
+                                      str_data(str), str_len(str));
+               }
+       }
+       o_stream_nsend_str(client->conn.output, "\n");
+       return 1;
+}
+
 static int
 master_client_stop(struct master_client *client, const char *const *args)
 {
@@ -76,6 +111,8 @@ master_client_input_args(struct connection *conn, const char *const *args)
 
        if (strcmp(cmd, "SERVICE-STATUS") == 0)
                return master_client_service_status(client);
+       if (strcmp(cmd, "PROCESS-STATUS") == 0)
+               return master_client_process_status(client, args);
        if (strcmp(cmd, "STOP") == 0)
                return master_client_stop(client, args);
        i_error("%s: Unknown command: %s", conn->name, cmd);