syslog: syslog_device ops are handled internally by the driver.

This commit is contained in:
Fotis Panagiotopoulos 2021-04-07 17:35:18 +03:00 committed by Xiang Xiao
parent 4ca34ac5b5
commit ee7276e7a7
10 changed files with 190 additions and 415 deletions

View file

@ -374,14 +374,6 @@ channel include:
means that interrupt level SYSLOG output will be lost unless
the interrupt buffer is enabled to support serialization.
- ``CONFIG_SYSLOG_CHAR_CRLF``. If ``CONFIG_SYSLOG_CHAR_CRLF`` is
selected, then linefeeds in the SYSLOG output will be expanded
to Carriage Return plus Linefeed. Since the character device is
not a console device, the addition of carriage returns to line
feeds would not be performed otherwise. You would probably want
this expansion if you use a serial terminal program with the
character device output.
References: ``drivers/syslog/syslog_devchannel.c`` and
``drivers/syslog/syslog_device.c``

View file

@ -13,10 +13,6 @@ config ARCH_SYSLOG
# Selected if the SYSLOG device supports multi-byte write operations
config SYSLOG_WRITE
bool
default n
config SYSLOG_MAX_CHANNELS
int "Maximum SYSLOG channels"
default 1
@ -77,7 +73,6 @@ endif
config SYSLOG_BUFFER
bool "Use buffered output"
default n
depends on SYSLOG_WRITE
select MM_IOB
---help---
Enables an buffering logic that will be used to serialize debug
@ -193,7 +188,6 @@ choice
config SYSLOG_CHAR
bool "Log to a character device"
select SYSLOG_WRITE
---help---
Enable the generic character device for the SYSLOG. The full path to the
SYSLOG device is provided by SYSLOG_DEVPATH. A valid character device (or
@ -211,7 +205,6 @@ config RAMLOG_SYSLOG
config SYSLOG_CONSOLE
bool "Log to /dev/console"
depends on DEV_CONSOLE
select SYSLOG_WRITE
---help---
Use the system console as a SYSLOG output device.
@ -219,7 +212,6 @@ config SYSLOG_RPMSG
bool "Log to RPMSG"
depends on OPENAMP
depends on SCHED_WORKQUEUE
select SYSLOG_WRITE
---help---
Use the rpmsg as a SYSLOG output device, send message to remote proc.
@ -246,7 +238,6 @@ config SYSLOG_RPMSG_SERVER
config SYSLOG_FILE
bool "Syslog file output"
default n
select SYSLOG_WRITE
---help---
Build in support to use a file to collect SYSLOG output. File SYSLOG
channels differ from other SYSLOG channels in that they cannot be
@ -269,14 +260,6 @@ config CONSOLE_SYSLOG
example, if the only console is a Telnet console. Then in that case,
console output from non-Telnet threads will go to the syslog output.
config SYSLOG_CHAR_CRLF
bool "SYSLOG device CR/LF"
default y
depends on SYSLOG_CHAR
---help---
Pre-pend a carriage return before every linefeed that goes to the
character device.
config SYSLOG_DEVPATH
string "System log device"
default "/dev/ttyS1"

View file

@ -120,21 +120,31 @@ SYSLOG Channels
SYSLOG channel is represented by an interface defined in
include/nuttx/syslog/syslog.h:
/* This structure provides the interface to a SYSLOG device */
/* SYSLOG I/O redirection methods */
typedef CODE int (*syslog_putc_t)(int ch);
typedef CODE int (*syslog_flush_t)(void);
typedef CODE ssize_t (*syslog_write_t)(FAR struct syslog_channel_s *channel,
FAR const char *buf, size_t buflen);
typedef CODE int (*syslog_putc_t)(FAR struct syslog_channel_s *channel,
int ch);
typedef CODE int (*syslog_flush_t)(FAR struct syslog_channel_s *channel);
/* SYSLOG device operations */
struct syslog_channel_ops_s
{
syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
syslog_write_t sc_write; /* Write multiple bytes */
};
/* This structure provides the interface to a SYSLOG channel */
struct syslog_channel_s
{
/* I/O redirection methods */
/* Channel operations */
#ifdef CONFIG_SYSLOG_WRITE
syslog_write_t sc_write; /* Write multiple bytes */
#endif
syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
FAR const struct syslog_channel_ops_s *sc_ops;
/* Implementation specific logic may follow */
};
@ -340,12 +350,6 @@ SYSLOG Channel Options
* The forced SYSLOG output always goes to the bit-bucket. This means
that interrupt level SYSLOG output will be lost unless the interrupt
buffer is enabled to support serialization.
* CONFIG_SYSLOG_CHAR_CRLF. If CONFIG_SYSLOG_CHAR_CRLF is selected, then
linefeeds in the SYSLOG output will be expanded to Carriage Return +
Linefeed. Since the character device is not a console device, the
addition of carriage returns to line feeds would not be performed
otherwise. You would probably want this expansion if you use a serial
terminal program with the character device output.
References: drivers/syslog/syslog_devchannel.c and
drivers/syslog/syslog_device.c

View file

@ -284,62 +284,6 @@ ssize_t syslog_write(FAR const char *buffer, size_t buflen);
int syslog_force(int ch);
/****************************************************************************
* Name: syslog_dev_write
*
* Description:
* This is the low-level, multiple byte, system logging interface provided
* for the character driver interface.
*
* Input Parameters:
* channel - Handle to syslog channel to be used.
* buffer - The buffer containing the data to be output.
* buflen - The number of bytes in the buffer.
*
* Returned Value:
* On success, the character is echoed back to the caller. A negated errno
* value is returned on any failure.
*
****************************************************************************/
ssize_t syslog_dev_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen);
/****************************************************************************
* Name: syslog_dev_putc
*
* Description:
* This is the low-level system logging interface provided for the
* character driver interface.
*
* Input Parameters:
* channel - Handle to syslog channel to be used.
* ch - The character to add to the SYSLOG (must be positive).
*
* Returned Value:
* On success, the character is echoed back to the caller. A negated
* errno value is returned on any failure.
*
****************************************************************************/
int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch);
/****************************************************************************
* Name: syslog_dev_flush
*
* Description:
* Flush any buffer data in the file system to media.
*
* Input Parameters:
* channel - Handle to syslog channel to be used.
*
* Returned Value:
* Zero (OK) on success; a negated errno value is returned on any failure.
*
****************************************************************************/
int syslog_dev_flush(FAR struct syslog_channel_s *channel);
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -28,9 +28,7 @@
#include <fcntl.h>
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h"
@ -40,71 +38,17 @@
* Pre-processor Definitions
****************************************************************************/
#undef HAVE_LOWPUTC
#if defined(CONFIG_ARCH_LOWPUTC)
# define HAVE_LOWPUTC 1
#endif
#define OPEN_FLAGS (O_WRONLY)
#define OPEN_MODE (S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR)
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* SYSLOG channel methods */
static int syslog_console_force(FAR struct syslog_channel_s *channel,
int ch);
/****************************************************************************
* Private Data
****************************************************************************/
/* This structure describes the channel's operations. */
static const struct syslog_channel_ops_s g_syslog_ops =
{
syslog_dev_putc,
syslog_console_force,
syslog_dev_flush,
#ifdef CONFIG_SYSLOG_WRITE
syslog_dev_write,
#endif
};
/* Handle to the SYSLOG channel */
FAR static struct syslog_channel_s *g_syslog_console_channel;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: syslog_console_force
*
* Description:
* A dummy FORCE method
*
****************************************************************************/
static int syslog_console_force(FAR struct syslog_channel_s *channel,
int ch)
{
UNUSED(channel);
#ifdef HAVE_LOWPUTC
return up_putc(ch);
#endif
return ch;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -147,10 +91,6 @@ int syslog_console_channel(void)
return -ENOMEM;
}
/* Register the channel operations */
g_syslog_console_channel->sc_ops = &g_syslog_ops;
/* Use the character driver as the SYSLOG channel */
return syslog_channel(g_syslog_console_channel);

