add lstat&sysinfo....syscall. (#7555)

This commit is contained in:
geniusgogo 2023-05-23 22:43:38 +08:00 committed by GitHub
parent 17ce4a462b
commit 0315c0dee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 231 additions and 1 deletions

View File

@ -76,6 +76,8 @@
#include "lwp_ipc_internal.h"
#include <sched.h>
#include <sys/sysinfo.h>
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK 0x0001
#endif /* GRND_NONBLOCK */
@ -2621,6 +2623,54 @@ sysret_t sys_stat(const char *file, struct stat *buf)
return ret;
}
sysret_t sys_lstat(const char *file, struct stat *buf)
{
int ret = 0;
int err;
size_t len;
size_t copy_len;
char *copy_path;
struct stat statbuff = {0};
if (!lwp_user_accessable((void *)buf, sizeof(struct stat)))
{
return -EFAULT;
}
len = lwp_user_strlen(file, &err);
if (err)
{
return -EFAULT;
}
copy_path = (char*)rt_malloc(len + 1);
if (!copy_path)
{
return -ENOMEM;
}
copy_len = lwp_get_from_user(copy_path, (void*)file, len);
if (copy_len == 0)
{
rt_free(copy_path);
return -EFAULT;
}
copy_path[copy_len] = '\0';
#ifdef RT_USING_DFS_V2
ret = _SYS_WRAP(dfs_file_lstat(copy_path, &statbuff));
#else
ret = _SYS_WRAP(stat(copy_path, &statbuff));
#endif
rt_free(copy_path);
if (ret == 0)
{
lwp_put_to_user(buf, &statbuff, sizeof statbuff);
}
return ret;
}
sysret_t sys_notimpl(void)
{
return -ENOSYS;
@ -4292,6 +4342,99 @@ sysret_t sys_setaffinity(pid_t pid, size_t size, void *set)
return -1;
}
sysret_t sys_getaffinity(pid_t pid, size_t size, void *set)
{
#ifdef ARCH_MM_MMU
cpu_set_t mask;
struct rt_lwp *lwp;
if (size <= 0 || size > sizeof(cpu_set_t))
{
return -EINVAL;
}
if (!lwp_user_accessable(set, size))
{
return -EFAULT;
}
if (pid == 0) lwp = lwp_self();
else lwp = lwp_from_pid(pid);
if (!lwp)
{
return -ESRCH;
}
#ifdef RT_USING_SMP
if (lwp->bind_cpu == RT_CPUS_NR) /* not bind */
{
CPU_ZERO_S(size, &mask);
}
else /* set bind cpu */
{
/* TODO: only single-core bindings are now supported of rt-smart */
CPU_SET_S(lwp->bind_cpu, size, &mask);
}
#else
CPU_SET_S(0, size, &mask);
#endif
if (lwp_put_to_user(set, &mask, size) != size)
{
return -1;
}
return 0;
#else
return -1;
#endif
}
sysret_t sys_sysinfo(void *info)
{
#ifdef ARCH_MM_MMU
struct sysinfo kinfo = {0};
rt_size_t total_pages = 0, free_pages = 0;
if (!lwp_user_accessable(info, sizeof(struct sysinfo)))
{
return -EFAULT;
}
kinfo.uptime = rt_tick_get_millisecond() / 1000;
/* TODO: 1, 5, and 15 minute load averages */
kinfo.loads[0] = kinfo.loads[1] = kinfo.loads[2] = rt_object_get_length(RT_Object_Class_Thread);
rt_page_get_info(&total_pages, &free_pages);
kinfo.totalram = total_pages;
kinfo.freeram = free_pages;
/* TODO: implementation procfs, here is counter the lwp number */
struct lwp_avl_struct *pids = lwp_get_pid_ary();
for (int index = 0; index < RT_LWP_MAX_NR; index++)
{
struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data;
if (lwp)
{
kinfo.procs++;
}
}
rt_page_high_get_info(&total_pages, &free_pages);
kinfo.totalhigh = total_pages;
kinfo.freehigh = free_pages;
kinfo.mem_unit = ARCH_PAGE_SIZE;
if (lwp_put_to_user(info, &kinfo, sizeof(struct sysinfo)) != sizeof(struct sysinfo))
{
return -EFAULT;
}
return 0;
#else
return -1;
#endif
}
sysret_t sys_sched_setparam(pid_t pid, void *param)
{
struct sched_param *sched_param = (struct sched_param *)param;
@ -4901,6 +5044,60 @@ sysret_t sys_umount2(char *__special_file, int __flags)
return ret;
}
sysret_t sys_link(const char *existing, const char *new)
{
int ret = -1;
#ifdef ARCH_MM_MMU
int err;
lwp_user_strlen(existing, &err);
if (err)
{
return -EFAULT;
}
lwp_user_strlen(new, &err);
if (err)
{
return -EFAULT;
}
#endif
#ifdef RT_USING_DFS_V2
ret = dfs_file_link(existing, new);
#else
SET_ERRNO(EFAULT);
#endif
return (ret < 0 ? GET_ERRNO() : ret);
}
sysret_t sys_symlink(const char *existing, const char *new)
{
int ret = -1;
#ifdef ARCH_MM_MMU
int err;
lwp_user_strlen(existing, &err);
if (err)
{
return -EFAULT;
}
lwp_user_strlen(new, &err);
if (err)
{
return -EFAULT;
}
#endif
#ifdef RT_USING_DFS_V2
ret = dfs_file_symlink(existing, new);
#else
SET_ERRNO(EFAULT);
#endif
return (ret < 0 ? GET_ERRNO() : ret);
}
const static struct rt_syscall_def func_table[] =
{
SYSCALL_SIGN(sys_exit), /* 01 */
@ -5110,7 +5307,7 @@ const static struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_mq_notify),
SYSCALL_SIGN(sys_mq_getsetattr),
SYSCALL_SIGN(sys_mq_close),
SYSCALL_SIGN(sys_stat), //TODO should be replaced by sys_lstat if symbolic link are implemented
SYSCALL_SIGN(sys_lstat),
SYSCALL_SIGN(sys_uname), /* 170 */
SYSCALL_SIGN(sys_statfs),
SYSCALL_SIGN(sys_statfs64),
@ -5119,6 +5316,10 @@ const static struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_openat), /* 175 */
SYSCALL_SIGN(sys_mount),
SYSCALL_SIGN(sys_umount2),
SYSCALL_SIGN(sys_link),
SYSCALL_SIGN(sys_symlink),
SYSCALL_SIGN(sys_getaffinity), /* 180 */
SYSCALL_SIGN(sys_sysinfo),
};
const void *lwp_get_sys_api(rt_uint32_t number)

