proc文件系统支持

This commit is contained in:
zhangzheng
2025-03-31 21:35:14 +08:00
parent be26567cfc
commit 6541993082
29 changed files with 1847 additions and 14 deletions

4
.vscode/launch.json vendored
View File

@@ -71,8 +71,8 @@
// "miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
// "miDebuggerPath": "/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
// "miDebuggerPath": "/home/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
"miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb",
// "miDebuggerPath": "/home/zhangzheng/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/bin/arm-none-eabi-gdb",
// "miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb",
"miDebuggerPath": "/home/zhangzheng/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/bin/arm-none-eabi-gdb",
"miDebuggerServerAddress": "127.0.0.1:33333",
"MIMode": "gdb",
"setupCommands": [

View File

@@ -223,7 +223,8 @@
"stdarg.h": "c",
"ipcstat.h": "c",
"fs_cli.h": "c",
"fs_backend.h": "c"
"fs_backend.h": "c",
"ns_types.h": "c"
},
"cortex-debug.showRTOS": false,
"cortex-debug.variableUseNaturalFormat": true,

View File

@@ -146,11 +146,11 @@ static void ipc_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag,
case IPC_DO:
{
//!< 如果是ipc协议则当成一个ipc处理
if (ipc->svr_tk == cur_task)
{
tag = msg_tag_init4(0, 0, 0, -ECANCELED);
break;
}
// if (ipc->svr_tk == cur_task)
// {
// tag = msg_tag_init4(0, 0, 0, -ECANCELED);
// break;
// }
again:
if (ipc->svr_tk == NULL)
{

View File

@@ -41,6 +41,7 @@ enum task_op_code
TASK_GET_PID, //!< 获取task的pid
TASK_COPY_DATA, //!< 拷贝数据到task的数据区域
TASK_SET_OBJ_NAME, //!< 设置对象的名字
TASK_GET_OBJ_NAME, //!< 获取对象的名字
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
TASK_SET_COM_POINT, //!< 通信点
TASK_COM_UNLOCK, //!< 任务通信解锁
@@ -232,6 +233,29 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
switch (sys_p.op)
{
case TASK_GET_OBJ_NAME:
{
mword_t status = spinlock_lock(&tag_task->kobj.lock);
if (status < 0)
{
tag = msg_tag_init4(0, 0, 0, -EINVAL);
break;
}
kobject_t *source_kobj = obj_space_lookup_kobj(&cur_task->obj_space, f->regs[0]);
if (!source_kobj)
{
spinlock_set(&tag_task->kobj.lock, status);
tag = msg_tag_init4(0, 0, 0, -EINVAL);
break;
}
char *kobj_name = kobject_get_name(source_kobj);
memcpy((char *)(&f->regs[1]), kobj_name, KOBJ_NAME_SIZE);
spinlock_set(&tag_task->kobj.lock, status);
tag = msg_tag_init4(0, 0, 0, 1);
}
break;
case TASK_SET_OBJ_NAME:
{
mword_t status = spinlock_lock(&tag_task->kobj.lock);

View File

@@ -18,6 +18,7 @@ typedef struct
umword_t (*map_buf)[CONFIG_THREAD_MAP_BUF_LEN];
} fast_ipc_info_t;
msg_tag_t u_task_get_obj_name(obj_handler_t dst_task, obj_handler_t obj, char name[8/*FIXME:使用宏*/]);
msg_tag_t u_task_set_obj_name(obj_handler_t dst_task, obj_handler_t obj, const char *name);
msg_tag_t u_task_set_pid(obj_handler_t dst_task, umword_t pid);
msg_tag_t u_task_get_pid(obj_handler_t dst_task, umword_t *data);

View File

@@ -14,6 +14,7 @@ enum task_op_code
TASK_GET_PID,
TASK_COPY_DATA,
TASK_SET_OBJ_NAME,
TASK_GET_OBJ_NAME,
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
TASK_SET_COM_POINT,
TASK_COM_UNLOCK,
@@ -41,6 +42,33 @@ msg_tag_t u_task_set_obj_name(obj_handler_t dst_task, obj_handler_t obj, const c
return tag;
}
MK_SYSCALL
msg_tag_t u_task_get_obj_name(obj_handler_t dst_task, obj_handler_t obj, char name[8/*FIXME:使用宏*/])
{
register volatile umword_t r0 asm(ARCH_REG_0);
register volatile umword_t r1 asm(ARCH_REG_1);
register volatile umword_t r2 asm(ARCH_REG_2);
mk_syscall(syscall_prot_create(TASK_GET_OBJ_NAME, TASK_PROT, dst_task).raw,
obj,
0,
0,
0,
0,
0);
asm __volatile__(""
:
:
: ARCH_REG_0, ARCH_REG_1, ARCH_REG_2);
if (name)
{
uint32_t *name_word = (uint32_t *)name;
*name_word++ = r1;
*name_word = r2;
}
return msg_tag_init(r0);
}
MK_SYSCALL
msg_tag_t u_task_set_pid(obj_handler_t dst_task, umword_t pid)
{
register volatile umword_t r0 asm(ARCH_REG_0);

View File

@@ -198,9 +198,13 @@ next:
#endif
int s_inx = msg_tag_get_val(tag);
if (s_inx == strlen(path))
if (path[s_inx] != '/' && path[s_inx - 1] == '/')
{
if (reg_hd(path, newfd, msg_tag_get_val(tag)) == FALSE)
s_inx--;
}
if (msg_tag_get_val(tag)== strlen(path))
{
if (reg_hd(path, newfd, s_inx) == FALSE)
{
printf("The client service cache is full.\n");
#if 0
@@ -210,7 +214,7 @@ next:
}
}
*svr_hd = newfd;
return msg_tag_get_val(tag);
return s_inx;
}
int ns_query_svr(const char *path, obj_handler_t *svr_hd)
{

View File

@@ -22,6 +22,7 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
)
target_link_libraries(
sys_util

View File

@@ -123,6 +123,7 @@ void sig_init(void)
tag = u_facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_wait_hd), 0, 1);
assert(msg_tag_get_val(tag) >= 0);
#if 0
char proc_path[20];
umword_t pid;
@@ -130,5 +131,6 @@ void sig_init(void)
snprintf(proc_path, sizeof(proc_path), "/proc/%d", pid);
assert(ns_register(proc_path, sig_ipc, 0) >= 0 && "task proc init failed.\n");
#endif
}
#endif

View File

@@ -4,5 +4,5 @@ cmake_minimum_required(VERSION 3.13)
# add_subdirectory(cpiofs)
add_subdirectory(fatfs)
add_subdirectory(appfs)
# add_subdirectory(procfs)
add_subdirectory(procfs)
# add_subdirectory(lxext4)

View File

@@ -1,5 +1,31 @@
cmake_minimum_required(VERSION 3.13)
file(GLOB proc_src src/proc.c src/procfs.c src/procfs_rpc.c src/procfs_impl.c)
add_library(
proc
STATIC
${proc_src}
)
target_include_directories(
proc
PUBLIC
${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/procfs/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc/${ARCH_NAME}
)
target_link_libraries(
proc
PUBLIC
-Bstatic
${LIBC_NAME}
${START_LIB}
sys
sys_util
sys_svr
fd
${GCC_LIB_PATH}/libgcc.a
)
file(
GLOB deps
src/*.c

View File

@@ -0,0 +1,124 @@
ENTRY(_start_)
SECTIONS
{
.text : {
. = ALIGN(4);
__text_start__ = .;
KEEP(*(.first))
*(.text)
*(.text.*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(SORT(.rodata.*))
*(.rodata)
KEEP(*(.eh_frame*))
. = ALIGN(4);
__rel_start__ = .;
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
__rel_end__ = .;
}
.ARM.exidx : {
. = ALIGN(4);
__exdix_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
__exdix_end = .;
}
.permissions_table : {
. = ALIGN(4);
__permissions_table_start__ = .;
KEEP(*(.permissions_table))
__permissions_table_end__ = .;
}
PROVIDE(__ram_size__ = __bss_end__ - __data_start__);
.data : {
. = ALIGN(4);
__data_start__ = .;
__got_start__ = .;
*(.got)
__got_end__ = .;
. = ALIGN(4);
*(.data)
*(.data.*)
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
_shell_command_start = .;
KEEP(*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
/* All data end */
__data_end__ = .;
}
PROVIDE(__heap_size__ = __heap_end__ - __heap_start__);
PROVIDE(__stack_size__ = __stack_end__ - __stack_start__);
.bss : {
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
__bss_start__ = .;
*(.bss)
*(COMMON)
. = ALIGN(4);
__heap_start__ = .;
KEEP(*(.bss.heap))
__heap_end__ = .;
. = ALIGN(4);
__stack_start__ = .;
KEEP(*(.bss.stack))
__stack_end__ = .;
*(.bss.*)
/* This is used by the startup in order to initialize the .bss secion */
. = ALIGN(4);
__bss_end__ = .;
}
_end = .;
}

View File

@@ -0,0 +1,66 @@
#pragma once
#include <assert.h>
#include <stdint.h>
#include "u_rpc.h"
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#define NS_NODE_NAME_LEN 32
typedef enum proc_node_type
{
NODE_TYPE_PROC_DUMMY, //!< 虚拟节点,可以有子节点
NODE_TYPE_PROC_FILE, //!< 服务节点,不能有子节点
NODE_TYPE_PROC_ROOT, //!< ROOT节点
} proc_node_type_t;
struct proc_node;
typedef struct proc_node proc_node_t;
typedef struct proc_file_operation
{
int (*proc_open)(proc_node_t *node, const char *path, int flags, int mode);
int (*proc_read)(proc_node_t *node, void *buf, size_t len, long offset);
int (*proc_write)(proc_node_t *node, void *buf, size_t len, long offset);
void (*proc_close)(proc_node_t *node);
// int (*proc_readdir)(proc_node_t *node, dirent_t *dir);
int (*proc_lseek)(proc_node_t *node, int offs, int whence);
// int (*proc_ftruncate)(proc_node_t *node, off_t off);
// int (*proc_fstat)(proc_node_t *node, void *buf);
int (*proc_ioctl)(proc_node_t *node, int req, void *arg);
// int (*proc_fcntl)(proc_node_t *node, int cmd, void *arg);
// int (*proc_fsync)(proc_node_t *node);
} proc_file_operation_t;
typedef struct proc_node
{
char name[NS_NODE_NAME_LEN]; //!< 节点名字
proc_node_type_t type; //!< 节点类型
struct proc_node *parent; //!< 父节点
struct proc_node *next; //!< 兄弟节点的下一个节点
struct proc_node *sub; //!< 子树节点
const proc_file_operation_t *op; //!< proc的操作节点
int ref; //!< 引用计数
} proc_node_t;
void proc_root_node_init(void);
proc_node_t *proc_node_find(proc_node_t **pnode, const char *path, int *ret, int *svr_inx, int *p_inx);
proc_node_t *proc_node_find_full_dir(const char *path, int *ret, int *cur_inx);
proc_node_t *proc_node_find_full_file(const char *path, int *ret, int *cur_inx);
proc_node_t *proc_node_find_svr_file(const char *path, int *ret, int *cur_inx);
int proc_nodes_count(proc_node_t *tree);
proc_node_t *proc_node_get_inx(proc_node_t *tree, int inx);
int proc_delnode(const char *path);
int proc_mknode(const char *path, proc_node_type_t type, const proc_file_operation_t *op);
static inline proc_node_t *proc_node_get_next(proc_node_t *tree_node, proc_node_t *cur_node)
{
assert(cur_node);
return cur_node->next;
}
static inline proc_node_t *proc_node_get_first(proc_node_t *tree_node)
{
assert(tree_node);
return tree_node->sub;
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include "kstat.h"
#include "proc.h"
#include "u_rpc.h"
#include "u_types.h"
#include <dirent.h>
#include <fcntl.h>
void procfs_lock(void);
void proc_unlock(void);
int proc_ns_open(const char *name, int flags, int mode);
int proc_ns_write(int fd, void *data, int len);
int proc_ns_read(int fd, void *data, int len);
int proc_ns_ioctl(int fd, unsigned long cmd, unsigned long arg);
int proc_ns_lseek(int fd, int offset, unsigned long whence);
int proc_ns_truncate(int fd, off_t length);
int proc_ns_fstat(int fd, struct kstat *st);
int proc_ns_stat(const char *path, struct kstat *st);
int proc_ns_close(int fd);
int proc_ns_remove(const char *name);
int proc_ns_readdir(int fd, struct dirent *_dir);
int proc_ns_mkdir(char *path);
int proc_ns_rmdir(const char *name);
void proc_ns_del_file_by_pid(const char *path, pid_t pid);
int proc_register_file(const char *path, const proc_file_operation_t *op);
int proc_ns_open_init(void);

View File

@@ -0,0 +1,3 @@
#pragma once
int proc_default_file_register(void);

View File

@@ -0,0 +1,4 @@
#pragma once
void procfs_svr_init(void);

View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e -x
mkdir -p build
cmake -G Ninja -B build .
cd build && ninja

View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -e -x
rm -r build

View File

@@ -0,0 +1,13 @@
#include <u_util.h>
#include <u_types.h>
#define HEAP_SIZE (4096)
#define STACK_SIZE (1024*2)
#define HEAP_ATTR __attribute__((__section__(".bss.heap")))
#define STACK_ATTR __attribute__((__section__(".bss.stack")))
__attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE];
__attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE];
__attribute__((used)) umword_t _____mm_bitmap_____[ROUND(HEAP_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];

View File

@@ -0,0 +1,201 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "proc.h"
#include "procfs.h"
#include <assert.h>
int procfs_mkdir_test(void)
{
int ret;
ret = proc_ns_mkdir("/bin/tst/");
assert(ret < 0);
ret = proc_ns_mkdir("/bin/");
assert(ret >= 0);
ret = proc_ns_mkdir("/bin2");
assert(ret >= 0);
ret = proc_ns_mkdir("/bin/tst/");
assert(ret >= 0);
ret = proc_ns_remove("/bin/tst");
assert(ret < 0);
ret = proc_ns_rmdir("/bin/tst");
assert(ret >= 0);
return 0;
}
int procfs_scan_dir_test(void)
{
#define TEST_CN 10
int ret;
ret = proc_ns_mkdir("/bin/");
assert(ret >= 0);
for (int i = 0; i < TEST_CN; i++)
{
char dir_name[32];
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
ret = proc_ns_mkdir(dir_name);
assert(ret >= 0);
}
int fd;
fd = proc_ns_open("/bin/", O_RDWR, 0777);
assert(fd >= 0);
struct dirent dir_info;
for (int i = 0; i < (TEST_CN + 1); i++)
{
ret = proc_ns_readdir(fd, &dir_info);
if (i < TEST_CN)
{
assert(ret >= 0);
printf("readdir info :%s\n", dir_info.d_name);
fflush(stdout);
}
else
{
assert(ret < 0);
}
}
ret = proc_ns_lseek(fd, 2, SEEK_SET);
printf("old seek: %d\n", ret);
assert(ret >= 0);
for (int i = 0; i < (TEST_CN - 2 + 1); i++)
{
ret = proc_ns_readdir(fd, &dir_info);
if (i < TEST_CN - 2)
{
assert(ret >= 0);
printf("readdir info :%s\n", dir_info.d_name);
fflush(stdout);
}
else
{
assert(ret < 0);
}
}
ret = proc_ns_close(fd);
assert(ret >= 0);
ret = proc_ns_readdir(fd, &dir_info);
assert(ret < 0);
for (int i = 0; i < TEST_CN; i++)
{
char dir_name[32];
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
ret = proc_ns_rmdir(dir_name);
assert(ret >= 0);
}
ret = proc_ns_rmdir("/bin");
assert(ret >= 0);
#undef TEST_CN
return 0;
}
int procfs_mksvr_node(void)
{
int ret;
struct dirent dir;
ret = proc_ns_mkdir("/bin/");
assert(ret >= 0);
ret = proc_mknode("/bin/tst1", NODE_TYPE_PROC_FILE, NULL);
assert(ret >= 0);
int fd;
fd = proc_ns_open("/bin/tst1", O_RDWR, 0777);
assert(fd < 0);
fd = proc_ns_open("/bin/", O_RDWR, 0777);
assert(fd >= 0);
ret = proc_ns_readdir(fd, &dir);
assert(ret >= 0);
printf("readdir info :%s\n", dir.d_name);
ret = proc_ns_close(fd);
assert(ret >= 0);
ret = proc_ns_remove("/bin/tst1/");
assert(ret >= 0);
ret = proc_ns_rmdir("/bin/");
assert(ret >= 0);
return 0;
}
int procfs_query_svr_node(void)
{
int ret;
ret = proc_ns_mkdir("/bin/");
assert(ret >= 0);
proc_node_t *node;
proc_node_t *pnode;
int cur_inx;
int p_inx;
node = proc_node_find_full_file("/bin/", &ret, &cur_inx);
assert(node == NULL && ret < 0);
#define SVR_NODE "/svr_tst"
ret = proc_mknode(SVR_NODE, NODE_TYPE_PROC_FILE, NULL);
assert(ret >= 0);
node = proc_node_find_full_file(SVR_NODE, &ret, &cur_inx);
assert(node != NULL && ret >= 0);
assert(cur_inx == strlen(SVR_NODE));
node = proc_node_find(&pnode, SVR_NODE "/1/2/3", &ret, &cur_inx, &p_inx);
assert(node != NULL && ret >= 0);
assert(cur_inx == strlen(SVR_NODE) + 1);
ret = proc_ns_mkdir(SVR_NODE "/1");
assert(ret < 0);
#undef SVR_NODE
ret = proc_ns_remove("/svr_tst");
assert(ret >= 0);
#define SVR_NODE "/bin/svr_tst"
ret = proc_mknode(SVR_NODE, NODE_TYPE_PROC_FILE, NULL);
assert(ret >= 0);
node = proc_node_find_full_file(SVR_NODE, &ret, &cur_inx);
assert(node != NULL && ret >= 0);
assert(cur_inx == strlen(SVR_NODE));
node = proc_node_find_svr_file(SVR_NODE "/1/2/3", &ret, &cur_inx);
assert(node != NULL && ret >= 0);
assert(cur_inx == strlen(SVR_NODE) + 1);
ret = proc_ns_rmdir("/bin/");
assert(ret < 0);
ret = proc_ns_remove(SVR_NODE);
assert(ret >= 0);
ret = proc_ns_rmdir("/bin/");
assert(ret >= 0);
return 0;
}
int procfs_stat_test(void)
{
int ret;
struct kstat fst;
int fd;
ret = proc_ns_mkdir("/tstdir/");
assert(ret >= 0);
fd = proc_ns_open("/tstdir/", O_RDWR, 0777);
assert(fd >= 0);
ret = proc_ns_fstat(fd, &fst);
assert(ret >= 0);
ret = proc_ns_close(fd);
assert(ret >= 0);
return 0;
}
int main(int argc, char *argv[])
{
procfs_mkdir_test();
procfs_scan_dir_test();
procfs_stat_test();
procfs_mksvr_node();
procfs_query_svr_node();
return 0;
}

View File

@@ -0,0 +1,406 @@
#include <errno.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "proc.h"
#ifdef MKRTOS
#include <u_hd_man.h>
#include <malloc.h>
#include <u_task.h>
#endif
// 其他进程可以注册节点进来,并且可以注册子节点进来,子节点可以注册更多的子节点进来。
// 可以注册两种节点DUMMY和SVR节点
// 只有DUMMY节点里面可以注册SVR节点
// 查找节点时采取最大服务匹配的原则即匹配到最后一个SVR节点时返回最后一个SVR节点的HD以及截断的位置。
static proc_node_t root_node = {
.type = NODE_TYPE_PROC_DUMMY,
};
void proc_root_node_init(void)
{
root_node.op = NULL;
}
/**
* 从路径中copy名字
*/
static int proc_node_strcpy(char *dst, const char *src, int n)
{
int j;
for (j = 0; src[j] && src[j] != '/' && j < n; j++)
{
dst[j] = src[j];
}
if (j < n)
{
dst[j] = 0;
}
return j;
}
/**
* 找到节点中的子节点
*/
static proc_node_t *proc_node_find_sub(proc_node_t *tree, const char *name)
{
assert(name);
if (tree == NULL)
{
return NULL;
}
proc_node_t *cur = tree->sub;
while (cur)
{
if (strncmp(cur->name, name, NS_NODE_NAME_LEN) == 0)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
int proc_nodes_count(proc_node_t *tree)
{
int nr = 0;
assert(tree);
assert(tree->type == NODE_TYPE_PROC_DUMMY);
proc_node_t *cur = tree->next;
while (cur)
{
nr++;
cur = cur->next;
}
return nr;
}
static int proc_node_del(proc_node_t *tree, proc_node_t *del_node)
{
proc_node_t *tmp = tree->sub;
proc_node_t *pre = NULL;
while (tmp)
{
if (tmp == del_node)
{
if (pre == NULL)
{
// 删除第一个节点
tree->sub = tmp->next;
return 0;
}
else
{
pre->next = tmp->next;
return 0;
}
}
pre = tmp;
tmp = tmp->next;
}
return -1;
}
static proc_node_t *node_create(const char *name, proc_node_type_t type)
{
proc_node_t *tmp;
#ifdef MKRTOS
tmp = calloc(sizeof(proc_node_t), 1);
#else
tmp = calloc(sizeof(proc_node_t), 1);
#endif
if (!tmp)
{
return NULL;
}
strncpy(tmp->name, name, NS_NODE_NAME_LEN);
tmp->name[NS_NODE_NAME_LEN - 1] = 0;
tmp->type = type;
return tmp;
}
proc_node_t *proc_node_get_inx(proc_node_t *tree, int inx)
{
assert(tree);
assert(tree->type == NODE_TYPE_PROC_DUMMY);
int nr = 0;
proc_node_t *cur = tree->sub;
while (cur)
{
if (nr == inx)
{
return cur;
}
nr++;
cur = cur->next;
}
return cur;
}
/**
* 查找节点如果是dummy节点则一直循环查找。
* 如果是svr节点则立刻终止查找然后返回当前节点以及截断的位置
*/
proc_node_t *proc_node_find(proc_node_t **pnode, const char *path, int *ret, int *svr_inx, int *p_inx)
{
assert(ret);
assert(path);
proc_node_t *cur_node = NULL;
char name[NS_NODE_NAME_LEN];
int find_node_cut_inx = 0;
if (pnode)
{
*pnode = NULL;
}
if (path[0] != '/')
{
printf("[%s] path is error.\n", path);
*ret = -EINVAL;
return cur_node;
}
cur_node = &root_node;
int i = 0;
while (path[i])
{
proc_node_t *t_node;
int len;
// 获得节点的名字
len = proc_node_strcpy(name, path + i + 1, NS_NODE_NAME_LEN);
name[MIN(NS_NODE_NAME_LEN - 1, len)] = 0;
if (len == 0)
{
// find_node_cut_inx++;
goto end;
}
// 查找子节点
t_node = proc_node_find_sub(cur_node, name);
if (pnode)
{
*pnode = cur_node;
}
if (t_node)
{
if (t_node->type == NODE_TYPE_PROC_DUMMY)
{
cur_node = t_node;
}
else if (t_node->type == NODE_TYPE_PROC_FILE)
{
find_node_cut_inx = i + len + 1;
if (path[find_node_cut_inx] == '/')
{
find_node_cut_inx++;
}
// 找到服务节点,那直接返回,服务节点不会有子节点。
cur_node = t_node;
goto end;
}
}
else
{
if (cur_node == NULL)
{
goto end;
}
cur_node = NULL;
}
if (p_inx)
{
*p_inx = i;
}
if (path[i] == '/')
{
i++;
}
i += len;
}
end:
*svr_inx = find_node_cut_inx;
*ret = 0;
return cur_node;
}
/**
* 删除节点时,必须保证全路径匹配
*/
int proc_delnode(const char *path)
{
proc_node_t *cur_node;
int ret;
int cur_inx;
cur_node = proc_node_find(NULL, path, &ret, &cur_inx, NULL);
if (cur_node == NULL)
{
printf("ns node not find.\n");
return -ENOENT;
}
if (cur_node->type == NODE_TYPE_PROC_DUMMY && cur_node->ref != 0)
{
printf("ns dir is not empty.\n");
return -ENOTEMPTY;
}
ret = proc_node_del(cur_node->parent, cur_node);
if (cur_node->type == NODE_TYPE_PROC_FILE)
{
printf("ns del [%s].\n", path);
}
cur_node->parent->ref--;
#ifdef MKRTOS
free(cur_node);
#else
free(cur_node);
#endif
return ret;
}
/**
* 查找到完整的路径目录
*/
proc_node_t *proc_node_find_full_dir(const char *path, int *ret, int *cur_inx)
{
assert(path);
assert(ret);
assert(cur_inx);
proc_node_t *dir_node;
dir_node = proc_node_find(NULL, path, ret, cur_inx, NULL);
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_DUMMY || *cur_inx != 0)
{
#if 0
printf("ns node not find or path error.\n");
#endif
// 未找到节点不是dummy节点路径不是结尾处 则直接退出
*ret = -ENOENT;
return NULL;
}
return dir_node;
}
/**
* 查找到完整的路径文件
*/
proc_node_t *proc_node_find_full_file(const char *path, int *ret, int *cur_inx)
{
assert(path);
assert(ret);
assert(cur_inx);
proc_node_t *dir_node;
dir_node = proc_node_find(NULL, path, ret, cur_inx, NULL);
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_FILE || path[*cur_inx] != '\0')
{
#if 0
printf("ns node not find or path error.\n");
#endif
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
*ret = -ENOENT;
return NULL;
}
return dir_node;
}
static inline int is_root_node(proc_node_t *node)
{
return node == &root_node;
}
proc_node_t *proc_node_find_svr_file(const char *path, int *ret, int *cur_inx)
{
assert(path);
assert(ret);
assert(cur_inx);
proc_node_t *dir_node;
proc_node_t *parent_node;
dir_node = proc_node_find(&parent_node, path, ret, cur_inx, NULL);
if (is_root_node(dir_node))
{
(*cur_inx)++;
return dir_node;
}
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_FILE)
{
#if 0
printf("ns node not find or path error.\n");
#endif
if (is_root_node(parent_node))
{
return parent_node;
}
if (!parent_node)
{
*ret = -ENOENT;
return NULL;
}
if ((parent_node->type == NODE_TYPE_PROC_DUMMY && (dir_node == NULL || dir_node->type == NODE_TYPE_PROC_DUMMY)))
{
return &root_node;
}
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
*ret = -ENOENT;
return NULL;
}
return dir_node;
}
/**
* 创建一个节点
* 只能在前置节点全部为dummy的节点里面创建节点
*/
int proc_mknode(const char *path, proc_node_type_t type, const proc_file_operation_t *op)
{
proc_node_t *dir_node;
proc_node_t *new_node;
proc_node_t *cur_node;
int ret;
int cur_inx;
int p_inx;
char name[NS_NODE_NAME_LEN];
cur_node = proc_node_find(&dir_node, path, &ret, &cur_inx, &p_inx);
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_DUMMY || (cur_node != NULL))
{
if (cur_node != NULL && cur_node->type == NODE_TYPE_PROC_FILE)
{
return -EEXIST;
}
if (cur_node != NULL && cur_node->type == NODE_TYPE_PROC_DUMMY)
{
return -EISDIR;
}
return -ENOENT;
}
// 获得节点的名字
// int name_len = 0;
proc_node_strcpy(name, path + p_inx + 1, NS_NODE_NAME_LEN);
new_node = node_create(name, NODE_TYPE_PROC_DUMMY);
if (new_node == NULL)
{
return -ENOMEM;
}
// 加到目录的链表中
new_node->next = dir_node->sub;
dir_node->sub = new_node;
new_node->type = type;
new_node->parent = dir_node;
if (type == NODE_TYPE_PROC_FILE)
{
new_node->op = op;
}
else
{
new_node->sub = NULL;
}
// 增加引用计数
dir_node->ref++;
return 0;
}

