mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
libctdb: test: logging enhancement
Make children log through a pipe to the parent, which then spits it out only if the child has a problem. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (This used to be ctdb commit 8ac006cf6c6cbfd3fe1606178eb0f0127d33f632)
This commit is contained in:
parent
4c0f3dcffe
commit
fee11bf13b
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "tui.h"
|
||||
#include "log.h"
|
||||
#include "failtest.h"
|
||||
#include "ctdb-test.h"
|
||||
#include "talloc.h"
|
||||
#include "dlinklist.h"
|
||||
#include <stdlib.h>
|
||||
@ -229,8 +230,10 @@ bool should_i_fail_once(const char *location)
|
||||
bool should_i_fail(const char *func)
|
||||
{
|
||||
pid_t child;
|
||||
int status;
|
||||
int status, pfd[2];
|
||||
struct fail_decision *dec;
|
||||
size_t log_size;
|
||||
char *log;
|
||||
|
||||
if (failpath)
|
||||
return do_failpath(func);
|
||||
@ -253,6 +256,9 @@ bool should_i_fail(const char *func)
|
||||
|
||||
DLIST_ADD_END(decisions, dec, struct fail_decision);
|
||||
|
||||
if (pipe(pfd) != 0)
|
||||
err(1, "pipe failed for failtest!");
|
||||
|
||||
fflush(stdout);
|
||||
child = fork();
|
||||
if (child == -1)
|
||||
@ -261,6 +267,10 @@ bool should_i_fail(const char *func)
|
||||
/* The child actually fails. The script will screw up at this
|
||||
* point, but should not crash. */
|
||||
if (child == 0) {
|
||||
/* Log to parent (including stderr if things go really bad). */
|
||||
close(pfd[0]);
|
||||
dup2(pfd[1], STDOUT_FILENO);
|
||||
dup2(pfd[1], STDERR_FILENO);
|
||||
dec->failed = true;
|
||||
if (!failtest_no_report || !strstr(func, failtest_no_report))
|
||||
fails++;
|
||||
@ -268,6 +278,10 @@ bool should_i_fail(const char *func)
|
||||
}
|
||||
|
||||
dec->failed = false;
|
||||
|
||||
close(pfd[1]);
|
||||
log = grab_fd(pfd[0], &log_size);
|
||||
|
||||
while (waitpid(child, &status, 0) < 0) {
|
||||
if (errno != EINTR)
|
||||
err(1, "failtest waitpid failed for child %i",
|
||||
@ -276,19 +290,20 @@ bool should_i_fail(const char *func)
|
||||
|
||||
/* If child succeeded, or mere script failure, continue. */
|
||||
if (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS
|
||||
|| WEXITSTATUS(status) == EXIT_SCRIPTFAIL))
|
||||
|| WEXITSTATUS(status) == EXIT_SCRIPTFAIL)) {
|
||||
talloc_free(log);
|
||||
return false;
|
||||
|
||||
/* Report unless child already reported it. */
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SILENT) {
|
||||
/* Reproduce child's path */
|
||||
dec->failed = true;
|
||||
log_line(LOG_ALWAYS, "Child %s %i on failure path: %s",
|
||||
WIFEXITED(status) ? "exited" : "signalled",
|
||||
WIFEXITED(status) ? WEXITSTATUS(status)
|
||||
: WTERMSIG(status), failpath_string());
|
||||
}
|
||||
exit(EXIT_SILENT);
|
||||
|
||||
/* Reproduce child's path */
|
||||
dec->failed = true;
|
||||
|
||||
log_line(LOG_ALWAYS, "Child %s %i on failure path: %s",
|
||||
WIFEXITED(status) ? "exited" : "signalled",
|
||||
WIFEXITED(status) ? WEXITSTATUS(status)
|
||||
: WTERMSIG(status), failpath_string());
|
||||
log_line(LOG_ALWAYS, "Child output:\n%s", log);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void dump_failinfo(void)
|
||||
|
@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "expect.h"
|
||||
#include <string.h>
|
||||
#include <talloc.h>
|
||||
#include <err.h>
|
||||
|
||||
static struct {
|
||||
enum log_type type;
|
||||
@ -37,7 +38,6 @@ static struct {
|
||||
{ LOG_VERBOSE, "verbose" },
|
||||
};
|
||||
|
||||
static FILE *logstream;
|
||||
static int typemask = ~LOG_VERBOSE;
|
||||
|
||||
bool log_line(enum log_type type, const char *format, ...)
|
||||
@ -50,8 +50,10 @@ bool log_line(enum log_type type, const char *format, ...)
|
||||
line = talloc_vasprintf(NULL, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!type || (type & typemask))
|
||||
fprintf(logstream ?: stderr, "%s\n", line);
|
||||
if (!type || (type & typemask)) {
|
||||
printf("%s\n", line);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
ret = expect_log_hook(line);
|
||||
talloc_free(line);
|
||||
@ -69,8 +71,9 @@ static void log_partial_v(enum log_type type,
|
||||
|
||||
/* write to the end of buffer */
|
||||
if (vsnprintf(buf + len, bufsize - len - 1, format, ap)
|
||||
> bufsize - len - 1)
|
||||
log_line(LOG_ALWAYS, "log_line_partial buffer is full!");
|
||||
> bufsize - len - 1) {
|
||||
errx(1, "log_line_partial buffer is full!");
|
||||
}
|
||||
|
||||
ptr = buf;
|
||||
|
||||
@ -222,7 +225,6 @@ static void log_admin_help(int agc, char **argv)
|
||||
|
||||
static void log_init(void)
|
||||
{
|
||||
logstream = stdout;
|
||||
if (tui_quiet)
|
||||
typemask = 0;
|
||||
tui_register_command("log", log_admin, log_admin_help);
|
||||
|
@ -44,5 +44,4 @@ bool log_line(enum log_type type, const char *format, ...);
|
||||
/* Builds up buffer and prints out line at a time. */
|
||||
void log_partial(enum log_type type, char *buf, unsigned bufsize,
|
||||
const char *format, ...);
|
||||
|
||||
#endif /* __HAVE_LOG_H */
|
||||
|
@ -56,7 +56,6 @@ static inline bool strends(const char *a, const char *b)
|
||||
enum exitcodes {
|
||||
/* EXIT_SUCCESS, EXIT_FAILURE is in stdlib.h */
|
||||
EXIT_SCRIPTFAIL = EXIT_FAILURE + 1,
|
||||
EXIT_SILENT,
|
||||
};
|
||||
|
||||
/* init code */
|
||||
|
Loading…
x
Reference in New Issue
Block a user