因为用到xdp相关的东西,centos7操作系统的内核版本为3.10,准备编译升级一下。还从来没有手动编译安装过。 看了官方文档,没有啥特别流程,讲了一些注意事项。我按照网上的步骤来的。 下载内核: curl -O https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.230.tar.xz 解压: tar xf linux-4.19.230.tar.xz 然后,把之前内核编译配置复制过来: cd linux-4.19.230 && make mrproper, cp /boot/config-3.10.0-1160.53.1.el7.x86_64 ../.config 进行配置:make menuconfig,看文档应该是make oldconfig,可能用这个读的.config文件吧。 配置没太敢改,只改了Processor type and features —> Processor family (Core 2/newer Xeon) 选了newer Xeon。这个我还翘"?"看了一下介绍,可以cat /proc/cpuinfo,看看cpu family, 6为new,15为old。 编译: make -j 32 安装:make modules_install && make install 配置启动: 查看当前启动选择:grub2-editenv list 设置默认第一个启动:grub2-set-default 0 确认设置:grub2-editenv list,这里我在/boot/目录下找了一下grub.cfg配置,第一行确实是刚安装的内核版本。 重启:reboot 重启没有什么问题,安全起来了。 还有几个编译依赖文件,之前我对照官方文档检查了几个主要的,但是有些需要devel版本的,起始发现没装还是得重新安装。 yum install ncurses-devel.x86_64 elfutils-libelf-devel openssl-devel 没啥难度,毕竟也算世界上最大的开源项目了吧,应该做的很容易。最难的是内核定制,完全不知道应该怎么选择,选择哪些配置能提升性能,不然本地编译的还比不上版本分发带的普适版本的性能好。

Continue

FinalizeRunMode,检查了一下daemon和运行的模式是否匹配,然后模式保存到全局变量run_mode中。 StartInternalRunMode,这个是判断是否是一些打印相关的模式,如果是这些模式,调用相关的方法,这些方法就不看了。比如列出模式,打印软件帮助等这类的模式。 GlobalsInitPreConfig,先调用TimeInit,初始化了一个当前时间的自旋锁current_time_spinlock,具体干啥的还不知道,调用tzset设置时区变量。之后调用SupportFastPatternForSigMatchTypes,初始化sm_fp_support_smlist_list,是个链表,默认保存了DETECT_SM_LIST_PMATCH,优先级为3,具体不知道这个是干啥的。之后调用SCThresholdConfGlobalInit,我看主要是初始化了解析Thresholding的正则表达式。 LoadYamlConfig,加载配置文件,调用ConfYamlLoadFile,这个里边主要利用了yaml库解析配置文件,没查这个库具体函数,函数名很容易知道是干啥的。保存了一下配置文件的目录,主要是调用ConfYamlParse,把配置读入ConfNode结构的树里边,有父节点,然后是个链表。所以也不单纯是个树。没太仔细看具体解析流程,单纯就是读到树里了。 typedef struct ConfNode_ { char *name; char *val; int is_seq; /**< Flag that sets this nodes value as final. */ int final; struct ConfNode_ *parent; TAILQ_HEAD(, ConfNode_) head; TAILQ_ENTRY(ConfNode_) next; } ConfNode; ConfDump模式单纯就是把刚读如的链表树再打印一下。 查了一下“vlan.use-for-tracking”的值,这个参数看了一下配置文件介绍,基本用不到。 ConfGetBool获取配置中的bool值,先调用ConfGetValue获取值,里面通过ConfGetNode通过name找到node,key通过“.”进行分割,然后ConfNodeLookupChild查找当前等级的链表。看到这里发现,用c实现个json解析啥的好像也不太难啊。 SetupUserMode(&suricata);这个是设置非system模式的情况下,把日志和数据目录设置到当前目录,函数没跟进取,暂时不看了,这些模式不是看的重点。 SCLogLoadConfig应该是设置日志了,通过verbose设置等级,verbose通过参数有几个v来设置,等级为SC_LOG_NOTICE + verbose,看了一下SCLogLevel, 最高可以有5个v。获取logging.outputs的配置保存到outputs,SCLogAllocLogInitData初始化SCLogInitData,这个数据结构主要保存日志等级,格式,写到什么地方等信息。获取配置文件里"logging.default-log-level"配置的日志等级,然后跟参数里的比较,取等级最低的,保存到global_log_level。如果等级跟配置文件一致,使用配置文件的format。将outputs配置文件保存到变量,这些主要是日志的方式,console/file/syslog,没有细看,看了一下file的,这个用的多,调用SCLogInitFileOPIface,append模式打开文件,方式里面有个锁变量,注释说用来切割日志时候用的,然后调用OutputRegisterFileRotationFlag,把需要分割日志的这个flag都保存到output_file_rotation_flags里了,这个也是个链表。这里暂时有个疑问,我看flag初始化的时候没设置值,不知道后面会不会设置,还是我漏了。这里保存的是指针,可能不是漏了。日志等级还比较了outputs里的等级,取最低等级。然后调用SCLogInitLogModule,这个在之前调用过,之前可能是终端输出,现在可以配置文件了。 LogVersion,打印版本。 UtilCpuPrintSummary,打印cpu个数信息。 ParseInterfacesList,这里是看启动参数是否设置网口,如果设置会在配置里加一个xxx.live-interface的配置项,没设置就调用LiveBuildDeviceList,参数是模式,也是配置文件里的顶级名称,使用这个参数获取配置,如果interface为default,则忽略,这个是默认配置,其他情况调用LiveRegisterDeviceName,把接口插入队列,这个跟参数解析一致。所以看起来好像启动参数不加网口也可以啊。