View File

@@ -0,0 +1,689 @@
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <malloc.h>
#include <u_mutex.h>
#include <u_hd_man.h>
#include "proc.h"
#include "kstat.h"
#define DIR_INFO_CACHE_NR 32
typedef struct dir_info_cache
{
proc_node_t *info;
int ref;
} dir_info_cache_t;
static dir_info_cache_t dir_info_cache_list[DIR_INFO_CACHE_NR];
static u_mutex_t procfs_mutex_lock;
void procfs_lock(void)
{
u_mutex_lock(&procfs_mutex_lock, 0, NULL);
}
void proc_unlock(void)
{
u_mutex_unlock(&procfs_mutex_lock);
}
static int dir_info_cache_get(proc_node_t *info)
{
if (info == NULL)
{
return -EINVAL;
}
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
{
if (dir_info_cache_list[i].info == NULL)
{
continue;
}
if (dir_info_cache_list[i].info == info)
{
dir_info_cache_list[i].ref++;
return i;
}
}
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
{
if (dir_info_cache_list[i].info == NULL)
{
dir_info_cache_list[i].info = info;
dir_info_cache_list[i].ref++;
return i;
}
}
return -1;
}
static void dir_info_cache_put(proc_node_t *info)
{
assert(info);
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
{
if (dir_info_cache_list[i].info == NULL)
{
continue;
}
if (dir_info_cache_list[i].info == info)
{
dir_info_cache_list[i].ref--;
if (dir_info_cache_list[i].ref == 0)
{
dir_info_cache_list[i].info = NULL;
return;
}
}
}
}
enum proc_ns_type
{
FS_NS_FILE_TYPE,
FS_NS_DIR_TYPE,
};
#define DIR_INFO_NR 32
typedef struct proc_ns_file
{
int dir_info_fd; //!< dirinfo cache fd.
int tmp_fd; //!< current info fd.
uint8_t flags; //!< 文件操作的flags
int offset; //!< 文件操作的偏移
enum proc_ns_type type; //!< 类型
uint8_t used;
} proc_ns_file_t;
static proc_ns_file_t proc_ns_files[DIR_INFO_NR];
static proc_ns_file_t *proc_ns_get_file(int fd);
static int proc_ns_file_alloc(proc_node_t *file, int flags, enum proc_ns_type type)
{
int dir_info_fd = -1;
if (file != NULL)
{
dir_info_fd = dir_info_cache_get(file);
if (dir_info_fd < 0)
{
printf("dir_info cache is full.\n");
return dir_info_fd;
}
}
for (int i = 0; i < DIR_INFO_NR; i++)
{
if (proc_ns_files[i].used == 0)
{
// 不存在则增加一个新的
proc_ns_files[i].dir_info_fd = dir_info_fd;
proc_ns_files[i].tmp_fd = -1;
proc_ns_files[i].flags = flags;
proc_ns_files[i].offset = 0;
proc_ns_files[i].type = type;
proc_ns_files[i].used = 1;
return i;
}
}
return -1;
}
static proc_ns_file_t *proc_ns_get_file(int fd)
{
if (fd < 0 || fd >= DIR_INFO_NR)
{
return NULL;
}
if (proc_ns_files[fd].used == 0)
{
return NULL;
}
return proc_ns_files + fd;
}
int proc_ns_open(const char *name, int flags, int mode)
{
int ret;
proc_node_t *file;
int fd;
int cur_inx;
enum proc_ns_type type;
if (name[0] == '\0')
{
name = "/";
}
// 路径必须'/'卡头
if (name[0] != '/')
{
printf("nsfs path is error.\n");
return -EINVAL;
}
if (flags & O_CREAT)
{
// not support to create file.
return -ENOSYS;
}
procfs_lock();
// path must is dir.
file = proc_node_find_full_dir(name, &ret, &cur_inx);
if (file == NULL)
{
file = proc_node_find_full_file(name, &ret, &cur_inx);
if (file == NULL)
{
proc_unlock();
return -EINVAL;
}
type = FS_NS_FILE_TYPE;
if (file->op && file->op->proc_open)
{
ret = file->op->proc_open(file, name, flags, mode);
if (ret < 0)
{
proc_unlock();
return ret;
}
}
} else {
type = FS_NS_DIR_TYPE;
}
fd = proc_ns_file_alloc(file, flags, type);
if (fd < 0)
{
proc_unlock();
return fd;
}
proc_unlock();
return fd;
}
int proc_ns_write(int fd, void *data, int len)
{
proc_ns_file_t *file;
int ret = 0;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
ret = -ENOENT;
goto end;
}
if (file->type != FS_NS_FILE_TYPE)
{
ret = -EBADF;
goto end;
}
proc_node_t *info;
info = dir_info_cache_list[file->dir_info_fd].info;
if (!info->op || !info->op->proc_write)
{
ret = -EROFS;
goto end;
}
ret = info->op->proc_write(info, data, len, file->offset);
if (ret >= 0)
{
file->offset += ret;
}
end:
proc_unlock();
return ret;
}
int proc_ns_read(int fd, void *data, int len)
{
proc_ns_file_t *file;
int ret = 0;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
ret = -ENOENT;
goto end;
}
if (file->type != FS_NS_FILE_TYPE)
{
ret = -EBADF;
goto end;
}
proc_node_t *info;
info = dir_info_cache_list[file->dir_info_fd].info;
if (!info->op || !info->op->proc_read)
{
ret = -EIO;
goto end;
}
ret = info->op->proc_read(info, data, len, file->offset);
if (ret >= 0)
{
file->offset += ret;
}
end:
proc_unlock();
return ret;
}
int proc_ns_ioctl(int fd, unsigned long cmd, unsigned long arg)
{
proc_ns_file_t *file;
int ret = 0;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
ret = -ENOENT;
goto end;
}
if (file->type != FS_NS_FILE_TYPE)
{
ret = -EBADF;
goto end;
}
proc_node_t *info;
info = dir_info_cache_list[file->dir_info_fd].info;
if (!info->op || !info->op->proc_ioctl)
{
ret = -EIO;
goto end;
}
ret = info->op->proc_ioctl(info, cmd, (void *)arg);
if (ret >= 0)
{
file->offset += ret;
}
end:
proc_unlock();
return ret;
}
static int proc_ns_get_dir_size(proc_ns_file_t *file)
{
return proc_nodes_count(dir_info_cache_list[file->dir_info_fd].info);
}
int proc_ns_lseek(int fd, int offset, unsigned long whence)
{
proc_ns_file_t *file;
int new_offs = 0;
int old_offs = 0;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
proc_unlock();
return -ENOENT;
}
old_offs = file->offset;
switch (whence)
{
case SEEK_SET:
new_offs = offset;
break;
case SEEK_END:
{
new_offs = proc_ns_get_dir_size(file) + offset;
}
break;
case SEEK_CUR:
{
new_offs = offset + file->offset;
}
break;
default:
proc_unlock();
return -EINVAL;
}
if (new_offs > proc_ns_get_dir_size(file))
{
new_offs = proc_ns_get_dir_size(file);
}
if (new_offs < 0)
{
new_offs = 0;
}
if (file->type == FS_NS_DIR_TYPE)
{
proc_node_t *new_dir_info;
new_dir_info = proc_node_get_inx(dir_info_cache_list[file->dir_info_fd].info, new_offs);
if (new_dir_info == NULL)
{
proc_unlock();
return -ENOENT;
}
if (file->tmp_fd >= 0)
{
dir_info_cache_put(dir_info_cache_list[file->tmp_fd].info);
}
file->tmp_fd = dir_info_cache_get(new_dir_info);
}
file->offset = new_offs;
proc_unlock();
return old_offs;
}
int proc_ns_truncate(int fd, off_t length)
{
return -ENOSYS;
}
int proc_ns_fstat(int fd, struct kstat *st)
{
proc_ns_file_t *file;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
proc_unlock();
return -ENOENT;
}
memset(st, 0, sizeof(*st));
st->st_size = 0;
st->st_mode = file->type == FS_NS_FILE_TYPE ? S_IFREG : S_IFDIR;
st->st_nlink = dir_info_cache_list[file->dir_info_fd].info->ref;
proc_unlock();
return 0;
}
int proc_ns_stat(const char *path, struct kstat *st)
{
if (path[0] == '\0')
{
path = "/";
}
memset(st, 0, sizeof(*st));
proc_node_t *file;
int ret;
int cur_inx;
procfs_lock();
file = proc_node_find_full_dir(path, &ret, &cur_inx);
if (file == NULL)
{
file = proc_node_find_full_file(path, &ret, &cur_inx);
if (file == NULL)
{
proc_unlock();
return -ENOENT;
}
}
st->st_size = 0;
st->st_mode = file->type != NODE_TYPE_PROC_DUMMY ? S_IFREG : S_IFDIR;
st->st_nlink = file->ref;
proc_unlock();
return 0;
}
int proc_ns_close(int fd)
{
proc_ns_file_t *file;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
proc_unlock();
return -ENOENT;
}
proc_node_t *info = dir_info_cache_list[file->dir_info_fd].info;
if (file->type == FS_NS_FILE_TYPE)
{
if (info->op && info->op->proc_close)
{
// 不关心close的返回值
info->op->proc_close(info);
}
}
if (file->tmp_fd >= 0)
{
dir_info_cache_put(dir_info_cache_list[file->tmp_fd].info);
}
dir_info_cache_put(dir_info_cache_list[file->dir_info_fd].info);
file->dir_info_fd = -1;
file->tmp_fd = -1;
file->flags = 0;
file->offset = 0;
file->used = 0;
file->type = FS_NS_FILE_TYPE;
proc_unlock();
return 0;
}
int proc_ns_rmdir(const char *name)
{
proc_node_t *file;
int ret;
int dir_info_fd;
int cur_inx;
if (name[0] == '\0')
{
name = "/";
}
procfs_lock();
file = proc_node_find_full_dir(name, &ret, &cur_inx);
if (file == NULL)
{
proc_unlock();
return -ENOENT;
}
dir_info_fd = dir_info_cache_get(file);
if (dir_info_cache_list[dir_info_fd].ref == 1)
{
ret = proc_delnode(name);
if (ret < 0)
{
dir_info_cache_put(file);
proc_unlock();
return ret;
}
}
dir_info_cache_put(file);
proc_unlock();
return 0;
}
int proc_ns_remove(const char *name)
{
proc_node_t *file;
int ret;
int dir_info_fd;
int cur_inx;
if (name[0] == '\0')
{
name = "/";
}
procfs_lock();
file = proc_node_find_full_file(name, &ret, &cur_inx);
if (file == NULL)
{
proc_unlock();
return -ENOENT;
}
dir_info_fd = dir_info_cache_get(file);
if (dir_info_cache_list[dir_info_fd].ref == 1)
{
ret = proc_delnode(name);
if (ret < 0)
{
proc_unlock();
return ret;
}
}
dir_info_cache_put(file);
proc_unlock();
return 0;
}
int proc_ns_readdir(int fd, struct dirent *_dir)
{
int ret = -1;
proc_ns_file_t *file;
procfs_lock();
file = proc_ns_get_file(fd);
if (!file || file->used == 0)
{
proc_unlock();
return -ENOENT;
}
if (file->type != FS_NS_DIR_TYPE)
{
proc_unlock();
return -EACCES;
}
if (file->tmp_fd == -1)
{
proc_node_t *dir_info;
dir_info = proc_node_get_first(dir_info_cache_list[file->dir_info_fd].info);
if (dir_info == NULL)
{
proc_unlock();
return -ENOENT;
}
ret = dir_info_cache_get(dir_info);
if (ret < 0)
{
proc_unlock();
return ret;
}
file->tmp_fd = ret;
}
else if (file->tmp_fd == -2)
{
proc_unlock();
return -ENOENT;
}
proc_node_t *node_info;
node_info = dir_info_cache_list[file->tmp_fd].info;
_dir->d_reclen = sizeof(*_dir);
_dir->d_type = node_info->type == NODE_TYPE_PROC_DUMMY ? DT_DIR : DT_CHR; // DT_REG;
strncpy(_dir->d_name, node_info->name, sizeof(_dir->d_name));
_dir->d_name[sizeof(_dir->d_name) - 1] = 0;
proc_node_t *next_dir_info = proc_node_get_next(dir_info_cache_list[file->dir_info_fd].info, node_info);
dir_info_cache_put(node_info);
ret = dir_info_cache_get(next_dir_info);
if (ret >= 0)
{
file->tmp_fd = ret;
file->offset++;
}
else
{
file->tmp_fd = -2; // -2代表结束遍历
}
proc_unlock();
return sizeof(*_dir);
}
int proc_ns_mkdir(char *path)
{
int ret;
procfs_lock();
ret = proc_mknode(path, NODE_TYPE_PROC_DUMMY, NULL);
proc_unlock();
return ret;
}
int proc_ns_open_init(void)
{
int ret;
for (int i = 0; i < DIR_INFO_NR; i++)
{
proc_ns_files[i].dir_info_fd = -1;
proc_ns_files[i].tmp_fd = -1;
}
ret = u_mutex_init(&procfs_mutex_lock, handler_alloc());
if (ret < 0)
{
return ret;
}
return 0;
}
/**
* 通过pid删除nsfs中的文件
*/
void proc_ns_del_file_by_pid(const char *path, pid_t pid)
{
if (path == NULL)
{
return;
}
int fd;
char *new_path;
struct dirent dir;
int path_len;
path_len = strlen(path) + 64;
new_path = malloc(path_len);
if (new_path == NULL)
{
return;
}
fd = proc_ns_open(path, O_RDONLY, 0);
if (fd < 0)
{
free(new_path);
return;
}
while (1)
{
if (proc_ns_readdir(fd, &dir) < 0)
{
break;
}
if (path[0] == '/' && path[1] == '\0')
{
snprintf(new_path, path_len, "/%s", dir.d_name);
}
else
{
snprintf(new_path, path_len, "%s/%s", path, dir.d_name);
}
// 递归删除
if (dir.d_type == DT_DIR)
{
proc_ns_del_file_by_pid(new_path, pid);
continue;
}
struct kstat st;
if (proc_ns_stat(new_path, &st) < 0)
{
continue;
}
if (st.pid == pid)
{
proc_ns_remove(new_path);
}
}
free(new_path);
proc_ns_close(fd);
}
int proc_register_file(const char *path, const proc_file_operation_t *op)
{
assert(op);
assert(path);
int ret;
procfs_lock();
ret = proc_mknode(path, NODE_TYPE_PROC_FILE, op);
if (ret < 0)
{
printf("register [%s] failed.\n", (char *)(path));
}
proc_unlock();
return ret;
}