View File

@ -46,6 +46,7 @@ static struct rt_page *page_list_high[RT_PAGE_MAX_ORDER];
#define page_start ((rt_page_t)rt_mpr_start)
static rt_size_t page_nr;
static rt_size_t _high_pages_nr;
static rt_size_t early_offset;
static const char *get_name(rt_varea_t varea)
@ -672,6 +673,28 @@ void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr)
*free_nr = total_free;
}
void rt_page_high_get_info(rt_size_t *total_nr, rt_size_t *free_nr)
{
int i;
rt_size_t total_free = 0;
rt_base_t level;
level = rt_hw_interrupt_disable();
for (i = 0; i < RT_PAGE_MAX_ORDER; i++)
{
struct rt_page *p = page_list_high[i];
while (p)
{
total_free += (1UL << i);
p = p->next;
}
}
rt_hw_interrupt_enable(level);
*total_nr = _high_pages_nr;
*free_nr = total_free;
}
static void _install_page(rt_page_t mpr_head, rt_region_t region, void *insert_handler)
{
void (*insert)(rt_page_t *page_list, rt_page_t page, int size_bits) = insert_handler;
@ -723,6 +746,10 @@ static void _install_page(rt_page_t mpr_head, rt_region_t region, void *insert_h
/* insert to list */
rt_page_t *page_list = _get_page_list((void *)region.start);
if (page_list == page_list_high)
{
_high_pages_nr += 1 << (size_bits - ARCH_PAGE_SHIFT);
}
insert(page_list, (rt_page_t)((char *)p - early_offset), size_bits - ARCH_PAGE_SHIFT);
region.start += (1UL << size_bits);
}

View File

@ -88,6 +88,8 @@ rt_size_t rt_page_bits(rt_size_t size);
void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr);
void rt_page_high_get_info(rt_size_t *total_nr, rt_size_t *free_nr);
void *rt_page_page2addr(struct rt_page *p);
struct rt_page *rt_page_addr2page(void *addr);