Skip to content

Commit

Permalink
Enable logging to syslog.
Browse files Browse the repository at this point in the history
  • Loading branch information
davmac314 committed Jun 11, 2016
1 parent 95c34ef commit a2c7e27
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 31 deletions.
33 changes: 17 additions & 16 deletions src/dinit-log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <unistd.h>
#include <fcntl.h>
#include <sys/syslog.h>

#include "dasync.h"

Expand Down Expand Up @@ -115,7 +116,7 @@ void BufferedLogStream::flushForRelease()
Rearm BufferedLogStream::gotEvent(EventLoop_t *loop, int fd, int flags) noexcept
{
auto &log_stream = *this;

if ((! partway) && log_stream.special) {
char * start = log_stream.special_buf + log_stream.msg_index;
char * end = std::find(log_stream.special_buf + log_stream.msg_index, (char *)nullptr, '\n');
Expand All @@ -137,9 +138,8 @@ Rearm BufferedLogStream::gotEvent(EventLoop_t *loop, int fd, int flags) noexcept
return Rearm::REARM;
}
}
else {
// spurious readiness, or EAGAIN/EWOULDBLOCK/EINTR
// There's not much we can do for other errors anyway.
else if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
return Rearm::REMOVE;
}
return Rearm::REARM;
}
Expand All @@ -148,7 +148,7 @@ Rearm BufferedLogStream::gotEvent(EventLoop_t *loop, int fd, int flags) noexcept

// TODO issue special message if we have discarded a log message

if (log_stream.current_index == 0) {
if (current_index == 0) {
release_console();
return Rearm::DISARM;
}
Expand Down Expand Up @@ -181,6 +181,9 @@ Rearm BufferedLogStream::gotEvent(EventLoop_t *loop, int fd, int flags) noexcept
}
}
}
else if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
return Rearm::REMOVE;
}
}

// We've written something by the time we get here. We could fall through to below, but
Expand All @@ -201,8 +204,8 @@ void init_log(ServiceSet *sset)
// Potentially throws std::bad_alloc or std::system_error
void setup_main_log(int fd)
{
log_stream[DLOG_MAIN].init(STDERR_FILENO);
log_stream[DLOG_MAIN].registerWith(&eventLoop, STDERR_FILENO, out_events);
log_stream[DLOG_MAIN].init(fd);
log_stream[DLOG_MAIN].registerWith(&eventLoop, fd, out_events);
}

bool is_log_flushed() noexcept
Expand Down Expand Up @@ -237,7 +240,7 @@ static int sum_length(const char *arg) noexcept
return std::strlen(arg);
}

template <typename U, typename ... T> static int sum_length(U first, T ... args) noexcept
template <typename ... T> static int sum_length(const char * first, T ... args) noexcept
{
return sum_length(first) + sum_length(args...);
}
Expand All @@ -248,7 +251,7 @@ static void append(BufferedLogStream &buf, const char *s)
buf.append(s, std::strlen(s));
}

template <typename U, typename ... T> static void append(BufferedLogStream &buf, U u, T ... t)
template <typename ... T> static void append(BufferedLogStream &buf, const char *u, T ... t)
{
append(buf, u);
append(buf, t...);
Expand Down Expand Up @@ -289,7 +292,11 @@ template <typename ... T> static void do_log_main(T ... args) noexcept
{
log_current_line[DLOG_CONS] = false;
log_current_line[DLOG_MAIN] = true;
push_to_log(args...);

char svcbuf[10];
snprintf(svcbuf, 10, "<%d> ", LOG_DAEMON | LOG_NOTICE);

push_to_log(svcbuf, args...);
}

// Log a message. A newline will be appended.
Expand All @@ -314,12 +321,6 @@ template <typename T> static void do_log_part(int idx, T arg) noexcept
}
}

// Log part of a message. A series of calls to do_log_part must be followed by a call to do_log_commit.
template <typename T> static void do_log_part(T arg) noexcept
{
do_log_part(DLOG_CONS, arg);
}

