1    	/*
2    	 * Copyright 2010-2026 the Pacemaker project contributors
3    	 *
4    	 * The version control history for this file may have further details.
5    	 *
6    	 * This source code is licensed under the GNU Lesser General Public License
7    	 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8    	 */
9    	
10   	#include <crm_internal.h>
11   	
12   	#include <stdbool.h>                    // bool, true, false
13   	#include <sys/types.h>
14   	#include <sys/stat.h>
15   	#include <sys/wait.h>
16   	#include <errno.h>
17   	#include <unistd.h>
18   	#include <dirent.h>
19   	#include <grp.h>
20   	#include <string.h>
21   	#include <sys/time.h>
22   	#include <sys/resource.h>
23   	
24   	#include "crm/crm.h"
25   	#include "crm/common/mainloop.h"
26   	#include "crm/services.h"
27   	#include "crm/services_internal.h"
28   	
29   	#include "services_private.h"
30   	
31   	static const char *filter_dir = NULL;
32   	
33   	static void close_pipe(int fildes[]);
34   	
35   	/* We have two alternative ways of handling SIGCHLD when synchronously waiting
36   	 * for spawned processes to complete. Both rely on polling a file descriptor to
37   	 * discover SIGCHLD events.
38   	 *
39   	 * If sys/signalfd.h is available (e.g. on Linux), we call signalfd() to
40   	 * generate the file descriptor. Otherwise, we use the "self-pipe trick"
41   	 * (opening a pipe and writing a byte to it when SIGCHLD is received).
42   	 */
43   	#ifdef HAVE_SYS_SIGNALFD_H
44   	
45   	// signalfd() implementation
46   	
47   	#include <sys/signalfd.h>
48   	
49   	// Everything needed to manage SIGCHLD handling
50   	struct sigchld_data_s {
51   	    sigset_t mask;      // Signals to block now (including SIGCHLD)
52   	    sigset_t old_mask;  // Previous set of blocked signals
53   	    bool ignored;       // If SIGCHLD for another child has been ignored
54   	};
55   	
56   	// Initialize SIGCHLD data and prepare for use
57   	static bool
58   	sigchld_setup(struct sigchld_data_s *data)
59   	{
60   	    sigemptyset(&(data->mask));
61   	    sigaddset(&(data->mask), SIGCHLD);
62   	
63   	    sigemptyset(&(data->old_mask));
64   	
65   	    // Block SIGCHLD (saving previous set of blocked signals to restore later)
66   	    if (sigprocmask(SIG_BLOCK, &(data->mask), &(data->old_mask)) < 0) {
67   	        pcmk__info("Wait for child process completion failed: %s "
68   	                   QB_XS " source=sigprocmask",
69   	                   pcmk_rc_str(errno));
70   	        return false;
71   	    }
72   	
73   	    data->ignored = false;
74   	
75   	    return true;
76   	}
77   	
78   	// Get a file descriptor suitable for polling for SIGCHLD events
79   	static int
80   	sigchld_open(struct sigchld_data_s *data)
81   	{
82   	    int fd;
83   	
84   	    CRM_CHECK(data != NULL, return -1);
85   	
86   	    fd = signalfd(-1, &(data->mask), SFD_NONBLOCK);
87   	    if (fd < 0) {
88   	        pcmk__info("Wait for child process completion failed: %s "
89   	                   QB_XS " source=signalfd",
90   	                   pcmk_rc_str(errno));
91   	    }
92   	    return fd;
93   	}
94   	
95   	// Close a file descriptor returned by sigchld_open()
96   	static void
97   	sigchld_close(int fd)
98   	{
99   	    if (fd > 0) {
100  	        close(fd);
101  	    }
102  	}
103  	
104  	// Return true if SIGCHLD was received from polled fd
105  	static bool
106  	sigchld_received(int fd, int pid, struct sigchld_data_s *data)
107  	{
108  	    struct signalfd_siginfo fdsi;
109  	    ssize_t s;
110  	
111  	    if (fd < 0) {
112  	        return false;
113  	    }
114  	    s = read(fd, &fdsi, sizeof(struct signalfd_siginfo));
115  	    if (s != sizeof(struct signalfd_siginfo)) {
116  	        pcmk__info("Wait for child process completion failed: %s "
117  	                   QB_XS " source=read",
118  	                   pcmk_rc_str(errno));
119  	
120  	    } else if (fdsi.ssi_signo == SIGCHLD) {
121  	        if (fdsi.ssi_pid == pid) {
122  	            return true;
123  	
124  	        } else {
125  	            /* This SIGCHLD is for another child. We have to ignore it here but
126  	             * will still need to resend it after this synchronous action has
127  	             * completed and SIGCHLD has been restored to be handled by the
128  	             * previous SIGCHLD handler, so that it will be handled.
129  	             */
130  	            data->ignored = true;
131  	            return false;
132  	        }
133  	    }
134  	    return false;
135  	}
136  	
137  	// Do anything needed after done waiting for SIGCHLD
138  	static void
139  	sigchld_cleanup(struct sigchld_data_s *data)
140  	{
141  	    // Restore the original set of blocked signals
142  	    if ((sigismember(&(data->old_mask), SIGCHLD) == 0)
143  	        && (sigprocmask(SIG_UNBLOCK, &(data->mask), NULL) < 0)) {
144  	        pcmk__warn("Could not clean up after child process completion: %s",
145  	                   pcmk_rc_str(errno));
146  	    }
147  	
148  	    // Resend any ignored SIGCHLD for other children so that they'll be handled.
149  	    if (data->ignored && kill(getpid(), SIGCHLD) != 0) {
150  	        pcmk__warn("Could not resend ignored SIGCHLD to ourselves: %s",
151  	                   pcmk_rc_str(errno));
152  	    }
153  	}
154  	
155  	#else // HAVE_SYS_SIGNALFD_H not defined
156  	
157  	// Self-pipe implementation (see above for function descriptions)
158  	
159  	struct sigchld_data_s {
160  	    int pipe_fd[2];             // Pipe file descriptors
161  	    struct sigaction sa;        // Signal handling info (with SIGCHLD)
162  	    struct sigaction old_sa;    // Previous signal handling info
163  	    bool ignored;               // If SIGCHLD for another child has been ignored
164  	};
165  	
166  	// We need a global to use in the signal handler
167  	volatile struct sigchld_data_s *last_sigchld_data = NULL;
168  	
169  	static void
170  	sigchld_handler(void)
171  	{
172  	    // We received a SIGCHLD, so trigger pipe polling
173  	    if ((last_sigchld_data != NULL)
174  	        && (last_sigchld_data->pipe_fd[1] >= 0)
175  	        && (write(last_sigchld_data->pipe_fd[1], "", 1) == -1)) {
176  	        pcmk__info("Wait for child process completion failed: %s "
177  	                   QB_XS " source=write",
178  	                   pcmk_rc_str(errno));
179  	    }
180  	}
181  	
182  	static bool
183  	sigchld_setup(struct sigchld_data_s *data)
184  	{
185  	    int rc;
186  	
187  	    data->pipe_fd[0] = data->pipe_fd[1] = -1;
188  	
189  	    if (pipe(data->pipe_fd) == -1) {
190  	        pcmk__info("Wait for child process completion failed: %s "
191  	                   QB_XS " source=pipe",
192  	                   pcmk_rc_str(errno));
193  	        return false;
194  	    }
195  	
196  	    rc = pcmk__set_nonblocking(data->pipe_fd[0]);
197  	    if (rc != pcmk_rc_ok) {
198  	        pcmk__info("Could not set pipe input non-blocking: %s " QB_XS " rc=%d",
199  	                   pcmk_rc_str(rc), rc);
200  	    }
201  	    rc = pcmk__set_nonblocking(data->pipe_fd[1]);
202  	    if (rc != pcmk_rc_ok) {
203  	        pcmk__info("Could not set pipe output non-blocking: %s " QB_XS " rc=%d",
204  	                   pcmk_rc_str(rc), rc);
205  	    }
206  	
207  	    // Set SIGCHLD handler
208  	    data->sa.sa_handler = (sighandler_t) sigchld_handler;
209  	    data->sa.sa_flags = 0;
210  	    sigemptyset(&(data->sa.sa_mask));
211  	    if (sigaction(SIGCHLD, &(data->sa), &(data->old_sa)) < 0) {
212  	        pcmk__info("Wait for child process completion failed: %s "
213  	                   QB_XS " source=sigaction",
214  	                   pcmk_rc_str(errno));
215  	    }
216  	
217  	    data->ignored = false;
218  	
219  	    // Remember data for use in signal handler
220  	    last_sigchld_data = data;
221  	    return true;
222  	}
223  	
224  	static int
225  	sigchld_open(struct sigchld_data_s *data)
226  	{
227  	    CRM_CHECK(data != NULL, return -1);
228  	    return data->pipe_fd[0];
229  	}
230  	
231  	static void
232  	sigchld_close(int fd)
233  	{
234  	    // Pipe will be closed in sigchld_cleanup()
235  	}
236  	
237  	static bool
238  	sigchld_received(int fd, int pid, struct sigchld_data_s *data)
239  	{
240  	    char ch;
241  	
242  	    if (fd < 0) {
243  	        return false;
244  	    }
245  	
246  	    // Clear out the self-pipe
247  	    while (read(fd, &ch, 1) == 1) /*omit*/;
248  	    return true;
249  	}
250  	
251  	static void
252  	sigchld_cleanup(struct sigchld_data_s *data)
253  	{
254  	    // Restore the previous SIGCHLD handler
255  	    if (sigaction(SIGCHLD, &(data->old_sa), NULL) < 0) {
256  	        pcmk__warn("Could not clean up after child process completion: %s",
257  	                   pcmk_rc_str(errno));
258  	    }
259  	
260  	    close_pipe(data->pipe_fd);
261  	
262  	    // Resend any ignored SIGCHLD for other children so that they'll be handled.
263  	    if (data->ignored && kill(getpid(), SIGCHLD) != 0) {
264  	        pcmk__warn("Could not resend ignored SIGCHLD to ourselves: %s",
265  	                   pcmk_rc_str(errno));
266  	    }
267  	}
268  	
269  	#endif
270  	
271  	/*!
272  	 * \internal
273  	 * \brief Close the two file descriptors of a pipe
274  	 *
275  	 * \param[in,out] fildes  Array of file descriptors opened by pipe()
276  	 */
277  	static void
278  	close_pipe(int fildes[])
279  	{
280  	    if (fildes[0] >= 0) {
281  	        close(fildes[0]);
282  	        fildes[0] = -1;
283  	    }
284  	    if (fildes[1] >= 0) {
285  	        close(fildes[1]);
286  	        fildes[1] = -1;
287  	    }
288  	}
289  	
290  	#define out_type(is_stderr) ((is_stderr)? "stderr" : "stdout")
291  	
292  	// Maximum number of bytes of stdout or stderr we'll accept
293  	#define MAX_OUTPUT (10 * 1024 * 1024)
294  	
295  	static gboolean
296  	svc_read_output(int fd, svc_action_t * op, bool is_stderr)
297  	{
298  	    char *data = NULL;
299  	    ssize_t rc = 0;
300  	    size_t len = 0;
301  	    size_t discarded = 0;
302  	    char buf[500];
303  	    static const size_t buf_read_len = sizeof(buf) - 1;
304  	
305  	    if (fd < 0) {
306  	        pcmk__trace("No fd for %s", op->id);
307  	        return FALSE;
308  	    }
309  	
310  	    if (is_stderr && op->stderr_data) {
311  	        len = strlen(op->stderr_data);
312  	        data = op->stderr_data;
313  	        pcmk__trace("Reading %s stderr into offset %zu", op->id, len);
314  	
315  	    } else if (is_stderr == FALSE && op->stdout_data) {
316  	        len = strlen(op->stdout_data);
317  	        data = op->stdout_data;
318  	        pcmk__trace("Reading %s stdout into offset %zu", op->id, len);
319  	
320  	    } else {
321  	        pcmk__trace("Reading %s %s", op->id, out_type(is_stderr));
322  	    }
323  	
324  	    do {
325  	        errno = 0;
326  	        rc = read(fd, buf, buf_read_len);
327  	        if (rc > 0) {
328  	            if (len < MAX_OUTPUT) {
329  	                buf[rc] = 0;
330  	                pcmk__trace("Received %zd bytes of %s %s: %.80s", rc, op->id,
331  	                            out_type(is_stderr), buf);
332  	                data = pcmk__realloc(data, len + rc + 1);
333  	                strcpy(data + len, buf);
334  	                len += rc;
335  	            } else {
336  	                discarded += rc;
337  	            }
338  	
339  	        } else if (errno != EINTR) { // Fatal error or EOF
340  	            rc = 0;
341  	            break;
342  	        }
343  	    } while ((rc == buf_read_len) || (rc < 0));
344  	
345  	    if (discarded > 0) {
346  	        pcmk__warn("Truncated %s %s to %zu bytes (discarded %zu)", op->id,
347  	                   out_type(is_stderr), len, discarded);
348  	    }
349  	
350  	    if (is_stderr) {
351  	        op->stderr_data = data;
352  	    } else {
353  	        op->stdout_data = data;
354  	    }
355  	
356  	    return rc != 0;
357  	}
358  	
359  	static int
360  	dispatch_stdout(gpointer userdata)
361  	{
362  	    svc_action_t *op = (svc_action_t *) userdata;
363  	
364  	    return svc_read_output(op->opaque->stdout_fd, op, FALSE);
365  	}
366  	
367  	static int
368  	dispatch_stderr(gpointer userdata)
369  	{
370  	    svc_action_t *op = (svc_action_t *) userdata;
371  	
372  	    return svc_read_output(op->opaque->stderr_fd, op, TRUE);
373  	}
374  	
375  	static void
376  	pipe_out_done(gpointer user_data)
377  	{
378  	    svc_action_t *op = (svc_action_t *) user_data;
379  	
380  	    pcmk__trace("%p", op);
381  	
382  	    op->opaque->stdout_gsource = NULL;
383  	    if (op->opaque->stdout_fd > STDOUT_FILENO) {
384  	        close(op->opaque->stdout_fd);
385  	    }
386  	    op->opaque->stdout_fd = -1;
387  	}
388  	
389  	static void
390  	pipe_err_done(gpointer user_data)
391  	{
392  	    svc_action_t *op = (svc_action_t *) user_data;
393  	
394  	    op->opaque->stderr_gsource = NULL;
395  	    if (op->opaque->stderr_fd > STDERR_FILENO) {
396  	        close(op->opaque->stderr_fd);
397  	    }
398  	    op->opaque->stderr_fd = -1;
399  	}
400  	
401  	static struct mainloop_fd_callbacks stdout_callbacks = {
402  	    .dispatch = dispatch_stdout,
403  	    .destroy = pipe_out_done,
404  	};
405  	
406  	static struct mainloop_fd_callbacks stderr_callbacks = {
407  	    .dispatch = dispatch_stderr,
408  	    .destroy = pipe_err_done,
409  	};
410  	
411  	static void
412  	set_ocf_env(const char *key, const char *value, gpointer user_data)
413  	{
414  	    // @FIXME @COMPAT This seems like it should be a fatal error
415  	    if (setenv(key, value, 1) != 0) {
416  	        int rc = errno;
417  	
418  	        pcmk__err("setenv failed for key='%s' and value='%s': %s",
419  	                  pcmk__s(key, ""), pcmk__s(value, ""), strerror(rc));
420  	    }
421  	}
422  	
423  	static void
424  	set_ocf_env_with_prefix(gpointer key, gpointer value, gpointer user_data)
425  	{
426  	    const char *ckey = key;
427  	
428  	    if (pcmk__str_eq(ckey, "OCF_CHECK_LEVEL", pcmk__str_none)) {
429  	        set_ocf_env(ckey, value, user_data);
430  	
431  	    } else {
432  	        char *buffer = pcmk__assert_asprintf("OCF_RESKEY_%s", ckey);
433  	
434  	        set_ocf_env(buffer, value, user_data);
435  	        free(buffer);
436  	    }
437  	}
438  	
439  	static void
440  	set_alert_env(gpointer key, gpointer value, gpointer user_data)
441  	{
442  	    int rc;
443  	
444  	    if (value != NULL) {
445  	        rc = setenv(key, value, 1);
446  	    } else {
447  	        rc = unsetenv(key);
448  	    }
449  	
450  	    if (rc < 0) {
451  	        // @FIXME @COMPAT This seems like it should be a fatal error
452  	        rc = errno;
453  	
454  	        if (value != NULL) {
455  	            pcmk__err("setenv %s='%s' failed: %s", (const char *) key,
456  	                      (const char *) value, strerror(rc));
457  	        } else {
458  	            pcmk__err("unsetenv %s failed: %s", (const char *) key,
459  	                      strerror(rc));
460  	        }
461  	
462  	    } else {
463  	        if (value != NULL) {
464  	            pcmk__trace("setenv %s='%s'", (const char *) key,
465  	                        (const char *) value);
466  	        } else {
467  	            pcmk__trace("unsetenv %s", (const char *) key);
468  	        }
469  	    }
470  	}
471  	
472  	/*!
473  	 * \internal
474  	 * \brief Add environment variables suitable for an action
475  	 *
476  	 * \param[in] op  Action to use
477  	 */
478  	static void
479  	add_action_env_vars(const svc_action_t *op)
480  	{
481  	    void (*env_setter)(gpointer, gpointer, gpointer) = NULL;
482  	    if (op->agent == NULL) {
483  	        env_setter = set_alert_env;  /* we deal with alert handler */
484  	
485  	    } else if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_OCF, pcmk__str_casei)) {
486  	        env_setter = set_ocf_env_with_prefix;
487  	    }
488  	
489  	    if (env_setter != NULL && op->params != NULL) {
490  	        g_hash_table_foreach(op->params, env_setter, NULL);
491  	    }
492  	
493  	    if (env_setter == NULL || env_setter == set_alert_env) {
494  	        return;
495  	    }
496  	
497  	    set_ocf_env("OCF_RA_VERSION_MAJOR", PCMK_OCF_MAJOR_VERSION, NULL);
498  	    set_ocf_env("OCF_RA_VERSION_MINOR", PCMK_OCF_MINOR_VERSION, NULL);
499  	    set_ocf_env("OCF_ROOT", PCMK_OCF_ROOT, NULL);
500  	    set_ocf_env("OCF_EXIT_REASON_PREFIX", PCMK_OCF_REASON_PREFIX, NULL);
501  	
502  	    if (op->rsc) {
503  	        set_ocf_env("OCF_RESOURCE_INSTANCE", op->rsc, NULL);
504  	    }
505  	
506  	    if (op->agent != NULL) {
507  	        set_ocf_env("OCF_RESOURCE_TYPE", op->agent, NULL);
508  	    }
509  	
510  	    /* Notes: this is not added to specification yet. Sept 10,2004 */
511  	    if (op->provider != NULL) {
512  	        set_ocf_env("OCF_RESOURCE_PROVIDER", op->provider, NULL);
513  	    }
514  	}
515  	
516  	static void
517  	pipe_in_single_parameter(gpointer key, gpointer value, gpointer user_data)
518  	{
519  	    svc_action_t *op = user_data;
520  	    char *buffer = pcmk__assert_asprintf("%s=%s\n", (const char *) key,
521  	                                         (const char *) value);
522  	    size_t len = strlen(buffer);
523  	    size_t total = 0;
524  	    ssize_t ret = 0;
525  	
526  	    do {
527  	        errno = 0;
528  	        ret = write(op->opaque->stdin_fd, buffer + total, len - total);
529  	        if (ret > 0) {
530  	            total += ret;
531  	        }
532  	    } while ((errno == EINTR) && (total < len));
533  	    free(buffer);
534  	}
535  	
536  	/*!
537  	 * \internal
538  	 * \brief Pipe parameters in via stdin for action
539  	 *
540  	 * \param[in] op  Action to use
541  	 */
542  	static void
543  	pipe_in_action_stdin_parameters(const svc_action_t *op)
544  	{
545  	    if (op->params) {
546  	        g_hash_table_foreach(op->params, pipe_in_single_parameter, (gpointer) op);
547  	    }
548  	}
549  	
550  	gboolean
551  	recurring_action_timer(gpointer data)
552  	{
553  	    svc_action_t *op = data;
554  	
(1) Event path: Switch case default.
(2) Event path: Condition "trace_cs == NULL", taking true branch.
(3) Event path: Condition "crm_is_callsite_active(trace_cs, _level, 0)", taking false branch.
(4) Event path: Breaking from switch.
555  	    pcmk__debug("Scheduling another invocation of %s", op->id);
556  	
557  	    /* Clean out the old result */
(5) Event path: Condition "_p", taking true branch.
558  	    g_clear_pointer(&op->stdout_data, free);
CID (unavailable; MK=43f02ea62d3ee740c4b10f7c56f43ccf) (#2 of 2): Inconsistent C union access (INCONSISTENT_UNION_ACCESS):
(6) Event assign_union_field: The union field "in" of "_pp" is written.
(7) Event inconsistent_union_field_access: In "_pp.out", the union field used: "out" is inconsistent with the field most recently stored: "in".
559  	    g_clear_pointer(&op->stderr_data, free);
560  	    op->opaque->repeat_timer = 0;
561  	
562  	    services_action_async(op, NULL);
563  	    return FALSE;
564  	}
565  	
566  	/*!
567  	 * \internal
568  	 * \brief Finalize handling of an asynchronous operation
569  	 *
570  	 * Given a completed asynchronous operation, cancel or reschedule it as
571  	 * appropriate if recurring, call its callback if registered, stop tracking it,
572  	 * and clean it up.
573  	 *
574  	 * \param[in,out] op  Operation to finalize
575  	 *
576  	 * \return Standard Pacemaker return code
577  	 * \retval EINVAL      Caller supplied NULL or invalid \p op
578  	 * \retval EBUSY       Uncanceled recurring action has only been cleaned up
579  	 * \retval pcmk_rc_ok  Action has been freed
580  	 *
581  	 * \note If the return value is not pcmk_rc_ok, the caller is responsible for
582  	 *       freeing the action.
583  	 */
584  	int
585  	services__finalize_async_op(svc_action_t *op)
586  	{
587  	    CRM_CHECK((op != NULL) && !(op->synchronous), return EINVAL);
588  	
589  	    if (op->interval_ms != 0) {
590  	        // Recurring operations must be either cancelled or rescheduled
591  	        if (op->cancel) {
592  	            services__set_cancelled(op);
593  	            cancel_recurring_action(op);
594  	        } else {
595  	            op->opaque->repeat_timer = pcmk__create_timer(op->interval_ms,
596  	                                                          recurring_action_timer,
597  	                                                          op);
598  	        }
599  	    }
600  	
601  	    if (op->opaque->callback != NULL) {
602  	        op->opaque->callback(op);
603  	    }
604  	
605  	    // Stop tracking the operation (as in-flight or blocked)
606  	    op->pid = 0;
607  	    services_untrack_op(op);
608  	
609  	    if ((op->interval_ms != 0) && !(op->cancel)) {
610  	        // Do not free recurring actions (they will get freed when cancelled)
611  	        services_action_cleanup(op);
612  	        return EBUSY;
613  	    }
614  	
615  	    services_action_free(op);
616  	    return pcmk_rc_ok;
617  	}
618  	
619  	static void
620  	close_op_input(svc_action_t *op)
621  	{
622  	    if (op->opaque->stdin_fd >= 0) {
623  	        close(op->opaque->stdin_fd);
624  	    }
625  	}
626  	
627  	static void
628  	finish_op_output(svc_action_t *op, bool is_stderr)
629  	{
630  	    mainloop_io_t **source;
631  	    int fd;
632  	
633  	    if (is_stderr) {
634  	        source = &(op->opaque->stderr_gsource);
635  	        fd = op->opaque->stderr_fd;
636  	    } else {
637  	        source = &(op->opaque->stdout_gsource);
638  	        fd = op->opaque->stdout_fd;
639  	    }
640  	
641  	    if (op->synchronous || *source) {
642  	        pcmk__trace("Finish reading %s[%d] %s", op->id, op->pid,
643  	                    (is_stderr? "stderr" : "stdout"));
644  	        svc_read_output(fd, op, is_stderr);
645  	        if (op->synchronous) {
646  	            close(fd);
647  	        } else {
648  	            mainloop_del_fd(*source);
649  	            *source = NULL;
650  	        }
651  	    }
652  	}
653  	
654  	// Log an operation's stdout and stderr
655  	static void
656  	log_op_output(svc_action_t *op)
657  	{
658  	    char *prefix = pcmk__assert_asprintf("%s[%d] error output", op->id,
659  	                                         op->pid);
660  	
661  	    /* The library caller has better context to know how important the output
662  	     * is, so log it at info and debug severity here. They can log it again at
663  	     * higher severity if appropriate.
664  	     */
665  	    crm_log_output(LOG_INFO, prefix, op->stderr_data);
666  	    strcpy(prefix + strlen(prefix) - strlen("error output"), "output");
667  	    crm_log_output(LOG_DEBUG, prefix, op->stdout_data);
668  	    free(prefix);
669  	}
670  	
671  	static void
672  	parse_exit_reason_from_stderr(svc_action_t *op)
673  	{
674  	    const char *reason = NULL;
675  	
676  	    if ((op->stderr_data == NULL) ||
677  	        // Only OCF agents have exit reasons in stderr
678  	        !pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_OCF, pcmk__str_none)) {
679  	        return;
680  	    }
681  	
682  	    // Find the last occurrence of the magic string indicating an exit reason
683  	    reason = g_strrstr(op->stderr_data, PCMK_OCF_REASON_PREFIX);
684  	
685  	    if (reason != NULL) {
686  	        // Skip over the magic string itself
687  	        reason += sizeof(PCMK_OCF_REASON_PREFIX) - 1;
688  	    }
689  	
690  	    if (pcmk__str_empty(reason) || (reason[0] == '\n')) {
691  	        // No exit reason or empty exit reason
692  	        return;
693  	    }
694  	
695  	    // Exit reason goes to end of line (or end of output)
696  	    free(op->opaque->exit_reason);
697  	    op->opaque->exit_reason = strndup(reason, strcspn(reason, "\n"));
698  	}
699  	
700  	/*!
701  	 * \internal
702  	 * \brief Process the completion of an asynchronous child process
703  	 *
704  	 * \param[in,out] p         Child process that completed
705  	 * \param[in]     core      (Unused)
706  	 * \param[in]     signo     Signal that interrupted child, if any
707  	 * \param[in]     exitcode  Exit status of child process
708  	 */
709  	static void
710  	async_action_complete(mainloop_child_t *p, int core, int signo, int exitcode)
711  	{
712  	    svc_action_t *op = mainloop_child_userdata(p);
713  	
714  	    mainloop_clear_child_userdata(p);
715  	    CRM_CHECK(op->pid == p->pid,
716  	              services__set_result(op, services__generic_error(op),
717  	                                   PCMK_EXEC_ERROR, "Bug in mainloop handling");
718  	              return);
719  	
720  	    /* Depending on the priority the mainloop gives the stdout and stderr
721  	     * file descriptors, this function could be called before everything has
722  	     * been read from them, so force a final read now.
723  	     */
724  	    finish_op_output(op, true);
725  	    finish_op_output(op, false);
726  	
727  	    close_op_input(op);
728  	
729  	    if (signo == 0) {
730  	        pcmk__debug("%s[%d] exited with status %d", op->id, op->pid, exitcode);
731  	        services__set_result(op, exitcode, PCMK_EXEC_DONE, NULL);
732  	        log_op_output(op);
733  	        parse_exit_reason_from_stderr(op);
734  	
735  	    } else if (mainloop_child_timeout(p)) {
736  	        const char *kind = services__action_kind(op);
737  	
738  	        pcmk__info("%s %s[%d] timed out after %s", kind, op->id, op->pid,
739  	                   pcmk__readable_interval(op->timeout));
740  	        services__format_result(op, services__generic_error(op),
741  	                                PCMK_EXEC_TIMEOUT,
742  	                                "%s did not complete within %s",
743  	                                kind, pcmk__readable_interval(op->timeout));
744  	
745  	    } else if (op->cancel) {
746  	        /* If an in-flight recurring operation was killed because it was
747  	         * cancelled, don't treat that as a failure.
748  	         */
749  	        pcmk__info("%s[%d] terminated with signal %d (%s)", op->id, op->pid,
750  	                   signo, strsignal(signo));
751  	        services__set_result(op, PCMK_OCF_OK, PCMK_EXEC_CANCELLED, NULL);
752  	
753  	    } else {
754  	        pcmk__info("%s[%d] terminated with signal %d (%s)", op->id, op->pid,
755  	                   signo, strsignal(signo));
756  	        services__format_result(op, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_ERROR,
757  	                                "%s interrupted by %s signal",
758  	                                services__action_kind(op), strsignal(signo));
759  	    }
760  	
761  	    services__finalize_async_op(op);
762  	}
763  	
764  	/*!
765  	 * \internal
766  	 * \brief Return agent standard's exit status for "generic error"
767  	 *
768  	 * When returning an internal error for an action, a value that is appropriate
769  	 * to the action's agent standard must be used. This function returns a value
770  	 * appropriate for errors in general.
771  	 *
772  	 * \param[in] op  Action that error is for
773  	 *
774  	 * \return Exit status appropriate to agent standard
775  	 * \note Actions without a standard will get PCMK_OCF_UNKNOWN_ERROR.
776  	 */
777  	int
778  	services__generic_error(const svc_action_t *op)
779  	{
780  	    if ((op == NULL) || (op->standard == NULL)) {
781  	        return PCMK_OCF_UNKNOWN_ERROR;
782  	    }
783  	
784  	#if PCMK__ENABLE_LSB
785  	    if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)
786  	        && pcmk__str_eq(op->action, PCMK_ACTION_STATUS, pcmk__str_casei)) {
787  	
788  	        return PCMK_LSB_STATUS_UNKNOWN;
789  	    }
790  	#endif
791  	
792  	    return PCMK_OCF_UNKNOWN_ERROR;
793  	}
794  	
795  	/*!
796  	 * \internal
797  	 * \brief Return agent standard's exit status for "not installed"
798  	 *
799  	 * When returning an internal error for an action, a value that is appropriate
800  	 * to the action's agent standard must be used. This function returns a value
801  	 * appropriate for "not installed" errors.
802  	 *
803  	 * \param[in] op  Action that error is for
804  	 *
805  	 * \return Exit status appropriate to agent standard
806  	 * \note Actions without a standard will get PCMK_OCF_UNKNOWN_ERROR.
807  	 */
808  	int
809  	services__not_installed_error(const svc_action_t *op)
810  	{
811  	    if ((op == NULL) || (op->standard == NULL)) {
812  	        return PCMK_OCF_UNKNOWN_ERROR;
813  	    }
814  	
815  	#if PCMK__ENABLE_LSB
816  	    if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)
817  	        && pcmk__str_eq(op->action, PCMK_ACTION_STATUS, pcmk__str_casei)) {
818  	
819  	        return PCMK_LSB_STATUS_NOT_INSTALLED;
820  	    }
821  	#endif
822  	
823  	    return PCMK_OCF_NOT_INSTALLED;
824  	}
825  	
826  	/*!
827  	 * \internal
828  	 * \brief Return agent standard's exit status for "insufficient privileges"
829  	 *
830  	 * When returning an internal error for an action, a value that is appropriate
831  	 * to the action's agent standard must be used. This function returns a value
832  	 * appropriate for "insufficient privileges" errors.
833  	 *
834  	 * \param[in] op  Action that error is for
835  	 *
836  	 * \return Exit status appropriate to agent standard
837  	 * \note Actions without a standard will get PCMK_OCF_UNKNOWN_ERROR.
838  	 */
839  	int
840  	services__authorization_error(const svc_action_t *op)
841  	{
842  	    if ((op == NULL) || (op->standard == NULL)) {
843  	        return PCMK_OCF_UNKNOWN_ERROR;
844  	    }
845  	
846  	#if PCMK__ENABLE_LSB
847  	    if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)
848  	        && pcmk__str_eq(op->action, PCMK_ACTION_STATUS, pcmk__str_casei)) {
849  	
850  	        return PCMK_LSB_STATUS_INSUFFICIENT_PRIV;
851  	    }
852  	#endif
853  	
854  	    return PCMK_OCF_INSUFFICIENT_PRIV;
855  	}
856  	
857  	/*!
858  	 * \internal
859  	 * \brief Return agent standard's exit status for "not configured"
860  	 *
861  	 * When returning an internal error for an action, a value that is appropriate
862  	 * to the action's agent standard must be used. This function returns a value
863  	 * appropriate for "not configured" errors.
864  	 *
865  	 * \param[in] op        Action that error is for
866  	 * \param[in] is_fatal  Whether problem is cluster-wide instead of only local
867  	 *
868  	 * \return Exit status appropriate to agent standard
869  	 * \note Actions without a standard will get PCMK_OCF_UNKNOWN_ERROR.
870  	 */
871  	int
872  	services__configuration_error(const svc_action_t *op, bool is_fatal)
873  	{
874  	    if ((op == NULL) || (op->standard == NULL)) {
875  	        return PCMK_OCF_UNKNOWN_ERROR;
876  	    }
877  	
878  	#if PCMK__ENABLE_LSB
879  	    if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)
880  	        && pcmk__str_eq(op->action, PCMK_ACTION_STATUS, pcmk__str_casei)) {
881  	
882  	        return PCMK_LSB_NOT_CONFIGURED;
883  	    }
884  	#endif
885  	
886  	    return is_fatal? PCMK_OCF_NOT_CONFIGURED : PCMK_OCF_INVALID_PARAM;
887  	}
888  	
889  	
890  	/*!
891  	 * \internal
892  	 * \brief Set operation rc and status per errno from stat(), fork() or execvp()
893  	 *
894  	 * \param[in,out] op     Operation to set rc and status for
895  	 * \param[in]     error  Value of errno after system call
896  	 *
897  	 * \return void
898  	 */
899  	void
900  	services__handle_exec_error(svc_action_t * op, int error)
901  	{
902  	    const char *name = op->opaque->exec;
903  	
904  	    if (name == NULL) {
905  	        name = op->agent;
906  	        if (name == NULL) {
907  	            name = op->id;
908  	        }
909  	    }
910  	
911  	    switch (error) {   /* see execve(2), stat(2) and fork(2) */
912  	        case ENOENT:   /* No such file or directory */
913  	        case EISDIR:   /* Is a directory */
914  	        case ENOTDIR:  /* Path component is not a directory */
915  	        case EINVAL:   /* Invalid executable format */
916  	        case ENOEXEC:  /* Invalid executable format */
917  	            services__format_result(op, services__not_installed_error(op),
918  	                                    PCMK_EXEC_NOT_INSTALLED, "%s: %s",
919  	                                    name, pcmk_rc_str(error));
920  	            break;
921  	        case EACCES:   /* permission denied (various errors) */
922  	        case EPERM:    /* permission denied (various errors) */
923  	            services__format_result(op, services__authorization_error(op),
924  	                                    PCMK_EXEC_ERROR, "%s: %s",
925  	                                    name, pcmk_rc_str(error));
926  	            break;
927  	        default:
928  	            services__set_result(op, services__generic_error(op),
929  	                                 PCMK_EXEC_ERROR, pcmk_rc_str(error));
930  	    }
931  	}
932  	
933  	/*!
934  	 * \internal
935  	 * \brief Exit a child process that failed before executing agent
936  	 *
937  	 * \param[in] op           Action that failed
938  	 * \param[in] exit_status  Exit status code to use
939  	 * \param[in] exit_reason  Exit reason to output if for OCF agent
940  	 */
941  	static void
942  	exit_child(const svc_action_t *op, int exit_status, const char *exit_reason)
943  	{
944  	    if ((op != NULL) && (exit_reason != NULL)
945  	        && pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_OCF,
946  	                        pcmk__str_none)) {
947  	        fprintf(stderr, PCMK_OCF_REASON_PREFIX "%s\n", exit_reason);
948  	    }
949  	    pcmk_common_cleanup();
950  	    _exit(exit_status);
951  	}
952  	
953  	static void
954  	action_launch_child(svc_action_t *op)
955  	{
956  	    int rc;
957  	
958  	    /* SIGPIPE is ignored (which is different from signal blocking) by the gnutls library.
959  	     * Depending on the libqb version in use, libqb may set SIGPIPE to be ignored as well. 
960  	     * We do not want this to be inherited by the child process. By resetting this the signal
961  	     * to the default behavior, we avoid some potential odd problems that occur during OCF
962  	     * scripts when SIGPIPE is ignored by the environment. */
963  	    signal(SIGPIPE, SIG_DFL);
964  	
965  	    if (sched_getscheduler(0) != SCHED_OTHER) {
966  	        struct sched_param sp;
967  	
968  	        memset(&sp, 0, sizeof(sp));
969  	        sp.sched_priority = 0;
970  	
971  	        if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) {
972  	            pcmk__info("Could not reset scheduling policy for %s", op->id);
973  	        }
974  	    }
975  	
976  	    if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
977  	        pcmk__info("Could not reset process priority for %s", op->id);
978  	    }
979  	
980  	    /* Man: The call setpgrp() is equivalent to setpgid(0,0)
981  	     * _and_ compiles on BSD variants too
982  	     * need to investigate if it works the same too.
983  	     */
984  	    setpgid(0, 0);
985  	
986  	    pcmk__close_fds_in_child();
987  	
988  	    /* It would be nice if errors in this function could be reported as
989  	     * execution status (for example, PCMK_EXEC_NO_SECRETS for the secrets error
990  	     * below) instead of exit status. However, we've already forked, so
991  	     * exit status is all we have. At least for OCF actions, we can output an
992  	     * exit reason for the parent to parse.
993  	     *
994  	     * @TODO It might be better to substitute secrets in the parent before
995  	     * forking, so that if it fails, we can give a better message and result,
996  	     * and avoid the fork.
997  	     */
998  	
999  	#if PCMK__ENABLE_CIBSECRETS
1000 	    rc = pcmk__substitute_secrets(op->rsc, op->params);
1001 	    if (rc != pcmk_rc_ok) {
1002 	        if (pcmk__str_eq(op->action, PCMK_ACTION_STOP, pcmk__str_casei)) {
1003 	            pcmk__info("Proceeding with stop operation for %s despite being "
1004 	                       "unable to load CIB secrets (%s)",
1005 	                       op->rsc, pcmk_rc_str(rc));
1006 	        } else {
1007 	            pcmk__err("Considering %s unconfigured because unable to load CIB "
1008 	                      "secrets: %s",
1009 	                      op->rsc, pcmk_rc_str(rc));
1010 	            exit_child(op, services__configuration_error(op, false),
1011 	                       "Unable to load CIB secrets");
1012 	        }
1013 	    }
1014 	#endif
1015 	
1016 	    add_action_env_vars(op);
1017 	
1018 	    /* Become the desired user */
1019 	    if (op->opaque->uid && (geteuid() == 0)) {
1020 	
1021 	        // If requested, set effective group
1022 	        if (op->opaque->gid && (setgid(op->opaque->gid) < 0)) {
1023 	            pcmk__err("Considering %s unauthorized because could not set child "
1024 	                      "group to %d: %s",
1025 	                      op->id, op->opaque->gid, strerror(errno));
1026 	            exit_child(op, services__authorization_error(op),
1027 	                       "Could not set group for child process");
1028 	        }
1029 	
1030 	        // Erase supplementary group list
1031 	        // (We could do initgroups() if we kept a copy of the username)
1032 	        if (setgroups(0, NULL) < 0) {
1033 	            pcmk__err("Considering %s unauthorized because could not clear "
1034 	                      "supplementary groups: %s",
1035 	                      op->id, strerror(errno));
1036 	            exit_child(op, services__authorization_error(op),
1037 	                       "Could not clear supplementary groups for child process");
1038 	        }
1039 	
1040 	        // Set effective user
1041 	        if (setuid(op->opaque->uid) < 0) {
1042 	            pcmk__err("Considering %s unauthorized because could not set user "
1043 	                      "to %d: %s",
1044 	                      op->id, op->opaque->uid, strerror(errno));
1045 	            exit_child(op, services__authorization_error(op),
1046 	                       "Could not set user for child process");
1047 	        }
1048 	    }
1049 	
1050 	    // Execute the agent (doesn't return if successful)
1051 	    execvp(op->opaque->exec, op->opaque->args);
1052 	
1053 	    // An earlier stat() should have avoided most possible errors
1054 	    rc = errno;
1055 	    services__handle_exec_error(op, rc);
1056 	    pcmk__err("Unable to execute %s: %s", op->id, strerror(rc));
1057 	    exit_child(op, op->rc, "Child process was unable to execute file");
1058 	}
1059 	
1060 	/*!
1061 	 * \internal
1062 	 * \brief Wait for synchronous action to complete, and set its result
1063 	 *
1064 	 * \param[in,out] op    Action to wait for
1065 	 * \param[in,out] data  Child signal data
1066 	 */
1067 	static void
1068 	wait_for_sync_result(svc_action_t *op, struct sigchld_data_s *data)
1069 	{
1070 	    int status = 0;
1071 	    int timeout = op->timeout;
1072 	    time_t start = time(NULL);
1073 	    struct pollfd fds[3];
1074 	    int wait_rc = 0;
1075 	    const char *wait_reason = NULL;
1076 	
1077 	    fds[0].fd = op->opaque->stdout_fd;
1078 	    fds[0].events = POLLIN;
1079 	    fds[0].revents = 0;
1080 	
1081 	    fds[1].fd = op->opaque->stderr_fd;
1082 	    fds[1].events = POLLIN;
1083 	    fds[1].revents = 0;
1084 	
1085 	    fds[2].fd = sigchld_open(data);
1086 	    fds[2].events = POLLIN;
1087 	    fds[2].revents = 0;
1088 	
1089 	    pcmk__trace("Waiting for %s[%d]", op->id, op->pid);
1090 	    do {
1091 	        int poll_rc = poll(fds, 3, timeout);
1092 	
1093 	        wait_reason = NULL;
1094 	
1095 	        if (poll_rc > 0) {
1096 	            if (fds[0].revents & POLLIN) {
1097 	                svc_read_output(op->opaque->stdout_fd, op, FALSE);
1098 	            }
1099 	
1100 	            if (fds[1].revents & POLLIN) {
1101 	                svc_read_output(op->opaque->stderr_fd, op, TRUE);
1102 	            }
1103 	
1104 	            if ((fds[2].revents & POLLIN)
1105 	                && sigchld_received(fds[2].fd, op->pid, data)) {
1106 	                wait_rc = waitpid(op->pid, &status, WNOHANG);
1107 	
1108 	                if ((wait_rc > 0) || ((wait_rc < 0) && (errno == ECHILD))) {
1109 	                    // Child process exited or doesn't exist
1110 	                    break;
1111 	
1112 	                } else if (wait_rc < 0) {
1113 	                    wait_reason = pcmk_rc_str(errno);
1114 	                    pcmk__info("Wait for completion of %s[%d] failed: %s "
1115 	                               QB_XS " source=waitpid",
1116 	                               op->id, op->pid, wait_reason);
1117 	                    wait_rc = 0; // Act as if process is still running
1118 	
1119 	#ifndef HAVE_SYS_SIGNALFD_H
1120 	                } else {
1121 	                   /* The child hasn't exited, so this SIGCHLD could be for
1122 	                    * another child. We have to ignore it here but will still
1123 	                    * need to resend it after this synchronous action has
1124 	                    * completed and SIGCHLD has been restored to be handled by
1125 	                    * the previous handler, so that it will be handled.
1126 	                    */
1127 	                    data->ignored = true;
1128 	#endif
1129 	                }
1130 	            }
1131 	
1132 	        } else if (poll_rc == 0) {
1133 	            // Poll timed out with no descriptors ready
1134 	            timeout = 0;
1135 	            break;
1136 	
1137 	        } else if ((poll_rc < 0) && (errno != EINTR)) {
1138 	            wait_reason = pcmk_rc_str(errno);
1139 	            pcmk__info("Wait for completion of %s[%d] failed: %s "
1140 	                       QB_XS " source=poll",
1141 	                       op->id, op->pid, wait_reason);
1142 	            break;
1143 	        }
1144 	
1145 	        timeout = op->timeout - (time(NULL) - start) * 1000;
1146 	
1147 	    } while ((op->timeout < 0 || timeout > 0));
1148 	
1149 	    pcmk__trace("Stopped waiting for %s[%d]", op->id, op->pid);
1150 	    finish_op_output(op, true);
1151 	    finish_op_output(op, false);
1152 	    close_op_input(op);
1153 	    sigchld_close(fds[2].fd);
1154 	
1155 	    if (wait_rc <= 0) {
1156 	
1157 	        if ((op->timeout > 0) && (timeout <= 0)) {
1158 	            services__format_result(op, services__generic_error(op),
1159 	                                    PCMK_EXEC_TIMEOUT,
1160 	                                    "%s did not exit within specified timeout",
1161 	                                    services__action_kind(op));
1162 	            pcmk__info("%s[%d] timed out after %dms", op->id, op->pid,
1163 	                       op->timeout);
1164 	
1165 	        } else {
1166 	            services__set_result(op, services__generic_error(op),
1167 	                                 PCMK_EXEC_ERROR, wait_reason);
1168 	        }
1169 	
1170 	        /* If only child hasn't been successfully waited for, yet.
1171 	           This is to limit killing wrong target a bit more. */
1172 	        if ((wait_rc == 0) && (waitpid(op->pid, &status, WNOHANG) == 0)) {
1173 	            if (kill(op->pid, SIGKILL)) {
1174 	                pcmk__warn("Could not kill rogue child %s[%d]: %s", op->id,
1175 	                           op->pid, pcmk_rc_str(errno));
1176 	            }
1177 	            /* Safe to skip WNOHANG here as we sent non-ignorable signal. */
1178 	            while ((waitpid(op->pid, &status, 0) == (pid_t) -1)
1179 	                   && (errno == EINTR)) {
1180 	                /* keep waiting */;
1181 	            }
1182 	        }
1183 	
1184 	    } else if (WIFEXITED(status)) {
1185 	        services__set_result(op, WEXITSTATUS(status), PCMK_EXEC_DONE, NULL);
1186 	        parse_exit_reason_from_stderr(op);
1187 	        pcmk__info("%s[%d] exited with status %d", op->id, op->pid, op->rc);
1188 	
1189 	    } else if (WIFSIGNALED(status)) {
1190 	        int signo = WTERMSIG(status);
1191 	
1192 	        services__format_result(op, services__generic_error(op),
1193 	                                PCMK_EXEC_ERROR, "%s interrupted by %s signal",
1194 	                                services__action_kind(op), strsignal(signo));
1195 	        pcmk__info("%s[%d] terminated with signal %d (%s)", op->id, op->pid,
1196 	                   signo, strsignal(signo));
1197 	
1198 	#ifdef WCOREDUMP
1199 	        if (WCOREDUMP(status)) {
1200 	            pcmk__warn("%s[%d] dumped core", op->id, op->pid);
1201 	        }
1202 	#endif
1203 	
1204 	    } else {
1205 	        // Shouldn't be possible to get here
1206 	        services__set_result(op, services__generic_error(op), PCMK_EXEC_ERROR,
1207 	                             "Unable to wait for child to complete");
1208 	    }
1209 	}
1210 	
1211 	/*!
1212 	 * \internal
1213 	 * \brief Execute an action whose standard uses executable files
1214 	 *
1215 	 * \param[in,out] op  Action to execute
1216 	 *
1217 	 * \return Standard Pacemaker return value
1218 	 * \retval EBUSY          Recurring operation could not be initiated
1219 	 * \retval pcmk_rc_error  Synchronous action failed
1220 	 * \retval pcmk_rc_ok     Synchronous action succeeded, or asynchronous action
1221 	 *                        should not be freed (because it's pending or because
1222 	 *                        it failed to execute and was already freed)
1223 	 *
1224 	 * \note If the return value for an asynchronous action is not pcmk_rc_ok, the
1225 	 *       caller is responsible for freeing the action.
1226 	 */
1227 	int
1228 	services__execute_file(svc_action_t *op)
1229 	{
1230 	    int stdout_fd[2];
1231 	    int stderr_fd[2];
1232 	    int stdin_fd[2] = {-1, -1};
1233 	    int rc;
1234 	    struct stat st;
1235 	    struct sigchld_data_s data = { .ignored = false };
1236 	
1237 	    // Catch common failure conditions early
1238 	    if (stat(op->opaque->exec, &st) != 0) {
1239 	        rc = errno;
1240 	        pcmk__info("Cannot execute '%s': %s " QB_XS " stat rc=%d",
1241 	                   op->opaque->exec, pcmk_rc_str(rc), rc);
1242 	        services__handle_exec_error(op, rc);
1243 	        goto done;
1244 	    }
1245 	
1246 	    if (pipe(stdout_fd) < 0) {
1247 	        rc = errno;
1248 	        pcmk__info("Cannot execute '%s': %s " QB_XS " pipe(stdout) rc=%d",
1249 	                   op->opaque->exec, pcmk_rc_str(rc), rc);
1250 	        services__handle_exec_error(op, rc);
1251 	        goto done;
1252 	    }
1253 	
1254 	    if (pipe(stderr_fd) < 0) {
1255 	        rc = errno;
1256 	
1257 	        close_pipe(stdout_fd);
1258 	
1259 	        pcmk__info("Cannot execute '%s': %s " QB_XS " pipe(stderr) rc=%d",
1260 	                   op->opaque->exec, pcmk_rc_str(rc), rc);
1261 	        services__handle_exec_error(op, rc);
1262 	        goto done;
1263 	    }
1264 	
1265 	    if (pcmk__is_set(pcmk_get_ra_caps(op->standard), pcmk_ra_cap_stdin)) {
1266 	        if (pipe(stdin_fd) < 0) {
1267 	            rc = errno;
1268 	
1269 	            close_pipe(stdout_fd);
1270 	            close_pipe(stderr_fd);
1271 	
1272 	            pcmk__info("Cannot execute '%s': %s " QB_XS " pipe(stdin) rc=%d",
1273 	                       op->opaque->exec, pcmk_rc_str(rc), rc);
1274 	            services__handle_exec_error(op, rc);
1275 	            goto done;
1276 	        }
1277 	    }
1278 	
1279 	    if (op->synchronous && !sigchld_setup(&data)) {
1280 	        close_pipe(stdin_fd);
1281 	        close_pipe(stdout_fd);
1282 	        close_pipe(stderr_fd);
1283 	        sigchld_cleanup(&data);
1284 	        services__set_result(op, services__generic_error(op), PCMK_EXEC_ERROR,
1285 	                             "Could not manage signals for child process");
1286 	        goto done;
1287 	    }
1288 	
1289 	    op->pid = fork();
1290 	    switch (op->pid) {
1291 	        case -1:
1292 	            rc = errno;
1293 	            close_pipe(stdin_fd);
1294 	            close_pipe(stdout_fd);
1295 	            close_pipe(stderr_fd);
1296 	
1297 	            pcmk__info("Cannot execute '%s': %s " QB_XS " fork rc=%d",
1298 	                       op->opaque->exec, pcmk_rc_str(rc), rc);
1299 	            services__handle_exec_error(op, rc);
1300 	            if (op->synchronous) {
1301 	                sigchld_cleanup(&data);
1302 	            }
1303 	            goto done;
1304 	            break;
1305 	
1306 	        case 0:                /* Child */
1307 	            close(stdout_fd[0]);
1308 	            close(stderr_fd[0]);
1309 	            if (stdin_fd[1] >= 0) {
1310 	                close(stdin_fd[1]);
1311 	            }
1312 	            if (STDOUT_FILENO != stdout_fd[1]) {
1313 	                if (dup2(stdout_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
1314 	                    pcmk__warn("Can't redirect output from '%s': %s "
1315 	                               QB_XS " errno=%d",
1316 	                               op->opaque->exec, pcmk_rc_str(errno), errno);
1317 	                }
1318 	                close(stdout_fd[1]);
1319 	            }
1320 	            if (STDERR_FILENO != stderr_fd[1]) {
1321 	                if (dup2(stderr_fd[1], STDERR_FILENO) != STDERR_FILENO) {
1322 	                    pcmk__warn("Can't redirect error output from '%s': %s "
1323 	                               QB_XS " errno=%d",
1324 	                               op->opaque->exec, pcmk_rc_str(errno), errno);
1325 	                }
1326 	                close(stderr_fd[1]);
1327 	            }
1328 	            if ((stdin_fd[0] >= 0) &&
1329 	                (STDIN_FILENO != stdin_fd[0])) {
1330 	                if (dup2(stdin_fd[0], STDIN_FILENO) != STDIN_FILENO) {
1331 	                    pcmk__warn("Can't redirect input to '%s': %s "
1332 	                               QB_XS " errno=%d",
1333 	                               op->opaque->exec, pcmk_rc_str(errno), errno);
1334 	                }
1335 	                close(stdin_fd[0]);
1336 	            }
1337 	
1338 	            if (op->synchronous) {
1339 	                sigchld_cleanup(&data);
1340 	            }
1341 	
1342 	            action_launch_child(op);
1343 	            pcmk__assert(false); // action_launch_child() should not return
1344 	    }
1345 	
1346 	    /* Only the parent reaches here */
1347 	    close(stdout_fd[1]);
1348 	    close(stderr_fd[1]);
1349 	    if (stdin_fd[0] >= 0) {
1350 	        close(stdin_fd[0]);
1351 	    }
1352 	
1353 	    op->opaque->stdout_fd = stdout_fd[0];
1354 	    rc = pcmk__set_nonblocking(op->opaque->stdout_fd);
1355 	    if (rc != pcmk_rc_ok) {
1356 	        pcmk__info("Could not set '%s' output non-blocking: %s "
1357 	                   QB_XS " rc=%d",
1358 	                   op->opaque->exec, pcmk_rc_str(rc), rc);
1359 	    }
1360 	
1361 	    op->opaque->stderr_fd = stderr_fd[0];
1362 	    rc = pcmk__set_nonblocking(op->opaque->stderr_fd);
1363 	    if (rc != pcmk_rc_ok) {
1364 	        pcmk__info("Could not set '%s' error output non-blocking: %s "
1365 	                   QB_XS " rc=%d",
1366 	                   op->opaque->exec, pcmk_rc_str(rc), rc);
1367 	    }
1368 	
1369 	    op->opaque->stdin_fd = stdin_fd[1];
1370 	    if (op->opaque->stdin_fd >= 0) {
1371 	        // using buffer behind non-blocking-fd here - that could be improved
1372 	        // as long as no other standard uses stdin_fd assume stonith
1373 	        rc = pcmk__set_nonblocking(op->opaque->stdin_fd);
1374 	        if (rc != pcmk_rc_ok) {
1375 	            pcmk__info("Could not set '%s' input non-blocking: %s "
1376 	                       QB_XS " fd=%d,rc=%d", op->opaque->exec,
1377 	                       pcmk_rc_str(rc), op->opaque->stdin_fd, rc);
1378 	        }
1379 	        pipe_in_action_stdin_parameters(op);
1380 	        // as long as we are handling parameters directly in here just close
1381 	        close(op->opaque->stdin_fd);
1382 	        op->opaque->stdin_fd = -1;
1383 	    }
1384 	
1385 	    // after fds are setup properly and before we plug anything into mainloop
1386 	    if (op->opaque->fork_callback) {
1387 	        op->opaque->fork_callback(op);
1388 	    }
1389 	
1390 	    if (op->synchronous) {
1391 	        wait_for_sync_result(op, &data);
1392 	        sigchld_cleanup(&data);
1393 	        goto done;
1394 	    }
1395 	
1396 	    pcmk__trace("Waiting async for '%s'[%d]", op->opaque->exec, op->pid);
1397 	    if (pcmk__is_set(op->flags, SVC_ACTION_LEAVE_GROUP)) {
1398 	        mainloop_child_add_with_flags(op->pid, op->timeout, op->id, op,
1399 	                                      mainloop_leave_pid_group,
1400 	                                      async_action_complete);
1401 	    } else {
1402 	        mainloop_child_add_with_flags(op->pid, op->timeout, op->id, op, 0,
1403 	                                      async_action_complete);
1404 	    }
1405 	
1406 	    op->opaque->stdout_gsource = mainloop_add_fd(op->id,
1407 	                                                 G_PRIORITY_LOW,
1408 	                                                 op->opaque->stdout_fd, op,
1409 	                                                 &stdout_callbacks);
1410 	    op->opaque->stderr_gsource = mainloop_add_fd(op->id,
1411 	                                                 G_PRIORITY_LOW,
1412 	                                                 op->opaque->stderr_fd, op,
1413 	                                                 &stderr_callbacks);
1414 	    services_add_inflight_op(op);
1415 	    return pcmk_rc_ok;
1416 	
1417 	done:
1418 	    if (op->synchronous) {
1419 	        return (op->rc == PCMK_OCF_OK)? pcmk_rc_ok : pcmk_rc_error;
1420 	    } else {
1421 	        return services__finalize_async_op(op);
1422 	    }
1423 	}
1424 	
1425 	/*!
1426 	 * \internal
1427 	 * \brief \c scandir() filter for non-hidden executable regular files
1428 	 *
1429 	 * \param[in] entry  Directory entry
1430 	 *
1431 	 * \retval 1 if the entry is an executable regular file and its name does not
1432 	 *           begin with \c "."
1433 	 * \retval 0 otherwise
1434 	 */
1435 	static int
1436 	exec_file_filter(const struct dirent *entry)
1437 	{
1438 	    char *buf = NULL;
1439 	    struct stat sb;
1440 	    int rc = 0;
1441 	
1442 	    if (entry->d_name[0] == '.') {
1443 	        return rc;
1444 	    }
1445 	
1446 	    buf = pcmk__assert_asprintf("%s/%s", filter_dir, entry->d_name);
1447 	
1448 	    if ((stat(buf, &sb) == 0) && S_ISREG(sb.st_mode)
1449 	        && pcmk__any_flags_set(sb.st_mode, S_IXUSR|S_IXGRP|S_IXOTH)) {
1450 	
1451 	        rc = 1;
1452 	    }
1453 	
1454 	    free(buf);
1455 	    return rc;
1456 	}
1457 	
1458 	/*!
1459 	 * \internal
1460 	 * \brief \c scandir() filter for non-hidden directories
1461 	 *
1462 	 * \param[in] entry  Directory entry
1463 	 *
1464 	 * \retval 1 if the entry is a directory and its name does not begin with \c "."
1465 	 * \retval 0 otherwise
1466 	 */
1467 	static int
1468 	directory_filter(const struct dirent *entry)
1469 	{
1470 	    char *buf = NULL;
1471 	    struct stat sb;
1472 	    int rc = 0;
1473 	
1474 	    if (entry->d_name[0] == '.') {
1475 	        return rc;
1476 	    }
1477 	
1478 	    buf = pcmk__assert_asprintf("%s/%s", filter_dir, entry->d_name);
1479 	
1480 	    if ((stat(buf, &sb) == 0) && S_ISDIR(sb.st_mode)) {
1481 	        rc = 1;
1482 	    }
1483 	
1484 	    free(buf);
1485 	    return rc;
1486 	}
1487 	
1488 	/*!
1489 	 * \internal
1490 	 * \brief List directory's top-level contents of the given type
1491 	 *
1492 	 * Hidden files (those beginning with \c '.') are skipped.
1493 	 *
1494 	 * \param[in] dir         Full path of directory to list
1495 	 * \param[in] exec_files  If \c true, list only executable files within \p dir.
1496 	 *                        If \c false, list only directories within \p dir.
1497 	 *
1498 	 * \return Newly allocated list of newly allocated names of directory entries
1499 	 *
1500 	 * \note The caller is responsible for freeing the return value using
1501 	 *       <tt>g_list_free_full(list, free)</tt>.
1502 	 */
1503 	GList *
1504 	services__list_dir(const char *dir, bool exec_files)
1505 	{
1506 	    GList *list = NULL;
1507 	    struct dirent **namelist = NULL;
1508 	    int entries = 0;
1509 	
1510 	    filter_dir = dir;
1511 	    entries = scandir(dir, &namelist,
1512 	                      (exec_files? exec_file_filter : directory_filter),
1513 	                      alphasort);
1514 	    filter_dir = NULL;
1515 	
1516 	    if (entries < 0) {
1517 	        return NULL;
1518 	    }
1519 	
1520 	    for (int i = 0; i < entries; i++) {
1521 	        list = g_list_append(list, pcmk__str_copy(namelist[i]->d_name));
1522 	        free(namelist[i]);
1523 	    }
1524 	    free(namelist);
1525 	    return list;
1526 	}
1527