From 606c03100020570f7a40fcde3522c1bea3af05f8 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 3 Aug 2012 22:04:14 +0000 Subject: Improve capability to traverse inodes in the NuttX psuedo-filesystem; now returns statfs git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5005 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/fs/fs_files.c | 2 +- nuttx/fs/fs_foreachinode.c | 230 ++++++++++++++++++++++++++++++++++++++++ nuttx/fs/fs_foreachmountpoint.c | 185 ++++++++++++++++++++++++++++++++ nuttx/fs/fs_inode.c | 24 ++++- nuttx/fs/fs_inoderemove.c | 7 +- nuttx/fs/fs_internal.h | 187 ++++++++++++++++++++++++++++++-- nuttx/fs/fs_syslog.c | 79 ++++++++------ 7 files changed, 669 insertions(+), 45 deletions(-) create mode 100644 nuttx/fs/fs_foreachinode.c create mode 100644 nuttx/fs/fs_foreachmountpoint.c (limited to 'nuttx/fs') diff --git a/nuttx/fs/fs_files.c b/nuttx/fs/fs_files.c index 3646c51e7..033cd8c63 100644 --- a/nuttx/fs/fs_files.c +++ b/nuttx/fs/fs_files.c @@ -412,7 +412,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd) } /**************************************************************************** - * Name: _files_close + * Name: files_close * * Description: * Close an inode (if open) diff --git a/nuttx/fs/fs_foreachinode.c b/nuttx/fs/fs_foreachinode.c new file mode 100644 index 000000000..7aefcb1c6 --- /dev/null +++ b/nuttx/fs/fs_foreachinode.c @@ -0,0 +1,230 @@ +/**************************************************************************** + * fs/fs_foreachinode.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "fs_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Is it better to allocate the struct inode_path_s from the heap? or + * from the stack? This decision depends on how often this is down and + * how much stack space you can afford. + */ + +#define ENUM_INODE_ALLOC 1 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure manages the full path to the inode. */ + +struct inode_path_s +{ + foreach_inode_t handler; + FAR void *arg; + char path[CONFIG_PATH_MAX]; +}; + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: foreach_inodelevel + * + * Description: + * This is the recursive 'heart' of foreach_inode. It will visit each + * inode at this level in the hierarchy and recurse handle each inode + * at the next level down. + * + * Assumptions: + * The caller holds the inode semaphore. + * + ****************************************************************************/ + +int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info) +{ + int ret; + + /* Visit each node at this level */ + + for (; node; node = node->i_peer) + { + /* Give the next inode to the callback */ + + ret = info->handler(node, info->path, info->arg); + + /* Return early if the handler returns a non-zero value */ + + if (ret != 0) + { + return ret; + } + + /* If there is a level 'beneath' this one, then recurse to visit all + * of the inodes at that level. + */ + + if (node->i_child) + { + /* Construct the path to the next level */ + + int pathlen = strlen(info->path); + int namlen = strlen(node->i_name) + 1; + + /* Make sure that this would not exceed the maximum path length */ + + if (pathlen + namlen < PATH_MAX) + { + /* Append the path segment to this inode */ + + strcat(info->path, "/"); + strcat(info->path, node->i_name); + ret = foreach_inodelevel(node->i_child, info); + + /* Truncate the path name back to the correct length */ + + info->path[pathlen] = '\0'; + + /* Return early if the handler at the lower level returned a non- + * zero value + */ + + if (ret != 0) + { + return ret; + } + } + } + } + + /* No handler complained... return zero */ + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: foreach_inode + * + * Description: + * Visit each inode in the pseudo-file system. The traversal is terminated + * when the callback 'handler' returns a non-zero value, or when all of + * the inodes have been visited. + * + * NOTE 1: Use with caution... The psuedo-file system is locked throughout + * the traversal. + * NOTE 2: The search algorithm is recursive and could, in principle, use + * an indeterminant amount of stack space. This will not usually be a + * real work issue. + * + ****************************************************************************/ + +int foreach_inode(foreach_inode_t handler, FAR void *arg) +{ +#ifdef ENUM_MOUNTPOINT_ALLOC + FAR struct inode_path_s *info; + int ret; + + /* Allocate the mountpoint info structure */ + + info = (FAR struct inode_path_s *)malloc(sizeof(struct inode_path_s)); + if (!path) + { + return -ENOMEM; + } + + /* Initialize the path structure */ + + info->handler = handler; + info->arg = arg; + info->path[0] = '/'; + info->path[1] = '\0'; + + /* Start the recursion at the root inode */ + + inode_semtake(); + ret = foreach_inodelevel(root_inode, info); + inode_semgive(); + + /* Free the path structure and return the result */ + + free(info); + return ret; + +#else + struct inode_path_s info; + int ret; + + /* Initialize the path structure */ + + info.handler = handler; + info.arg = arg; + info.path[0] = '/'; + info.path[1] = '\0'; + + /* Start the recursion at the root inode */ + + inode_semtake(); + ret = foreach_inodelevel(root_inode, &info); + inode_semgive(); + + return ret; + +#endif +} + diff --git a/nuttx/fs/fs_foreachmountpoint.c b/nuttx/fs/fs_foreachmountpoint.c new file mode 100644 index 000000000..a2867c55e --- /dev/null +++ b/nuttx/fs/fs_foreachmountpoint.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * fs/fs_foreachmountpoint.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include "fs_internal.h" + +#ifndef CONFIG_DISABLE_MOUNTPOUNT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Is it better to allocate the struct enum_mountpoint_s from the heap? or + * from the stack? + */ + +#define ENUM_MOUNTPOINT_ALLOC 1 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure just remembers the final consumer of the mountpoint + * information (and its argument). + */ + +struct enum_mountpoint_s +{ + foreach_mountpoint_t handler; + FAR void *arg; + char path[CONFIG_PATH_MAX]; +}; + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int mountpoint_filter(FAR struct inode *node, + FAR const char *dirpath, FAR void *arg) +{ + FAR struct enum_mountpoint_s *info = (FAR struct enum_mountpoint_s *)arg; + struct statfs statbuf; + int ret = OK; + + DEBUGASSERT(node && node->u.i_mops && info && info->handler); + + /* Check if the inode is a mountpoint. Mountpoints must support statfs. + * If this one does not for some reason, then it will be ignored. + */ + + if (INODE_IS_MOUNTPT(node) && node->u.i_mops->statfs) + { + /* Yes... get the full path to the inode by concatenating the inode + * name and the path to the directory containing the inode. + */ + + snprintf(info->path, PATH_MAX, "%s/%s", dirpath, node->i_name); + + /* Get the status of the file system */ + + ret = node->u.i_mops->statfs(node, &statbuf); + if (ret == OK) + { + /* And pass the full path and file system status to the handler */ + + ret = info->handler(info->path, &statbuf, info->arg); + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + /**************************************************************************** + * Name: foreach_mountpoint + * + * Description: + * Visit each mountpoint in the pseudo-file system. The traversal is + * terminated when the callback 'handler' returns a non-zero value, or when + * all of the mountpoints have been visited. + * + * This is just a front end "filter" to foreach_inode() that forwards only + * mountpoint inodes. It is intended to support the mount() command to + * when the mount command is used to enumerate mounts. + * + * NOTE 1: Use with caution... The psuedo-file system is locked throughout + * the traversal. + * NOTE 2: The search algorithm is recursive and could, in principle, use + * an indeterminant amount of stack space. This will not usually be a + * real work issue. + * + ****************************************************************************/ + +int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg) +{ +#ifdef ENUM_MOUNTPOINT_ALLOC + FAR struct enum_mountpoint_s *info; + int ret; + + /* Allocate the mountpoint info structure */ + + info = (FAR struct enum_mountpoint_s *)malloc(sizeof(struct enum_mountpoint_s)); + if (!info) + { + return -ENOMEM; + } + + /* Let foreach_inode do the real work */ + + info->handler = handler; + info->arg = arg; + + ret = foreach_inode(mountpoint_filter, (FAR void *)info); + free(info); + return ret; +#else + struct enum_mountpoint_s info; + + /* Let foreach_inode do the real work */ + + info.handler = handler; + info.arg = arg; + + return foreach_inode(mountpoint_filter, (FAR void *)&info); +#endif +} + +#endif diff --git a/nuttx/fs/fs_inode.c b/nuttx/fs/fs_inode.c index 0b88c4b3b..14da54cea 100644 --- a/nuttx/fs/fs_inode.c +++ b/nuttx/fs/fs_inode.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/fs_inode.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -70,9 +70,13 @@ FAR struct inode *root_inode = NULL; /**************************************************************************** * Name: _inode_compare + * + * Description: + * Compare two inode names + * ****************************************************************************/ -static int _inode_compare(const char *fname, +static int _inode_compare(FAR const char *fname, FAR struct inode *node) { char *nname = node->i_name; @@ -174,6 +178,10 @@ void fs_initialize(void) /**************************************************************************** * Name: inode_semtake + * + * Description: + * Get exclusive access to the in-memory inode tree (tree_sem). + * ****************************************************************************/ void inode_semtake(void) @@ -192,6 +200,10 @@ void inode_semtake(void) /**************************************************************************** * Name: inode_semgive + * + * Description: + * Relinquish exclusive access to the in-memory inode tree (tree_sem). + * ****************************************************************************/ void inode_semgive(void) @@ -315,6 +327,10 @@ FAR struct inode *inode_search(const char **path, /**************************************************************************** * Name: inode_free + * + * Description: + * Free resources used by an inode + * ****************************************************************************/ void inode_free(FAR struct inode *node) @@ -331,8 +347,8 @@ void inode_free(FAR struct inode *node) * Name: inode_nextname * * Description: - * Given a path with node names separated by '/', return - * the next node name. + * Given a path with node names separated by '/', return the next node + * name. * ****************************************************************************/ diff --git a/nuttx/fs/fs_inoderemove.c b/nuttx/fs/fs_inoderemove.c index cad136f3b..c349b1759 100644 --- a/nuttx/fs/fs_inoderemove.c +++ b/nuttx/fs/fs_inoderemove.c @@ -105,11 +105,14 @@ static void inode_unlink(struct inode *node, /**************************************************************************** * Name: inode_remove * - * NOTE: Caller must hold the inode semaphore + * Description: + * Remove a node from the in-memory, inode tree + * + * NOTE: Caller must hold the inode semaphore * ****************************************************************************/ -int inode_remove(const char *path) +int inode_remove(FAR const char *path) { const char *name = path; FAR struct inode *node; diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h index 326a4f8b5..4405b07ba 100644 --- a/nuttx/fs/fs_internal.h +++ b/nuttx/fs/fs_internal.h @@ -84,6 +84,13 @@ * Public Types ****************************************************************************/ +/* Callback used by foreach_inode to traverse all inodes in the pseudo- + * file system. + */ + +typedef int (*foreach_inode_t)(FAR struct inode *node, + FAR const char *dirpath, FAR void *arg); + /**************************************************************************** * Global Variables ****************************************************************************/ @@ -103,44 +110,210 @@ extern "C" { #endif /* fs_inode.c ***************************************************************/ +/**************************************************************************** + * Name: inode_semtake + * + * Description: + * Get exclusive access to the in-memory inode tree (tree_sem). + * + ****************************************************************************/ EXTERN void inode_semtake(void); + +/**************************************************************************** + * Name: inode_semgive + * + * Description: + * Relinquish exclusive access to the in-memory inode tree (tree_sem). + * + ****************************************************************************/ + EXTERN void inode_semgive(void); + +/**************************************************************************** + * Name: inode_search + * + * Description: + * Find the inode associated with 'path' returning the inode references + * and references to its companion nodes. + * + * Assumptions: + * The caller holds the tree_sem + * + ****************************************************************************/ + EXTERN FAR struct inode *inode_search(FAR const char **path, FAR struct inode **peer, FAR struct inode **parent, FAR const char **relpath); + +/**************************************************************************** + * Name: inode_free + * + * Description: + * Free resources used by an inode + * + ****************************************************************************/ + EXTERN void inode_free(FAR struct inode *node); + +/**************************************************************************** + * Name: inode_nextname + * + * Description: + * Given a path with node names separated by '/', return the next node + * name. + * + ****************************************************************************/ + EXTERN const char *inode_nextname(FAR const char *name); -/* fs_inodereserver.c ********************************************************/ +/* fs_inodereserver.c *******************************************************/ +/**************************************************************************** + * Name: inode_reserve + * + * Description: + * Reserve an (initialized) inode the pseudo file system. + * + * NOTE: Caller must hold the inode semaphore + * + * Input parameters: + * path - The path to the inode to create + * inode - The location to return the inode pointer + * + * Returned Value: + * Zero on success (with the inode point in 'inode'); A negated errno + * value is returned on failure: + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + ****************************************************************************/ EXTERN int inode_reserve(FAR const char *path, FAR struct inode **inode); -/* fs_inoderemove.c **********************************************************/ +/* fs_inoderemove.c *********************************************************/ +/**************************************************************************** + * Name: inode_remove + * + * Description: + * Remove a node from the in-memory, inode tree + * + * NOTE: Caller must hold the inode semaphore + * + ****************************************************************************/ EXTERN int inode_remove(FAR const char *path); -/* fs_inodefind.c ************************************************************/ +/* fs_inodefind.c ***********************************************************/ +/**************************************************************************** + * Name: inode_find + * + * Description: + * This is called from the open() logic to get a reference to the inode + * associated with a path. + * + ****************************************************************************/ EXTERN FAR struct inode *inode_find(FAR const char *path, const char **relpath); -/* fs_inodeaddref.c **********************************************************/ +/* fs_inodeaddref.c *********************************************************/ EXTERN void inode_addref(FAR struct inode *inode); -/* fs_inoderelease.c *********************************************************/ +/* fs_inoderelease.c ********************************************************/ EXTERN void inode_release(FAR struct inode *inode); -/* fs_files.c ****************************************************************/ +/* fs_foreachinode.c ********************************************************/ +/**************************************************************************** + * Name: foreach_inode + * + * Description: + * Visit each inode in the pseudo-file system. The traversal is terminated + * when the callback 'handler' returns a non-zero value, or when all of + * the inodes have been visited. + * + * NOTE 1: Use with caution... The psuedo-file system is locked throughout + * the traversal. + * NOTE 2: The search algorithm is recursive and could, in principle, use + * an indeterminant amount of stack space. This will not usually be a + * real work issue. + * + ****************************************************************************/ + +EXTERN int foreach_inode(foreach_inode_t handler, FAR void *arg); + +/* fs_files.c ***************************************************************/ +/**************************************************************************** + * Name: files_initialize + * + * Description: + * This is called from the FS initialization logic to configure the files. + * + ****************************************************************************/ EXTERN void weak_function files_initialize(void); + +/**************************************************************************** + * Name: files_allocate + * + * Description: + * Allocate a struct files instance and associate it with an inode instance. + * Returns the file descriptor == index into the files array. + * + ****************************************************************************/ + EXTERN int files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd); + +/**************************************************************************** + * Name: files_close + * + * Description: + * Close an inode (if open) + * + * Assumuptions: + * Caller holds the list semaphore because the file descriptor will be freed. + * + ****************************************************************************/ + EXTERN int files_close(int filedes); + +/**************************************************************************** + * Name: files_release + * + * Assumuptions: + * Similar to files_close(). Called only from open() logic on error + * conditions. + * + ****************************************************************************/ + EXTERN void files_release(int filedes); -/* fs_findblockdriver.c ******************************************************/ +/* fs_findblockdriver.c *****************************************************/ +/**************************************************************************** + * Name: find_blockdriver + * + * Description: + * Return the inode of the block driver specified by 'pathname' + * + * Inputs: + * pathname - the full path to the block driver to be located + * mountflags - if MS_RDONLY is not set, then driver must support write + * operations (see include/sys/mount.h) + * ppinode - address of the location to return the inode reference + * + * Return: + * Returns zero on success or a negated errno on failure: + * + * EINVAL - pathname or pinode is NULL + * ENOENT - No block driver of this name is registered + * ENOTBLK - The inode associated with the pathname is not a block driver + * EACCESS - The MS_RDONLY option was not set but this driver does not + * support write access + * + ****************************************************************************/ EXTERN int find_blockdriver(FAR const char *pathname, int mountflags, FAR struct inode **ppinode); diff --git a/nuttx/fs/fs_syslog.c b/nuttx/fs/fs_syslog.c index 6586b90bc..1fe8c03a1 100644 --- a/nuttx/fs/fs_syslog.c +++ b/nuttx/fs/fs_syslog.c @@ -390,49 +390,66 @@ int syslog_putc(int ch) * that is why that case is handled in syslog_semtake(). */ - if (g_sysdev.sl_state == SYSLOG_UNINITIALIZED || - g_sysdev.sl_state == SYSLOG_INITIALIZING || - up_interrupt_context()) - { - return -EAGAIN; - } + /* Case (4) */ - if (g_sysdev.sl_state == SYSLOG_FAILURE) + if (up_interrupt_context()) { - return -ENXIO; + return -ENOSYS; /* Not supported */ } - /* syslog_initialize() is called as soon as enough of the operating system - * is in place to support the open operation... but it is possible that the - * SYSLOG device is not yet registered at that time. In this case, we - * know that the system is sufficiently initialized to support an attempt - * to re-open the SYSLOG device. - * - * NOTE that the scheduler is locked. That is because we do not have fully - * initialized semaphore capability until the SYSLOG device is successfully - * initialized + /* We can save checks in the usual case: That after the SYSLOG device + * has been successfully opened. */ - sched_lock(); - if (g_sysdev.sl_state == SYSLOG_REOPEN) + if (g_sysdev.sl_state != SYSLOG_OPENED) { - /* Try again to initialize the device. We may do this repeatedly - * because the log device might be something that was not ready the - * first time that syslog_intialize() was called (such as a USB - * serial device that has not yet been connected or a file in - * an NFS mounted file system that has not yet been mounted). + /* Case (1) and (2) */ + + if (g_sysdev.sl_state == SYSLOG_UNINITIALIZED || + g_sysdev.sl_state == SYSLOG_INITIALIZING) + { + return -EAGAIN; /* Can't access the SYSLOG now... maybe next time? */ + } + + /* Case (5) */ + + if (g_sysdev.sl_state == SYSLOG_FAILURE) + { + return -ENXIO; /* There is no SYSLOG device */ + } + + /* syslog_initialize() is called as soon as enough of the operating + * system is in place to support the open operation... but it is + * possible that the SYSLOG device is not yet registered at that time. + * In this case, we know that the system is sufficiently initialized + * to support an attempt to re-open the SYSLOG device. + * + * NOTE that the scheduler is locked. That is because we do not have + * fully initialized semaphore capability until the SYSLOG device is + * successfully initialized */ - ret = syslog_initialize(); - if (ret < 0) + sched_lock(); + if (g_sysdev.sl_state == SYSLOG_REOPEN) { - sched_unlock(); - return ret; + /* Try again to initialize the device. We may do this repeatedly + * because the log device might be something that was not ready + * the first time that syslog_intialize() was called (such as a + * USB serial device that has not yet been connected or a file in + * an NFS mounted file system that has not yet been mounted). + */ + + ret = syslog_initialize(); + if (ret < 0) + { + sched_unlock(); + return ret; + } } - } - sched_unlock(); - DEBUGASSERT(g_sysdev.sl_state == SYSLOG_OPENED); + sched_unlock(); + DEBUGASSERT(g_sysdev.sl_state == SYSLOG_OPENED); + } /* Ignore carriage returns */ -- cgit v1.2.3