Continue

SuricataMain是入口函数,先调用SCInstanceInit,把SCInstance变量数据清0,不知道为啥以及memset0了,还要变量名再置0一次。SCInstance就是suricata进程相关的一些变量,其中一个有意思的事是还保存了执行命令的文件名,看这个感觉可能直接改二进制的名也没问题的。run_mode设置为RUNMODE_UNKNOWN。 之后调用InitGlobal,主要设置suricata_context变量,这个变量在rust-context.h文件定义,全是操作函数,具体赋值的函数还没有看,这个先过了。 在InitGlobal里调用rs_init,这个看了一下好像是给rust调用用的,sc赋值给rust里的sc,这样在rust里可能就能试用context的函数了,我看在core.rs中都是contxt里的函数声明。具体c和rust怎么交互的,我还需要再看看。粗略看了一下,协议判断好像都在rust里写的。 然后初始化engine_stage为0,这个变量为原子变量,原子操作都定义在util-atomic.h,没细看怎么实现的,先知道干啥的吧。这个变量注释说的是表明引擎是在初始化还是在处理数据包了,总共包括三个状态SURICATA_INIT,SURICATA_RUNTIME and SURICATA_FINALIZE。 SCLogInitLogModule,初始化日志模块。没细看,参数传的NULL,使用默认日志系统。info等级打印到console,可以设置正则过滤,这几个设置项都可以通过环境变量设置。 之后ParseSizeInit,初始化了一个正则匹配器parse_regex,这个正则表达式不知道干啥的,看后面好像是把字符串“10kB,10GB”类似的转换成具体的大小数据,可能是配置文件之类的解析,先过了。 之后RunModeRegisterRunModes,跟函数名一个意思,注册的模块还没看。看配置文件就知道四五种,没想到还挺多。注册到数组runmodes。找了几个看看,发现就是list-runmodes里的模式,把对应的模式和具体模式的方法进行注册。每种模式都是调用RunModeRegisterNewRunMode注册到runmodes数组保存。RunModeFunc是对应的模式函数,这个先没看,等用到再看 之后ConfInit,初始化配置模块,ConfNode是一个列表,里面是kv键值对。起始就是初始化一个链表。 到这InitGlobal就结束了。 ParseCommandLine解析命令行参数,列出了所有参数,pfring或pfring-int参数启动pfring,设置run_mode为RUNMODE_PFRING, 如果后面跟参数,设置pcap_dev,这个应该是网口名了。LiveRegisterDeviceName就是把网口插入到一个链表里,相当于注册了。变量名pre_live_devices。capture-plugin还能设置插件名,这个模式RUNMODE_PLUGIN,可能dpdk得插件实现。netmap参数只能设置一次,看来只能在一个网口使用,而且还不能多个模式。 suricata --list-app-layer-protos 列出七层协议 suricata --list-runmodes 列出模式 list-keywords 关键字 -l设置日志目录 -i和af-packet都走af-packet,-i如果支持,默认也走af-packet。 这些参数在help里都有,暂时不看了,到时候回来看具体设置了什么参数,因为我看的代码比较新,之前版本的还有没有的参数。

Continue

今天折腾了一天的ubuntu系统,先是18.04对于为这个电脑好多硬件不支持,声音,GPU都不行。决定升级20.04,20.04支持硬件驱动,但是从18.04到20.04升级太曲折了,升级完系统,wifi和声音都有问题,导致进不了系统,刚开始为切换到shell,禁止加载mod也是不行。 最后竟然发现进入恢复模式后,再切换到正常启动就能进入桌面了。恢复模式也提示了,桌面环境有的可能需要正常启动才能使用。为这个可能没正常启动,导致一些检测跳过了吧。后来装显卡驱动,升级了内核版本,然后突然间就好了。不知道为啥升级系统的版本的时候不给我直接升级内核版本。 哦对,不正常启动的时候,竟然cpu不太高,风扇呼呼转,不知道咋回事。正常了后也正常了。日志里的报错也没啥用,直到是wifi和声音mod的问题,但是没办法解决。 正常后的20.04的界面还挺好用,很流畅,也比之前好看多了。 开始界面调整外观风格没有变化,后来发现需要升级一下桌面,apt install ubuntu-desktop就可以了。 sudo lspci | grep -i nvidia 这个命令查看显卡信息的时候,因为没有显示,网上找了一个网站能通过id查询。 http://pci-ids.ucw.cz/mods/PC/10de?action=help?help=pci url里的id是供应商id 再后来,帖子看多了,发现可以直接升级本地pci数据库。看来这电脑还真是硬件配置新啊。 sudo update-pciids 显卡驱动最后也没安装成功,懒得折腾了,暂时也用不到显卡的特殊功能,先这样吧。

Continue

最近又在写ansible相关的东西,因为得集成python项目,我开始都想之间命令方式调用ansible了。因为之前搞了好几个版本的ansible集成,每次都是大折腾一段时间,而且最早的时候,因为要集成或者解决问题,需要查看ansible源码,发现就是一坨。我好像不止一次跟别的同事说ansible是看过的最垃圾的开源代码。 最近又开始折腾了,虽然封装的接口还是不好用,但是看源码和修改给的example,最起码折腾起来轻松一点点了。源码也写的比之前好太多了。 playbook这玩意更坑,可能也是我写的不太多。

Continue