View file

@ -29,7 +29,6 @@
#include <errno.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h"
@ -42,94 +41,14 @@
#define OPEN_FLAGS (O_WRONLY)
#define OPEN_MODE (S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR)
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* SYSLOG channel methods */
#ifdef CONFIG_SYSLOG_CHAR_CRLF
static int syslog_devchan_putc(FAR struct syslog_channel_s *channel,
int ch);
#endif
static int syslog_devchan_force(FAR struct syslog_channel_s *channel,
int ch);
/****************************************************************************
* Private Data
****************************************************************************/
/* This structure describes the channel's operations. */
static const struct syslog_channel_ops_s g_syslog_ops =
{
#ifdef CONFIG_SYSLOG_CHAR_CRLF
syslog_devchan_putc,
#else
syslog_dev_putc,
#endif
syslog_devchan_force,
syslog_dev_flush,
#ifdef CONFIG_SYSLOG_WRITE
syslog_dev_write,
#endif
};
/* Handle to the SYSLOG channel */
FAR static struct syslog_channel_s *g_syslog_dev_channel;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: syslog_devchan_putc
*
* Description:
* A front-end to syslog_dev_putc that does LF -> CR-LF expansion
*
****************************************************************************/
#ifdef CONFIG_SYSLOG_CHAR_CRLF
static int syslog_devchan_putc(FAR struct syslog_channel_s *channel, int ch)
{
int ret;
/* Check for a linefeed */
if (ch == '\n')
{
/* Pre-pend a carriage return */
ret = syslog_dev_putc(channel, '\r');
if (ret < 0)
{
return ret;
}
}
/* Output the provided character */
return syslog_dev_putc(channel, ch);
}
#endif
/****************************************************************************
* Name: syslog_devchan_force
*
* Description:
* A dummy FORCE method
*
****************************************************************************/
static int syslog_devchan_force(FAR struct syslog_channel_s *channel,
int ch)
{
UNUSED(channel);
return ch;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -169,10 +88,6 @@ int syslog_dev_channel(void)
return -ENOMEM;
}
/* Register the channel operations */
g_syslog_dev_channel->sc_ops = &g_syslog_ops;
/* Use the character driver as the SYSLOG channel */
return syslog_channel(g_syslog_dev_channel);

