16 #include <sys/types.h>
25 #include <sys/resource.h>
33 #if SUPPORT_CIBSECRETS
37 static void close_pipe(
int fildes[]);
47 #ifdef HAVE_SYS_SIGNALFD_H
51 #include <sys/signalfd.h>
54 struct sigchld_data_s {
61 sigchld_setup(
struct sigchld_data_s *
data)
63 sigemptyset(&(
data->mask));
64 sigaddset(&(
data->mask), SIGCHLD);
66 sigemptyset(&(
data->old_mask));
69 if (sigprocmask(SIG_BLOCK, &(
data->mask), &(
data->old_mask)) < 0) {
70 crm_err(
"Wait for child process completion failed: %s "
79 sigchld_open(
struct sigchld_data_s *
data)
85 fd = signalfd(-1, &(
data->mask), SFD_NONBLOCK);
87 crm_err(
"Wait for child process completion failed: %s "
104 sigchld_received(
int fd)
106 struct signalfd_siginfo fdsi;
112 s = read(fd, &fdsi,
sizeof(
struct signalfd_siginfo));
113 if (s !=
sizeof(
struct signalfd_siginfo)) {
114 crm_err(
"Wait for child process completion failed: %s "
117 }
else if (fdsi.ssi_signo == SIGCHLD) {
125 sigchld_cleanup(
struct sigchld_data_s *
data)
128 if ((sigismember(&(
data->old_mask), SIGCHLD) == 0)
129 && (sigprocmask(SIG_UNBLOCK, &(
data->mask), NULL) < 0)) {
130 crm_warn(
"Could not clean up after child process completion: %s",
135 #else // HAVE_SYS_SIGNALFD_H not defined
139 struct sigchld_data_s {
142 struct sigaction old_sa;
155 crm_err(
"Wait for child process completion failed: %s "
161 sigchld_setup(
struct sigchld_data_s *
data)
165 data->pipe_fd[0] =
data->pipe_fd[1] = -1;
167 if (pipe(
data->pipe_fd) == -1) {
168 crm_err(
"Wait for child process completion failed: %s "
175 crm_warn(
"Could not set pipe input non-blocking: %s " CRM_XS " rc=%d",
180 crm_warn(
"Could not set pipe output non-blocking: %s " CRM_XS " rc=%d",
185 data->sa.sa_handler = sigchld_handler;
186 data->sa.sa_flags = 0;
187 sigemptyset(&(
data->sa.sa_mask));
188 if (sigaction(SIGCHLD, &(
data->sa), &(
data->old_sa)) < 0) {
189 crm_err(
"Wait for child process completion failed: %s "
199 sigchld_open(
struct sigchld_data_s *
data)
202 return data->pipe_fd[0];
206 sigchld_close(
int fd)
213 sigchld_received(
int fd)
222 while (read(fd, &ch, 1) == 1) ;
227 sigchld_cleanup(
struct sigchld_data_s *
data)
230 if (sigaction(SIGCHLD, &(
data->old_sa), NULL) < 0) {
231 crm_warn(
"Could not clean up after child process completion: %s",
235 close_pipe(
data->pipe_fd);
247 close_pipe(
int fildes[])
249 if (fildes[0] >= 0) {
253 if (fildes[1] >= 0) {
260 svc_read_output(
int fd,
svc_action_t * op,
bool is_stderr)
265 static const size_t buf_read_len =
sizeof(buf) - 1;
276 crm_trace(
"Reading %s stderr into offset %d", op->
id, len);
278 }
else if (is_stderr == FALSE && op->
stdout_data) {
281 crm_trace(
"Reading %s stdout into offset %d", op->
id, len);
284 crm_trace(
"Reading %s %s into offset %d", op->
id, is_stderr?
"stderr":
"stdout", len);
288 rc = read(fd, buf, buf_read_len);
291 crm_trace(
"Got %d chars: %.80s", rc, buf);
292 data = realloc_safe(
data, len + rc + 1);
293 len += sprintf(
data + len,
"%s", buf);
295 }
else if (errno != EINTR) {
303 }
while (rc == buf_read_len || rc < 0);
315 dispatch_stdout(gpointer userdata)
323 dispatch_stderr(gpointer userdata)
331 pipe_out_done(gpointer user_data)
345 pipe_err_done(gpointer user_data)
358 .destroy = pipe_out_done,
363 .destroy = pipe_err_done,
367 set_ocf_env(
const char *key,
const char *value, gpointer user_data)
369 if (
setenv(key, value, 1) != 0) {
370 crm_perror(LOG_ERR,
"setenv failed for key:%s and value:%s", key, value);
375 set_ocf_env_with_prefix(gpointer key, gpointer value, gpointer user_data)
379 snprintf(buffer,
sizeof(buffer),
"OCF_RESKEY_%s", (
char *)key);
380 set_ocf_env(buffer, value, user_data);
384 set_alert_env(gpointer key, gpointer value, gpointer user_data)
389 rc =
setenv(key, value, 1);
396 (
char*)key, (value? (
char*)value :
""));
398 crm_trace(
"setenv %s=%s", (
char*)key, (value? (
char*)value :
""));
411 void (*env_setter)(gpointer, gpointer, gpointer) = NULL;
412 if (op->
agent == NULL) {
413 env_setter = set_alert_env;
416 env_setter = set_ocf_env_with_prefix;
419 if (env_setter != NULL && op->
params != NULL) {
420 g_hash_table_foreach(op->
params, env_setter, NULL);
423 if (env_setter == NULL || env_setter == set_alert_env) {
427 set_ocf_env(
"OCF_RA_VERSION_MAJOR",
"1", NULL);
428 set_ocf_env(
"OCF_RA_VERSION_MINOR",
"0", NULL);
433 set_ocf_env(
"OCF_RESOURCE_INSTANCE", op->
rsc, NULL);
436 if (op->
agent != NULL) {
437 set_ocf_env(
"OCF_RESOURCE_TYPE", op->
agent, NULL);
442 set_ocf_env(
"OCF_RESOURCE_PROVIDER", op->
provider, NULL);
447 pipe_in_single_parameter(gpointer key, gpointer value, gpointer user_data)
451 int ret, total = 0, len = strlen(buffer);
460 }
while ((errno == EINTR) && (total < len));
475 g_hash_table_foreach(op->
params, pipe_in_single_parameter, (gpointer) op);
484 crm_debug(
"Scheduling another invocation of %s", op->
id);
559 op->
id, op->
pid, (is_stderr?
"stdout" :
"stderr"));
560 svc_read_output(fd, op, is_stderr);
577 strcpy(prefix + strlen(prefix) - strlen(
"error output"),
"output");
594 finish_op_output(op,
true);
595 finish_op_output(op,
false);
600 crm_debug(
"%s[%d] exited with status %d", op->
id, op->
pid, exitcode);
614 op->
id, op->
pid, strsignal(signo), signo);
620 op->
id, op->
pid, strsignal(signo), signo);
639 services_handle_exec_error(
svc_action_t * op,
int error)
641 int rc_not_installed, rc_insufficient_priv, rc_exec_error;
670 op->
rc = rc_not_installed;
675 op->
rc = rc_insufficient_priv;
679 op->
rc = rc_exec_error;
692 signal(SIGPIPE, SIG_DFL);
694 #if defined(HAVE_SCHED_SETSCHEDULER)
695 if (sched_getscheduler(0) != SCHED_OTHER) {
696 struct sched_param sp;
698 memset(&sp, 0,
sizeof(sp));
699 sp.sched_priority = 0;
701 if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) {
702 crm_perror(LOG_ERR,
"Could not reset scheduling policy to SCHED_OTHER for %s", op->
id);
706 if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
707 crm_perror(LOG_ERR,
"Could not reset process priority to 0 for %s", op->
id);
718 #if SUPPORT_CIBSECRETS
723 crm_info(
"proceeding with the stop operation for %s", op->
rsc);
726 crm_err(
"failed to get secrets for %s, "
727 "considering resource not configured", op->
rsc);
733 add_action_env_vars(op);
736 if (op->
opaque->
uid && (geteuid() == 0)) {
746 if (setgroups(0, NULL) < 0) {
747 crm_perror(LOG_ERR,
"Could not set child groups");
762 services_handle_exec_error(op, errno);
773 struct pollfd fds[3];
777 fds[0].events = POLLIN;
781 fds[1].events = POLLIN;
784 fds[2].fd = sigchld_open(
data);
785 fds[2].events = POLLIN;
791 int poll_rc = poll(fds, 3, timeout);
794 if (fds[0].revents & POLLIN) {
798 if (fds[1].revents & POLLIN) {
802 if ((fds[2].revents & POLLIN) && sigchld_received(fds[2].fd)) {
803 wait_rc = waitpid(op->
pid, &status, WNOHANG);
805 if ((wait_rc > 0) || ((wait_rc < 0) && (errno == ECHILD))) {
809 }
else if (wait_rc < 0) {
810 crm_warn(
"Wait for completion of %s[%d] failed: %s "
817 }
else if (poll_rc == 0) {
822 }
else if ((poll_rc < 0) && (errno != EINTR)) {
823 crm_err(
"Wait for completion of %s[%d] failed: %s "
829 timeout = op->
timeout - (time(NULL) - start) * 1000;
831 }
while ((op->
timeout < 0 || timeout > 0));
837 if (op->
timeout > 0 && timeout <= 0) {
839 crm_warn(
"%s[%d] timed out after %dms",
848 if (wait_rc == 0 && waitpid(op->
pid, &status, WNOHANG) == 0) {
849 if (kill(op->
pid, SIGKILL)) {
850 crm_warn(
"Could not kill rogue child %s[%d]: %s",
854 while (waitpid(op->
pid, &status, 0) == (pid_t) -1 && errno == EINTR) ;
857 }
else if (WIFEXITED(status)) {
859 op->
rc = WEXITSTATUS(status);
862 }
else if (WIFSIGNALED(status)) {
863 int signo = WTERMSIG(status);
867 op->
id, op->
pid, strsignal(signo), signo);
870 if (WCOREDUMP(status)) {
875 finish_op_output(op,
true);
876 finish_op_output(op,
false);
878 sigchld_close(fds[2].fd);
888 int stdin_fd[2] = {-1, -1};
891 struct sigchld_data_s
data;
898 services_handle_exec_error(op, rc);
905 if (pipe(stdout_fd) < 0) {
907 crm_err(
"Cannot execute '%s': %s " CRM_XS " pipe(stdout) rc=%d",
909 services_handle_exec_error(op, rc);
916 if (pipe(stderr_fd) < 0) {
919 close_pipe(stdout_fd);
921 crm_err(
"Cannot execute '%s': %s " CRM_XS " pipe(stderr) rc=%d",
923 services_handle_exec_error(op, rc);
931 if (pipe(stdin_fd) < 0) {
934 close_pipe(stdout_fd);
935 close_pipe(stderr_fd);
937 crm_err(
"Cannot execute '%s': %s " CRM_XS " pipe(stdin) rc=%d",
939 services_handle_exec_error(op, rc);
948 close_pipe(stdin_fd);
949 close_pipe(stdout_fd);
950 close_pipe(stderr_fd);
951 sigchld_cleanup(&
data);
959 close_pipe(stdin_fd);
960 close_pipe(stdout_fd);
961 close_pipe(stderr_fd);
965 services_handle_exec_error(op, rc);
970 sigchld_cleanup(&
data);
976 if (stdin_fd[1] >= 0) {
979 if (STDOUT_FILENO != stdout_fd[1]) {
980 if (dup2(stdout_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
981 crm_warn(
"Can't redirect output from '%s': %s "
987 if (STDERR_FILENO != stderr_fd[1]) {
988 if (dup2(stderr_fd[1], STDERR_FILENO) != STDERR_FILENO) {
989 crm_warn(
"Can't redirect error output from '%s': %s "
995 if ((stdin_fd[0] >= 0) &&
996 (STDIN_FILENO != stdin_fd[0])) {
997 if (dup2(stdin_fd[0], STDIN_FILENO) != STDIN_FILENO) {
998 crm_warn(
"Can't redirect input to '%s': %s "
1006 sigchld_cleanup(&
data);
1009 action_launch_child(op);
1014 close(stdout_fd[1]);
1015 close(stderr_fd[1]);
1016 if (stdin_fd[0] >= 0) {
1023 crm_warn(
"Could not set '%s' output non-blocking: %s "
1031 crm_warn(
"Could not set '%s' error output non-blocking: %s "
1042 crm_warn(
"Could not set '%s' input non-blocking: %s "
1046 pipe_in_action_stdin_parameters(op);
1058 action_synced_wait(op, &
data);
1059 sigchld_cleanup(&
data);
1067 operation_finished);
1088 struct dirent **namelist;
1089 int entries = 0, lpc = 0;
1090 char buffer[PATH_MAX];
1092 entries = scandir(root, &namelist, NULL,
alphasort);
1097 for (lpc = 0; lpc < entries; lpc++) {
1100 if (
'.' == namelist[lpc]->d_name[0]) {
1101 free(namelist[lpc]);
1105 snprintf(buffer,
sizeof(buffer),
"%s/%s", root, namelist[lpc]->d_name);
1107 if (stat(buffer, &sb)) {
1111 if (S_ISDIR(sb.st_mode)) {
1113 free(namelist[lpc]);
1117 }
else if (S_ISREG(sb.st_mode)) {
1118 if (files == FALSE) {
1119 free(namelist[lpc]);
1122 }
else if (executable
1123 && (sb.st_mode & S_IXUSR) == 0
1124 && (sb.st_mode & S_IXGRP) == 0 && (sb.st_mode & S_IXOTH) == 0) {
1125 free(namelist[lpc]);
1130 list = g_list_append(list, strdup(namelist[lpc]->d_name));
1132 free(namelist[lpc]);
1148 GList *gIter = NULL;
1149 GList *result = NULL;
1150 GList *providers = NULL;
1155 snprintf(buffer,
sizeof(buffer),
"%s/resource.d/%s",
OCF_ROOT_DIR, provider);
1160 for (gIter = providers; gIter != NULL; gIter = gIter->next) {
1161 GList *tmp1 = result;
1165 result = g_list_concat(tmp1, tmp2);
1168 g_list_free_full(providers, free);
1176 gboolean rc = FALSE;
1179 if (provider == NULL || agent == NULL) {
1184 if (stat(buf, &st) == 0) {
1196 GList *plugin_list = NULL;
1197 GList *result = NULL;
1198 GList *gIter = NULL;
1203 for (gIter = plugin_list; gIter != NULL; gIter = gIter->next) {
1204 const char *plugin = gIter->data;
1208 if (stat(metadata, &st) == 0) {
1209 result = g_list_append(result, strdup(plugin));
1214 g_list_free_full(plugin_list, free);
1222 gboolean rc = FALSE;
1230 if (stat(buf, &st) == 0) {