Blob Blame History Raw
commit 2c6e6e1ad3ecbb186f9a43f89280d0d4391277e5
Author: Andrew Beekhof <andrew@beekhof.net>
Date:   Tue Apr 8 12:13:44 2014 +1000

    Fix: lrmd: Provide stderr output from agents if available, otherwise fall back to stdout
    
    (cherry picked from commit d9cc751625ff3adfa158a2f769ab9038f6e317fd)

diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c
index ac0138f..534e362 100644
--- a/lib/services/services_linux.c
+++ b/lib/services/services_linux.c
@@ -57,34 +57,37 @@ set_fd_opts(int fd, int opts)
 }
 
 static gboolean
-read_output(int fd, svc_action_t * op)
+svc_read_output(int fd, svc_action_t * op, bool is_stderr)
 {
     char *data = NULL;
     int rc = 0, len = 0;
-    gboolean is_err = FALSE;
     char buf[500];
     static const size_t buf_read_len = sizeof(buf) - 1;
 
-    crm_trace("%p", op);
 
     if (fd < 0) {
+        crm_trace("No fd for %s", op->id);
         return FALSE;
     }
 
-    if (fd == op->opaque->stderr_fd) {
-        is_err = TRUE;
-        if (op->stderr_data) {
-            len = strlen(op->stderr_data);
-            data = op->stderr_data;
-        }
-    } else if (op->stdout_data) {
+    if (is_stderr && op->stderr_data) {
+        len = strlen(op->stderr_data);
+        data = op->stderr_data;
+        crm_trace("Reading %s stderr into offset %d", op->id, len);
+
+    } else if (is_stderr == FALSE && op->stdout_data) {
         len = strlen(op->stdout_data);
         data = op->stdout_data;
+        crm_trace("Reading %s stdout into offset %d", op->id, len);
+
+    } else {
+        crm_trace("Reading %s %s", op->id, is_stderr?"stderr":"stdout", len);
     }
 
     do {
         rc = read(fd, buf, buf_read_len);
         if (rc > 0) {
+            crm_trace("Got %d characters starting with %.20s", rc, buf);
             buf[rc] = 0;
             data = realloc(data, len + rc + 1);
             sprintf(data + len, "%s", buf);
@@ -99,7 +102,7 @@ read_output(int fd, svc_action_t * op)
 
     } while (rc == buf_read_len || rc < 0);
 
-    if (data != NULL && is_err) {
+    if (data != NULL && is_stderr) {
         op->stderr_data = data;
     } else if (data != NULL) {
         op->stdout_data = data;
@@ -113,7 +116,7 @@ dispatch_stdout(gpointer userdata)
 {
     svc_action_t *op = (svc_action_t *) userdata;
 
-    return read_output(op->opaque->stdout_fd, op);
+    return svc_read_output(op->opaque->stdout_fd, op, FALSE);
 }
 
 static int
@@ -121,7 +124,7 @@ dispatch_stderr(gpointer userdata)
 {
     svc_action_t *op = (svc_action_t *) userdata;
 
-    return read_output(op->opaque->stderr_fd, op);
+    return svc_read_output(op->opaque->stderr_fd, op, TRUE);
 }
 
 static void
@@ -264,18 +267,23 @@ operation_finished(mainloop_child_t * p, pid_t pid, int core, int signo, int exi
     op->status = PCMK_LRM_OP_DONE;
     CRM_ASSERT(op->pid == pid);
 
+    crm_trace("%s %p %p", prefix, op->opaque->stderr_gsource, op->opaque->stdout_gsource);
     if (op->opaque->stderr_gsource) {
         /* Make sure we have read everything from the buffer.
          * Depending on the priority mainloop gives the fd, operation_finished
          * could occur before all the reads are done.  Force the read now.*/
+        crm_trace("%s dispatching stderr", prefix);
         dispatch_stderr(op);
+        crm_trace("%s: %p", op->stderr_data);
     }
 
     if (op->opaque->stdout_gsource) {
         /* Make sure we have read everything from the buffer.
          * Depending on the priority mainloop gives the fd, operation_finished
          * could occur before all the reads are done.  Force the read now.*/
+        crm_trace("%s dispatching stdout", prefix);
         dispatch_stdout(op);
+        crm_trace("%s: %p", op->stdout_data);
     }
 
     if (signo) {
@@ -495,11 +503,11 @@ services_os_action_execute(svc_action_t * op, gboolean synchronous)
 
             if (poll_rc > 0) {
                 if (fds[0].revents & POLLIN) {
-                    read_output(op->opaque->stdout_fd, op);
+                    svc_read_output(op->opaque->stdout_fd, op, FALSE);
                 }
 
                 if (fds[1].revents & POLLIN) {
-                    read_output(op->opaque->stderr_fd, op);
+                    svc_read_output(op->opaque->stderr_fd, op, TRUE);
                 }
 
                 if (fds[2].revents & POLLIN) {
@@ -578,8 +586,8 @@ services_os_action_execute(svc_action_t * op, gboolean synchronous)
         }
 #endif
 
-        read_output(op->opaque->stdout_fd, op);
-        read_output(op->opaque->stderr_fd, op);
+        svc_read_output(op->opaque->stdout_fd, op, FALSE);
+        svc_read_output(op->opaque->stderr_fd, op, TRUE);
 
         close(op->opaque->stdout_fd);
         close(op->opaque->stderr_fd);
diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c
index 65421d0..517e98f 100644
--- a/lrmd/lrmd.c
+++ b/lrmd/lrmd.c
@@ -599,7 +599,9 @@ action_complete(svc_action_t * action)
     cmd->lrmd_op_status = action->status;
     rsc = cmd->rsc_id ? g_hash_table_lookup(rsc_list, cmd->rsc_id) : NULL;
 
-    if (action->stdout_data) {
+    if (action->stderr_data) {
+        cmd->output = strdup(action->stderr_data);
+    } else if (action->stdout_data) {
         cmd->output = strdup(action->stdout_data);
     }
 #if SUPPORT_NAGIOS