doveadm-instance.c revision d47a87c927ca77e780480f4eaf575511698d42c8
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include "lib.h"
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include "master-instance.h"
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include "doveadm.h"
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include "doveadm-print.h"
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include <unistd.h>
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include <fcntl.h>
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen#include <signal.h>
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenextern struct doveadm_cmd doveadm_cmd_instance[];
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenstatic void instance_cmd_help(doveadm_command_t *cmd) ATTR_NORETURN;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenstatic bool pid_file_read(const char *path)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen{
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen char buf[32];
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen int fd;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen ssize_t ret;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen pid_t pid;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen bool found = FALSE;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen fd = open(path, O_RDONLY);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (fd == -1) {
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (errno != ENOENT)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen i_error("open(%s) failed: %m", path);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen return FALSE;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen }
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen ret = read(fd, buf, sizeof(buf));
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (ret < 0)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen i_error("read(%s) failed: %m", path);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen else if (ret > 0 && buf[ret-1] == '\n') {
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen buf[ret-1] = '\0';
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (str_to_pid(buf, &pid) == 0) {
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen found = !(pid == getpid() ||
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen (kill(pid, 0) < 0 && errno == ESRCH));
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen }
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen }
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen (void)close(fd);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen return found;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen}
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenstatic void cmd_instance_list(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen{
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen struct master_instance_list *list;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen struct master_instance_list_iter *iter;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen const struct master_instance *inst;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen const char *pidfile_path;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print_header("path", "path", DOVEADM_PRINT_HEADER_FLAG_EXPAND);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print_header_simple("name");
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print_header_simple("running");
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen list = master_instance_list_init(MASTER_INSTANCE_PATH);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen iter = master_instance_list_iterate_init(list);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen while ((inst = master_instance_iterate_list_next(iter)) != NULL) {
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print(inst->base_dir);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print(inst->name);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen pidfile_path = t_strconcat(inst->base_dir, "/master.pid", NULL);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (pid_file_read(pidfile_path))
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print("yes");
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen else
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_print("no");
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen }
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen master_instance_iterate_list_deinit(&iter);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen master_instance_list_deinit(&list);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen}
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenstatic void cmd_instance_remove(int argc, char *argv[])
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen{
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen struct master_instance_list *list;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen int ret;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (argc != 2)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen instance_cmd_help(cmd_instance_remove);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen list = master_instance_list_init(MASTER_INSTANCE_PATH);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if ((ret = master_instance_list_remove(list, argv[1])) < 0)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen i_error("Failed to remove instance");
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen else if (ret == 0)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen i_error("Instance already didn't exist");
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen master_instance_list_deinit(&list);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen}
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenstruct doveadm_cmd doveadm_cmd_instance[] = {
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen { cmd_instance_list, "instance list", "" },
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen { cmd_instance_remove, "instance remove", "<base dir>" }
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen};
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenstatic void instance_cmd_help(doveadm_command_t *cmd)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen{
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen unsigned int i;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_instance); i++) {
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen if (doveadm_cmd_instance[i].cmd == cmd)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen help(&doveadm_cmd_instance[i]);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen }
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen i_unreached();
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen}
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainenvoid doveadm_register_instance_commands(void)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen{
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen unsigned int i;
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_instance); i++)
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen doveadm_register_cmd(&doveadm_cmd_instance[i]);
d47a87c927ca77e780480f4eaf575511698d42c8Timo Sirainen}