Linux内核架构与底层--读书笔记

linux中管道符“|”的作用

命令格式:命令A|命令B,即命令1的正确输出作为命令B的操作对象(下图应用别人的图片)

 

1. 例如: ps aux | grep "test"  在 ps aux中的結果中查找test。

2. 例如:   find . -name "*.txt" | xargs grep "good" -n --color=auto   把find的结果当成参数传入到grep中,即在那些文件内部查找good关键字。

注:本例中xargs将find产生的长串文件列表拆散成多个子串,

        如“”find /path -type f -print0 | xargs -0 rm

             xargs将 find产生的长串文件列表 拆散成多个子串,然后对每个子串调用 rm  
     xargs 可能就会误判了,如果需要处理特殊字符,需要使用-0参数进行处理。
    选项解释
    -0 :当sdtin含有特殊字元时候,将其当成一般字符,想/'空格等

2.1 Linux的文件系统

Linux将所有的事物都看成文件,这一点人尽皆知。我想说的是,除了传统的ext文件系统,Linux在抽象不同的资源的时候其实有各种不同的文件系统,都是从需求和使用出发,怎么方便怎么来,比如proc文件系统就是针对进程的抽象,使得修改对应进程的值就可以直接改变进程的行为。再比如,对于远程ssh登录的pts设备,Linux有对应的devpts文件系统。

2.2 Linux的权限管理

Linux的-rwxrwxrwx权限管理也可谓人尽皆知,其实Linux自己也意识到了这样的权限管理所带来的一些局限性。首先rwx的权限管理是基于用户和组的,并且只是大致的分为owner|group|other这三类,无法再作更加细粒度的划分。有鉴于此,Linux目前默认是有ACL(Access Control List)管理的,所谓ACL就是能够提供更加细粒度的用户和组管理,比如可以明确哪个user可以有什么样的权限。如下示例

?
1
2
3
4
5
6
7
8
9
getfacl abc
# file: abc
# owner: someone
# group: someone
user::rw-
user:johny:r-x
group::r--
mask::r-x
other::r--

而SELinux提供了不基于用户与组的权限管理,SELinux是基于应用程序的,什么样的应用程序可以使用什么资源,对于这些资源这个应用程序能干嘛,这个就是SELinux的管理方式。

2.3 Linux上的Service

Linux上的Service组织得非常清晰,当然也是传统所致。/etc/init.d/里面包含了所有的Service启动脚本,对应的二进制文件在/usr/bin 、 /usr/sbin 、 /usr/local/bin等目录下,一般而言配置文件在/etc/app_name下,还有一个chkconfig的工具来管理各个runlevel下需要启动的Service。这样的约定俗成使得管理员在配置和使用的时候非常方便。Linux标准的Service都会将log记录到/var/log/messages中,使得系统管理员不需要翻阅各种log,直接在/var/log/messages中就可以找到绝大部分的log来判断当前系统是否正常。更甚的,syslogd被rsyslogd替换以后,可以将/var/log/messages中的内容通过UDP发送到远端用专业的log分析工具进行分析。我们需要学习Linux上Service的这些优秀的编程习惯和技巧。

3 磁盘

根据$1中的需求,主要是创建Linux下的LVM,以及一些基本的磁盘操作。

  • df -lah 查看磁盘的使用情况
  • fdisk -l 查看插入到磁盘驱动器中的硬盘; sd(a,b,c)(1,2,3),其中a是第一块磁盘,b是第二块磁盘,1,2,3表示磁盘上的主分区,最多4个。用fdisk从磁盘创建分区并且格式化。
  • LVM(logical volume manager),主要就是满足加硬盘就能直接写数据的功能,而不会出现磁盘满了,然后挂了。lvm有几个概念,VG, PV, LVM,将磁盘lvm格式化,创建PV, 创建VG,将创建的PV加入VG,然后在VG中创建lvm,然后就可以动态增加大小了。注意,将磁盘格式化为lvm,但是lv的格式化需要用ext,然后才能mount上去。参考这篇文章CentOS 6 卷组挂载硬盘教程
  • mount -t type(ext4|nfs) /dev/sdxn /path/dir 来挂载。如果要重启生效,必须将挂载信息写入到/etc/fstab
  • 磁盘IO效率(IOPS)需要用vmstat, top等工具来查看。

