Author: aconway
Date: Wed Dec 10 22:17:29 2014
New Revision: 1644532
URL: http://svn.apache.org/r1644532
Log:
DISPATCH-83: Error messages are not displayed if an error occurs when starting
in deamon mode.
Examples:
$ qdrouterd -d -U xx
Daemon error: Can't look up user xx
$ qdrouterd -d -I xx
Daemon error: Cannot stat python library path 'xx'
$ qdrouterd -d -c xx
Daemon error: Exception: Cannot load configuration file xx: [Errno 2] No such
file or directory: 'xx'
$ qdrouterd -d -P /xx
Daemon error: Can't write pidfile /xx
Modified:
qpid/dispatch/trunk/include/qpid/dispatch/error.h
qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
qpid/dispatch/trunk/router/src/main.c
qpid/dispatch/trunk/src/error.c
Modified: qpid/dispatch/trunk/include/qpid/dispatch/error.h
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/include/qpid/dispatch/error.h?rev=1644532&r1=1644531&r2=1644532&view=diff
==============================================================================
--- qpid/dispatch/trunk/include/qpid/dispatch/error.h (original)
+++ qpid/dispatch/trunk/include/qpid/dispatch/error.h Wed Dec 10 22:17:29 2014
@@ -46,7 +46,8 @@ typedef enum {
QD_ERROR_CONFIG, ///< Error in configuration
QD_ERROR_TYPE, ///< Value of inappropriate type.
QD_ERROR_VALUE, ///< Invalid value.
- QD_ERROR_RUNTIME ///< Run-time failure.
+ QD_ERROR_RUNTIME, ///< Run-time failure.
+ QD_ERROR_SYSTEM ///< System error from errno
} qd_error_t;
ENUM_DECLARE(qd_error);
@@ -62,8 +63,9 @@ qd_error_t qd_error_impl(qd_error_t code
/**
* Clear thread-local error code and message.
+ *@return QD_ERROR_NONE
*/
-void qd_error_clear();
+qd_error_t qd_error_clear();
/**
* @return Thread local error message. Includes text for error code.
@@ -96,4 +98,14 @@ qd_error_t qd_error_py_impl(const char *
#define QD_ERROR_RET() do { if (qd_error_code()) return qd_error_code(); }
while(0)
#define QD_ERROR_PY_RET() do { if (qd_error_py()) return qd_error_code(); }
while(0)
+/**
+ * Check for an errno error.
+ *
+ * If errnum is non-0, set error code QD_ERROR_SYSTEM with a message including
the errno text.
+ * Otherwise, call qd_error_clear() and return QD_ERROR_NONE.
+ */
+#define qd_error_errno(errnum, fmt, ...) qd_error_impl(errnum, __FILE__,
__LINE__, fmt, ##__VA_ARGS__)
+
+qd_error_t qd_error_errno_impl(int errnum, const char *file, int line, const
char *fmt, ...);
+
#endif
Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py?rev=1644532&r1=1644531&r2=1644532&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
(original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py Wed
Dec 10 22:17:29 2014
@@ -36,7 +36,10 @@ class Config(object):
self.config_types = [e for e in schema.entity_types.itervalues()
if schema.is_configuration(e)]
if filename:
- self.load(filename)
+ try:
+ self.load(filename)
+ except Exception, e:
+ raise Exception("Cannot load configuration file %s: %s" %
(filename, e))
else:
self.entities = []
Modified: qpid/dispatch/trunk/router/src/main.c
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/router/src/main.c?rev=1644532&r1=1644531&r2=1644532&view=diff
==============================================================================
--- qpid/dispatch/trunk/router/src/main.c (original)
+++ qpid/dispatch/trunk/router/src/main.c Wed Dec 10 22:17:29 2014
@@ -25,7 +25,9 @@
#include <pwd.h>
#include <fcntl.h>
#include <unistd.h>
+#include <string.h>
#include <getopt.h>
+#include <errno.h>
#include "config.h"
static int exit_with_sigint = 0;
@@ -82,16 +84,31 @@ static void server_signal_handler(void*
static void check(int fd) {
if (qd_error_code()) {
qd_log(log_source, QD_LOG_CRITICAL, "Router start-up failed: %s",
qd_error_message());
- if (fd > 0)
- write(fd, "X", 1);
+ write(fd, qd_error_message(), strlen(qd_error_message()));
+ char eos = '\0';
+ write(fd, &eos, 1);
+ close(fd);
exit(1);
}
}
+#define fail(fd, fmt, ...) \
+ do { \
+ if (!qd_error_errno(errno, fmt, ##__VA_ARGS__)) \
+ qd_error(QD_ERROR_RUNTIME, fmt, ##__VA_ARGS__); \
+ check(fd); \
+ } while(false)
static void main_process(const char *config_path, const char *python_pkgdir,
int fd)
{
qd_error_clear();
+ struct stat st;
+ if (stat(python_pkgdir, &st)) fail(fd, "Cannot stat python library path
'%s'", python_pkgdir);
+ if (!S_ISDIR(st.st_mode)) {
+ qd_error(QD_ERROR_RUNTIME, "Python library path '%s' not a directory",
python_pkgdir);
+ check(fd);
+ }
+
dispatch = qd_dispatch(python_pkgdir);
check(fd);
log_source = qd_log_source("MAIN"); /* Logging is initialized by
qd_dispatch. */
@@ -108,7 +125,7 @@ static void main_process(const char *con
signal(SIGINT, signal_handler);
if (fd > 0) {
- write(fd, "0", 1); // Success signal
+ dprintf(fd, "ok"); // Success signal
close(fd);
}
@@ -155,11 +172,7 @@ static void daemon_process(const char *c
//
// Detach any terminals and create an independent session
//
- if (setsid() < 0) {
- write(pipefd[1], "1", 1);
- exit(0);
- }
-
+ if (setsid() < 0) fail(pipefd[1], "Cannot start a new session");
//
// Second fork
//
@@ -174,45 +187,27 @@ static void daemon_process(const char *c
close(1);
close(0);
int fd = open("/dev/null", O_RDWR);
- if (fd != 0) {
- write(pipefd[1], "2", 1);
- exit(0);
- }
- if (dup(fd) < 0) {
- write(pipefd[1], "3", 1);
- exit(0);
- }
- if (dup(fd) < 0) {
- write(pipefd[1], "4", 1);
- exit(0);
- }
+ if (fd != 0) fail(pipefd[1], "Can't redirect stdin to /dev/null");
+ if (dup(fd) < 0) fail(pipefd[1], "Can't redirect stdout to
/dev/null");
+ if (dup(fd) < 0) fail(pipefd[1], "Can't redirect stderr
/dev/null");
//
// Set the umask to 0
//
- if (umask(0) < 0) {
- write(pipefd[1], "5", 1);
- exit(0);
- }
+ if (umask(0) < 0) fail(pipefd[1], "Can't set umask");
//
// Set the current directory to "/" to avoid blocking
// mount points
//
- if (chdir("/") < 0) {
- write(pipefd[1], "6", 1);
- exit(0);
- }
+ if (chdir("/") < 0) fail(pipefd[1], "Can't chdir /");
//
// If a pidfile was provided, write the daemon pid there.
//
if (pidfile) {
FILE *pf = fopen(pidfile, "w");
- if (pf == 0) {
- write(pipefd[1], "7", 1);
- exit(0);
- }
+ if (pf == 0) fail(pipefd[1], "Can't write pidfile %s",
pidfile);
fprintf(pf, "%d\n", getpid());
fclose(pf);
}
@@ -223,18 +218,9 @@ static void daemon_process(const char *c
//
if (user) {
struct passwd *pwd = getpwnam(user);
- if (pwd == 0) {
- write(pipefd[1], "8", 1);
- exit(0);
- }
- if (setuid(pwd->pw_uid) < 0) {
- write(pipefd[1], "9", 1);
- exit(0);
- }
- if (setgid(pwd->pw_gid) < 0) {
- write(pipefd[1], "A", 1);
- exit(0);
- }
+ if (pwd == 0) fail(pipefd[1], "Can't look up user %s", user);
+ if (setuid(pwd->pw_uid) < 0) fail(pipefd[1], "Can't set user
ID for user %s", user);
+ if (setgid(pwd->pw_gid) < 0) fail(pipefd[1], "Cant set group
ID for user %s", user);
}
main_process(config_path, python_pkgdir, pipefd[1]);
@@ -249,16 +235,17 @@ static void daemon_process(const char *c
// Wait for a success signal ('0') from the daemon process.
// If we get success, exit with 0. Otherwise, exit with 1.
//
- char code;
close(pipefd[1]); // Close write end.
- if (read(pipefd[0], &code, 1) < 0) {
+ char result[256];
+ memset(result, 0, sizeof(result));
+ if (read(pipefd[0], &result, sizeof(result)-1) < 0) {
perror("Error reading inter-process pipe");
exit(1);
}
- if (code == '0')
+ if (strcmp(result, "ok") == 0)
exit(0);
- fprintf(stderr, "Error occurred during daemon initialization, please
see logs. [code=%c]\n", code);
+ fprintf(stderr, "Daemon error: %s\n", result);
exit(1);
}
}
@@ -337,6 +324,7 @@ int main(int argc, char **argv)
usage(argv);
exit(1);
}
+
if (daemon_mode)
daemon_process(config_path, python_pkgdir, pidfile, user);
else
Modified: qpid/dispatch/trunk/src/error.c
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/error.c?rev=1644532&r1=1644531&r2=1644532&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/error.c (original)
+++ qpid/dispatch/trunk/src/error.c Wed Dec 10 22:17:29 2014
@@ -23,6 +23,7 @@
#include <qpid/dispatch/log.h>
#include <stdarg.h>
#include <stdio.h>
+#include <errno.h>
#include "log_private.h"
#include "aprintf.h"
@@ -36,7 +37,8 @@ static const char *qd_error_names[] = {
"Configuration",
"Type",
"Value",
- "Run Time"
+ "Run Time",
+ "System"
};
ENUM_DEFINE(qd_error, qd_error_names);
@@ -60,11 +62,13 @@ qd_error_t qd_error_impl(qd_error_t code
if (code) {
char *begin = ts.error_message;
char *end = begin + ERROR_MAX;
- const char* name = qd_error_name(code);
- if (name)
- aprintf(&begin, end, "%s: ", name);
- else
- aprintf(&begin, end, "%d: ", code);
+ /* FIXME aconway 2014-12-10: */
+ (void)aprintf;
+ /* const char* name = qd_error_name(code); */
+ /* if (name) */
+ /* aprintf(&begin, end, "%s: ", name); */
+ /* else */
+ /* aprintf(&begin, end, "%d: ", code); */
va_list arglist;
va_start(arglist, fmt);
vaprintf(&begin, end, fmt, arglist);
@@ -78,9 +82,10 @@ qd_error_t qd_error_impl(qd_error_t code
return 0;
}
-void qd_error_clear() {
+qd_error_t qd_error_clear() {
ts.error_code = 0;
snprintf(ts.error_message, ERROR_MAX, "No Error");
+ return QD_ERROR_NONE;
}
const char* qd_error_message() {
@@ -168,3 +173,23 @@ qd_error_t qd_error_py_impl(const char *
}
return qd_error_code();
}
+
+qd_error_t qd_error_errno_impl(int errnum, const char *file, int line, const
char *fmt, ...) {
+ if (errnum) {
+ ts.error_code = QD_ERROR_SYSTEM;
+ char buf[ERROR_MAX];
+ char *errstr = strerror_r(errno, buf, sizeof(buf));
+
+ char *begin = ts.error_message;
+ char *end = begin + ERROR_MAX;
+ va_list arglist;
+ va_start(arglist, fmt);
+ vaprintf(&begin, end, fmt, arglist);
+ va_end(arglist);
+ aprintf(&begin, end, ": %s", errstr);
+ qd_log_impl(log_source, QD_LOG_ERROR, file, line, "%s",
qd_error_message());
+ return qd_error_code();
+ }
+ else
+ return qd_error_clear();
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]