Extend SYSLOG logic so that we can send SYSLOG output to a file. Not verified on initial commit.

This commit is contained in:
Gregory Nutt 2016-06-21 12:25:15 -06:00
parent 417236e91f
commit e6a1d53869
8 changed files with 189 additions and 31 deletions

View File

@ -136,6 +136,20 @@ config SYSLOG_NONE
endchoice
config SYSLOG_FILE
bool "Sylog file output"
default n
---help---
Build in support to use a file to collect SYSOG output. File SYSLOG
channels differ from other SYSLOG channels in that they cannot be
established until after fully booting and mounting the target file
system. The function syslog_file_channel() would need to be called
from board-specific bring-up logic AFTER mounting the file system
containing 'devpath'.
NOTE interrupt level SYSLOG output will be lost in this case unless
the interrupt buffer is used.
config CONSOLE_SYSLOG
bool "Use SYSLOG for /dev/console"
default n

View File

@ -72,10 +72,14 @@ ifeq ($(CONFIG_SYSLOG_CHAR),y)
CSRCS += syslog_devchannel.c
endif
ifeq ($(CONFIG_DEV_CONSOLE),y)
ifeq ($(CONFIG_SYSLOG_CONSOLE),y)
CSRCS += syslog_consolechannel.c
endif
ifeq ($(CONFIG_SYSLOG_FILE),y)
CSRCS += syslog_filechannel.c
endif
# (Add other SYSLOG drivers here)
ifeq ($(CONFIG_CONSOLE_SYSLOG),y)

View File

@ -58,9 +58,15 @@ extern "C"
#define EXTERN extern
#endif
/* This is the current syslog channel in use */
/* The default SYSLOG channel */
struct syslog_channel_s; /* Forward reference */
EXTERN const struct syslog_channel_s g_default_syslog_channel;
/* This is the current syslog channel in use. It initially points to
* g_default_syslog_channel.
*/
EXTERN FAR const struct syslog_channel_s *g_syslog_channel;
/****************************************************************************
@ -85,6 +91,8 @@ EXTERN FAR const struct syslog_channel_s *g_syslog_channel;
*
* Input Parameters:
* devpath - The full path to the character device to be used.
* oflags - File open flags
* mode - File open mode (only if oflags include O_CREAT)
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
@ -93,9 +101,33 @@ EXTERN FAR const struct syslog_channel_s *g_syslog_channel;
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int syslog_dev_initialize(FAR const char *devpath);
int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode);
#endif
/****************************************************************************
* Name: syslog_dev_uninitialize
*
* Description:
* Called to disable the last device/file channel in preparation to use
* a different SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
* Assumptions:
* The caller has already switched the SYSLOG source to some safe channel
* (the default channel).
*
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SYSLOG_FILE)
int syslog_dev_uninitialize(void);
#endif /* CONFIG_SYSLOG_FILE */
/****************************************************************************
* Name: syslog_dev_channel
*
@ -151,7 +183,7 @@ int syslog_dev_channel(void);
*
****************************************************************************/
#ifdef CONFIG_DEV_CONSOLE
#ifdef CONFIG_SYSLOG_CONSOLE
int syslog_console_channel(void);
#endif

View File

@ -63,25 +63,25 @@ static int syslog_default_putc(int ch);
static int syslog_default_flush(void);
/****************************************************************************
* Private Data
* Public Data
****************************************************************************/
#if defined(CONFIG_RAMLOG_SYSLOG)
static const struct syslog_channel_s g_default_channel =
const struct syslog_channel_s g_default_channel =
{
ramlog_putc,
ramlog_putc,
syslog_default_flush
};
#elif defined(CONFIG_SYSLOG_SERIAL_CONSOLE) && defined(CONFIG_ARCH_LOWPUTC)
static const struct syslog_channel_s g_default_channel =
const struct syslog_channel_s g_default_channel =
{
up_putc,
up_putc,
syslog_default_flush
};
#else
static const struct syslog_channel_s g_default_channel =
const struct syslog_channel_s g_default_channel =
{
syslog_default_putc,
syslog_default_putc,
@ -89,10 +89,6 @@ static const struct syslog_channel_s g_default_channel =
};
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/* This is the current syslog channel in use */
FAR const struct syslog_channel_s *g_syslog_channel = &g_default_channel;

View File

@ -39,6 +39,9 @@
#include <nuttx/config.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <nuttx/arch.h>
#include <nuttx/syslog/syslog.h>
@ -47,7 +50,7 @@
#ifdef CONFIG_SYSLOG_CONSOLE
/****************************************************************************
* Private Functions
* Pre-processor Definitions
****************************************************************************/
#undef HAVE_LOWPUTC
@ -55,6 +58,9 @@
# define HAVE_LOWPUTC 1
#endif
#define OPEN_FLAGS (O_WRONLY)
#define OPEN_MODE (S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR)
/****************************************************************************
* Private Functions
****************************************************************************/
@ -73,7 +79,7 @@ static int syslog_console_force(int ch);
* Private Data
****************************************************************************/
/* This structure describes the ITM SYSLOG channel */
/* This structure describes the SYSLOG channel */
static const struct syslog_channel_s g_syslog_console_channel =
{
@ -142,7 +148,7 @@ int syslog_console_channel(void)
/* Initialize the character driver interface */
ret = syslog_dev_initialize("/dev/console");
ret = syslog_dev_initialize("/dev/console", OPEN_FLAGS, OPEN_MODE);
if (ret < 0)
{
return ret;

View File

@ -39,6 +39,9 @@
#include <nuttx/config.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <nuttx/syslog/syslog.h>
#include "syslog.h"
@ -46,9 +49,12 @@
#ifdef CONFIG_SYSLOG_CHAR
/****************************************************************************
* Private Functions
* Pre-processor Definitions
****************************************************************************/
#define OPEN_FLAGS (O_WRONLY)
#define OPEN_MODE (S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR)
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -61,7 +67,7 @@ static int syslog_dev_force(int ch);
* Private Data
****************************************************************************/
/* This structure describes the ITM SYSLOG channel */
/* This structure describes the SYSLOG channel */
static const struct syslog_channel_s g_syslog_dev_channel =
{
@ -95,8 +101,8 @@ static int syslog_dev_force(int ch)
* Name: syslog_dev_channel
*
* Description:
* Configure to use the character device (or file) at
* CONFIG_SYSLOG_DEVPATH as the SYSLOG channel.
* Configure to use the character device at CONFIG_SYSLOG_DEVPATH as the
* SYSLOG channel.
*
* This tiny function is simply a wrapper around syslog_dev_initialize()
* and syslog_channel(). It calls syslog_dev_initialize() to configure
@ -121,7 +127,7 @@ int syslog_dev_channel(void)
/* Initialize the character driver interface */
ret = syslog_dev_initialize(CONFIG_SYSLOG_DEVPATH);
ret = syslog_dev_initialize(CONFIG_SYSLOG_DEVPATH, OPEN_FLAGS, OPEN_MODE);
if (ret < 0)
{
return ret;

View File

@ -45,13 +45,15 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <fcntl.h>
#include <semaphore.h>
#include <errno.h>
#include <assert.h>
#include <nuttx/fs/fs.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/syslog/syslog.h>
#include "syslog.h"
@ -92,11 +94,13 @@ enum syslog_dev_state
struct syslog_dev_s
{
uint8_t sl_state; /* See enum syslog_dev_state */
sem_t sl_sem; /* Enforces mutually exclusive access */
pid_t sl_holder; /* PID of the thread that holds the semaphore */
struct file sl_file; /* The syslog file structure */
FAR const char *sl_devpath; /* Full path to the character device */
uint8_t sl_state; /* See enum syslog_dev_state */
uint8_t sl_oflags; /* Saved open mode (for re-open) */
uint16_t sl_mode; /* Saved open flags (for re-open) */
sem_t sl_sem; /* Enforces mutually exclusive access */
pid_t sl_holder; /* PID of the thread that holds the semaphore */
struct file sl_file; /* The syslog file structure */
FAR char *sl_devpath; /* Full path to the character device */
};
/****************************************************************************
@ -222,6 +226,8 @@ static inline ssize_t syslog_dev_write(FAR const void *buf, size_t nbytes)
*
* Input Parameters:
* devpath - The full path to the character device to be used.
* oflags - File open flags
* mode - File open mode (only if oflags include O_CREAT)
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
@ -229,7 +235,7 @@ static inline ssize_t syslog_dev_write(FAR const void *buf, size_t nbytes)
*
****************************************************************************/
int syslog_dev_initialize(FAR const char *devpath)
int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode)
{
int fd;
int ret;
@ -262,6 +268,8 @@ int syslog_dev_initialize(FAR const char *devpath)
*/
DEBUGASSERT(g_syslog_dev.sl_devpath == NULL);
g_syslog_dev.sl_oflags = oflags;
g_syslog_dev.sl_mode = mode;
g_syslog_dev.sl_devpath = strdup(devpath);
DEBUGASSERT(g_syslog_dev.sl_devpath != NULL);
}
@ -270,7 +278,7 @@ int syslog_dev_initialize(FAR const char *devpath)
/* Open the device driver. */
fd = open(devpath, O_WRONLY);
fd = open(devpath, oflags, mode);
if (fd < 0)
{
int errcode = get_errno();
@ -315,6 +323,57 @@ int syslog_dev_initialize(FAR const char *devpath)
return OK;
}
/****************************************************************************
* Name: syslog_dev_uninitialize
*
* Description:
* Called to disable the last device/file channel in preparation to use
* a different SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
* Assumptions:
* The caller has already switched the SYSLOG source to some safe channel
* (the default channel).
*
****************************************************************************/
#ifdef CONFIG_SYSLOG_FILE /* Currently only used in this configuration */
int syslog_dev_uninitialize(void)
{
/* Attempt to flush any buffered data */
sched_lock();
(void)syslog_dev_flush();
/* Close the detached file instance */
(void)file_close_detached(&g_syslog_dev.sl_file);
/* Free the device path */
if (g_syslog_dev.sl_devpath != NULL)
{
kmm_free(g_syslog_dev.sl_devpath);
}
/* Destroy the semaphore */
sem_destroy(&g_syslog_dev.sl_sem);
/* Reset the state structure */
memset(&g_syslog_dev, 0, sizeof(struct syslog_dev_s));
sched_unlock();
return OK;
}
#endif /* CONFIG_SYSLOG_FILE */
/****************************************************************************
* Name: syslog_dev_putc
*
@ -416,7 +475,9 @@ int syslog_dev_putc(int ch)
*/
DEBUGASSERT(g_syslog_dev.sl_devpath != NULL);
ret = syslog_dev_initialize(g_syslog_dev.sl_devpath);
ret = syslog_dev_initialize(g_syslog_dev.sl_devpath,
(int)g_syslog_dev.sl_oflags,
(int)g_syslog_dev.sl_mode);
if (ret < 0)
{
sched_unlock();
@ -522,8 +583,7 @@ int syslog_dev_flush(void)
/* Is this a mountpoint? Does it support the sync method? */
DEBUGASSERT(inode != NULL);
if (inode->u.i_mops->sync)
if (inode && inode->u.i_mops->sync)
{
/* Yes... synchronize to the stream */

View File

@ -194,6 +194,46 @@ int syslog_initialize(enum syslog_init_e phase);
# define syslog_initialize(phase)
#endif
/****************************************************************************
* Name: syslog_file_channel
*
* Description:
* Configure to use a file in a mounted file system at 'devpath' as the
* SYSLOG channel.
*
* This tiny function is simply a wrapper around syslog_dev_initialize()
* and syslog_channel(). It calls syslog_dev_initialize() to configure
* the character file at 'devpath then calls syslog_channel() to use that
* device as the SYSLOG output channel.
*
* File SYSLOG channels differ from other SYSLOG channels in that they
* cannot be established until after fully booting and mounting the target
* file system. This function would need to be called from board-specific
* bring-up logic AFTER mounting the file system containing 'devpath'.
*
* SYSLOG data generated prior to calling syslog_file_channel will, of
* course, not be included in the file.
*
* NOTE interrupt level SYSLOG output will be lost in this case unless
* the interrupt buffer is used.
*
* Input Parameters:
* devpath - The full path to the file to be used for SYSLOG output.
* This may be an existing file or not. If the file exists,
* syslog_file_channel() will append new SYSLOG data to the end of the
* file. If it does not, then syslog_file_channel() will create the
* file.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_SYSLOG_FILE
int syslog_file_channel(FAR const char *devpath);
#endif
/****************************************************************************
* Name: syslog_flush
*