This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit e53aeea60ee38882b08a1526da07bd05506dfd37 Author: zhuyanlin <[email protected]> AuthorDate: Thu Oct 14 19:39:44 2021 +0800 fs:procfs: add tcbinfo procfs interface Add tcbinfo in procfs system. Signed-off-by: zhuyanlin <[email protected]> --- fs/procfs/Kconfig | 5 + fs/procfs/Make.defs | 2 +- fs/procfs/fs_procfs.c | 5 + fs/procfs/fs_procfstcbinfo.c | 299 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 310 insertions(+), 1 deletion(-) diff --git a/fs/procfs/Kconfig b/fs/procfs/Kconfig index f0bd7a6..6d28080 100644 --- a/fs/procfs/Kconfig +++ b/fs/procfs/Kconfig @@ -131,5 +131,10 @@ config FS_PROCFS_EXCLUDE_SMARTFS depends on FS_SMARTFS default n +config FS_PROCFS_EXCLUDE_TCBINFO + bool "Exclude tcbinfo procfs" + depends on DEBUG_TCBINFO + default n + endmenu # Exclude individual procfs entries endif # FS_PROCFS diff --git a/fs/procfs/Make.defs b/fs/procfs/Make.defs index 8145c16..c7104eb 100644 --- a/fs/procfs/Make.defs +++ b/fs/procfs/Make.defs @@ -23,7 +23,7 @@ ifeq ($(CONFIG_FS_PROCFS),y) CSRCS += fs_procfs.c fs_procfsutil.c fs_procfsproc.c fs_procfsuptime.c CSRCS += fs_procfscpuload.c fs_procfsmeminfo.c fs_procfsiobinfo.c -CSRCS += fs_procfsversion.c +CSRCS += fs_procfsversion.c fs_procfstcbinfo.c ifeq ($(CONFIG_SCHED_CRITMONITOR),y) CSRCS += fs_procfscritmon.c diff --git a/fs/procfs/fs_procfs.c b/fs/procfs/fs_procfs.c index e0a41c7..85a53e4 100644 --- a/fs/procfs/fs_procfs.c +++ b/fs/procfs/fs_procfs.c @@ -70,6 +70,7 @@ extern const struct procfs_operations iobinfo_operations; extern const struct procfs_operations module_operations; extern const struct procfs_operations uptime_operations; extern const struct procfs_operations version_operations; +extern const struct procfs_operations tcbinfo_operations; /* This is not good. These are implemented in other sub-systems. Having to * deal with them here is not a good coupling. What is really needed is a @@ -165,6 +166,10 @@ static const struct procfs_entry_s g_procfs_entries[] = #if !defined(CONFIG_FS_PROCFS_EXCLUDE_VERSION) { "version", &version_operations, PROCFS_FILE_TYPE }, #endif + +#if defined(CONFIG_DEBUG_TCBINFO) && !defined(CONFIG_FS_PROCFS_EXCLUDE_TCBINFO) + { "tcbinfo", &tcbinfo_operations, PROCFS_FILE_TYPE }, +#endif }; #ifdef CONFIG_FS_PROCFS_REGISTER diff --git a/fs/procfs/fs_procfstcbinfo.c b/fs/procfs/fs_procfstcbinfo.c new file mode 100644 index 0000000..8551b66 --- /dev/null +++ b/fs/procfs/fs_procfstcbinfo.c @@ -0,0 +1,299 @@ +/**************************************************************************** + * fs/procfs/fs_procfstcbinfo.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <assert.h> +#include <errno.h> +#include <debug.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/fs/fs.h> +#include <nuttx/fs/procfs.h> + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) +#ifdef CONFIG_DEBUG_TCBINFO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ + +#define TCBINFO_LINELEN 128 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes one open "file" */ + +struct tcbinfo_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + unsigned int linesize; /* Number of valid characters in line[] */ + char line[TCBINFO_LINELEN]; /* Pre-allocated buffer for formatted lines */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* File system methods */ + +static int tcbinfo_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int tcbinfo_close(FAR struct file *filep); +static ssize_t tcbinfo_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); + +static int tcbinfo_dup(FAR const struct file *oldp, + FAR struct file *newp); + +static int tcbinfo_stat(FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern struct tcbinfo_s g_tcbinfo; + +/* See fs_mount.c -- this structure is explicitly externed there. + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +const struct procfs_operations tcbinfo_operations = +{ + tcbinfo_open, /* open */ + tcbinfo_close, /* close */ + tcbinfo_read, /* read */ + NULL, /* write */ + + tcbinfo_dup, /* dup */ + + NULL, /* opendir */ + NULL, /* closedir */ + NULL, /* readdir */ + NULL, /* rewinddir */ + + tcbinfo_stat /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tcbinfo_open + ****************************************************************************/ + +static int tcbinfo_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct tcbinfo_file_s *attr; + + finfo("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) + { + ferr("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* "tcbinfo" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "tcbinfo") != 0) + { + ferr("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* Allocate a container to hold the file attributes */ + + attr = (FAR struct tcbinfo_file_s *) + kmm_zalloc(sizeof(struct tcbinfo_file_s)); + + if (attr == NULL) + { + ferr("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Save the attributes as the open-specific state in filep->f_priv */ + + filep->f_priv = (FAR void *)attr; + return OK; +} + +/**************************************************************************** + * Name: tcbinfo_close + ****************************************************************************/ + +static int tcbinfo_close(FAR struct file *filep) +{ + FAR struct tcbinfo_file_s *attr; + + /* Recover our private data from the struct file instance */ + + attr = (FAR struct tcbinfo_file_s *)filep->f_priv; + DEBUGASSERT(attr); + + /* Release the file attributes structure */ + + kmm_free(attr); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: tcbinfo_read + ****************************************************************************/ + +static ssize_t tcbinfo_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct tcbinfo_file_s *attr; + size_t linesize; + off_t offset; + ssize_t ret; + + finfo("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Recover our private data from the struct file instance */ + + attr = (FAR struct tcbinfo_file_s *)filep->f_priv; + DEBUGASSERT(attr); + + if (filep->f_pos == 0) + { + linesize = procfs_snprintf(attr->line, TCBINFO_LINELEN, + "pointer %p size %d\n", g_tcbinfo, + sizeof(struct tcbinfo_s)); + + /* Save the linesize in case we are re-entered with f_pos > 0 */ + + attr->linesize = linesize; + } + + offset = filep->f_pos; + ret = procfs_memcpy(attr->line, attr->linesize, buffer, buflen, &offset); + + /* Update the file offset */ + + if (ret > 0) + { + filep->f_pos += ret; + } + + return ret; +} + +/**************************************************************************** + * Name: tcbinfo_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int tcbinfo_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct tcbinfo_file_s *oldattr; + FAR struct tcbinfo_file_s *newattr; + + finfo("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldattr = (FAR struct tcbinfo_file_s *)oldp->f_priv; + DEBUGASSERT(oldattr); + + /* Allocate a new container to hold the task and attribute selection */ + + newattr = (FAR struct tcbinfo_file_s *) + kmm_malloc(sizeof(struct tcbinfo_file_s)); + + if (!newattr) + { + ferr("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attributes from the old attributes to the new */ + + memcpy(newattr, oldattr, sizeof(struct tcbinfo_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newattr; + return OK; +} + +/**************************************************************************** + * Name: tcbinfo_stat + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int tcbinfo_stat(FAR const char *relpath, FAR struct stat *buf) +{ + /* "tcbinfo" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "tcbinfo") != 0) + { + ferr("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* "tcbinfo" is the name for a read-only file */ + + memset(buf, 0, sizeof(struct stat)); + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_DEBUG_TCBINFO */ +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS */
