# linux_cpu **Repository Path**: han_gx/linux_cpu ## Basic Information - **Project Name**: linux_cpu - **Description**: 存储项目,基于ceph压力测试,cpie接口获取数据持久化到本地ssd盘 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2022-03-04 - **Last Updated**: 2024-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 软件新机布置步骤 ```shell yum stop firewalld yum disable firewalld yum install -y vsftpd # 修改文件 /etc/vsftpd/vsftpd.conf chroot_local_user=YES chroot_list_enable=YES chroot_list_file=/etc/vsftpd/chroot_list userlist_enable=NO # 添加目录 /etc/vsftpd/chroot_list 其中只写root, vi /etc/vsftpd/user_list # 中打开root用户 vi /etc/vsftpd/ftpusers # 中将root用户注释掉, 这个文件里面包含的用户都不能连接ftp服务 systemctl restart vsftpd # 重启服务 ``` ```shell # 配置阿里yum源 https://developer.aliyun.com/mirror/ yum install -y wget yum install -y net-tools yum install -y OpenIPMI ipmitool yum install -y smartmontools # 安装 python web 环境 yum install -y python3 python -m pip install -U pip pip install bottle cd /home/han/linux_cpu/pserver make clean && make chmod 777 check_md0.sh check_num.sh check_test_main.sh check_test.sh cd /home/han/linux_cpu/xbmd_drv make clean && make cd /home/han/linux_cpu/utils/start_reboot chmod 777 ./* cd /home/han/linux_cpu/src # 修改 socket ip地址, 40GB网口的ip地址 # 修改 主 存 cd /home/han/linux_cpu/pserver/server/static/js/index.js # 盘数值改为 对应的盘数 # 40网口 免密登陆 ``` ## 系统时间设定 ```shell date -s "2006-11-23" date -s "22:07:21" date -s "2005-6-4 17:26" 同步系统和BIOS时间 hwclock --show 显示bios时间 hwclock --systohc 将系统时间写入bios hwclock --hctosys 将bios时间写入系统 hwclock --help 显示帮助 ``` ## 开机加载驱动模块 1. 将 xxx.ko 拷贝到以下drivers 以下对应的模块里面, 例如我的是PCIE, 拷贝到 xx/pci/pcie下 > /lib/modules/`uname -r`/kernel/drivers/xxx 2. 执行命令 `depmod -a`, 不执行的话,系统第一次检测不到 新放入到 xxx/kernel/drivers/xxx 下的驱动模块,第三部执行不成功 3. 在 /etc/sysconfig/modules 中新建脚本 `xxx.modules`, 这里一定要注意是一 `.modules`结尾的可执行文件 这个脚本是负责开机自启动的脚本 ```shell #!/bin/sh /sbin/modinfo -F filename xbmd > /dev/null 2>&1 if [ $? -eq 0 ]; then /sbin/modprobe xbmd fi ``` 3. 修改文件权限 ```shell chmod 777 xxx.modules ./xxx.modules # 执行该文件 lsmod | grep xbmd #查看是否加载上 ``` 4. 如果第三步能够加载上,则重启在查看驱动是否加载上 ## 开机脚本 `crontab -e` ```shell @reboot sleep 30; /home/han/linux_cpu/utils/start_reboot/start_main.sh @reboot sleep 35; /home/han/linux_cpu/utils/start_reboot/start_ssdtemp.sh @reboot sleep 20; /home/han/linux_cpu/utils/start_reboot/start_syncsytem_time.sh @reboot sleep 50; /home/han/linux_cpu/utils/start_reboot/start_cephagent.sh #一台机器上有就行了 #@reboot sleep 35; /home/han/linux_cpu/utils/start_reboot/start_ssdtemp_main.sh #@reboot sleep 40; /home/han/linux_cpu/utils/start_reboot/start_web.sh ``` ## 开机需要配置 ```shell #两台机器都需要执行 mount -t ceph 192.168.70.11:/ /mnt/cephfs/ route add default gw 192.168.137.1 # 添加文件 /etc/sysconfig/network..../route-网卡名称 default via 192.168.206.1 ##永久路由配置 ``` 脚本配置 ```shell #!/bin/bash mount -t ceph 192.168.70.11:/ /mnt/cephfs/ #挂载文件 cd /home/han/liunx_cpu/xbmd_drv/ ./insmod.sh #启动驱动程序 cd /home/han/liunx_cpu/src/ ./a.out #启动正式程序 ``` ## 裸IO `tune2fs -l /dev/md0|grep "Block size"` ` 查看文件块大小` `getconf PAGESIZE` 查看内存块大小 [详细文档 ]() ## 文件映射 #### mmap ```c // 接口文档 官方: https://www.man7.org/linux/man-pages/man2/mmap.2.html #include void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *addr, size_t length); ``` addr:如果不为NULL,内核会在此地址创建映射;否则,内核会选择一个合适的虚拟地址。大部分情况不指定虚拟地址,意义不大,而是让内核选择返回一个地址给用户空间使用。 length:表示映射到进程地址空间的大小。 prot:内存区域的读/写/执行属性。 PROT_READ, PROT_WRITE, PROT_EXEC, PROT_GROWSDOWN flags:内存映射的属性,共享、私有、匿名、文件等。 MAP_SHARED, MAP_PRIVATE, MAP_SHARED_VALIDATE fd:表示这是一个文件映射,fd是打开文件的句柄。如果是文件映射,需要指定fd;匿名映射就指定一个特殊的-1。 offset:在文件映射时,表示相对文件头的偏移量;返回的地址是偏移量对应的虚拟地址。 #### lseek > off_t lseek(int fildes, off_t offset, int whence); SEEK_SET 参数offset 即为新的读写位置. SEEK_CUR 以目前的读写位置往后增加offset 个位移量. SEEK_END 将读写位置指向文件尾后再增加offset 个位移量. 当whence 值为SEEK_CUR 或 SEEK_END 时, 参数offet 允许负值的出现. #### fseek > int fseek(FILE *fp,long offset,int from); ```c /*将读写位置移动到离文件开头100字节处*/ fseek(fp,100L,0); /*将读写位置移动到离文件当前位置100字节处*/ fseek(fp,100L,1); /*将读写位置退回到离文件结尾100字节处*/ fseek(fp,-100L,2); /*将读写位置移动到文件的起始位置*/ fseek(fp,0L,SEEK_SET); /*将读写位置移动到文件尾*/ fseek(fp,0L,SEEK_END); ``` #### ftell > long ftell(FILE *fp); //获取当前文件位置指针相对于文件首的偏移字节数。 ### 注意的问题 > Linux默认环境下打开、读、写超过2G的文件会返回错误 ```c #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 ``` ## GPIO操作 文件目录 /sys/class/gpio/export **export** `echo 19 > export` 通过写GPIO #19 申城gpio19的节点 `echo 19 > unexport` **节点生成后** `/sys/class/gpio/gpio9/ ` 有这个目录 1. **direction** 读 "in" 或是 "out" ```shell echo out > /sys/class/gpio/gpio389/direction #设置引脚是输出 可写 write value echo in > /sys/class/gpio/gpio389/direction #设置引脚是输入 可读 read value ``` 2. **value** 读 0 或是 1 ```shell cat /sys/class/gpio/gpio333/value #如果1中设置的是 in输入, 则可以读取值 echo 1 > /sys/class/gpio/gpio333/value #如果1中设置的是 out 输出, 则可以写入值 ``` 3. **edge** 控制中断触发模式,只对 direction 为 in是起作用 引脚配置为中断口可以使用 `poll()` 函数监听引脚 ```shell echo "none" > edge #非中断引脚 echo "rising" > edge #上升沿触发 echo "falling" > edge #下降沿触发 echo "both" > edge #边沿触发 ``` 例子: ```shell [root@node2 debug]# cat /sys/kernel/debug/gpio gpiochip0: GPIOs 265-511, parent: platform/INT3536:00, INT3536:00: gpio-389 ( |sysfs ) in lo IRQ # 其中 in 代表低电平, lo, IRQ 代表可中断 ``` utils_gpio.c ```c #include #include #include #include #define FILE_EXIT_NO -1 #define GET_POWER_SIGNAL "1" /** 判断文件是否存在 */ void isExit() { int ret = access(SYSFS_GPIO_RST_VAL, F_OK); if(FILE_EXIT_NO == ret) { LOG_DEBUG("create gpio power keep off \n"); //对引脚 389 的设置 system("echo 389 > /sys/class/gpio/export"); //创建引脚 system("echo in > /sys/class/gpio/gpio389/direction"); //设置引脚低电平 system("echo both > /sys/class/gpio/gpio389/edge"); //设置引脚可中断 } } //函数中断 int gpio_break() { isExit(); int fd = open(SYSFS_GPIO_RST_VAL, O_RDONLY); uint8 res[4]; int len; if(fd == -1) { LOG_DEBUG("#ERR: -GPIO ERROR- error to open %s \n", SYSFS_GPIO_RST_VAL); return KT_ERROR; } struct pollfd fds[1]; fds[0].fd = fd; fds[0].events = POLLPRI; while (1) { if(-1 == poll(fds, 1, 0)) { LOG_ERROR("#ERR: -GPIO ERROR- error to poll fd, fd: %d \n", fds[0].fd); } if(fds[0].revents & POLLPRI) { if(-1 == lseek(fd, 0, SEEK_SET)) { LOG_ERROR("#ERR: -GPIO ERROR- error to lseek fd, fd %d \n", fds[0].fd); } if(-1 == (len = read(fd, res, sizeof(res)))) { LOG_ERROR("#ERR: -GPIO ERROR- error to read fd, fd %d \n", fds[0].fd); } //todo 符合条件则做以下操作 if(res[0]=='1') { return KT_OK; } usleep(10*1000); //10ms } } return KT_ERROR; } ``` ### liunx gpio 子系统 当前 CPU 和 PCH 型号 CPU 支持第一代和第二代 Intel® Xeon SP 系列处理器 英特尔 PCH C621 芯片组 ```shell ls /sys/class/gpio/ export gpiochip265 unexport #export文件用于通知系统需要导出控制的GPIO引脚编号; #unexport用于通知系统取消导出; #gpiochipX目录保存系统中GPIO寄存器信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数。 echo 512 > export # 这条命令是创建 512 这个引脚, 这个数值范围是需要查看当前 gpiochip256 的基地址到 基地址+地址个数, 既 265 ~ 511 # 基地址和CPU或是PCH 引脚关系对应图如下 cat /sys/kernel/debug/pinctrl/INT3536:00/gpio-ranges #查看基地址以及基础地址和引脚个数 0: INT3536:00 GPIOS [265 - 288] PINS [0 - 23] 24: INT3536:00 GPIOS [289 - 312] PINS [24 - 47] 48: INT3536:00 GPIOS [313 - 336] PINS [48 - 71] 72: INT3536:00 GPIOS [337 - 360] PINS [72 - 95] 96: INT3536:00 GPIOS [361 - 384] PINS [96 - 119] 120: INT3536:00 GPIOS [385 - 397] PINS [120 - 132] 133: INT3536:00 GPIOS [398 - 409] PINS [133 - 144] 145: INT3536:00 GPIOS [410 - 433] PINS [145 - 168] 169: INT3536:00 GPIOS [434 - 445] PINS [169 - 180] 181: INT3536:00 GPIOS [446 - 469] PINS [181 - 204] 205: INT3536:00 GPIOS [470 - 493] PINS [205 - 228] 229: INT3536:00 GPIOS [494 - 511] PINS [229 - 246] cat /sys/kernel/debug/pinctrl/INT3536:00/pins #查看所有的PCH 或是芯片的引脚 # 也可以通过以下方式查看 cd gpiochip265/ ls base device label ngpio power subsystem uevent cat base #查看基地址 265 cat label # 查看芯片型号 INT3536:00 cat ngpio # 查看当前芯片的引脚数量 247 # 1. 这里创建 4 个引脚 echo 265 > export echo 400 > export echo 401 > export echo 511 > export # 2. 查看引脚 cat /sys/kernel/debug/gpio gpio-265 ( |sysfs ) in hi gpio-400 ( |sysfs ) in hi gpio-401 ( |sysfs ) in hi gpio-511 ( |sysfs ) in lo # 3. 查看 pinctrl 引脚占用情况, 发现创建的 GPIO 引脚并没有和 PCH 引脚对应上, PCH 对应的引脚还是 MUX UNCLAIMED 的状态 cat /sys/kernel/debug/pinctrl/INT3536:00/pinmux-pins Pinmux settings per pin Format: pin (name): mux_owner gpio_owner hog? pin 0 (RCINB): (MUX UNCLAIMED) INT3536:00:265 ... pin 135 (GBE_TMS): (MUX UNCLAIMED) INT3536:00:400 ... ... # 4. 关联 GPIO 引脚 到 pinctrl ``` ### PCH C621 引脚号 GPP A 0~23 B 0~23 C 0~23 D 0~23 J 0~23 F 0~23 G 0~23 H 0~23 I 0~10 E 0~12 K 0~10 L 0~19 GPD 0~11 GPIO_R-COMP3_3 GPIO_R-COMP_1P8_3_3 ### GPIO subsystem 简介 http://www.wowotech.net/gpio_subsystem/pinctrl-driver-summary.html > 1)前面讲了,由于 pinctrl subsystem的特殊性,对于pin configuration以及pin multiplexing而言,要怎么配置、怎么复用,只有pinctrl driver自己知道。同理,各个consumer也是云里雾里,啥都搞不清楚(想象各位编写设备驱动需要用到pinctrl的时候的心情吧!)。 > > 2)那这样的配置有道理吗?有!记得我们在[6]中提到过,对一个确定的产品来说,某个设备所使用的pinctrl功能(function)、以及所对应的pin(或者pin group)、还有这些pin(或者pin group)的属性配置,基本上在产品设计的时候就确定好了,consumer没必要(也不想)关心技术细节。因此pinctrl driver就要多做一些事情,帮助consumer厘清pin有关资源的使用情况,并在这些设备需要使用的时候(例如probe时),一声令下,将资源准备好。 > > 3)因此,pinctrl subsystem的设计理念就是:不需要consumer关心pin controller的技术细节,只需要在特定的时候向pinctrl driver发出一些简单的指令,告诉pinctrl driver自己的需求即可(例如我在运行时需要使用这样一组配置,在休眠时使用那样一组配置)。 > > 4)最后,需求的细节(例如需要使用哪些pin、配置为什么功能、等等),要怎么确定呢?一般是通过machine的配置文件、具体版型的device tree等,告诉pinctrl subsystem,以便在需要的时候使用。 ```shell /sys/kernel/debug/pinctrl/ #x86 引脚一般的都会在这个下初始化 /sys/kernel/debug/pinctrl/INT3536:00 #这个是当前CPU型号PCH C621的引脚初始化操作 #目录下的文件 gpio-ranges pinconf-groups pinconf-pins pingroups pinmux-functions pinmux-pins pins cat gpio-ranges # 查看 GPIO 引脚的范围 cat pins # 查看 GPIO 引脚的 寄存器范围和编号 ``` 经过对比 ![](./public/images/gpioccc.png) ... ![](./public/images/GPIO.png) .... # 项目架构图 ![](./public/images/daimajiagoutu.png) [linux c 并发编程 笔记](https://gitee.com/han_gx/my_notes/blob/master/liunx_C/linux_c_%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B.md) ## 多线程 1. 经测试, 如果循环里面打印函数会大量降低程序占用CPU处理资源, 原因IO这部分 2. PCIE -> 驱动 5.5GB/s 驱动 -> CPU内存 5.4GB/s 内存 -> IO 3.02GB/s ## linux 下测试多线程内存占用 RSS 栈内存和堆内存,以及其他的内存 (物理内存) VSZ/VSS 进程分配的虚拟内存 TIME 该进程启动后占用的CPU总和 ### ps -aux ``` 使用当前命令查看线程 ID ``` ### htop ``` 再使用 htop -p 线程ID 实时查看线程的资源占用情况 ``` https://www.cnblogs.com/xudong-bupt/p/8643094.html ### 存在BUG 1. 在程序停止光纤采集的时候,线程结束, 但是无序队列总是有几个数据处于BUSY中 2. 线程中传入参数, 运行一段时间变成其他数值 传入线程中的参数最好使用malloc的方式 # 二进制查看文件命令 ```java hexdump 文件名| less ``` 1,048,576 ## yum 代理配置 ```shell #测试代理 curl -I --proxy 192.168.70.55:808 www.baidu.com #yum 配置代理 vi /etc/yum.conf gpgcheck=1 installonly_limit=3 clean_requirements_on_remove=True best=True skip_if_unavailable=False ###### 配置代理 proxy=http://192.168.70.55:808 proxy_username=han001 proxy_password=123456 ``` ## 查看CPU系统温度 ```shell yum install -y OpenIPMI ipmitool ##需要安装 ipmitool lan print 8 ipmitool lan set 8 ipsrc static ipmitool -I open lan set 8 ipaddr 192.168.70.2 ##时间比较久 ipmitool sensor list ipmitool -I lanplus -H -U admin -P admin sdr get 12V ipmitool -I lanplus -H -U admin -P admin sdr get 'CPU Temp' ipmitool -I lanplus -H -U admin -P admin sdr get 'Board Temp' ipmitool sdr get 'P12V' ipmitool sdr get 'CPU Temp' ipmitool sdr get 'Board Temp' ``` 各个控件列表介绍 https://blog.csdn.net/kunkliu/article/details/114662746 ## 内存溢出 多线程中, 调用pthread_join 函数才会释放线程中使用的内存 ## 多盘组阵列 **raid各个版本的性能对比** [https://www.cnblogs.com/ivictor/p/6099807.html]() https://blog.csdn.net/qq_38639426/article/details/88546913 ```shell mdadm -C /dev/md0 -l 0 -n 4 /dev/nvme0n1 /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 mdadm --detail /dev/md0 #查看组阵盘详细信息 mkfs.ext4 /dev/md0 #设置文件系统 mount /dev/md0 /mnt/raid0/ #挂载 mdadm --stop /dev/md0 mdadm --misc --zero-superblock /dev/nvme0n1 #删除子盘,否则可能子盘格式化了,但是开机组盘的md0信息仍然在 mkfs -t ext4 /dev/nvme9n1 ## 组盘 mdadm -C /dev/md0 -l 0 -n 12 \ /dev/nvme0n1 \ /dev/nvme10n1 \ /dev/nvme11n1 \ /dev/nvme1n1 \ /dev/nvme2n1 \ /dev/nvme3n1 \ /dev/nvme4n1 \ /dev/nvme5n1 \ /dev/nvme6n1 \ /dev/nvme7n1 \ /dev/nvme8n1 \ /dev/nvme9n1 ``` ## 分布式 ceph ```shell mount -t ceph 192.168.70.11:/ /mnt/cephfs/ ``` ## 环境配置 1.两台机器之间配置ssh免密登录 2.在两天机器上 新建/etc/profile.d/han_start.sh ```shell #!/bin/sh route add default gw 192.168.137.1 ``` ```shell #!/bin/sh mount -t ceph 192.168.70.11:/ /mnt/cephfs/ route add default gw 192.168.137.1 ``` ## 开机自启crontab ```shell @reboot sleep 30; /usr/shells/start.sh //开机延时三十秒执行某个脚本 ```