doveadm-master.c revision bf333c7645b8ddb6eedd6834db2fd908888793e1
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include "lib.h"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include "doveadm.h"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include <unistd.h>
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include <fcntl.h>
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include <signal.h>
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#define MASTER_PID_FILE_NAME "master.pid"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic bool pid_file_read(const char *path, pid_t *pid_r)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen char buf[32];
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen int fd;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen ssize_t ret;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen bool found;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen fd = open(path, O_RDONLY);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (fd == -1) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (errno == ENOENT)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen return FALSE;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("open(%s) failed: %m", path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen ret = read(fd, buf, sizeof(buf));
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (ret <= 0) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (ret == 0)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_error("Empty PID file in %s", path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen else
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("read(%s) failed: %m", path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen found = FALSE;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen } else {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (buf[ret-1] == '\n')
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen ret--;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen buf[ret] = '\0';
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (str_to_pid(buf, pid_r) < 0)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen found = FALSE;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen else {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen found = !(*pid_r == getpid() ||
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen (kill(*pid_r, 0) < 0 && errno == ESRCH));
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen (void)close(fd);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen return found;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenvoid doveadm_master_send_signal(int signo)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen const char *pidfile_path;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen unsigned int i;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen pid_t pid;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen pidfile_path = t_strconcat(doveadm_settings->base_dir,
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen "/"MASTER_PID_FILE_NAME, NULL);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (!pid_file_read(pidfile_path, &pid))
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("Dovecot is not running (read from %s)", pidfile_path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (kill(pid, signo) < 0)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("kill(%s, %d) failed: %m", dec2str(pid), signo);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (signo == SIGTERM) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen /* wait for a while for the process to die */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen usleep(1000);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen for (i = 0; i < 30; i++) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (kill(pid, 0) < 0) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (errno != ESRCH)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_error("kill() failed: %m");
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen break;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen usleep(100000);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic void cmd_stop(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen doveadm_master_send_signal(SIGTERM);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic void cmd_reload(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen doveadm_master_send_signal(SIGHUP);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstruct doveadm_cmd doveadm_cmd_stop = {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen cmd_stop, "stop", "", NULL
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen};
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstruct doveadm_cmd doveadm_cmd_reload = {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen cmd_reload, "reload", "", NULL
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen};