分享
史蒂夫·乔布斯(Steve Jobs):“假设你可以缩短10秒钟的开机时间,把这个乘上500万,那就是每天5000万秒了。一年下来大概是好几十辈子的时间。想想看,如果你可以让开机速度快10秒钟的话,就拯救了数十条生命。这很值得啊,你不觉得吗?” 《硅谷革命:成就苹果公司的疯狂往事》
Startup Messages
有两种方式可以查看内核引导和运行诊断信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
[root@li1437-101 ~]# dmesg [ 0.000000] Linux version 4.9.7-x86_64-linode80 (maker@build) (gcc version 4.7.2 (Debian 4.7.2-5) ) #2 SMP Thu Feb 2 15:43:55 EST 2017 [ 0.000000] Command line: root=/dev/sda console=tty1 console=ttyS0 ro devtmpfs.mount=1 [ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' [ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' [ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers' [ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256 [ 0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format. [ 0.000000] x86/fpu: Using 'eager' FPU context switches. [ 0.000000] e820: BIOS-provided physical RAM map: ……. [ 0.000000] NX (Execute Disable) protection: active [ 0.000000] SMBIOS 2.8 present. [ 0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014 [ 0.000000] Hypervisor detected: KVM …… [ 0.371925] raid6: sse2x1 gen() 7490 MB/s [ 0.428689] raid6: sse2x1 xor() 5953 MB/s [ 0.485463] raid6: sse2x2 gen() 9289 MB/s [ 0.542230] raid6: sse2x2 xor() 6754 MB/s [ 0.599013] raid6: sse2x4 gen() 10954 MB/s [ 0.656189] raid6: sse2x4 xor() 5522 MB/s [ 0.656943] raid6: using algorithm sse2x4 gen() 10954 MB/s [ 0.657588] raid6: .... xor() 5522 MB/s, rmw enabled …… [ 1.053697] Netfilter messages via NETLINK v0.30. [ 1.054471] nfnl_acct: registering with nfnetlink. [ 1.055332] nf_conntrack version 0.5.0 (8192 buckets, 32768 max) [ 1.056324] ctnetlink v0.93: registering with nfnetlink. [ 1.057335] nf_tables: (c) 2007-2009 Patrick McHardy [ 1.058393] nf_tables_compat: (c) 2012 Pablo Neira Ayuso [ 1.059599] xt_time: kernel timezone is -0000 [ 1.060296] ip_set: protocol 6 [ 1.060791] IPVS: Registered protocols (TCP, UDP, SCTP, AH, ESP) [ 1.061940] IPVS: Connection hash table configured (size=4096, memory=64Kbytes) [ 1.063162] IPVS: Creating netns size=2104 id=0 [ 1.064139] IPVS: ipvs loaded. …… [ 1.744221] systemd[1]: Detected virtualization kvm. [ 1.745058] systemd[1]: Detected architecture x86-64. [ 1.747402] systemd[1]: Set hostname to [ 1.834328] tsc: Refined TSC clocksource calibration: 2800.119 MHz [ 1.835512] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x285cb16f950, max_idle_ns: 440795333193 ns [ 1.843476] systemd[1]: Created slice Root Slice. [ 1.844251] systemd[1]: Starting Root Slice. [ 1.845835] systemd[1]: Created slice System Slice. [ 1.846631] systemd[1]: Starting System Slice. [ 1.848257] systemd[1]: Listening on udev Kernel Socket. [ 1.849119] systemd[1]: Starting udev Kernel Socket. [ 2.014715] EXT4-fs (sda): re-mounted. Opts: (null) [ 2.038202] systemd-journald[2010]: Received request to flush runtime journal from PID 1 [ 2.241341] audit: type=1305 audit(1488188850.897:2): audit_pid=2215 old=0 auid=4294967295 ses=4294967295 res=1 [ 2.287758] Adding 262140k swap on /dev/sdb. Priority:-1 extents:1 across:262140k FS [ 2.905177] IPVS: Creating netns size=2104 id=1 [ 2.954613] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready [ 2.955987] 8021q: adding VLAN 0 to HW filter on device eth0 [ 8.009765] random: crng init done |
在故障排查中,dmesg信息需要首先查看,例如输出最近10条系统信息,
可以查看到引起性能问题的错误。
1 2 3 4 5 6 7 8 |
$ dmesg | tail [1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0 [...] [1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child [1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-r ss:0kB [2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP cou nters. |
Kernel initialization and Boot Options
在启动时,Linux内核初始化的顺序如下:
文件/proc/cmdline记录了系统内核启动参数:
1 2 |
[root@li1437-101 ~]# cat /proc/cmdline root=/dev/sda console=tty1 console=ttyS0 ro devtmpfs.mount=1 |
查看运行级别:
1 2 3 |
[root@li1437-101 ~]# who -r run-level 3 2017-02-27 09:47 [root@li1437-101 ~]# |
用户空间启动顺序:
init(initialization的简写)是 Unix 和 类Unix 系统中用来产生其它所有进程的程序。它以守护进程的方式存在,其进程号为1。Linux系统在开机时加载Linux内核后,便由Linux内核加载init程序,由init程序完成余下的开机过程,比如加载运行级别,加载服务,引导Shell/图形化界面等等。
1 2 3 |
[root@li1437-101 ~]# ps -ef | grep init root 1 0 0 Feb27 ? 00:03:05 /sbin/init root 28683 28663 0 02:44 pts/0 00:00:00 grep --color=auto init |
1 2 3 4 5 6 7 8 9 |
// Mac OS bash-3.2$ ps -ef | grep init 0 243 1 0 15 517 ?? 0:00.74 /System/Library/CoreServices/CrashReporterSupportHelper server-init 0 533 1 0 15 517 ?? 0:02.07 /System/Library/CoreServices/SubmitDiagInfo server-init 501 52150 1 0 日01下午 ?? 0:15.49 /usr/libexec/secinitd 0 69864 1 0 11:35上午 ?? 0:00.20 /usr/libexec/secinitd 0 72830 1 0 1:51下午 ?? 0:00.19 /usr/libexec/secinitd Darwin ACA80166.ipt.aol.com 16.5.0 Darwin Kernel Version 16.5.0: Fri Mar 3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64 bash-3.2$ |
在Linux发行版中,init有三种主要的实现形式:
Android 和 BSD (运行存放于’/etc/rc’的初始化 shell 脚本)也有它们自己的init版本,一些发行版也将System V init 修改为类似BSD风格的实现。目前大部分Linux发行版都已采用新的systemd替代System V和Upstart,但systemd向下兼容System V。
System V init: 存在一个启动序列,同一时间只能启动一个任务,这种架构下,很容易解决依赖问题,但是性能方面要受一些影响。
systemd is goal oriented. : 针对System V init的不足,systemd所有的服务都并发启动。systemd时基于目标的,需要定义要实现的目标,以及它的依赖项。systemd 将所有过程都抽象为一个配置单元,即 unit。可以认为一个服务是一个配置单元;一个挂载点是一个配置单元。
Upstart is reactionary.:Upstart是基于事件的,Upstart的事件驱动模型允许它以异步方式对生成的事件作出回应。
System V init Vs UpStart Vs Systemd
Linux内核不能通过访问PC BIOS 或者 EFI接口从磁盘获取数据,所以为了mount它的root filesystem, 对于底层存储需要驱动程序支持。解决方案是在内核运行之前,由boot loader加载驱动模块及工具到内存。在启动时,内核读取相关模块到一个临时的RAM filesystem(initramfs),挂载在/根目录,initramsfs允许内核为真正的root filesystem加载必要的驱动模块。
最后,再挂载真正的root filesystem、启动init。
Linux在很多场景下都需要创建一个基于内存的文件系统,提供一个可以接近零延迟的快速存储区域。目前有两类主要的RAM磁盘可用,她们个有优劣:ramfs和tmpfs。(注意:创建之前可以使用 free 命令查看未使用的RAM)
1 2 3 4 |
# mkdir /mnt/ramdisk # mount -t tmpfs -o size=512m tmpfs /mnt/ramdisk # vi /etc/fstab #tmpfs /mnt/ramdisk tmpfs nodev,nosuid,noexec,nodiratime,size=1024M 0 0 |
电子书《Linux Perf Master》
How Linux Works
动态追踪技术