麒麟v10安装PREEMPT_RT实时补丁

项目里需要对麒麟v10打实时补丁(PREEMPT_RT),但安装elrepo源时提示nothing provides system-release < 8 needed by elrepo-release-7.0-6...的问题,试了几个elrepo版本都没有解决。后改用源码打补丁的方式编译安装通过,这里记录安装过程。此方法也适用升级内核或打其他内核补丁的场景。

首先查看当前内核版本号,例如下面的4.19.90。我们这次并不想升级内核版本因此后面将使用相同版本号:

> uname -a
Linux bogon 4.19.90-24.4.v2101.ky10.x86_64 #1 SMP Thu Dec 19 15:21:06 
CST 2024 x86_64 x86_64 x86_64 GNU/Linux

下载Linux内核源码和实时补丁并解压缩,它们的版本号要完全相同,否则patch时会失败:

wget https://mirrors.aliyun.com/linux-kernel/v4.x/linux-4.19.90.tar.gz
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patch-4.19.90-rt35.patch.gz

tar zxvf linux-4.19.90.tar.gz
gunzip patch-4.19.325-rt140.patch.gz

对源码打实时补丁:

cd linux-4.19.90
patch -p1 < patch-4.19.325-rt140.patch

安装必要的依赖:

yum install ncurses-devel bison flex elfutils-devel openssl-devel

配置内核参数:

make menuconfig
  • General setup -> Preemption Model里修改选项为Fully Preemptible Kernel
  • Timer subsystem里确认启用了High Resolution Timer Support
  • 保存为默认的.config文件退出

file

编译和安装内核:

# 4为线程数,根据cpu线程数配置
make -j4
make modules_install -j4
make install -j4

更新grub2:

grub2-mkconfig -o /boot/grub2/grub.cfg

重启服务器并在开机画面选择新内核验证效果;如果是远程操作可以先grub2-reboot 0实现一次性修改默认启动项,然后reboot重启系统进入新内核。

验证内核是否已打好PREEMPT_RT实时补丁:

> uname -a
Linux bogon 4.19.90-rt35 #1 SMP PREEMPT RT Thu Dec 19 16:57:18 
CST 2024 x86_64 x86_64 x86_64 GNU/Linux

Linux inode和常用操作

Linux系统里的inode中文名索引文件,用于保存文件的大小、时间、权限等元信息。每个文件都对应一个inode,每个inode也对应一个文件。因为在Linux里目录、设备等也是文件,所以也对应一个inode。

inode与文件块是分开保存的,它们都会占用磁盘空间,通常情况下是后者先占满,但当磁盘上有大量小文件时,可能前者会先达到上限,从而导致磁盘虽然还有空间但无法写入新文件。这种场景应提前考虑增加inode的上限数量,例如将2KB降为1KB。

file
图片来源:Wikipedia

让我们做一些实验来验证一下inode的行为:

查看磁盘已用和可用inode数量

执行df -i可查看分区里inode数量,一个分区下最大inode数量是格式化时确定的,默认最大数量是分区大小除以2KB得到
file

查看文件inode信息

执行ls -i可查看当前目录每个文件的inode值:
file

验证软链接有自己的inode

软链接是一个文件,其inode值与链接目标文件是不相同的。
file

验证硬链接共享同一个inode

硬链接不是一个文件,其inode号与链接目标文件相同。其实很正常,linux内部对文件的管理都是通过inode完成的,文件名只是一个易读的符号。
file

验证.和..是硬链接

分别对应当前目录的inode和上一级目录的inode。
file

验证通过inode号反查文件名

find -inum命令:
file

文件名存储在哪里?

inode里并不保存文件名(否则硬链接无法实现),那么文件名存储在哪里?答案是存储在“目录文件”里,当我们ls时,Linux就查询目录文件(但我们不能直接cat目录),此文件包含此目录下所有文件名到inode的映射关系。
file

