This source file includes following definitions.
- crmd_child_exit
- stop_subsystem
- start_subsystem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <sys/resource.h>
24 #include <sys/stat.h>
25 #include <sys/time.h>
26 #include <unistd.h>
27
28 #include <crm/common/util.h>
29 #include <crm/crm.h>
30
31 #include <crmd_fsa.h>
32
33
34 static void
35 crmd_child_exit(mainloop_child_t * p, pid_t pid, int core, int signo, int exitcode)
36 {
37
38 const char *name = mainloop_child_name(p);
39
40 if (signo) {
41 crm_notice("Child process %s terminated with signal %d (pid=%d, core=%d)",
42 name, signo, pid, core);
43
44 } else {
45 do_crm_log(exitcode == 0 ? LOG_INFO : LOG_ERR,
46 "Child process %s exited (pid=%d, rc=%d)", name,
47 pid, exitcode);
48 }
49 }
50
51 gboolean
52 stop_subsystem(struct crm_subsystem_s *the_subsystem, gboolean force_quit)
53 {
54 int quit_signal = SIGTERM;
55
56 crm_trace("Stopping sub-system \"%s\"", the_subsystem->name);
57 clear_bit(fsa_input_register, the_subsystem->flag_required);
58
59 if (the_subsystem->pid <= 0) {
60 crm_trace("Client %s not running", the_subsystem->name);
61 return FALSE;
62
63 }
64
65 if (is_set(fsa_input_register, the_subsystem->flag_connected) == FALSE) {
66
67 crm_debug("Stopping %s before it had connected", the_subsystem->name);
68 }
69
70
71
72
73
74
75
76
77
78 errno = 0;
79 if (kill(the_subsystem->pid, quit_signal) == 0) {
80 crm_info("Sent -TERM to %s: [%d]", the_subsystem->name, the_subsystem->pid);
81 the_subsystem->sent_kill = TRUE;
82
83 } else {
84 crm_perror(LOG_ERR, "Sent -TERM to %s: [%d]", the_subsystem->name, the_subsystem->pid);
85 }
86
87 return TRUE;
88 }
89
90 gboolean
91 start_subsystem(struct crm_subsystem_s * the_subsystem)
92 {
93 pid_t pid;
94 struct stat buf;
95 int s_res;
96 unsigned int j;
97 struct rlimit oflimits;
98 const char *devnull = "/dev/null";
99
100 crm_info("Starting sub-system \"%s\"", the_subsystem->name);
101
102 if (the_subsystem->pid > 0) {
103 crm_warn("Client %s already running as pid %d",
104 the_subsystem->name, (int)the_subsystem->pid);
105
106
107 return TRUE;
108 }
109
110
111
112
113
114
115 if (access(the_subsystem->path, F_OK | X_OK) != 0) {
116 crm_perror(LOG_ERR, "Cannot (access) exec %s", the_subsystem->path);
117 return FALSE;
118 }
119
120 s_res = stat(the_subsystem->command, &buf);
121 if (s_res != 0) {
122 crm_perror(LOG_ERR, "Cannot (stat) exec %s", the_subsystem->command);
123 return FALSE;
124 }
125
126
127 switch (pid = fork()) {
128 case -1:
129 crm_err("Cannot fork.");
130 return FALSE;
131
132 default:
133 mainloop_child_add(pid, 0, the_subsystem->name, the_subsystem, crmd_child_exit);
134 crm_trace("Client %s is has pid: %d", the_subsystem->name, pid);
135 the_subsystem->pid = pid;
136 return TRUE;
137
138 case 0:
139
140
141
142 setpgid(0, 0);
143 break;
144 }
145
146 crm_debug("Executing \"%s (%s)\" (pid %d)",
147 the_subsystem->command, the_subsystem->name, (int)getpid());
148
149
150 getrlimit(RLIMIT_NOFILE, &oflimits);
151 for (j = 0; j < oflimits.rlim_cur; ++j) {
152 close(j);
153 }
154
155 (void)open(devnull, O_RDONLY);
156 (void)open(devnull, O_WRONLY);
157 (void)open(devnull, O_WRONLY);
158
159 {
160 char *opts[2];
161
162 opts[0] = strdup(the_subsystem->command);
163 opts[1] = NULL;
164
165
166 (void)execvp(the_subsystem->command, opts);
167 }
168
169
170 crm_perror(LOG_ERR, "FATAL: Cannot exec %s", the_subsystem->command);
171
172 return crm_exit(DAEMON_RESPAWN_STOP);
173 }