syslog_daemon: Converted to BServer.
* Instead of letting the kernel search for the syslog port, the daemon now registers itself with the kernel (which even solves a TODO). * A port is created for the actual log messages from the launch_daemon, and used on start. * However, the SyslogTest does not yet work, due to the BMessage <-> KMessage communication problems.
This commit is contained in:
parent
9d69dc097d
commit
4bf862e368
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de
|
||||
* Copyright 2002-2015, Axel Dörfler, axeld@pinc-software.de
|
||||
* Distributed under the terms of the Haiku License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
|
@ -221,8 +221,9 @@ extern bool debug_is_debugged_team(team_id teamID);
|
|||
|
||||
extern struct arch_debug_registers* debug_get_debug_registers(int32 cpu);
|
||||
|
||||
extern status_t _user_kernel_debugger(const char *message);
|
||||
extern void _user_debug_output(const char *userString);
|
||||
extern status_t _user_kernel_debugger(const char *message);
|
||||
extern void _user_register_syslog_daemon(port_id port);
|
||||
extern void _user_debug_output(const char *userString);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2003-2015, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef SYSLOG_DAEMON_H
|
||||
|
@ -9,7 +9,7 @@
|
|||
#include <OS.h>
|
||||
|
||||
|
||||
#define SYSLOG_PORT_NAME "syslog_daemon"
|
||||
#define B_SYSTEM_LOGGER_SIGNATURE "application/x-vnd.Haiku-SystemLogger"
|
||||
|
||||
#define SYSLOG_MESSAGE '_Syl'
|
||||
#define SYSLOG_ADD_LISTENER 'aSyl'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2011, Haiku, Inc. All rights reserved.
|
||||
* Copyright 2004-2015, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_SYSCALLS_H
|
||||
|
@ -472,6 +472,7 @@ extern status_t _kern_get_port_message_info_etc(port_id port,
|
|||
|
||||
// debug support functions
|
||||
extern status_t _kern_kernel_debugger(const char *message);
|
||||
extern void _kern_register_syslog_daemon(port_id port);
|
||||
extern void _kern_debugger(const char *message);
|
||||
extern int _kern_disable_debugger(int state);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
SubDir HAIKU_TOP src servers syslog_daemon ;
|
||||
|
||||
UsePrivateHeaders syslog_daemon ;
|
||||
UsePrivateHeaders app syslog_daemon ;
|
||||
UsePrivateSystemHeaders ;
|
||||
|
||||
AddResources syslog_daemon : SyslogDaemon.rdef ;
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#include <Path.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#include <LaunchRoster.h>
|
||||
#include <syscalls.h>
|
||||
#include <syslog_daemon.h>
|
||||
|
||||
#include "listener_output.h"
|
||||
#include "syslog_output.h"
|
||||
|
||||
|
@ -24,12 +28,9 @@
|
|||
#define B_TRANSLATION_CONTEXT "SyslogDaemon"
|
||||
|
||||
|
||||
const char* kSignature = "application/x-vnd.Haiku-SystemLogger";
|
||||
|
||||
|
||||
SyslogDaemon::SyslogDaemon()
|
||||
:
|
||||
BApplication(kSignature),
|
||||
BApplication(B_SYSTEM_LOGGER_SIGNATURE),
|
||||
fHandlerLock("handler lock")
|
||||
{
|
||||
}
|
||||
|
@ -38,10 +39,12 @@ SyslogDaemon::SyslogDaemon()
|
|||
void
|
||||
SyslogDaemon::ReadyToRun()
|
||||
{
|
||||
fPort = create_port(256, SYSLOG_PORT_NAME);
|
||||
fDaemon = spawn_thread(daemon_thread, "daemon", B_NORMAL_PRIORITY, this);
|
||||
fPort = BLaunchRoster().GetPort("logger");
|
||||
fDaemon = spawn_thread(_DaemonThread, "daemon", B_NORMAL_PRIORITY, this);
|
||||
|
||||
if (fPort >= 0 && fDaemon >= 0) {
|
||||
_kern_register_syslog_daemon(fPort);
|
||||
|
||||
if (fPort >= B_OK && fDaemon >= B_OK) {
|
||||
init_syslog_output(this);
|
||||
init_listener_output(this);
|
||||
|
||||
|
@ -128,7 +131,7 @@ SyslogDaemon::AddHandler(handler_func function)
|
|||
|
||||
|
||||
void
|
||||
SyslogDaemon::Daemon()
|
||||
SyslogDaemon::_Daemon()
|
||||
{
|
||||
char buffer[SYSLOG_MESSAGE_BUFFER_SIZE + 1];
|
||||
syslog_message& message = *(syslog_message*)buffer;
|
||||
|
@ -168,13 +171,16 @@ SyslogDaemon::Daemon()
|
|||
|
||||
|
||||
int32
|
||||
SyslogDaemon::daemon_thread(void* data)
|
||||
SyslogDaemon::_DaemonThread(void* data)
|
||||
{
|
||||
((SyslogDaemon*)data)->Daemon();
|
||||
((SyslogDaemon*)data)->_Daemon();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -28,8 +28,9 @@ public:
|
|||
|
||||
void AddHandler(handler_func function);
|
||||
|
||||
void Daemon();
|
||||
static int32 daemon_thread(void* data);
|
||||
private:
|
||||
void _Daemon();
|
||||
static int32 _DaemonThread(void* data);
|
||||
|
||||
private:
|
||||
thread_id fDaemon;
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
|
||||
#include "syslog_output.h"
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
|
||||
static const char *kFacilities[] = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2002-2015, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
|
@ -98,6 +98,8 @@ static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
|
|||
static int32 sDebuggerOnCPU = -1;
|
||||
|
||||
static sem_id sSyslogNotify = -1;
|
||||
static thread_id sSyslogWriter = -1;
|
||||
static port_id sSyslogPort = -1;
|
||||
static struct syslog_message* sSyslogMessage;
|
||||
static struct ring_buffer* sSyslogBuffer;
|
||||
static size_t sSyslogBufferOffset = 0;
|
||||
|
@ -1188,8 +1190,6 @@ cmd_switch_cpu(int argc, char** argv)
|
|||
static status_t
|
||||
syslog_sender(void* data)
|
||||
{
|
||||
status_t error = B_BAD_PORT_ID;
|
||||
port_id port = -1;
|
||||
bool bufferPending = false;
|
||||
int32 length = 0;
|
||||
|
||||
|
@ -1208,69 +1208,56 @@ syslog_sender(void* data)
|
|||
|
||||
sSyslogMessage->when = real_time_clock();
|
||||
|
||||
if (error == B_BAD_PORT_ID) {
|
||||
// last message couldn't be sent, try to locate the syslog_daemon
|
||||
port = find_port(SYSLOG_PORT_NAME);
|
||||
if (port < 0) {
|
||||
// Don't recheck too quickly, since find_port) is rather
|
||||
// expensive.
|
||||
// TODO: Maybe using the port notification mechanism would be
|
||||
// the better option here. Alternatively, and probably even
|
||||
// better, the syslog daemon could register itself via a syscall
|
||||
// (like the messaging service). We could even wait with
|
||||
// starting this thread before that happened (end exit as soon
|
||||
// as the port is gone).
|
||||
snooze(1000000);
|
||||
continue;
|
||||
if (!bufferPending) {
|
||||
// We need to have exclusive access to our syslog buffer
|
||||
cpu_status state = disable_interrupts();
|
||||
acquire_spinlock(&sSpinlock);
|
||||
|
||||
length = ring_buffer_readable(sSyslogBuffer)
|
||||
- sSyslogBufferOffset;
|
||||
if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
|
||||
length = SYSLOG_MAX_MESSAGE_LENGTH;
|
||||
|
||||
length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset,
|
||||
(uint8*)sSyslogMessage->message, length);
|
||||
sSyslogBufferOffset += length;
|
||||
if (sSyslogDropped) {
|
||||
// Add drop marker - since parts had to be dropped, it's
|
||||
// guaranteed that we have enough space in the buffer now.
|
||||
ring_buffer_write(sSyslogBuffer, (uint8*)"<DROP>", 6);
|
||||
sSyslogDropped = false;
|
||||
}
|
||||
|
||||
release_spinlock(&sSpinlock);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
|
||||
if (port >= B_OK) {
|
||||
if (!bufferPending) {
|
||||
// we need to have exclusive access to our syslog buffer
|
||||
cpu_status state = disable_interrupts();
|
||||
acquire_spinlock(&sSpinlock);
|
||||
if (length == 0) {
|
||||
// The buffer we came here for might have been sent already
|
||||
bufferPending = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
length = ring_buffer_readable(sSyslogBuffer)
|
||||
- sSyslogBufferOffset;
|
||||
if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
|
||||
length = SYSLOG_MAX_MESSAGE_LENGTH;
|
||||
status_t status = write_port_etc(sSyslogPort, SYSLOG_MESSAGE,
|
||||
sSyslogMessage, sizeof(struct syslog_message) + length,
|
||||
B_RELATIVE_TIMEOUT, 0);
|
||||
if (status == B_BAD_PORT_ID) {
|
||||
// The port is gone, there is no need to run anymore
|
||||
sSyslogWriter = -1;
|
||||
return status;
|
||||
}
|
||||
|
||||
length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset,
|
||||
(uint8*)sSyslogMessage->message, length);
|
||||
sSyslogBufferOffset += length;
|
||||
if (sSyslogDropped) {
|
||||
// Add drop marker - since parts had to be dropped, it's
|
||||
// guaranteed that we have enough space in the buffer now.
|
||||
ring_buffer_write(sSyslogBuffer, (uint8*)"<DROP>", 6);
|
||||
sSyslogDropped = false;
|
||||
}
|
||||
if (status != B_OK) {
|
||||
// Sending has failed - just wait, maybe it'll work later.
|
||||
bufferPending = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
release_spinlock(&sSpinlock);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
// the buffer we came here for might have been sent already
|
||||
bufferPending = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
error = write_port_etc(port, SYSLOG_MESSAGE, sSyslogMessage,
|
||||
sizeof(struct syslog_message) + length, B_RELATIVE_TIMEOUT, 0);
|
||||
|
||||
if (error < B_OK) {
|
||||
// sending has failed - just wait, maybe it'll work later.
|
||||
bufferPending = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bufferPending) {
|
||||
// we could write the last pending buffer, try to read more
|
||||
// from the syslog ring buffer
|
||||
release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
|
||||
bufferPending = false;
|
||||
}
|
||||
if (bufferPending) {
|
||||
// We could write the last pending buffer, try to read more
|
||||
// from the syslog ring buffer
|
||||
release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
|
||||
bufferPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1318,12 +1305,8 @@ syslog_init_post_threads(void)
|
|||
return B_OK;
|
||||
|
||||
sSyslogNotify = create_sem(0, "syslog data");
|
||||
if (sSyslogNotify >= B_OK) {
|
||||
thread_id thread = spawn_kernel_thread(syslog_sender, "syslog sender",
|
||||
B_LOW_PRIORITY, NULL);
|
||||
if (thread >= B_OK && resume_thread(thread) == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
if (sSyslogNotify >= 0)
|
||||
return B_OK;
|
||||
|
||||
// initializing kernel syslog service failed -- disable it
|
||||
|
||||
|
@ -2275,18 +2258,17 @@ debug_is_debugged_team(team_id teamID)
|
|||
|
||||
|
||||
status_t
|
||||
_user_kernel_debugger(const char *userMessage)
|
||||
_user_kernel_debugger(const char* userMessage)
|
||||
{
|
||||
if (geteuid() != 0)
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
char message[512];
|
||||
strcpy(message, "USER: ");
|
||||
size_t len = strlen(message);
|
||||
size_t length = strlen(message);
|
||||
|
||||
if (userMessage == NULL || !IS_USER_ADDRESS(userMessage)
|
||||
|| user_strlcpy(message + len, userMessage, sizeof(message) - len)
|
||||
< 0) {
|
||||
if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) || user_strlcpy(
|
||||
message + length, userMessage, sizeof(message) - length) < 0) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
|
@ -2295,6 +2277,23 @@ _user_kernel_debugger(const char *userMessage)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
_user_register_syslog_daemon(port_id port)
|
||||
{
|
||||
if (geteuid() != 0 || !sSyslogOutputEnabled || sSyslogNotify < 0)
|
||||
return;
|
||||
|
||||
sSyslogPort = port;
|
||||
|
||||
if (sSyslogWriter < 0) {
|
||||
sSyslogWriter = spawn_kernel_thread(syslog_sender, "syslog sender",
|
||||
B_LOW_PRIORITY, NULL);
|
||||
if (sSyslogWriter >= 0)
|
||||
resume_thread(sSyslogWriter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_user_debug_output(const char* userString)
|
||||
{
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
/*
|
||||
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2003-2015, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <syslog_daemon.h>
|
||||
#include <TLS.h>
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <launch.h>
|
||||
#include <syslog_daemon.h>
|
||||
#include <TLS.h>
|
||||
#include <util/KMessage.h>
|
||||
|
||||
|
||||
struct syslog_context {
|
||||
char ident[B_OS_NAME_LENGTH];
|
||||
|
@ -28,6 +31,7 @@ static syslog_context sTeamContext = {
|
|||
LOG_CONS
|
||||
};
|
||||
static int32 sThreadContextSlot = -1;
|
||||
static port_id sSystemLoggerPort = -1;
|
||||
|
||||
|
||||
static syslog_context *
|
||||
|
@ -102,6 +106,22 @@ message_to_console(syslog_context *context, const char *text, va_list args)
|
|||
}
|
||||
|
||||
|
||||
/*! Retrieves the port of the system logger from the launch_daemon.
|
||||
*/
|
||||
static port_id
|
||||
get_system_logger_port()
|
||||
{
|
||||
if (sSystemLoggerPort >= 0)
|
||||
return sSystemLoggerPort;
|
||||
|
||||
BPrivate::KMessage data;
|
||||
if (BPrivate::get_launch_data(B_SYSTEM_LOGGER_SIGNATURE, data) == B_OK)
|
||||
sSystemLoggerPort = data.GetInt32("logger_port", -1);
|
||||
|
||||
return sSystemLoggerPort;
|
||||
}
|
||||
|
||||
|
||||
/*! Creates the message from the given context and sends it to the syslog
|
||||
daemon, if the priority mask matches.
|
||||
If the message couldn't be delivered, and LOG_CONS was set, it will
|
||||
|
@ -117,7 +137,7 @@ send_syslog_message(syslog_context *context, int priority, const char *text,
|
|||
if ((context->mask & LOG_MASK(SYSLOG_PRIORITY(priority))) == 0)
|
||||
return;
|
||||
|
||||
port_id port = find_port(SYSLOG_PORT_NAME);
|
||||
port_id port = get_system_logger_port();
|
||||
if ((options & LOG_PERROR) != 0
|
||||
|| ((options & LOG_CONS) != 0 && port < B_OK)) {
|
||||
// if asked for, print out the (simplified) message on stderr
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
SubDir HAIKU_TOP src tests system libroot posix ;
|
||||
|
||||
UsePrivateHeaders libroot syslog_daemon ;
|
||||
|
||||
|
||||
# filter warnings about strftime()-formats in locale_test
|
||||
TARGET_WARNING_C++FLAGS_$(TARGET_PACKAGING_ARCH)
|
||||
on [ FGristFiles locale_test.o ] += -Wno-format ;
|
||||
|
||||
# POSIX/libc tests
|
||||
SimpleTest abort_test : abort_test.cpp ;
|
||||
SimpleTest SyslogTest : SyslogTest.cpp syslog.cpp ;
|
||||
SimpleTest SyslogTest : SyslogTest.cpp ;
|
||||
SimpleTest clearenv : clearenv.cpp ;
|
||||
SimpleTest dirent_test : dirent_test.cpp ;
|
||||
SimpleTest flock_test : flock_test.cpp ;
|
||||
|
@ -72,10 +69,5 @@ SimpleTest test_wctype : test_wctype.c ;
|
|||
SimpleTest wcs_test : wcs_test.cpp ;
|
||||
|
||||
|
||||
# Tell Jam where to find these sources
|
||||
SEARCH on [ FGristFiles
|
||||
syslog.cpp
|
||||
] = [ FDirName $(HAIKU_TOP) src system libroot posix ] ;
|
||||
|
||||
SubInclude HAIKU_TOP src tests system libroot posix math ;
|
||||
SubInclude HAIKU_TOP src tests system libroot posix string ;
|
||||
|
|
|
@ -1,27 +1,20 @@
|
|||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2003-2015, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <syslog_daemon.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
int
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
port_id port = find_port(SYSLOG_PORT_NAME);
|
||||
if (port < B_OK)
|
||||
fprintf(stderr, "The (new) syslog_daemon should be running!\n");
|
||||
|
||||
openlog_team("SyslogTest", LOG_PID, LOG_USER);
|
||||
|
||||
|
||||
log_team(LOG_ERR, "this is %.", "a test");
|
||||
|
||||
int mask = setlogmask_team(LOG_MASK(LOG_CRIT));
|
||||
|
|
Loading…
Reference in New Issue