面试面到这个问题,以前只知道dba大概用的啥工具,从来没想自己搞过,现在面试要求有这方面技能,回答的不是太好,我只知道通过binlog可以支持异步同步,具体不知道怎么做。配置软件的事还要问,也是醉了。 先搞最简单的模式,mysql自带的replication,这个应该就是最普通读写分离的主从模式了,可以一写多读。流量不高还是可以的,然后需要加一下主备,我看之前一般是通过keepalived去做的,多主这种一般使用percona的工具去做的,支持强一致的模式,这些都没搞过。我看mysql文档,mysql支持innodb集群,支持多主,这个文档还没看,后面再研究。还提到一个NDB Cluster。 我的mysql是安装的8.0.26,看官网不但支持普通的replication模式,通过binlog日志和同步的位置来同步,还支持global transaction identifiers (GTIDs) 的模式,这个replication模式不需要binlog了,看名字是事务相关。相关的文档还没看,只是先走了一下普通的模式。 首先,需要设置实例的server_id,这个需要集群里唯一,可在/etc/my.cnf里面加一条 [mysqld] server-id=142 主从库都需要配置。 主库需要开启binlog,这个默认是开启的。从库视情况,如果需要作为别的从库的主库,也是必须要开启的。 从库需要配置一下relay-log,默认是按照主机名配置的,说是防止主机名变动,导致错误。 relay-log=/var/lib/mysql/re-relay-log relay-log-index=/var/lib/mysql/re-relay-log.i 创建用于同步的专属用户 mysql> CREATE USER 'repl'@'%.example.com' IDENTIFIED BY 'password'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.example.com'; 官网说,这个用户的密码是明文保存在从库中的,所以为了安全还是有必要创建一个的。 然后需要确定binlog同步的位置 先在主库加表的读锁,这样会阻塞写事务的提交。 mysql> FLUSH TABLES WITH READ LOCK; 新启动一个mysqlsession,执行SHOW MASTER STATUS,查看binary log的文件名和位置。文档说如果之前主库禁止了binlog,这个命令会返回空,在后边需要用到这俩值的时候,文件名为'',位置为4 释放锁的命令, UNLOCK TABLES; 最后一步是涉及在从库配置刚刚日志位置信息和主库信息。分两种情况,一种是新搭建的集群,另一种是主库本来有数据的情况。 我是刚搭建的环境,先用第一种。不同版本的mysql有两种方式,从8.0.23版本开始使用下面的语句 CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.1.11.142', SOURCE_USER='repl', SOURCE_PASSWORD='123456', SOURCE_LOG_FILE='binlog.000001', SOURCE_LOG_POS=1012; 使用START REPLICA 启动同步 查看从库状态: show slave status\G Slave_IO_Running: Yes Slave_SQL_Running: Yes 这两个状态为yes基本就没啥问题了 第二种情况,需要手动先把已有的数据从主库同步到从库中,其他一致。官方推荐使用mysqldump,特别是使用innodb引擎的时候。这种模式需要保持表锁不释放,不能退出session。 mysqldump 添加--master-data参数会包含CHANGE REPLICATION SOURCE 语句。然后导入到从库中。文档说有mysql插件可以方便做到数据迁移和从库配置。 又大概看了一些replication实现的文档,主实例有一个dump线程, SHOW PROCESSLIST里为Binlog Dump。从库两个线程,一个线程接受主库的dump线程的数据,写到单独日志文件,上边状态的Slave_IO_running为这个线程状态。一个线程应用前一个线程的relay日志的线程。多从的情况,主库会为每个从库配置一个dump线程。 复制的数据格式,有三种模式,一种基于语句的( statement-based replication),这种的在特定语句引擎会造成数据不一致。默认是基于行数据的( row-based logging),这种好像是复制更改内容的。还有一种是混合模式,是前两种的结合。

Continue

