14 #include <sys/types.h>
23 #include <sys/resource.h>
25 #ifdef HAVE_SYS_SIGNALFD_H
26 #include <sys/signalfd.h>
35 #if SUPPORT_CIBSECRETS
40 svc_read_output(
int fd,
svc_action_t * op,
bool is_stderr)
45 static const size_t buf_read_len =
sizeof(buf) - 1;
56 crm_trace(
"Reading %s stderr into offset %d", op->
id, len);
61 crm_trace(
"Reading %s stdout into offset %d", op->
id, len);
64 crm_trace(
"Reading %s %s into offset %d", op->
id, is_stderr?
"stderr":
"stdout", len);
68 rc = read(fd, buf, buf_read_len);
71 crm_trace(
"Got %d chars: %.80s", rc, buf);
72 data = realloc_safe(
data, len + rc + 1);
73 len += sprintf(
data + len,
"%s", buf);
75 }
else if (errno != EINTR) {
83 }
while (rc == buf_read_len || rc < 0);
95 dispatch_stdout(gpointer userdata)
103 dispatch_stderr(gpointer userdata)
111 pipe_out_done(gpointer user_data)
125 pipe_err_done(gpointer user_data)
138 .destroy = pipe_out_done,
143 .destroy = pipe_err_done,
147 set_ocf_env(
const char *key,
const char *value, gpointer user_data)
149 if (
setenv(key, value, 1) != 0) {
150 crm_perror(LOG_ERR,
"setenv failed for key:%s and value:%s", key, value);
155 set_ocf_env_with_prefix(gpointer key, gpointer value, gpointer user_data)
159 snprintf(buffer,
sizeof(buffer),
"OCF_RESKEY_%s", (
char *)key);
160 set_ocf_env(buffer, value, user_data);
164 set_alert_env(gpointer key, gpointer value, gpointer user_data)
169 rc =
setenv(key, value, 1);
176 (
char*)key, (value? (
char*)value :
""));
178 crm_trace(
"setenv %s=%s", (
char*)key, (value? (
char*)value :
""));
191 void (*env_setter)(gpointer, gpointer, gpointer) = NULL;
192 if (op->
agent == NULL) {
193 env_setter = set_alert_env;
196 env_setter = set_ocf_env_with_prefix;
199 if (env_setter != NULL && op->
params != NULL) {
200 g_hash_table_foreach(op->
params, env_setter, NULL);
203 if (env_setter == NULL || env_setter == set_alert_env) {
207 set_ocf_env(
"OCF_RA_VERSION_MAJOR",
"1", NULL);
208 set_ocf_env(
"OCF_RA_VERSION_MINOR",
"0", NULL);
213 set_ocf_env(
"OCF_RESOURCE_INSTANCE", op->
rsc, NULL);
216 if (op->
agent != NULL) {
217 set_ocf_env(
"OCF_RESOURCE_TYPE", op->
agent, NULL);
222 set_ocf_env(
"OCF_RESOURCE_PROVIDER", op->
provider, NULL);
227 pipe_in_single_parameter(gpointer key, gpointer value, gpointer user_data)
231 int ret, total = 0, len = strlen(buffer);
240 }
while ((errno == EINTR) && (total < len));
255 g_hash_table_foreach(op->
params, pipe_in_single_parameter, (gpointer) op);
264 crm_debug(
"Scheduling another invocation of %s", op->
id);
330 crm_trace(
"%s dispatching stderr", prefix);
341 crm_trace(
"%s dispatching stdout", prefix);
362 crm_info(
"%s - terminated with signal %d", prefix, signo);
367 crm_warn(
"%s - terminated with signal %d", prefix, signo);
374 crm_debug(
"%s - exited with rc=%d", prefix, exitcode);
399 services_handle_exec_error(
svc_action_t * op,
int error)
401 int rc_not_installed, rc_insufficient_priv, rc_exec_error;
430 op->
rc = rc_not_installed;
435 op->
rc = rc_insufficient_priv;
439 op->
rc = rc_exec_error;
452 signal(SIGPIPE, SIG_DFL);
454 #if defined(HAVE_SCHED_SETSCHEDULER)
455 if (sched_getscheduler(0) != SCHED_OTHER) {
456 struct sched_param sp;
458 memset(&sp, 0,
sizeof(sp));
459 sp.sched_priority = 0;
461 if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) {
462 crm_perror(LOG_ERR,
"Could not reset scheduling policy to SCHED_OTHER for %s", op->
id);
466 if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
467 crm_perror(LOG_ERR,
"Could not reset process priority to 0 for %s", op->
id);
478 #if SUPPORT_CIBSECRETS
483 crm_info(
"proceeding with the stop operation for %s", op->
rsc);
486 crm_err(
"failed to get secrets for %s, "
487 "considering resource not configured", op->
rsc);
493 add_action_env_vars(op);
496 if (op->
opaque->
uid && (geteuid() == 0)) {
506 if (setgroups(0, NULL) < 0) {
507 crm_perror(LOG_ERR,
"Could not set child groups");
522 services_handle_exec_error(op, errno);
527 #ifndef HAVE_SYS_SIGNALFD_H
528 static int sigchld_pipe[2] = { -1, -1 };
533 if ((sigchld_pipe[1] >= 0) && (write(sigchld_pipe[1],
"", 1) == -1)) {
546 struct pollfd fds[3];
549 #ifdef HAVE_SYS_SIGNALFD_H
552 sfd = signalfd(-1, mask, SFD_NONBLOCK);
558 sfd = sigchld_pipe[0];
562 fds[0].events = POLLIN;
566 fds[1].events = POLLIN;
570 fds[2].events = POLLIN;
576 int poll_rc = poll(fds, 3, timeout);
579 if (fds[0].revents & POLLIN) {
583 if (fds[1].revents & POLLIN) {
587 if (fds[2].revents & POLLIN) {
588 #ifdef HAVE_SYS_SIGNALFD_H
589 struct signalfd_siginfo fdsi;
592 s = read(sfd, &fdsi,
sizeof(
struct signalfd_siginfo));
593 if (s !=
sizeof(
struct signalfd_siginfo)) {
594 crm_perror(LOG_ERR,
"Read from signal fd %d failed", sfd);
596 }
else if (fdsi.ssi_signo == SIGCHLD) {
601 while (read(sfd, &ch, 1) == 1) ;
603 wait_rc = waitpid(op->
pid, &status, WNOHANG);
608 }
else if (wait_rc < 0){
609 if (errno == ECHILD) {
622 }
else if (poll_rc == 0) {
626 }
else if (poll_rc < 0) {
627 if (errno != EINTR) {
633 timeout = op->
timeout - (time(NULL) - start) * 1000;
635 }
while ((op->
timeout < 0 || timeout > 0));
641 if (op->
timeout > 0 && timeout <= 0) {
651 if (wait_rc == 0 && waitpid(op->
pid, &status, WNOHANG) == 0) {
652 if (kill(op->
pid, SIGKILL)) {
653 crm_err(
"kill(%d, KILL) failed: %d", op->
pid, errno);
656 while (waitpid(op->
pid, &status, 0) == (pid_t) -1 && errno == EINTR) ;
659 }
else if (WIFEXITED(status)) {
661 op->
rc = WEXITSTATUS(status);
662 crm_info(
"Managed %s process %d exited with rc=%d", op->
id, op->
pid, op->
rc);
664 }
else if (WIFSIGNALED(status)) {
665 int signo = WTERMSIG(status);
668 crm_err(
"Managed %s process %d exited with signal=%d", op->
id, op->
pid, signo);
671 if (WCOREDUMP(status)) {
672 crm_err(
"Managed %s process %d dumped core", op->
id, op->
pid);
685 #ifdef HAVE_SYS_SIGNALFD_H
697 int stdin_fd[2] = {-1, -1};
700 sigset_t *pmask = NULL;
702 #ifdef HAVE_SYS_SIGNALFD_H
705 #define sigchld_cleanup() do { \
706 if (sigismember(&old_mask, SIGCHLD) == 0) { \
707 if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) { \
708 crm_perror(LOG_ERR, "sigprocmask() failed to unblock sigchld"); \
714 struct sigaction old_sa;
715 #define sigchld_cleanup() do { \
716 if (sigaction(SIGCHLD, &old_sa, NULL) < 0) { \
717 crm_perror(LOG_ERR, "sigaction() failed to remove sigchld handler"); \
719 close(sigchld_pipe[0]); \
720 close(sigchld_pipe[1]); \
721 sigchld_pipe[0] = sigchld_pipe[1] = -1; \
729 services_handle_exec_error(op, rc);
736 if (pipe(stdout_fd) < 0) {
741 services_handle_exec_error(op, rc);
748 if (pipe(stderr_fd) < 0) {
756 services_handle_exec_error(op, rc);
764 if (pipe(stdin_fd) < 0) {
774 services_handle_exec_error(op, rc);
783 #ifdef HAVE_SYS_SIGNALFD_H
785 sigaddset(&mask, SIGCHLD);
786 sigemptyset(&old_mask);
788 if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) {
789 crm_perror(LOG_ERR,
"sigprocmask() failed to block sigchld");
794 if(pipe(sigchld_pipe) == -1) {
800 crm_warn(
"Could not set pipe input non-blocking: %s " CRM_XS " rc=%d",
805 crm_warn(
"Could not set pipe output non-blocking: %s " CRM_XS " rc=%d",
809 sa.sa_handler = sigchld_handler;
811 sigemptyset(&sa.sa_mask);
812 if (sigaction(SIGCHLD, &sa, &old_sa) < 0) {
813 crm_perror(LOG_ERR,
"sigaction() failed to set sigchld handler");
829 if (stdin_fd[0] >= 0) {
835 services_handle_exec_error(op, rc);
846 if (stdin_fd[1] >= 0) {
849 if (STDOUT_FILENO != stdout_fd[1]) {
850 if (dup2(stdout_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
851 crm_err(
"dup2() failed (stdout)");
855 if (STDERR_FILENO != stderr_fd[1]) {
856 if (dup2(stderr_fd[1], STDERR_FILENO) != STDERR_FILENO) {
857 crm_err(
"dup2() failed (stderr)");
861 if ((stdin_fd[0] >= 0) &&
862 (STDIN_FILENO != stdin_fd[0])) {
863 if (dup2(stdin_fd[0], STDIN_FILENO) != STDIN_FILENO) {
864 crm_err(
"dup2() failed (stdin)");
873 action_launch_child(op);
880 if (stdin_fd[0] >= 0) {
887 crm_warn(
"Could not set child output non-blocking: %s "
895 crm_warn(
"Could not set child error output non-blocking: %s "
906 crm_warn(
"Could not set child input non-blocking: %s "
910 pipe_in_action_stdin_parameters(op);
922 action_synced_wait(op, pmask);
953 struct dirent **namelist;
954 int entries = 0, lpc = 0;
955 char buffer[PATH_MAX];
957 entries = scandir(root, &namelist, NULL,
alphasort);
962 for (lpc = 0; lpc < entries; lpc++) {
965 if (
'.' == namelist[lpc]->d_name[0]) {
970 snprintf(buffer,
sizeof(buffer),
"%s/%s", root, namelist[lpc]->d_name);
972 if (stat(buffer, &sb)) {
976 if (S_ISDIR(sb.st_mode)) {
982 }
else if (S_ISREG(sb.st_mode)) {
983 if (files == FALSE) {
987 }
else if (executable
988 && (sb.st_mode & S_IXUSR) == 0
989 && (sb.st_mode & S_IXGRP) == 0 && (sb.st_mode & S_IXOTH) == 0) {
995 list = g_list_append(list, strdup(namelist[lpc]->d_name));
1013 GList *gIter = NULL;
1014 GList *result = NULL;
1015 GList *providers = NULL;
1020 snprintf(buffer,
sizeof(buffer),
"%s/resource.d/%s",
OCF_ROOT_DIR, provider);
1025 for (gIter = providers; gIter != NULL; gIter = gIter->next) {
1026 GList *tmp1 = result;
1030 result = g_list_concat(tmp1, tmp2);
1033 g_list_free_full(providers, free);
1041 gboolean rc = FALSE;
1044 if (provider == NULL || agent == NULL) {
1049 if (stat(buf, &st) == 0) {
1061 GList *plugin_list = NULL;
1062 GList *result = NULL;
1063 GList *gIter = NULL;
1068 for (gIter = plugin_list; gIter != NULL; gIter = gIter->next) {
1069 const char *plugin = gIter->data;
1073 if (stat(metadata, &st) == 0) {
1074 result = g_list_append(result, strdup(plugin));
1079 g_list_free_full(plugin_list, free);
1087 gboolean rc = FALSE;
1095 if (stat(buf, &st) == 0) {