]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added "doveadm service status"
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 20 Oct 2016 10:12:34 +0000 (13:12 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 20 Oct 2016 20:04:41 +0000 (23:04 +0300)
This allows asking for services' 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 3c2da477bc463d74a2be32b28631d77efb716b62..7d50bcf141dcf0a4179fa53748b879f1c8b61067 100644 (file)
@@ -20,6 +20,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_stop_ver2,
        &doveadm_cmd_reload_ver2,
        &doveadm_cmd_stats_dump_ver2,
index ec54f414139cbb9e005e9345c8801191cdfafac8..f3c7796c3e3294bfc5651c443e5f27c6b61be83f 100644 (file)
@@ -149,6 +149,7 @@ void doveadm_cmd_params_clean(ARRAY_TYPE(doveadm_cmd_param_arr_t) *pargv);
 void doveadm_cmd_params_null_terminate_arrays(ARRAY_TYPE(doveadm_cmd_param_arr_t) *pargv);
 
 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_stop_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_reload_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_stats_reset_ver2;
index 06802a942693d81dab4ad93c12ef662e3e5b2384..ecf3ed3261e90ed405f8ece8432956b318de61aa 100644 (file)
@@ -6,6 +6,7 @@
 #include "istream.h"
 #include "write-full.h"
 #include "doveadm.h"
+#include "doveadm-print.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -148,6 +149,51 @@ static void cmd_service_stop(struct doveadm_cmd_context *cctx)
        i_stream_destroy(&input);
 }
 
+static void cmd_service_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("SERVICE-STATUS");
+
+       doveadm_print_init("pager");
+       doveadm_print_header_simple("name");
+       doveadm_print_header_simple("process_count");
+       doveadm_print_header_simple("process_avail");
+       doveadm_print_header_simple("process_limit");
+       doveadm_print_header_simple("client_limit");
+       doveadm_print_header_simple("throttle_secs");
+       doveadm_print_header_simple("exit_failure_last");
+       doveadm_print_header_simple("exit_failures_in_sec");
+       doveadm_print_header_simple("last_drop_warning");
+       doveadm_print_header_simple("listen_pending");
+       doveadm_print_header_simple("listening");
+
+       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) >= 11 &&
+                           (services == NULL ||
+                            str_array_find(services, args[0]))) {
+                               for (unsigned int i = 0; i < 11; 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",
@@ -172,3 +218,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_service_status_ver2 = {
+       .cmd = cmd_service_status,
+       .name = "service status",
+       .usage = "[<service> [...]]",
+DOVEADM_CMD_PARAMS_START
+DOVEADM_CMD_PARAM('\0', "service", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
+DOVEADM_CMD_PARAMS_END
+};
index 32cfbc3eb4f9714bbf106f89a9694ba7ef1528e1..64d9872229374a4f0a85792ea8864f43dd71b70c 100644 (file)
@@ -1,6 +1,9 @@
 /* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
 
 #include "common.h"
+#include "array.h"
+#include "str.h"
+#include "strescape.h"
 #include "ostream.h"
 #include "connection.h"
 #include "service.h"
@@ -11,6 +14,37 @@ struct master_client {
        struct connection conn;
 };
 
+static void
+master_client_service_status_output(string_t *str,
+                                   const struct service *service)
+{
+       str_append_tabescaped(str, service->set->name);
+       str_printfa(str, "\t%u\t%u\t%u\t%u\t%u\t%ld\t%u\t%ld\t%c\t%c\n",
+                   service->process_count, service->process_avail,
+                   service->process_limit, service->client_limit,
+                   service->to_throttle == NULL ? 0 : service->throttle_secs,
+                   (long)service->exit_failure_last,
+                   service->exit_failures_in_sec,
+                   (long)service->last_drop_warning,
+                   service->listen_pending ? 'y' : 'n',
+                   service->listening ? 'y' : 'n');
+}
+
+static int
+master_client_service_status(struct master_client *client)
+{
+       struct service *const *servicep;
+       string_t *str = t_str_new(128);
+
+       array_foreach(&services->services, servicep) {
+               str_truncate(str, 0);
+               master_client_service_status_output(str, *servicep);
+               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)
 {
@@ -40,6 +74,8 @@ master_client_input_args(struct connection *conn, const char *const *args)
        }
        args++;
 
+       if (strcmp(cmd, "SERVICE-STATUS") == 0)
+               return master_client_service_status(client);
        if (strcmp(cmd, "STOP") == 0)
                return master_client_stop(client, args);
        i_error("%s: Unknown command: %s", conn->name, cmd);