4 网络

网络的坑很多,需要把网络搞通没个3,4年很难。下面从网络的基本配置文件着手,简单理一下网络方面的内容。网络最难的方面应该是如何搭建一个合理的高效的局域网或者城域网,这个需要有专业的网络知识。

4.1 配置文件

/etc/hosts私有IP对应主机名
/etc/resolv.confnameserver DNS的IP
/etc/sysconfig/network其中NETWORKING=要不要有网络,HOSTNAME=主机名,NETWORKING_IPV6=支持ipv6否
/etc/sysconfig/network-scripts/ifcfg-xxx其中DEVICE=网卡代号,BOOTPROTO=是否使用dhcp,HWADDR,IPADDR,NETMASK,ONBOOT,GATEWAY
4.2 网络设计到的一些命令

router -n查看路由的命令,特别是要看带G的,表示gateway,而带U的表示up。
netstat -anp查看所有启动的tcp,udp,unix stream的应用程序,以及他们的状态,具体可以参考TCP/IP,JavaSocket简单分析一文。
5 安全

5.1 PAM

PAM总体来讲只需要简单了解就行,是一个可插拔的认证模块。按照我的说法,是开发Linux的极客们搞出来的可复用的一个组件。举个例子,现在有一个app,想要验证当前的登录用户是否有权限操作某个目录,那么在PAM里面有现成的模块,app只需要include这个模块,给出一个配置文件,就可以了。有一个非常好的关于PAM的视频教程,请看这里

  • PAM是应用程序用来进行身份验证的。早期的身份验证和应用程序本身耦合,后来把身份验证单独抽出来,通过PAM来进行管理
  • /etc/pam.d/xxx 是能用pam来进行管理的应用程序PAM设置,在安装应用程序的时候安装。/etc/security/mmm, /lib/security/pam_mmm是一套。
  • 总体来说PAM是利用Linux系统本身提供的机制,来进行验证

5.2 SELinux

关于SELinux也有一个非常好的视频教程,请看这里

  • getenforce来查看SELinux是否被启用
  • /etc/sysconfig/selinux enforcing启用SELinux
  • SELinux对“运行程序”配置和检查其是否有权限操作“对象”(文件系统),而普通的ACL(rwx)就是根据文件所属owner及其组来判断。SELinux是看bin的type和目录文件的type是否兼容,来决定bin是否能操作资源

5.3 防火墙

对于iptables也是一知半解,所以下面只是学习时候的一些摘录。特别一点,要开启内核参数net.ipv4.ip_forward=1,在/etc/sysctl.conf文件中,用sysctl -p来保存。所谓ip_forward指的是内核提供的从一个iface到另外一个iface的IP包转发,比如将IP包从192.168.1.10的eth0转发到10.0.0.123的eth1上。专业的防火墙配置是需要专业技能的。

tcp_wrapper需要libwrap.so的支持,所有凡是ldd出来没有的bin,都不能用tcp_wrapper
iptables是按照规则进行短路判断的,即 满足条件1->执行action1->结束
iptables-save来更加清晰的查看
先删掉全部规则,然后添加,比较简单。添加的时候,先添加策略,再添加细部规则。一般来讲,我们需要关注的是filter这个表的INPUT与OUTPUT
iptables -A(I) INPUT(OUTPUT,FORWARD) -i(o) iface -p tcp(ump,imp,all) -s (!)source -d dest -j ACCEPT(REJECT,DROP), 还支持的参数 —dport —sport
6 工具

一个好的Linux命令参考网站

6.1 CPU

  • top 特别注意load
  • ps aux和ps -ef 特别注意进程状态
  • vmstat 1表示每秒采集一次
  • sar -u 1 查看所有cpu相关的运行时间

6.2 Memory

  • free
  • vmstat 1 注意其中的swap ram block之间的关系
  • sar -r 1 内存使用率
  • sar -W 1 查看swap,查询是否由于内存不足产生大量内存交换

6.3 IO

  • lsof -i:port 查询哪个进程占用了这个端口号
  • lsof -u username 用户打开的文件
  • lsof -p pid 进程打开的文件