注:以上均默认ext2文件系统。

CentOS 7.6内核SLAB泄露问题

公司产品使用docker-java控制作业在指定的运行环境(docker容器)里执行,因此经常需要反复启动和停止docker容器,在项目中发现存在一段时间(若干天)后启动容器失败的现象。

问题现象

多次启动docker容器并停止后,发现buff/cache内存占用不断增加,且手工释放没有明显效果:
file

file

内存不足的一个表现是无法启动docker容器,报错如下:

OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:319: getting the final child's pid from pipe caused \"EOF\"": unknown

查看meminfo判断主要是slab过多:
file

问题解决

在网上查询后发现有用户遇到类似问题,原因是kernal 3.10的kmem memory limit不稳定,但这个feature是默认开启的。解决方法是升级内核到kernal 3.10.1075以上,或升级CentOS发行版到7.8或以上。

补充:后来发现3.10版的内核仍然没有完全解决这个问题,升级到4.x版内核后问题解决。

参考资料

https://github.com/moby/moby/issues/37722
https://zhuanlan.zhihu.com/p/106757502

阿里云Centos 6.5迁移到7.6记录

主要原因是tensorflow在centos 6.5环境下配置遇到很多问题,主要是gcc和相关环境的版本问题,因此新购一台阿里云ec2使用centos 7.6版本。原服务器上的webapp(v7和wordpress)需要迁移,大量文件(>300w个)需要迁移。

参考之前一篇centos 6.5的服务器配置记录:Amazon EC2配置步骤和一些问题

一、购买ec2并添加数据盘

过程略。

二、阿里云格式化数据盘

https://help.aliyun.com/document_detail/25426.html?spm=a2c4g.11186623.2.27.558a1692XkXC7y#concept-jl1-qzd-wdb

三、安装必要的工具

yum install git
yum install nano
yum install lsof
yum install unzip

四、迁移mysql数据

安装mysql 5.7

https://dev.mysql.com/doc/refman/5.6/en/linux-installation-yum-repo.html

恢复数据库

mysql -uroot mydatabase < myexportedfile.sql

创建用户并授权

grant all privileges ON mydatabase.* TO 'username'@'localhost' identified by 'mypassword' with grant option;
flush privileges;

五、迁移其他服务

安装服务器软件

yum install java-1.8.0-openjdk
yum install httpd
yum install php php-mysql
yum install tomcat

配置jk和ssl

2.4版apache参考这个链接:How do I install mod_jk on Apache 2.4 webserver

修改/etc/crontab定时任务

crontab -e

配置服务自启动

chkconfig mysqld on
chkconfig httpd on
chkconfig tomcat on

六、大量文件迁移

因为原来的数据盘容量100GB,已经转移了50GB到OSS对象存储,因此新购的数据盘容量为60GB。阿里云不支持“数据盘缩容”,且原数据盘由于是包年包月方式无法从原ec2卸载,因此需要先为原数据盘创建一个100GB的镜像,然后购买一个按量付费的数据盘并选择从镜像创建,将这个新数据盘挂在到新ec2下,再用Linux自带的cp命令(加-a参数以便保留文件属性)将大量文件复制到60GB的数据盘。完成后删除按量付费数据盘和100GB镜像。

实测cp命令一开始速度较低(约300KB/s,通过多次执行du命令手工计算),可能是阿里云新购数据盘需要预热过程的原因,1小时后逐渐上升到接近1MB/s,4小时后达到8MB/s。

这次没有来得及尝试lsyncd+rsync的方案,从网上资料看,对处理海量小文件效率比较高。

安装miniconda(根据系统自带python版本选择miniconda2或miniconda3)

yum install bzip2
wget https://repo.anaconda.com/miniconda/Miniconda2-latest-Linux-x86_64.sh
bash Miniconda2-latest-Linux-x86_64.sh
source ~/.bashrc
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/

七、安装tensorflow