本来以为很快安装完了,没想到安装过程中缺少不少文件,就决定再记录一下吧。 看系统软件库里版本太低,我就想直接源码编译安装。官网下载了2.4.3的版本。 编译命令:make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1 USE_SYSTEMD=1,这个是开启所有模式的编译方式,可看INSTALL文件配置 需要安装gcc:yum install gcc.x86_64 需要pcre:yum install pcre-devel.x86_64 需要openssl: yum install openssl.x86_64 openssl-devel.x86_64 需要安装lua,需要5.3版本以上,我从lua官网下载了5.4.3版本,可以直接make后,指定lua目录。make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1 USE_SYSTEMD=1 LUA_INC=/opt/source/lua-5.4.3/src/ LUA_LIB=/opt/source/lua-5.4.3/src/ 需要systemd-dev:yum install systemd-devel.x86_64 然后我现在记录才发现,就是参数指定的都需要额外安装的软件。 haproxy 配置文件 mkdir /etc/haproxy cp examples/option-http_proxy.cfg /etc/haproxy/haproxy.cfg 配置systemd cd admin/systemd/ make 会生成一个haproxy.service,我看就执行了替换bin目录 cp haproxy.service /usr/lib/systemd/system/ systemctl enable haproxy 直接start还是有问题,日志查看错误,需要改一下默认的配置文件和设置ulimit。 具体的详细配置还没看,只先瞟了一眼logging的配置。

Continue

最近接入他们大学的课题程序,很多都是用matplotlib画图,展示最终的精确度之类的。 然后我用pyenv+virtualenv安装那些程序的依赖,然后matplotlib需要_tkinter,这个还需要系统安装,虽然能装,但是挺费劲,还有种方式可能需要重新编译python,也是麻烦。网上搜索发现可以不使用的方法,每次装一次找一次,决定记录一下了。 直接import matplotlib.pyplot as plt 会报错ImportError: No module named _tkinter, please install the python-tk package 一般都是用plt.show()方式直接展示。我给改成plt.savefig()报错图片了。 网上找到的方法 在import之前加入两行:import matplotlib matplotlib.use('agg') 然后就可以了。好像是选了matplotlib里gui别的显示方式,就不依赖_tkinter了

Continue

安装没啥坑,提示还挺好,照着官方文档安装,基本都是回车:http://9p.io/wiki/plan9/installation_instructions/ 踩了三个坑, 一个是我选文件系统的时候选的fossil+venti ,硬盘选了2G,然后自动分区的时候可能把fossil分区的太少,复制文件的步骤太慢,而且各种报错,太慢了我感觉不堆,我又重启复制,报不同的错,最后才提示磁盘不足。我又重新开了个10g的硬盘,然后就可以了。 开始我还以为选择的镜像路线不对,然后发现可以ctrol+d退回到主菜单。 之后复制不到一分钟就复制完了,这个才是现代机器的速度嘛。然后重启后,输入用户名那里,提示的是none,我还以为进去创建文件,没想到的是需要输入默认用户名glenda,这个在安装文档里有,我后来报错才去看的文档。 放一张启动后的界面吧,感觉ui挺好看,就是还不成熟,vb中bug还挺多的。 我还看了点官方介绍,感觉备份那个思想现在Windows,mac应该都有,还有远程文件系统现在也都有,应该没啥新内容。待发掘

Continue

plan9可能有点古老了,看官网是80年代的产物,感觉那时候还没有操作系统垄断,dos可能也就刚出来,Windows还不知道在哪。今天想起来了,我又找了篇文章看了看plan9的介绍,反而激起了我对plan9的兴趣,感觉有些理念可以借鉴。被垄断后的思维就会狭隘,偏见,开开视野也是好的。 感觉好多古老的玩意还挺有意思的,比如老早之前知道,磁芯大战(core war or core wars),细胞自动机(cellular automata),《一种新科学》(A New Kind of Science)Stephen Wolfram。(这本书大体看了一下,有些思想我之前倒是想过,却没有这么深入细致的去研究) 记几个关键字,后边研究一下 装一下panl9操作系统,配置看一下那些特性,代码应该不会看。 Sam 和 Acme编辑器大体看看。 顺带知道一个操作系统Oberon,发现搜着看着东西越来越多了。 最近又看了篇文章,加深了对erlang的理解,之前还学过erlang语法,有时间再看看vm。 立了flag,不知道能不能看,发现要弄的东西不懂就难搞,不知道能不能坚持下来。下午有时间把plan9装一下。

Continue