1、内核架构
常见架构范式:
  • Linux内核上下层通信方式
  • 横向系统和纵向系统
横向系统如cgroup,proc,sys文件系统,系统调用的组织,调试系统,Core Dump,信号,内存管理等;
纵向系统是指具体的功能模块,如USB功能,一个对USB文件的操作要走完内核中的很多个层次,即文件系统层、缓存层、通用块层、SCSI层、USB层等。Linux一般将这些层次划分为3个大的层次,接口层、功能逻辑层和驱动层。
2、模块支持
  • 模块是Linux支持动态功能扩展的最主要机制。
  • 模块可以在编程时指定其可以接受的参数,这个参数是给用户用的。在模块加载之后,用户空间通过"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}"就可以动态修改模块参数。
  • 模块机制存在的意义就是可以动态的加载和卸载。
  • 模块签名,每个模块在编译时都会从内核目录中获得版本号写入编译的模块,运行中的内核在插入新的模块时会检测签名是否一致,若不一致就不会加载。可以使用modinfo查看模块签名信息。模块签名的内容有两部分:版本号、哈希签名
  • 模块编程可使用的内核组件:workqueue,Linux下的工作队列,可以将工作推后执行,对其进行睡眠、调度,系统有默认的workqueue内核线程,但也支持用户自己定义workqueue;中断系统和tasklet,中断亲合度可以用于应用运维工作中帮助锁定应用性能。
3、特殊软件机制
  • UIO,允许用户端直接访问设备细节,是一个在用户端实现内核驱动的机制。
  • VFIO,是软件对硬件设备内存暴露在用户空间的支持,是对UIO的升级。用户可以通过直接操作硬件的内存空间来操作硬件。
  • SysRq,类似于windows的Ctrl+Alt+Del组合键的效果,只要系统不是完全被锁死的状态,就会优先响应这个命令。
在Linux中可以控制SysRq的关闭和打开,使用echo "1" > /proc/sys/kernel/sysrq打开该机制。
在Linux中调用该系列命令的方式是“SysRq+命令”,SysRq在大部分键盘上一般是Print Screen按键的副功能,需要使用Alt键调用。
SysRq+b:立即重启系统
SysRq+c:产生一个系统级的crash dump
SysRq+d:显示当前使用中的所有锁
SysRq+e:发送SIGTERM给除init之外的全部进程
除以上之外还有十几个类似命令
  • 其他机制,PADATA,namespace
4、内核数据结构之链表与哈希表
  • 链表,具有弹性不动属性,可以把离散时间到达的数据结构串起来,使其可以更容易地被索引,并且不需要移动之前的内容。
  • 内核哈希表,是由链表群组成的,其每一个哈希桶都是一个链表。
  • 双向链表,其数据域一般包括prev、next与data,很容易做成一个环。
  • hlist,拥有只有一个指针大小的头部的双向链表(只使用一个头部,解决哈希桶的空间利用率问题)。
  • ScatterList,在DMA支持分离的多块内存同时的传输下所产生的一种软件结构,其表示的是多块分离的块内存。Linux允许对ScatterList进行拼接或合并。
  • llist,一种不需要加锁的list,这是内核出于提高处理效率而采用的一种无锁操作所使用的数据结构。
 
5、其它数据结构
  • B+树,Linux内核中实现了一个通用的B+树,主要用于文件系统中,当然也有一些文件系统是自己实现的类似的B+树。
  • radix tree树,内核中使用该数据结构将指针与long整数键值进行关联,例如IDR机制,并且具有很高的搜索效率。
  • 位数组bitmap,是以位为单位存储值的方式,大部分文件系统都用到了这一技术。如ext中使用inode位图和数据块位图,用来表示对应序号的inode或者数据块有没有被使用。在raid系统中,如raid1的数据一致性保障,会通过检查这样的一份位图,以发现两份数据的不一致问题。
  • FIFO,命名管道,是内核提供给用户空间的一个非常好用的工具,相当于一个跨进程的队列,提供了原生的阴塞和配合文件能力的工具。类似的能力也可以使用消息队列或UNIX domain socket来实现。FIFO文件还有一个特性,它是一个文件,即使没人在读取,也可以往文件里写内容。
  • FIFO文件在交互式shell中是非常有效的一种调试工具,使用mkfifo命令建立fifo文件。在阻塞模式下,一方保持cat该文件,如果没有数据就会一直阻塞在那里;若有一方使用了echo等向其写入了数据,cat就会立即执行读取数据。
  • 在Linux中,FIFO管道并没有专门的数据结构,而是通过将两个file结构指向同一个临时的VFS索引节点inode,而这个VFS索引节点又是指向一个物理页面而实现的。在写入FIFO文件的时候最好不要使用文件的缓存功能,要一次性地完整写入。
  • FIFO的使用并不容易,对于一个严肃的FIFO应用场景来说,需要满足以下使用条件:
跨进程传输数据
数据的产生和数据的监听不同步
数据只要被读取了就会被删除,第二次就不会被再次读取
需要等待超时、永久阻塞、立即返回其中的某些或全部特性
需要运维系统查看数据流
没有任何办法提前判断要读的阻塞式的FIFO内是否有数据

常见知识点总结

1.date -s 日期设置

[root@localhost ppp]# date -s 2015-7-5

2015年 07月 05日 星期日 00:00:00 CST

2.date -d 时间的设置

[root@localhost ppp]# date -d 3:45:45

2015年 07月 05日 星期日 03:45:45 CST

3.hwclcok -s 硬件时钟同步系统时钟

[root@localhost ppp]# date

2015年 07月 05日 星期日 00:03:28 CST

[root@localhost ppp]# hwclock -s

[root@localhost ppp]# date

2016年 03月 28日 星期一 03:07:49 CST

4.hwclock - w 系统时钟同步硬件时钟

[root@localhost ppp]# hwclock -w

[root@localhost ppp]# date

2015年 04月 05日 星期日 00:00:24 CST

5.bash中的引用:

'':强引用

"":弱引用

``:命令引用

6.通配符练习

(1) 显示/etc目录下,以非字母开头,后面跟了一个字母及其它任意长度任意字符的文件或目录; 

 [root@localhost /]# ls -d /etc/ [^[:alpha:]][a-z]*

ls: 无法访问[^[:alpha:]][a-z]*: 没有那个文件或目录

/etc/

(2)复制/etc目录下,所有以n开头,以非数字结尾的文件或目录至/tmp/etc目录下;

[root@localhost /]# mkdir /tmp/etc

[root@localhost /]# cp -r /etc/n*[^0-9] /tmp/etc

[root@localhost /]# ls -ld /tmp/etc

drwxr-xr-x. 3 root root 4096 4月   5 00:54 /tmp/etc

(3)显示/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录

[root@localhost etc]# ls -ld /usr/share/man/man[0-9]

drwxr-xr-x. 2 root root  69632 3月  28 2016 /usr/share/man/man1

drwxr-xr-x. 2 root root  20480 3月  28 2016 /usr/share/man/man2

drwxr-xr-x. 2 root root 495616 3月  28 2016 /usr/share/man/man3

drwxr-xr-x. 2 root root   4096 3月  28 2016 /usr/share/man/man4

drwxr-xr-x. 2 root root  20480 3月  28 2016 /usr/share/man/man5

drwxr-xr-x. 2 root root   4096 3月  28 2016 /usr/share/man/man6

drwxr-xr-x. 2 root root  12288 3月  28 2016 /usr/share/man/man7

drwxr-xr-x. 2 root root  36864 3月  28 2016 /usr/share/man/man8

drwxr-xr-x. 2 root root   4096 9月  23 2011 /usr/share/man/man9

(4)复制/etc目录下,所有以p,m,r开头的,且以.conf结尾的文件或目录至/tmp/conf.d目录下;

[root@localhost etc]# mkdir /tmp/conf.d

[root@localhost etc]# cp -r /etc/[pmr]*.conf /tmp/conf.d

[root@localhost etc]# ls -ld /tmp/conf.d

drwxr-xr-x. 2 root root 4096 4月   5 01:02 /tmp/conf.d

7.程序的数据流有三个:

输入数据流: <--,标准输入(stdin),键盘;  stdin=0

输出数据流:-->,标准输出(stdout), 显示器; stdin=1