conda create --name tensorflow python=3.5.2
source activate tensorflow
pip install tensorflow

从二进制包安装的tensorflow不支持CPU扩展指令集,例如阿里云ec2支持AVX2, FMA,因此如果要用CPU最好编译源代码安装(用GPU的可以忽略),方法见官方安装文档

这里需要注意一下,按官方安装文档安装的bazel是最新版(0.22),可能不支持某些历史版本的tensorflow(1.12),需要下载历史版本bazel)。实际上在安装文档下方有tensorflow和bazel版本对照表,可以查到tensorflow 1.12对应bazel 0.15.9,bazel安装包下载地址在https://github.com/bazelbuild/bazel/releases 。

八、迁移后发现的问题

1、tomcat日志文件catalina.out里没有内容

tomcat6时catalina.out里有webapp用log4j输出的信息,到tomcat7里没有了,catalina.out只有28个字节。原因猜测可能是tomcat6和tomcat7的缺省行为不一样。查看了此webapp下的log4j.properties(在WEB-INF/classes目录下),配置的是只输出到console,在tomcat7的server.xml的context里添加swallowOutput="true"后,localhost_2019-02-20.log里可以看到webapp输出的信息了,但格式不好内容不够紧凑。

但查资料发现swallowOutput这个属性的问题比较多,所以改为在webapp的log4j.properties里指定输出到文件,但文件路径纠结了一会儿:用相对路径发现无法生成日志文件,可能是权限原因(没有深究),所以仿照tomcat7自带的logging.properties文件,使用${catalina.base}/logs前缀:

log4j.rootLogger=INFO, console

log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=${catalina.base}/logs/v7.log
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %m%n

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Encoding=GBK
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %m%n

2、mysql里部分查询变慢

待解决

Linux中目录的x权限

直接放结论:

x权限对于目录来说是非常重要的,当用户对某个目录没有x权限时,则不管用户对该目录下的子目录拥有什么样的权限,都将无法对子目录进行任何操作。

举例:

通常/root缺省是没有x权限的,因此mysql导出文件(SELECT ... INTO OUTFILE)到/root下的任何目录都会提示无法写入,不论这个目录的owner是谁,也不论这个目录是否777权限:

ERROR 1 (HY000) at line 1: Can't create/write to file '/root/my/out.csv' (Errcode: 13)

而/home缺省是有x权限的,因此在这个目录下mysql用户的文件夹,是可以用于mysql导出到文件的。

linux-directory-x

Shell脚本编程中的若干注意事项

几个特殊变量

变量 含义
$$ Shell本身的PID(ProcessID)
$! Shell最后运行的后台Process的PID
$? 最后运行的命令的结束代码(返回值)
$- 使用Set命令设定的Flag一览
$* 所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$@ 所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$# 添加到Shell的参数个数
$0 Shell本身的文件名
$1~$n 添加到Shell的各参数值。$1是第1参数、$2是第2参数…。如果大于等于10序号要用花括号包起来,例如${10}

test命令

test命令用于检查文件类型和表达式(check file types and compare values),返回的结果放在“$?”里,结果为0表示true,结果不为0表示false。例如:

$ test "a" = "b"
$ echo $?
1

test命令可以用“[]”简写(注意[]里面要带有空格,否则提示command not found),后面加上&&符号则表示当表达式成立时执行后续操作。例如:

$ [ "a" = "a" ] && echo yes
yes

类似的,后面加上“||”则表示当表达式不成立时执行后续操作。

-z参数用来判断字符串是否为空,例如:

$ [ -z "" ] && echo yes
yes

还有一些类似的其他表达式参数,以及与文件相关的参数,可以man test查看。

参考链接:

 

在Debian里不重启切换两块声卡

在电磁干扰严重的狭小空间里,笔记本的内置声卡表现一般比较差,至少我的n600c底噪就很明显。要获得更好的效果或者需要数字输出时只能借助外置声卡了,包括pcmcia接口和usb接口两种,前者如创新的Audigy2 ZS Notebook,当然很贵了;后者如我的玲珑II,性价比还不错。