View File

@@ -0,0 +1,53 @@
#include "proc.h"
#include "procfs.h"
#include "procfs_rpc.h"
#include <string.h>
#include <stdio.h>
static int proc_open(proc_node_t *node, const char *path, int flags, int mode)
{
return 0;
}
static int proc_read(proc_node_t *node, void *buf, size_t len, long offset)
{
msg_tag_t tag;
char name[8];
if (offset >= sizeof(name))
{
return -1;
}
tag = u_task_get_obj_name(TASK_THIS, TASK_THIS, name);
memcpy(buf, name + offset, MIN(len, sizeof(name) - offset));
return MIN(len, sizeof(name));
}
static int proc_write(proc_node_t *node, void *buf, size_t len, long offset)
{
msg_tag_t tag;
char name[8];
if (len < sizeof(name) || offset >= sizeof(name))
{
return -1;
}
memcpy(name, buf, MIN(len, sizeof(name)));
tag = u_task_set_obj_name(TASK_THIS, TASK_THIS, name);
return MIN(len, sizeof(name));
}
static const proc_file_operation_t name_op =
{
.proc_open = proc_open,
.proc_read = proc_read,
.proc_write = proc_write,
};
int proc_default_file_register(void)
{
int ret;
ret = proc_register_file("/comm", &name_op);
if (ret < 0) {
printf("task reg [name] node failed.\n");
return ret;
}
return 0;
}