// Commit a message that was issued as a series of parts (via do_log_part).
static void do_log_commit(int idx) noexcept
{
Expand Down
73 changes: 60 additions & 13 deletions src/dinit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,11 @@ using EventLoop_t = EventLoop<NullMutex>;

EventLoop_t eventLoop = EventLoop_t();

// TODO remove:
//static void sigint_reboot_cb(struct ev_loop *loop, ev_signal *w, int revents);
//static void sigquit_cb(struct ev_loop *loop, ev_signal *w, int revents);
//static void sigterm_cb(struct ev_loop *loop, ev_signal *w, int revents);
static void sigint_reboot_cb(EventLoop_t *eloop) noexcept;
static void sigquit_cb(EventLoop_t *eloop) noexcept;
static void sigterm_cb(EventLoop_t *eloop) noexcept;
void open_control_socket(EventLoop_t *loop) noexcept;
void close_control_socket(EventLoop_t *loop) noexcept;
static void open_control_socket(EventLoop_t *loop) noexcept;
static void close_control_socket(EventLoop_t *loop) noexcept;

static void control_socket_cb(EventLoop_t *loop, int fd);

Expand Down Expand Up @@ -106,13 +102,16 @@ static ServiceSet *service_set;
static bool am_system_init = false; // true if we are the system init process

static bool control_socket_open = false;
static bool external_log_open = false;
int active_control_conns = 0;

// Control socket path. We maintain a string (control_socket_str) in case we need
// to allocate storage, but control_socket_path is the authoritative value.
static const char *control_socket_path = "/dev/dinitctl";
static std::string control_socket_str;

static const char *log_socket_path = "/dev/log";

static const char *user_home_path = nullptr;


Expand Down Expand Up @@ -300,7 +299,6 @@ int main(int argc, char **argv)
}

// Set up signal handlers
//ev_signal sigint_ev_signal;
CallbackSignalHandler sigint_watcher;
if (am_system_init) {
sigint_watcher.setCbFunc(sigint_reboot_cb);
Expand Down Expand Up @@ -425,7 +423,6 @@ int main(int argc, char **argv)

// PID 1 must not actually exit, although we should never reach this point:
while (true) {
// ev_loop(loop, EVLOOP_ONESHOT);
eventLoop.run();
}
}
Expand Down Expand Up @@ -454,7 +451,7 @@ static void control_socket_cb(EventLoop_t *loop, int sockfd)
}
}

void open_control_socket(EventLoop_t *loop) noexcept
static void open_control_socket(EventLoop_t *loop) noexcept
{
if (! control_socket_open) {
const char * saddrname = control_socket_path;
Expand Down Expand Up @@ -508,17 +505,14 @@ void open_control_socket(EventLoop_t *loop) noexcept
}

control_socket_open = true;
//ev_io_init(&control_socket_io, control_socket_cb, sockfd, EV_READ);
//ev_io_start(loop, &control_socket_io);
control_socket_io.registerWith(&eventLoop, sockfd, in_events);
}
}

void close_control_socket(EventLoop_t *loop) noexcept
static void close_control_socket(EventLoop_t *loop) noexcept
{
if (control_socket_open) {
int fd = control_socket_io.fd;
//ev_io_stop(loop, &control_socket_io);
control_socket_io.deregisterWatch(&eventLoop);
close(fd);

Expand All @@ -527,6 +521,59 @@ void close_control_socket(EventLoop_t *loop) noexcept
}
}

static void setup_external_log() noexcept
{
if (! external_log_open) {

const char * saddrname = log_socket_path;
uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen(saddrname) + 1;

struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
if (name == nullptr) {
log(LogLevel::ERROR, "Connecting to log socket: out of memory");
return;
}

name->sun_family = AF_UNIX;
strcpy(name->sun_path, saddrname);

int sockfd = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
if (sockfd == -1) {
log(LogLevel::ERROR, "Error creating log socket: ", strerror(errno));
free(name);
return;
}

if (connect(sockfd, (struct sockaddr *) name, sockaddr_size) == 0 || errno == EINPROGRESS) {
// TODO for EINPROGRESS, set up a watcher so we can properly wait until
// connection is established (or fails) before we pass it to the logging subsystem.
try {
setup_main_log(sockfd);
}
catch (std::exception &e) {
log(LogLevel::ERROR, "Setting up log failed: ", e.what());
close(sockfd);
}
}
else {
// Note if connect fails, we haven't warned at all, because the syslog server might not
// have started yet. TODO, have a special startup flag to indicate when syslog should
// be available.
close(sockfd);
}

free(name);
}
}

// Called from service when the system is "rw ready" (filesystem mounted r/w etc).
// May be called more than once.
void system_rw_ready() noexcept
{
open_control_socket(&eventLoop);
setup_external_log();
}

/* handle SIGINT signal (generated by kernel when ctrl+alt+del pressed) */
static void sigint_reboot_cb(EventLoop_t *eloop) noexcept
{
Expand Down
4 changes: 2 additions & 2 deletions src/service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/

// from dinit.cc:
void open_control_socket(EventLoop_t *loop) noexcept;
void system_rw_ready() noexcept;
extern EventLoop_t eventLoop;

// Find the requested service by name
Expand Down Expand Up @@ -558,7 +558,7 @@ void ServiceRecord::started() noexcept
notifyListeners(ServiceEvent::STARTED);

if (onstart_flags.rw_ready) {
open_control_socket(&eventLoop);
system_rw_ready();
}

if (force_stop || desired_state == ServiceState::STOPPED) {
Expand Down

0 comments on commit a2c7e27

Please sign in to comment.