错误数据流:-->,错误输出(stderr),显示器;  stdin=2

8.输出重定向知识点:

COMMAND >  /PATH/TO/SOMEFILE

覆盖重定向:覆盖目标文件中的原有内容; 

例如:touch liwenming

      cat /etc/fstab > liwenming 

COMMAND >> /PATH/TO/SOMEFILE

追加重定向:追加新产生的内容至目标文件尾部;

      cat /etc/fstab >> liwenming 

9.管道知识点总结练习:

(1)把/etc/passwd文件最后三行信息中所有小写字符改为大写后输出;

[root@localhost /]# tail -n 3 /etc/passwd | tr "a-z" "A-Z"

SSHD:X:74:74:PRIVILEGE-SEPARATED SSH:/VAR/EMPTY/SSHD:/SBIN/NOLOGIN

TCPDUMP:X:72:72::/:/SBIN/NOLOGIN

LWM:X:500:500:LWM:/HOME/LWM:/BIN/BASH


(2)取出/etc/fstab的第6行;

[root@localhost /]# head /etc/fstab | tail -1

NI HOA MA 

(3)取出/etc目录下所有以p开头的文件或目录,只显示前5个;

[root@localhost /]# ls -d /etc/p* | head -n 5

/etc/pam.d

/etc/pango

/etc/passwd

/etc/passwd-

/etc/pbm2ppa.conf

(4)tee命令,指的是双向输出,输出屏幕然后保存到文件中一份。

[root@localhost /]# echo lilili | tee li

lilili

(5)为用户提供默认配置的配置文件

/etc/login.defs, /etc/default/useradd


(6)把用户添加到组中,把用户移除组中

[root@localhost /]# useradd ming

[root@localhost /]# gpasswd -a ming li

Adding user ming to group li

[root@localhost /]# gpasswd -d ming li

Removing user ming from group li

(7)创建用户gentoo,UID为5000,基于组为gentoo,附加组为distro和peguin;

root@localhost /]# gpasswd -a gentoo distor 

gpasswd: group 'distor' does not exist in /etc/group

[root@localhost /]# gpasswd -a gentoo peguin

Adding user gentoo to group peguin

[root@localhost /]# gpasswd -a gentoo distor

gpasswd: group 'distor' does not exist in /etc/group

[root@localhost /]# gpasswd -a gentoo distro

Adding user gentoo to group distro

[root@localhost /]# 

(8)创建用户fedora,基于注释信息为"Fedora Core",默认shell为/bin/tcsh

 useradd -s /bin/tcsh fedora -c "Fedora Core"

 查看结果  cat /etc/passwd

[root@localhost etc]#useradd gentoo

[root@localhost etc]# useradd -g gentoo -G distro peguin

[root@localhost etc]# cat /etc/group

distro:x:1006:gentoo,peguin

(9)逻辑运算知识点总结

逻辑运算:

运算数:true, false

COMMAND:

0: TRUE

1-255: FALSE

与:

true && true = true

true && false = false

第一个操作数为true,其结果将取决于第二个操作数;

false && true = false

false && false = false

第一个操作数为False,其结果至此可断定,为false;

或:

true || true = true

true || false = true

第一个操作数为true,其结果至此可断定,为true;

false || true = true

false || false = false

第一个操作数为false,其结果将取决于第二个操作数;

非:

! true = false

! false = true 

(10)特殊变量:

$0:脚本文件路径本身;

$#;脚本参数的个数;

$*:所有参数

$@:所有参数 

(10)

内核编译过程:

步骤:

~]# tar  xf  linux-3.10.67.tar.xz  -C  /usr/src  将其内核源码压缩包进行解压,然后指明解压到的目录。

~]# cd  /usr/src 然后进入这个目录

~]# ln  -s  linux-3.10.67  linux   将其解压的文件做一个链接,链接到linux

~]# cd  linux  进入linux目录

~]# make menuconfig        进行配置内核选项

~]# make  [-j #] 编译内核,可使用-j指定编译线程数量,例如:make -j 4

~]# make modules_install 安装内核模块

~]# make install                进行内核的安装

猜你喜欢

转载自www.cnblogs.com/klb561/p/9027087.html