#include <my_global.h>#include <my_sys.h>#include <string.h>#include <signal.h>#include <sys/wait.h>#include <sys/stat.h>#include <sys/types.h>#include "manager.h"#include "options.h"#include "log.h"Include dependency graph for mysqlmanager.cc:

Enumerations | |
| enum | { CHILD_OK = 0, CHILD_NEED_RESPAWN, CHILD_EXIT_ANGEL } |
Functions | |
| void | init_environment (char *progname) |
| void | daemonize (const char *log_file_name) |
| void | angel (const Options &options) |
| int | main (int argc, char *argv[]) |
| void | reap_child (int __attribute__((unused)) signo) |
| void | terminate (int signo) |
Variables | |
| volatile sig_atomic_t | child_status = CHILD_OK |
| volatile sig_atomic_t | is_terminated = 0 |
|
|
00143 { CHILD_OK= 0, CHILD_NEED_RESPAWN, CHILD_EXIT_ANGEL };
|
|
|
00192 {
00193 /* install signal handlers */
00194 sigset_t zeromask; // to sigsuspend in parent
00195 struct sigaction sa_chld, sa_term;
00196 struct sigaction sa_chld_out, sa_term_out, sa_int_out, sa_hup_out;
00197
00198 sigemptyset(&zeromask);
00199 sigemptyset(&sa_chld.sa_mask);
00200 sigemptyset(&sa_term.sa_mask);
00201
00202 sa_chld.sa_handler= reap_child;
00203 sa_chld.sa_flags= SA_NOCLDSTOP;
00204 sa_term.sa_handler= terminate;
00205 sa_term.sa_flags= 0;
00206
00207 /* sigaction can fail only on wrong arguments */
00208 sigaction(SIGCHLD, &sa_chld, &sa_chld_out);
00209 sigaction(SIGTERM, &sa_term, &sa_term_out);
00210 sigaction(SIGINT, &sa_term, &sa_int_out);
00211 sigaction(SIGHUP, &sa_term, &sa_hup_out);
00212
00213 /* spawn a child */
00214 spawn:
00215 pid_t pid= fork();
00216 switch (pid) {
00217 case -1:
00218 die("angel(): fork failed, %s", strerror(errno));
00219 case 0: // child, success
00220 /*
00221 restore default actions for signals to let the manager work with
00222 signals as he wishes
00223 */
00224 sigaction(SIGCHLD, &sa_chld_out, 0);
00225 sigaction(SIGTERM, &sa_term_out, 0);
00226 sigaction(SIGINT, &sa_int_out, 0);
00227 sigaction(SIGHUP, &sa_hup_out, 0);
00228
00229 manager(options.socket_file_name);
00230 default: // parent, success
00231 while (child_status == CHILD_OK && is_terminated == 0)
00232 sigsuspend(&zeromask);
00233
00234 if (is_terminated)
00235 log_info("angel got signal %d, exiting", is_terminated);
00236 else if (child_status == CHILD_NEED_RESPAWN)
00237 {
00238 child_status= CHILD_OK;
00239 log_error("angel(): mysqlmanager exited abnormally: respawning...");
00240 sleep(1); /* don't respawn too fast */
00241 goto spawn;
00242 }
00243 /* mysqlmanager successfully exited, let's silently evaporate */
00244 }
00245 }
|
|
|
00103 {
00104 pid_t pid= fork();
00105 switch (pid) {
00106 case -1: // parent, fork error
00107 die("daemonize(): fork failed, %s", strerror(errno));
00108 case 0: // child, fork ok
00109 int fd;
00110 /*
00111 Become a session leader: setsid must succeed because child is
00112 guaranteed not to be a process group leader (it belongs to the
00113 process group of the parent.)
00114 The goal is not to have a controlling terminal.
00115 */
00116 setsid();
00117 /*
00118 As we now don't have a controlling terminal we will not receive
00119 tty-related signals - no need to ignore them.
00120 */
00121
00122 close(STDIN_FILENO);
00123
00124 fd= open(log_file_name, O_WRONLY | O_CREAT | O_APPEND | O_NOCTTY,
00125 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
00126 if (fd < 0)
00127 die("daemonize(): failed to open log file %s, %s", log_file_name,
00128 strerror(errno));
00129 dup2(fd, STDOUT_FILENO);
00130 dup2(fd, STDERR_FILENO);
00131 if (fd != STDOUT_FILENO && fd != STDERR_FILENO)
00132 close(fd);
00133
00134 /* TODO: chroot() and/or chdir() here */
00135 break;
00136 default:
00137 /* successfully exit from parent */
00138 exit(0);
00139 }
00140 }
|
|
|
|
|
||||||||||||
|
00067 {
00068 init_environment(argv[0]);
00069 Options options;
00070 options.load(argc, argv);
00071 if (options.run_as_service)
00072 {
00073 daemonize(options.log_file_name);
00074 angel(options);
00075 }
00076 else
00077 manager(options.log_file_name);
00078 return 0;
00079 }
|
|
|
00153 {
00154 int child_exit_status;
00155 /* As we have only one child, no need to cycle waitpid */
00156 if (waitpid(0, &child_exit_status, WNOHANG) > 0)
00157 {
00158 if (WIFSIGNALED(child_exit_status))
00159 child_status= CHILD_NEED_RESPAWN;
00160 else
00161 /*
00162 As we reap_child is not called for SIGSTOP, we should be here only
00163 if the child exited normally.
00164 */
00165 child_status= CHILD_EXIT_ANGEL;
00166 }
00167 }
|
|
|
00180 {
00181 is_terminated= signo;
00182 }
|
|
|
|
|
|
|
1.3.9.1