This allows asking for processes' current status in master process.
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,
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;
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",
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
+};
#include "ostream.h"
#include "connection.h"
#include "service.h"
+#include "service-process.h"
#include "service-monitor.h"
#include "master-client.h"
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)
{
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);