当前位置: 首页 > 工具软件 > Postfix > 使用案例 >

postfix master

惠翰藻
2023-12-01

 

--------src/master

 

typedef struct {

    char   *program; /* postfix */

    int     major; /* 2 */

    int     minor; /* 9 */

    int     patch; /* null */

    char   *snapshot; /* 20111209-nonprod */

} MAIL_VERSION;

 

 

进入master.cmain函数:

定义了相关的变量,postfix提供了相关的锁机制,

  static VSTREAM *lock_fp;

    static VSTREAM *data_lock_fp;

    VSTRING *lock_path;

    VSTRING *data_lock_path;

    off_t   inherited_limit;

    int     debug_me = 0;

    int     ch;

    int     fd;

    int     n;

    int     test_lock = 0;

    VSTRING *why;

    WATCHDOG *watchdog;

    ARGV   *import_env;

    int     wait_flag = 0;

    int     monitor_fd = -1;

 

    /*

     * Fingerprint executables and core dumps.

     */

检验版本

    MAIL_VERSION_STAMP_ALLOCATE;

 

    /*

     * Initialize.

     */

设置执行权限,只有用户有执行权限

    umask(077); /* never fails! */

 

//根据获取的环境变量,定义msg_verbosedebug_me的值,在后续的模块中会有相关的判断。

   if (getenv(CONF_ENV_VERB))

msg_verbose = 1;

    if (getenv(CONF_ENV_DEBUG))

debug_me = 1;

 

 

  /*

     * Don't die when a process goes away unexpectedly.

     */

为了避免进程退出,忽略SIGPIPE信号。

signal(SIGPIPE, SIG_IGN);

 

保存进程名称,调用basename()函数获取可执行文件名称,

然后将其复制到var_procname.

  /*

     * Strip and save the process name for diagnostics etc.

     */

var_procname = mystrdup(basename(argv[0]));

 

 

关闭文件描述符大于等于3的值

     */

    closefrom(3);

 

 

初始化日志,发送消息到系统日志。Openlog打开系统调试文件。

    /*

     * Initialize logging and exit handler.

     */

    msg_syslog_init(mail_task(var_procname), LOG_PID, LOG_FACILITY);

 

 

 

    /*

     * Check the Postfix library version as soon as we enable logging.

     */

    MAIL_VERSION_CHECK;

 

邮件系统必须要 root用户选择和操作,uid == o

    /*

     * The mail system must be run by the superuser so it can revoke

     * privileges for selected operations. That's right - it takes privileges

     * to toss privileges.

     */

    if (getuid() != 0)

msg_fatal("the master command is reserved for the superuser");

    if (unsafe() != 0)

msg_fatal("the master command must not run as a set-uid process");

 

    /*

 /

 

 

加载作业控制语言,由此参数传入进程,进程执行。

    /*

     * Process JCL.

     */

    while ((ch = GETOPT(argc, argv, "c:Dde:tvw")) > 0) {

switch (ch) {

case 'c':

    if (setenv(CONF_ENV_PATH, optarg, 1) < 0)

msg_fatal("out of memory");

    break;

case 'd':

    master_detach = 0;

    break;

case 'e':

    event_request_timer(master_exit_event, (void *) 0, atoi(optarg));

    break;

case 'D':

    debug_me = 1;

    break;

case 't':

    test_lock = 1;

    break;

case 'v':

    msg_verbose++;

    break;

case 'w':

    wait_flag = 1;

    break;

default:

    usage(argv[0]);

    /* NOTREACHED */

}

    }

 

 

 

 

 

    if (wait_flag)

monitor_fd = master_monitor(MASTER_INIT_TIMEOUT);

进入master_monitor

/* master_monitor - fork off a foreground monitor process */

 

int     master_monitor(int time_limit)

{

    pid_t   pid;

    int     pipes[2];

    char    buf[1];

 

 /*

     * Sanity check.

     */

    if (time_limit <= 0)

msg_panic("master_monitor: bad time limit: %d", time_limit);

 

   /*

     * Set up the plumbing for child-to-parent communication.

     */

    if (pipe(pipes) < 0)

msg_fatal("pipe: %m");

    close_on_exec(pipes[0], CLOSE_ON_EXEC);

    close_on_exec(pipes[1], CLOSE_ON_EXEC);

利用管道,创建一个子进程监视

    /*

     * Fork the child, and wait for it to report successful initialization.

     */

    switch (pid = fork()) {

    case -1:

/* Error. */

msg_fatal("fork: %m");

    case 0:

/* Child. Initialize as daemon in the background. */

close(pipes[0]);

return (pipes[1]);

    default:

/* Parent. Monitor the child in the foreground. */

close(pipes[1]);

switch (timed_read(pipes[0], buf, 1, time_limit, (void *) 0)) {

default:

    /* The child process still runs, but something is wrong. */

    (void) kill(pid, SIGKILL);

    /* FALLTHROUGH */

case 0:

    /* The child process exited prematurely. */

    msg_fatal("daemon initialization failure");

case 1:

    /* The child process initialized successfully. */

    exit(0);

}

    }

}

 

master.cf的配置文件中把参数信息加载进入进程中。

 /*

     * Final initializations. Unfortunately, we must read the global Postfix

     * configuration file after doing command-line processing, so that we get

     * consistent results when we SIGHUP the server to reload configuration

     * files.

     */

    master_vars_init();

 

  (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);

 

 

读取master模块的配置文件。

  void    master_config(void)

{

    MASTER_SERV *entry;

    MASTER_SERV *serv;

 

#define STR_DIFF strcmp

#define STR_SAME !strcmp

 

#define SWAP(type,a,b) { type temp = a; a = b; b = temp; }

 

    /*

     * A service is identified by its endpoint name AND by its transport

     * type, not just by its name alone. The name is unique within its

     * transport type. XXX Service privacy is encoded in the service name.

     */

    set_master_ent();

    while ((entry = get_master_ent()) != 0) {

if (msg_verbose)

    print_master_ent(entry);

for (serv = master_head; serv != 0; serv = serv->next)

    if (STR_SAME(serv->name, entry->name) && serv->type == entry->type)

break;

 

/*

 * Add a new service entry. We do not really care in what order the

 * service entries are kept in memory.

 */

if (serv == 0) {

    entry->next = master_head;

    master_head = entry;

    master_start_service(entry);

}

 

/*

 * Update an existing service entry. Make the current generation of

 * child processes commit suicide whenever it is convenient. The next

 * generation of child processes will run with the new configuration

 * settings.

 */

else {

    serv->flags &= ~MASTER_FLAG_MARK;

    if (entry->flags & MASTER_FLAG_CONDWAKE)

serv->flags |= MASTER_FLAG_CONDWAKE;

    else

serv->flags &= ~MASTER_FLAG_CONDWAKE;

    serv->wakeup_time = entry->wakeup_time;

    serv->max_proc = entry->max_proc;

    serv->throttle_delay = entry->throttle_delay;

    SWAP(char *, serv->ext_name, entry->ext_name);

    SWAP(char *, serv->path, entry->path);

    SWAP(ARGV *, serv->args, entry->args);

    SWAP(char *, serv->stress_param_val, entry->stress_param_val);

    master_restart_service(serv, DO_CONF_RELOAD);

    free_master_ent(entry);

}

    }

    end_master_ent();

}

转载于:https://www.cnblogs.com/fanchaostudy/p/7144026.html

 类似资料:

相关阅读

相关文章

相关问答