RK3588 linux 修改ulimit 配置

devtools/2024/11/13 9:13:09/

在这里插入图片描述

前言

在这里插入图片描述

ulimit 主要是用来限制进程对资源的使用情况的,它支持各种类型的限制,常用的有:

  • 内核文件的大小限制
  • 进程数据块的大小限制
  • Shell进程创建文件大小限制
  • 可加锁内存大小限制
  • 常驻内存集的大小限制
  • 打开文件句柄数限制
  • 分配堆栈的最大大小限制
  • CPU占用时间限制用户最大可用的进程数限制
  • Shell进程所能使用的最大虚拟内存限

源于一次粗心大意, 编写的程序忘记了关闭打开的文件, 导致文件打开失败, 失败的原因是打开的文件太多

测试代码

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <csignal>
#include <errno.h>void signt_handle(int s){printf("%s\n", __FUNCTION__);exit(0);
}int main(int argc, char** argv) {printf("[I]%s.START....\n", __FUNCTION__);std::signal(SIGINT, signt_handle);bool close = false;int num = 0;for(int i = 0; i < argc; i ++){printf("[D]%s arg:%s\n", __FUNCTION__, argv[i]);char* val = nullptr;if((val = strstr(argv[i], "num=")) != nullptr){num = atoi(val + 4);}else if(strcmp(argv[i], "close") == 0){close = true;}}for(int i = 0; i < num; i ++){FILE* fp = fopen("/bootTime", "r");if(fp != nullptr){printf("[D]%s.open %d\r", __FUNCTION__, i);//open success.}else{printf("[E]%s open %d failed: %d(%s)!\r", __FUNCTION__, i, errno, strerror(errno));}if(close)fclose(fp);}printf("\n");char c = getc(stdin);//while((c = getc(stdin)) != 'q');printf("[I]%s.FINISH....\n", __FUNCTION__);
}

报错 open failed: 24(Too many open files)

查看系统限制:

//查看所有的限制信息
$userdata# ulimit -a
real-time non-blocking time  (microseconds, -R) unlimited
core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 63277
max locked memory           (kbytes, -l) 64
max memory size             (kbytes, -m) unlimited
open files                          (-n) 1024
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 63277
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited//查看文件打开个数信息
$userdata# ulimit -n
1024

系统的文件打开数量限制为1024, 简单测试打开1025个文件:

# /userdata/test_ulimit num=1025
[I]main.START....
[D]main arg:/userdata/test_ulimit
[D]main arg:num=1025
[E]main open 1024 failed: 24(Too many open files)!
q
[I]main.FINISH....

再进程未结束是, 可以从lsof 可以看出当前进程打开的文件:

$ adb shell lsof | grep test_
16363	/userdata/test_ulimit	0	/dev/console
16363	/userdata/test_ulimit	1	/dev/console
16363	/userdata/test_ulimit	2	/dev/console
16363	/userdata/test_ulimit	3	/bootTime
16363	/userdata/test_ulimit	4	/bootTime
//中间省略N行.
16363	/userdata/test_ulimit	1026	/bootTime
16363	/userdata/test_ulimit	1027	/bootTime

如何解决

  1. 及时关闭文件, 避免文件数量超出, 上面的程序增加了close参数, 用于及时关闭文件
  2. 修改系统文件打开数量的限制:
ulimit -n 2048

buildroot__133">RK3588 buildroot 修改默认配置

1.无效的尝试

  • /etc/security/limits.conf

            # 添加如下的行* soft noproc 11000* hard noproc 11000* soft nofile 4100* hard nofile 4100 
    
  • /etc/init.d/rcS

    在这个启动脚本中,你可以将 ulimit -n 4096 放在 for 循环之前,确保在启动所有 init.d 脚本之前设置 ulimit。这样可以确保在执行任何其他初始化操作之前设置了最大打开文件数。

    所以你可以将 ulimit -n 4096 添加在 for 循环之前,类似这样:

    #!/bin/sh# Set maximum number of open files
    ulimit -n 4096# Start all init scripts in /etc/init.d executing them in numerical order.
    for i in /etc/init.d/S??* ;do# Ignore dangling symlinks (if any).[ ! -f "$i" ] && continuecase "$i" in*.sh)# Source shell script for speed.(trap - INT QUIT TSTPset start. $i);;*)# No sh extension, so fork subprocess.$i start;;esac
    done

    这样做可以确保在执行其他初始化脚本之前设置了 ulimit

  1. 有效的修改:
  • /etc/profile

    /etc/profile 是一个系统范围的 Shell 配置文件,用于设置系统中所有用户的环境变量和执行一些全局的 Shell 初始化任务。这个文件通常用于 Bourne-compatible shells(例如 Bash、Dash、Korn shell 等)。

    当用户登录时,Shell 会首先读取 /etc/profile 文件,然后再读取用户的个人配置文件(如 ~/.bash_profile~/.profile)。因此,/etc/profile 文件中的设置将影响到所有用户的登录 shell。

    /etc/profile 文件中,你可以设置系统范围的环境变量、导入全局的 Shell 函数、执行一些初始化命令等。这对于配置系统范围的默认行为和环境非常有用,例如设置全局的 PATH 变量、umask 值、语言环境等。

    需要注意的是,修改 /etc/profile 文件需要管理员权限,因为它是系统级别的配置文件。任何对该文件的更改都会影响到整个系统的行为,因此需要小心谨慎地修改。

  • /etc/bash.bashrc

    /etc/bash.bashrc 是另一个系统范围的 Bash Shell 配置文件,它与 /etc/profile 类似,但是它是针对 Bash Shell 的。与 /etc/profile 一样,/etc/bash.bashrc 文件也是在用户登录时被执行的。

    与用户级别的 .bashrc 文件类似,/etc/bash.bashrc 文件通常包含了一些 Bash Shell 的配置和初始化命令,用于设置系统范围的 Shell 环境。这些设置通常适用于所有的 Bash Shell 用户。

    /etc/bash.bashrc 文件中,你可以设置系统范围的 Bash Shell 环境变量、定义全局的 Bash 函数、启用或禁用 Bash Shell 的特性等。

    需要注意的是,/etc/bash.bashrc 文件是在 Bash Shell 启动时执行的,而不是用户登录时执行的,因此它可能不会像 /etc/profile 那样被所有类型的 Shell 执行。如果系统中有其他类型的 Shell 用户,它们可能不会执行 /etc/bash.bashrc 文件中的设置。

  • 针对特定进程修改其打开文件的个数限制(来自GPT, 未验证)

    要针对特定进程修改其打开文件的个数限制(ulimit),你可以使用 ulimit 命令结合 sudo 进行修改。但需要说明的是,ulimit 命令通常只能影响当前 shell 及其子进程的限制,对已经运行的进程并不生效。因此,如果你希望修改已经在运行的进程的文件打开数限制,你需要重新启动该进程或者重新登录用户以应用新的限制。

    下面是修改某个进程打开文件数限制的一般步骤:

    1. 确定进程ID(PID):首先,你需要确定你想要修改的进程的PID。你可以使用 ps 命令或者 pidof 命令来查找进程的PID。例如,如果你想要修改PID为1234的进程的限制,你可以执行:

      ps aux | grep <进程名>
      

      或者

      pidof <进程名>
      
    2. 使用 sudo 修改限制:一旦你有了PID,你可以使用 sudo 命令和 ulimit 命令来修改限制。例如,要将打开文件数限制修改为4096,你可以执行:

      sudo prlimit --pid <PID> --nofile=4096:4096
      

      或者

      sudo ulimit -n 4096 -p <PID>
      
    3. 验证更改:修改限制后,你可以使用 ulimit -a 命令检查更改是否已生效。此外,你也可以通过查看进程的 /proc/<PID>/limits 文件来验证限制是否已应用。

    请注意,ulimit 命令对不同的操作系统可能会有些许差异,而 prlimit 命令在一些系统上可能需要安装额外的软件包。确保在执行任何修改之前仔细阅读命令的文档以及系统的相关文档。

  1. 修改buildroot 源码默认配置为9999
$ git diff buildroot/system/skeleton/etc/profile
diff --git a/buildroot/system/skeleton/etc/profile b/buildroot/system/skeleton/etc/profile
index f2907e417..a6f44c6c2 100755
--- a/buildroot/system/skeleton/etc/profile
+++ b/buildroot/system/skeleton/etc/profile
@@ -25,3 +25,6 @@ for i in /etc/profile.d/*.sh ; dofidoneunset i
+
+ulimit -HSn 9999

清除, 编译!

参考

  1. ulimit - Set or display resource limits
  2. ulimit最详解
  3. linux ulimit作用
  4. [SOLVED] How to set ulimit at user level?
  5. /etc/security/limits.conf not applied
  6. ulimit 命令详解
  7. ulimit命令说明与用法
  8. 关于skeleton

在 Buildroot 中,skeleton 指的是包含基本文件和目录的目录树,这些文件和目录是运行最小化 Linux 系统所需的基本组件。它通常包括以下文件:

  • /bin/sbin:这些目录包含必要的可执行程序,例如 bashlscpmv
  • /etc:此目录包含各种系统服务的配置文件。
  • /lib/usr/lib:这些目录包含应用程序使用的库。
  • /proc:此目录包含有关正在运行的进程的信息。
  • /sys:此目录包含有关系统硬件的信息。
  • /dev:此目录包含设备节点,用于访问硬件设备。
  • /tmp:此目录用于临时文件。
  • /usr:此目录包含用户安装的程序和文件。

skeleton 通常从模板创建,该模板可以自定义以包含特定于目标系统的其他文件和目录。然后将 skeleton 复制到根文件系统,该文件系统在引导期间挂载在 / 上。

Buildroot skeleton 是创建自定义嵌入式 Linux 系统的有用起点。它提供了一个基本框架,可以轻松扩展以满足项目的特定需求。

使用 Buildroot 中的 skeleton 有以下一些好处:

  • *节省时间和精力。**您无需手动创建运行最小化 Linux 系统所需的所有文件和目录。
  • *确保根文件系统一致且组织良好。**skeleton 为根文件系统提供了一个标准布局,这使得更容易找到文件和目录。
  • *轻松添加自定义包。**只需将自定义包复制到适当的目录即可轻松将其添加到 skeleton 中。

如果您正在使用 Buildroot 开发嵌入式 Linux 系统,我建议使用 skeleton。它将节省您的时间和精力,并使其更容易创建满足您特定需求的系统。

以下是一些可能有用的额外资源:

  • Buildroot 关于 skeleton 的文档:https://buildroot.org/downloads/manual/manual.html
  • 自定义 skeleton 的示例:https://github.com/buildroot/buildroot
  • 关于如何创建自定义 skeleton 的讨论:https://buildroot.org/downloads/manual/manual.html

http://www.ppmy.cn/devtools/5284.html

相关文章

Python 中整洁的并行输出

原文&#xff1a;https://bernsteinbear.com/blog/python-parallel-output/ 代码&#xff1a;https://gist.github.com/tekknolagi/4bee494a6e4483e4d849559ba53d067b Python 并行输出 使用进程和锁并行输出多个任务的状态。 注&#xff1a;以下代码在linux下可用&#xff0c…

electron打包Vue前端(修正版)

electron打包部署到本地问题 前提条件&#xff1a;部署一个单机应用&#xff0c;前后端都放置在本地&#xff01;&#xff01;&#xff01; 根据 electron打包Vue前端 教程打包后运行错误分析 1. 账号密码无法正确显示 位置 src/views/login.vue 表单 loginForm: {userna…

个人开发者,Spring Boot 项目如何部署

今天给大家分享一下&#xff0c;作为个人开发者&#xff0c;Spring Boot 项目是如何部署的。 环境介绍 Linux docker docker-compose 目录结构 erwin-windrunner - backups - data - jars - build-docker-compose.sh - docker-compose.yml - Dockerfile文件 Dockerfile …

Flask vs FastApi 性能对比测试

Flask和Fastapi都是Python下流行的Web框架&#xff0c;前者有大量拥趸&#xff0c;是一个老牌框架&#xff0c;后者相对较新&#xff0c;但是利用了异步技术和uvloop&#xff0c;都说性能比Flask好很多&#xff0c;于是就我就对比实测一下。由于Windows下不支持uvloop&#xff…

burp弱口令爆破

暴力破解 通过枚举用户名或脆弱口令获取当前系统的认证信息&#xff0c;还有信息系统中参数、 url &#xff0c;常见的认证&#xff1a; ssh\ftp &#xff08;明文&#xff09; \telnet\rdp\smtp\snmp\pop3\http &#xff08;明文&#xff09; 强口令&#xff1a; 8 位以上…

WPF: XAML语法规范详解

WPF&#xff08;Windows Presentation Foundation&#xff09;是.NET框架的一个组成部分&#xff0c;用于构建桌面应用程序的用户界面。XAML&#xff08;Extensible Application Markup Language&#xff09;是一种基于XML的标记语言&#xff0c;用于定义WPF应用程序的界面和逻…

Windows 下 bat 脚本调用 Git bash 环境 sh 脚本

1、先找到 Git 安装目录 D:\Install\Git 2、Git bash 编写 sh 脚本 start.sh脚本 3、编写 start.bat脚本 echo offcd /d %~dp0 "D:\Install\Git\bin\sh.exe" --login -i -c "./test/start.sh"pause4、执行 bat 脚本 双击 start.bat 我们下期见&#xf…

设计模式---模板方法模式

一、介绍 所谓模板方法模式&#xff0c;就是提供一种方法的模板来实现一种规范&#xff0c;其他人可以利用这个模板定义自己的逻辑。 在Java编程中的应用&#xff0c;主要就是通过接口或者抽象类来实现的&#xff0c;抽象类中可以把逻辑函数声明为final类型&#xff0c;表示不能…