View File

@@ -0,0 +1,147 @@
#include "cons_cli.h"
#include "fs_svr.h"
#include "kstat.h"
#include "rpc_prot.h"
#include "u_env.h"
#include "u_log.h"
#include "u_rpc.h"
#include "u_rpc_svr.h"
#include "u_sig.h"
#include "u_task.h"
#include "pm_cli.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <u_malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <ns_cli.h>
#include "fd.h"
#include "u_path.h"
#include "procfs.h"
#include "procfs_impl.h"
static fs_t fs;
static meta_t procfs_meta;
static obj_handler_t procfs_ipc_hd;
static int fs_sig_call_back(pid_t pid, umword_t sig_val);
static int fs_svr_open(const char *path, int flags, int mode)
{
return proc_ns_open(path, flags, mode);
}
static int fs_svr_read(int fd, void *buf, size_t len)
{
return proc_ns_read(fd, buf, len);
}
static int fs_svr_write(int fd, void *buf, size_t len)
{
return proc_ns_write(fd, buf, len);
}
static void fs_svr_close(int fd)
{
proc_ns_close(fd);
}
static int fs_svr_readdir(int fd, dirent_t *dir)
{
return proc_ns_readdir(fd, dir);
}
static int fs_svr_lseek(int fd, int offs, int whence)
{
return proc_ns_lseek(fd, offs, whence);
}
static int fs_svr_ftruncate(int fd, off_t off)
{
return -ENOSYS;
}
static int fs_svr_fstat(int fd, void *_stat)
{
return proc_ns_fstat(fd, _stat);
}
static int fs_svr_ioctl(int fd, int req, void *arg)
{
return proc_ns_ioctl(fd, req, (unsigned long)arg);
}
static int fs_svr_fsync(int fd)
{
return -ENOSYS;
}
static int fs_svr_unlink(const char *path)
{
return proc_ns_remove(path);
}
static int fs_svr_symlink(const char *existing, const char *new)
{
return -ENOSYS;
}
static int fs_svr_mkdir(char *path)
{
return proc_ns_mkdir(path);
}
static int fs_svr_rmdir(char *path)
{
return proc_ns_rmdir(path);
}
static int fs_svr_rename(char *oldname, char *newname)
{
return -ENOSYS;
}
static int fs_svr_stat(const char *path, void *_buf)
{
return proc_ns_stat(path, _buf);
}
static ssize_t fs_svr_readlink(const char *path, char *buf, size_t bufsize)
{
return -ENOSYS;
}
static int fs_svr_statfs(const char *path, struct statfs *buf)
{
return -ENOSYS;
}
static const fs_operations_t ops =
{
.fs_svr_open = fs_svr_open,
.fs_svr_read = fs_svr_read,
.fs_svr_write = fs_svr_write,
.fs_svr_close = fs_svr_close,
.fs_svr_readdir = fs_svr_readdir,
.fs_svr_lseek = fs_svr_lseek,
.fs_svr_ftruncate = fs_svr_ftruncate,
.fs_svr_fstat = fs_svr_fstat,
.fs_svr_ioctl = fs_svr_ioctl,
// .fs_svr_fcntl = fs_svr_fcntl,
.fs_svr_fsync = fs_svr_fsync,
.fs_svr_unlink = fs_svr_unlink,
.fs_svr_symlink = fs_svr_symlink,
.fs_svr_mkdir = fs_svr_mkdir,
.fs_svr_rmdir = fs_svr_rmdir,
.fs_svr_rename = fs_svr_rename,
.fs_svr_stat = fs_svr_stat,
.fs_svr_readlink = fs_svr_readlink,
};
AUTO_CALL(101) __USED
void procfs_svr_init(void)
{
int ret;
char proc_path[20];
umword_t pid;
fs_init(&fs, &ops);
meta_obj_init(&procfs_meta);
rpc_meta_init(&procfs_meta, TASK_THIS, &procfs_ipc_hd);
meta_reg_svr_obj_raw(&procfs_meta, &fs.svr, FS_PROT);
u_task_get_pid(TASK_THIS, &pid);
snprintf(proc_path, sizeof(proc_path), "/proc/%d", pid);
ret = ns_register(proc_path, procfs_ipc_hd, 0);
if (ret < 0)
{
printf("task proc reg failed [%d].\n", ret);
}
proc_default_file_register();
}

View File

@@ -16,7 +16,7 @@ target_link_libraries(sh.elf
sys
sys_util
sys_svr
# mr
proc
LetterShell
--no-whole-archive
${GCC_LIB_PATH}/libgcc.a
@@ -29,6 +29,7 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/letter-shell/demo/mkrtos
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/letter-shell/src
${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/procfs/inc
)
set_target_properties(sh.elf PROPERTIES LINK_FLAGS
"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker "
@@ -64,5 +65,5 @@ add_dependencies(shell_dump sys_util)
add_dependencies(shell_dump sys_svr)
# add_dependencies(shell_dump start)
# add_dependencies(shell_dump muslc)
add_dependencies(shell_dump LetterShell)
add_dependencies(shell_dump LetterShell proc)