View file

@ -40,6 +40,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/semaphore.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h"
@ -88,10 +89,30 @@ struct syslog_dev_s
FAR char *sl_devpath; /* Full path to the character device */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static ssize_t syslog_dev_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen);
static int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch);
static int syslog_dev_force(FAR struct syslog_channel_s *channel, int ch);
static int syslog_dev_flush(FAR struct syslog_channel_s *channel);
/****************************************************************************
* Private Data
****************************************************************************/
/* This structure contains all SYSLOG device operations */
static const struct syslog_channel_ops_s g_syslog_dev_ops =
{
syslog_dev_putc,
syslog_dev_force,
syslog_dev_flush,
syslog_dev_write
};
static const uint8_t g_syscrlf[2] =
{
'\r', '\n'
@ -364,128 +385,6 @@ static int syslog_dev_outputready(FAR struct syslog_dev_s *syslog_dev)
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: syslog_dev_initialize
*
* Description:
* Initialize to use the character device (or file) at
* CONFIG_SYSLOG_DEVPATH as the SYSLOG sink.
*
* One power up, the SYSLOG facility is non-existent or limited to very
* low-level output. This function may be called later in the
* initialization sequence after full driver support has been initialized.
* (via syslog_initialize()) It installs the configured SYSLOG drivers
* and enables full SYSLOGing capability.
*
* NOTE that this implementation excludes using a network connection as
* SYSLOG device. That would be a good extension.
*
* 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:
* Returns a newly created SYSLOG channel, or NULL in case of any failure.
*
****************************************************************************/
FAR struct syslog_channel_s *syslog_dev_initialize(FAR const char *devpath,
int oflags, int mode)
{
FAR struct syslog_dev_s * syslog_dev;
syslog_dev = kmm_zalloc(sizeof(struct syslog_dev_s));
if (syslog_dev == NULL)
{
return NULL;
}
syslog_dev_open(syslog_dev, devpath, oflags, mode);
return (FAR struct syslog_channel_s *)syslog_dev;
}
/****************************************************************************
* 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:
* channel - Handle to syslog channel to be used.
*
* 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).
*
****************************************************************************/
void syslog_dev_uninitialize(FAR struct syslog_channel_s *channel)
{
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
/* Uninitializing a SYSLOG device should not take place within
* interrupt context.
*/
if (up_interrupt_context() || getpid() == 0)
{
DEBUGASSERT(!up_interrupt_context() && getpid() != 0);
return;
}
/* The device cannot be uninitialized while it is being
* initialized simultaneously.
*/
DEBUGASSERT(syslog_dev->sl_state != SYSLOG_UNINITIALIZED &&
syslog_dev->sl_state != SYSLOG_INITIALIZING);
/* Attempt to flush any buffered data. */
sched_lock();
syslog_dev_flush(channel);
/* Close the detached file instance, and destroy the semaphore. These are
* both only created when the device is in SYSLOG_OPENED or SYSLOG_FAILURE
* state.
*/
if (syslog_dev->sl_state == SYSLOG_OPENED ||
syslog_dev->sl_state == SYSLOG_FAILURE)
{
file_close(&syslog_dev->sl_file);
nxsem_destroy(&syslog_dev->sl_sem);
}
/* Set the device in UNINITIALIZED state. */
syslog_dev->sl_state = SYSLOG_UNINITIALIZED;
/* Free the device path */
if (syslog_dev->sl_devpath != NULL)
{
kmm_free(syslog_dev->sl_devpath);
}
/* Free the channel structure */
kmm_free(syslog_dev);
sched_unlock();
}
/****************************************************************************
* Name: syslog_dev_write
*
@ -504,8 +403,8 @@ void syslog_dev_uninitialize(FAR struct syslog_channel_s *channel)
*
****************************************************************************/
ssize_t syslog_dev_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen)
static ssize_t syslog_dev_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen)
{
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
FAR const char *endptr;
@ -643,7 +542,7 @@ errout_with_sem:
*
****************************************************************************/
int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch)
static int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch)
{
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
ssize_t nbytes;
@ -722,6 +621,27 @@ int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch)
return ch;
}
/****************************************************************************
* Name: syslog_dev_force
*
* Description:
* Dummy, do nothing force write operation.
*
* Input Parameters:
* channel - Handle to syslog channel to be used.
*
* Returned Value:
* On success, the character is echoed back to the caller. A negated
* errno value is returned on any failure.
*
****************************************************************************/
static int syslog_dev_force(FAR struct syslog_channel_s *channel, int ch)
{
UNUSED(channel);
return ch;
}
/****************************************************************************
* Name: syslog_dev_flush
*
@ -736,7 +656,7 @@ int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch)
*
****************************************************************************/
int syslog_dev_flush(FAR struct syslog_channel_s *channel)
static int syslog_dev_flush(FAR struct syslog_channel_s *channel)
{
#if defined(CONFIG_SYSLOG_FILE) && !defined(CONFIG_DISABLE_MOUNTPOINT)
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
@ -751,3 +671,127 @@ int syslog_dev_flush(FAR struct syslog_channel_s *channel)
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: syslog_dev_initialize
*
* Description:
* Initialize to use the character device (or file) at
* CONFIG_SYSLOG_DEVPATH as the SYSLOG sink.
*
* On power up, the SYSLOG facility is non-existent or limited to very
* low-level output. This function may be called later in the
* initialization sequence after full driver support has been initialized.
* (via syslog_initialize()) It installs the configured SYSLOG drivers
* and enables full SYSLOGing capability.
*
* NOTE that this implementation excludes using a network connection as
* SYSLOG device. That would be a good extension.
*
* 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:
* Returns a newly created SYSLOG channel, or NULL in case of any failure.
*
****************************************************************************/
FAR struct syslog_channel_s *syslog_dev_initialize(FAR const char *devpath,
int oflags, int mode)
{
FAR struct syslog_dev_s * syslog_dev;
syslog_dev = kmm_zalloc(sizeof(struct syslog_dev_s));
if (syslog_dev == NULL)
{
return NULL;
}
syslog_dev_open(syslog_dev, devpath, oflags, mode);
syslog_dev->channel.sc_ops = &g_syslog_dev_ops;
return (FAR struct syslog_channel_s *)syslog_dev;
}
/****************************************************************************
* Name: syslog_dev_uninitialize
*
* Description:
* Disable the last device/file channel in preparation to use a different
* SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE.
*
* Input Parameters:
* channel - Handle to syslog channel to be used.
*
* 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).
*
****************************************************************************/
void syslog_dev_uninitialize(FAR struct syslog_channel_s *channel)
{
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
/* Uninitializing a SYSLOG device should not take place within
* interrupt context.
*/
if (up_interrupt_context() || getpid() == 0)
{
DEBUGASSERT(!up_interrupt_context() && getpid() != 0);
return;
}
/* The device cannot be uninitialized while it is being
* initialized simultaneously.
*/
DEBUGASSERT(syslog_dev->sl_state != SYSLOG_UNINITIALIZED &&
syslog_dev->sl_state != SYSLOG_INITIALIZING);
/* Attempt to flush any buffered data. */
sched_lock();
syslog_dev_flush(channel);
/* Close the detached file instance, and destroy the semaphore. These are
* both only created when the device is in SYSLOG_OPENED or SYSLOG_FAILURE
* state.
*/
if (syslog_dev->sl_state == SYSLOG_OPENED ||
syslog_dev->sl_state == SYSLOG_FAILURE)
{
file_close(&syslog_dev->sl_file);
nxsem_destroy(&syslog_dev->sl_sem);
}
/* Set the device in UNINITIALIZED state. */
syslog_dev->sl_state = SYSLOG_UNINITIALIZED;
/* Free the device path */
if (syslog_dev->sl_devpath != NULL)
{
kmm_free(syslog_dev->sl_devpath);
}
/* Free the channel structure */
kmm_free(syslog_dev);
sched_unlock();
}

View file

@ -30,7 +30,6 @@
#include <errno.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h"
@ -43,52 +42,14 @@
#define OPEN_FLAGS (O_WRONLY | O_CREAT | O_APPEND)
#define OPEN_MODE (S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR)
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* SYSLOG channel methods */
static int syslog_file_force(FAR struct syslog_channel_s *channel, int ch);
/****************************************************************************
* Private Data
****************************************************************************/
/* This structure describes the channel's operations. */
static const struct syslog_channel_ops_s g_syslog_ops =
{
syslog_dev_putc,
syslog_file_force,
syslog_dev_flush,
#ifdef CONFIG_SYSLOG_WRITE
syslog_dev_write,
#endif
};
/* Handle to the SYSLOG channel */
FAR static struct syslog_channel_s *g_syslog_file_channel;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: syslog_file_force
*
* Description:
* A dummy FORCE method
*
****************************************************************************/
static int syslog_file_force(FAR struct syslog_channel_s *channel, int ch)
{
UNUSED(channel);
return ch;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -160,10 +121,6 @@ int syslog_file_channel(FAR const char *devpath)
goto errout_with_lock;
}
/* Register the channel operations */
g_syslog_file_channel->sc_ops = &g_syslog_ops;
/* Use the file as the SYSLOG channel. If this fails we are pretty much
* screwed.
*/

View file

@ -94,7 +94,6 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
break;
}
#ifdef CONFIG_SYSLOG_WRITE
if (g_syslog_channel[i]->sc_ops->sc_write)
{
nwritten =
@ -102,7 +101,6 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
buffer, buflen);
}
else
#endif
{
DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL);

View file

@ -101,9 +101,7 @@ struct syslog_channel_ops_s
syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
#ifdef CONFIG_SYSLOG_WRITE
syslog_write_t sc_write; /* Write multiple bytes */
#endif
};
/* This structure provides the interface to a SYSLOG channel */