在Linux里不像Windows那样可以简单的在控制面板里选择使用哪个声卡作为首选设备,经过一段时间的研究,我找到一个还可以接受的办法,至少不需要重启系统。首先 将以下的文本保存为/etc/modutils/sound_cards,然后sudo update-modules,这个命令会处理/etc/modutils里的所有文件,合成/etc/modules.conf文件。

alias snd-card-0 snd-maestro
alias snd-card-1 snd-usb-audio
options snd-maestro index=0
options snd-usb-audio index=1
options snd-usb-audio enable="1"

要切换到usb声卡时:

sudo /etc/init.d/alsa force-unload
sudo modprobe snd-usb-audio

类似的,要切换到内置声卡(使用maestro3芯片)时:

/etc/init.d/alsa force-unload
modprobe snd-maestro3

注意force-unload的时候会先自动杀掉所有使用声卡的进程,如firefox、音量控制和bmp等等,如果没有这样的进程在运行,可以直接unload,或者rmmod snd-maestro3这样卸载模块。

另外一种方法是在应用程序里切换,例如bmp,在首选项->插件->输出里把输出插件选为ALSA,然后在ALSA的配置里选择希望使用的音频设备和混音设备即可。其他应用程序类似,其实如果只关心某个应用程序,这样更省事。

最后,Gentoo用户请参考这个Tip,感谢acura提供。

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2005/12/16/298333.html

Windows分区转换为Debian分区

我的机器上是Debian和win2000双系统,今天把原来window的e盘转换成linux的分区了(因为PQMagic划分空间有一定的危险性),相当于给linux增加了10G容量,这下宽裕多了。

我是把/home放在了新分区上,因为用户要下载一些比较大的文件都放在这里面,方法如下:

1、在windows里把e盘上有用的东西移到其它盘上

2、重新启动进入Debian的recovery mode,即single模式

3、# mv /home /home2

4、# mkdir /home

5、# mkfs.ext3 /dev/hda6

6、# mount /dev/hda6 /home

7、# cp -ar /home2/* /home

最后再重启机器即可。

用Debian遇到的部分问题和解决

1、待机命令

echo mem>/sys/power/state

这之前要确认acpid服务已经启动;

2、打开Firefox的profilemanager

firefox -profilemanager

3、支持speedstep,在/etc/modules里加入speedstep-ich、cpufreq_powersave和cpufreq_userspace这三项,其中第一项是针对PIIIM的笔记本,如果是迅驰用speedstep-centrino;

4、查看pcmcia读卡器的设备名

cat /proc/partions

5、释放空间:

apt-get clean

6、Linux下听ape用SuperMMX的mac-port:http://sourceforge.net/projects/mac-port/

7、从stable转换到testing后,在一个窗口输入过汉字后,alt-tab会失效无法切换到其他窗口,考虑是fcitx的问题,所以决定 换输入法系统。apt-get install scim,scim-tables-zh,scim-gtk2-immodule,然后编辑/etc/X11/Xsession.d/90chinput -start内容如下:

export XMODIFIERS=@im=SCIM
export XIM=xim
export XIM_PROGRAM="scim -d"
export GTK_IM_MODULE=xim
export QT_IM_MODULE=xim
scim -d

scim-tables-zh里并不包括拼音输入法,所以apt-get install scim-pinyin(这个包以前叫scim-chinese),而且我是添加了一个unstable源才找到的。

Update2006-4-21:解决有些程序里不能输入中文的问题,要安装scim-gtk2-immodule这个包,然后把上面的90chinput-start文件改为如下:

export XMODIFIERS="@im=SCIM"
export GTK_IM_MODULE="SCIM"
scim -d

8、手动关闭显示器

xset dpms force off

9、更改gnome的splash:#update-alternatives --config desktop-splash,(来自Debian学习笔记

10、用totem播放其他格式:从这个地址下载win32codecs-essential-20040703.tar.bz2和rp9codecs-20050115.tar.bz2,解开的内容放到/usr/lib/win32(如果不存在建一个)即可。

11、DNS解析很慢可能是ipv6造成的,去掉ipv6的方法:在/etc/modprobe.d/aliases中,把“alias net-pf-10 ipv6”注释掉,然后update-modules,再重启。(这个方法更方便:在firefox地址栏里输入about:config,用 filter找到network.dns.disableIPv6,修改为true。来自Ubuntu快速入门手册

12、如遇到空间不足,可以考虑先清掉apt的cache:apt-get clean;还可以用debfoster工具删除不需要的deb包。

13、文件名转码工具convmv,用于转换windows分区拷文件过来可能出现文件名乱码,例如

convmv -f utf8 -t cp936 --notest *

14、把从cd抓下来的ape文件分为多个:安装cuetools和shntool,然后cuebreakpoints -i cue CDImage.cue|shnsplit -n track CDImage.ape,这样得到的是多个.wav文件,可以给shnsplit加-o ape参数转为ape,但要使用特别的mac版本,在shntool主页有下载。

15、修改grub的背景:修改/boot/grub/menu.lst,加入splashimage (hd0,2)/boot/grub/images/xxx.xpm.gz,图片文件要自己制作或者下载现成的。

16、修改console分辨率,在menu.lst的kernel行最后加入vga=791,表示1024x768的分辨率。好像还可以vga=ask?

17、彩蛋:在gnome里按alt+f2打开运行程序对话框,输入free the fish,会出现一条小鱼(旺达)在屏幕上游动。

18、对时用ntpdate,教育网内时间服务成员列表

19、用wget批量下载,方法1:seq 20 | awk '{print "http://mydomain/file"$1".zip"}' | wget -i -;方法2:for i in seq 1 20;do wget http://domain/$i.txt;done;更简单的:curl http://mydomain/file[1-20].zip -O

20、代理服务器的环境变量:

export http_proxy="myproxy:port"
export ALL_PROXY="myproxy:port"

21、使用usb光驱

mount -t iso9660 -o iocharset=cp936 /dev/scd0 /mnt/usb

22、网卡命名:nameif(链接

23、同步internet时间

ntpdate time.nist.gov

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2005/11/09/272253.html

Debian里编译内核

以Debian 2.6.8版本为例:

1、Debian.org上关于编译内核的说明;另一篇看起来不错的文章:Creating custom kernels with Debian's kernel-package system

2、下载内核源代码apt-get install kernel-source-2.6.8,在/usr/src下得到kernel-source-2.6.8.tar.bz2文件,用tar xfj命令展开;

3、下载需要的patch,比如休眠功能的patch是kernel-patch-suspend2,注意目前在experimental里才有,所以要在/etc/apt/sources.list里加上必要的源;

4、执行以下操作,如果当前语言是中文,执行前最好执行zhcon进入中文环境:

# cd /usr/src/kernel-source-2.6.8
# cp /boot/config* .
# make-kpkg clean
# make-kpkg --append_to_version -2 --added_patches suspend2 --config menuconfig
# make-kpkg --append_to_version -2 --initrd kernel_image
# cd ..
# dpkg -i kernel-image-2.6.8-2.i386.deb

注意在menuconfig的时候先载入原来的配置文件,即上面第二行复制过来的/usr/source/config-xxx文件,然后在这个配置上进行修改;另外,我如果不加--initrd参数,则新内核无法启动。

5、重启电脑用新内核启动。

Update(2005/12/23):不加--initrd参数可以启动了,关键是在menuconfig的时候要把ext2,ext3等文件类型加入内核,同时要把对ide设备的支持直接加入内核,我以前只注意了前者。

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2005/10/13/254213.html