Linux 中的三个特殊进程
Linux 下有 3 个特殊的进程:
idle 进程 (pid = 0);
init 进程 (pid = 1),Redhat/CentOS 中就是 systemd 进程;
kthreadd (pid = 2)。
idle 进程,pid = 0
由系统自动创建, 运行在内核态;
pid = 0,其前身是系统创建的第一个进程;
唯一一个没有通过 fork 或者 kernel_thread 产生的进程;
完成加载系统后,演变为进程调度、交换;
init 进程(pid = 1)
init 进程由 idle 通过 kernel_thread 创建,在内核空间完成初始化后, 加载 init 程序, 并最终用户空间;
由 0 进程创建,完成系统的初始化。它是系统中所有其它用户进程的祖先进程;
Linux 中的所有进程都是由 init 进程创建并运行的 - 首先 Linux 内核启动,然后在用户空间中启动 init 进程,再启动其他系统进程。在系统启动完成完成后,init 进程将变为守护进程,监视系统其他进程。
kthreadd 进程(pid = 2)
kthreadd 进程由 idle 通过 kernel_thread 创建,并始终运行在内核空间, 负责所有内核线程的调度和管理;
它的任务就是管理和调度其他内核线程 kernel_thread, 会循环执行一个 kthread 的函数,该函数的作用就是运行 kthread_create_list 全局链表中维护的 kthread, 当我们调用 kernel_thread 创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以 kthreadd 为父进程。
需求
为了更好掌握系统的运行情况,我们需要掌握系统上运行了哪些内核进程。
Show me the code
根据上面的原理可知,我们只需要获取所有kthreadd 创建的子进程即可, 处理逻辑:
内核进程的 ppid 都是 2;
与 CPU 或者设备相关的,类似[xfs-log/dm-127] 转换成 xfs-log;
[ipv6_addrconf] 转换成 ipv6_addrconf。
bash 脚本如下:
ps -e -o pid,ppid,cmd | awk '$2 == 2 && $1 != 1 {print $3}' | sort | uniq | sed 's/\[\([^/]*\)\/[^]]*\]/\1/;s/\[\([^]]*\)\]/\1/' | uniq
在如下内核版本的执行结果:
uname -r3.10.0-1160.105.1.el7.x86_64
输出
ata_sffbiosetcryptodeferwqdiodm_bufio_cachedm-thinedac-polleripv6_addrconfkaluadkauditdkblockdkcopydkdevtmpfskdmflushkhungtaskdkintegritydkipmi0kmpath_rdacdkpsmousedksmdksoftirqdkswapd0kswapd1kthrotldkvm-irqfd-cleankworkerlru-add-drainmdmigrationnetnsnfitnfsiodpoll_megasas0_srcu_bhrcu_schedrpciodscsi_eh_0scsi_eh_1scsi_eh_10scsi_eh_2scsi_eh_3scsi_eh_4scsi_eh_5scsi_eh_6scsi_eh_7scsi_eh_8scsi_eh_9scsi_tmf_0scsi_tmf_1scsi_tmf_10scsi_tmf_2scsi_tmf_3scsi_tmf_4scsi_tmf_5scsi_tmf_6scsi_tmf_7scsi_tmf_8scsi_tmf_9ttm_swapwatchdogwatchdogdwritebackxfsaildxfsallocxfs-bufxfs-cilxfs-convxfs-dataxfs-eofblocksxfs-logxfs_mru_cachexfs-reclaimxprtiod
通过 chatGPT 3.5 来看一下每个进程的解释(手工也做了一些整理,可能也不是太完善):
ata_sff: ATA Serial Framework - 处理ATA(Advanced Technology Attachment)硬盘驱动的核心组件。
bioset: 用于块 I/O 层的进程。
crypto: 处理加密相关的工作,可能涉及到加密算法和操作。
deferwq: 延迟工作队列,用于处理延迟执行的工作。
dio: 直接I/O,用于直接在用户空间和设备之间传递数据而无需通过内核缓冲区。
dm_bufio_cache: 设备映射层(Device Mapper)缓冲I/O cache。
dm-thin: 设备映射层中的 thin 目标,用于实现精简设备映射。
edac-poller: 故障注入用于内存错误检测和校正的内核组件。
ipv6_addrconf: IPv6 地址配置。
kaluad: KALU(Kernel Asynchronous Logging)守护程序,用于记录内核异步事件。
kauditd: 安全审计守护程序,负责记录系统的安全事件。
kblockd: 每个处理器核对应一个 kblockd 内核线程。用于管理系统的块设备,它会周期性地激活系统内的块设备驱动。
kcopyd: 设备映射层中的 copy 目标,用于实现块拷贝操作。
kdevtmpfs: 动态创建和管理 /dev 目录下的设备节点(使用 tmpfs)。
kdmflush: 设备映射层中的dm-flush-worker,用于刷新延迟写入的数据。
khungtaskd: 内核框架任务调度器。
kintegrityd: 文件完整性保护的内核组件。
kipmi0: IPMI驱动的内核组件。
kmpath_rdacd: 多路径RDAC Daemon,用于多路径存储设备的管理。
kpsmoused: 主要作用是支持ps/2接口的鼠标驱动。
ksmd: 全称为 Kernel Samepage Merging Daemon,主要功能是尝试合并相邻的内存页面,以减少内存占用。。
ksoftirqd: 内核软中断处理程序。
kswapd0, kswapd1: 内核交换空间守护程序,用于处理交换空间的页面交换。
kthrotld: 全称为 Kernel Thread Throttle Daemon,它用于限制与 I/O 调度相关的内核线程的执行速率。。
kvm-irqfd-clean: KVM虚拟机中的IRQfd清理程序。
kworker: 用于异步处理工作队列中的任务。这些任务包括处理硬件中断、文件系统事件、管理系统内存等。我们可能会看到多个 kworker 进程,每个进程的名称后面都有一个数字,例如 “kworker/0:1”等。这个数字表示了 kworker 是在哪个 CPU 核心上运行的以及任务的顺序。
lru-add-drain: 内核页面 LRU 添加守护程序,用于处理页面的 LRU 队列 - https://access.redhat.com/solutions/3681321。
md: 软 RAID(磁盘阵列)的内核组件。
migration: 每个处理器核对应一个migration内核线程,主要作用是作为相应CPU核的迁移进 程,用来执行进程迁移操作。
netns: 网络命名空间,用于创建隔离的网络环境。
nfit: NVDIMM(非易失性内存设备)的内核组件。
nfsiod: NFS I/O守护程序,用于处理NFS文件系统的异步I/O请求。
poll_megasas0_s: MegaRAID驱动的异步事件通知。
rcu_bh, rcu_sched: 内核RCU(Read-Copy Update)的后台和调度线程。
rpciod: 每个处理器核对应一个rpciod内核线程,主要作用是作为远过程调用服务的守护进程,用于从客 户端启动I/O服务,通常启动NFS服务时要用到它,。
scsi_eh_*: SCSI 错误处理线程,用于处理 SCSI 设备的错误事件。
scsi_tmf_*: SCSI 任务管理线程,用于处理 SCSI 任务管理函数。
ttm_swap: TTM(Translation Table Maps)交换调度器。
watchdog, watchdogd: 每个处理器核对应一个watchdog 内核线程,watchdog用于监视系统的运行,在系统出现故障时自动重新启动系统,包括一个内核 watchdog module 和一个用户空间的 watchdog 程序。在Linux 内核下, watchdog的基本工作原理是:当watchdog启动后(即/dev/watchdog设备被打开后),如果在某一设定的时间间隔(1分钟)内 /dev/watchdog没有被执行写操作, 硬件watchdog电路或软件定时器就会重新启动系统,每次写操作会导致重新设定定时器。
writeback: 在 Linux 中,"writeback" 进程通常指的是负责将脏页面(已修改但尚未写回磁盘)写回到磁盘的内核线程。这个进程的工作是确保文件系统中的数据与内存中的数据保持同步,以提供数据的持久性。以下是与 "writeback" 相关的一些概念:
pdflush: 在早期的内核版本中,"pdflush" 是负责将脏页面写回磁盘的内核线程。
kernel threads: 在较新的内核中,"pdflush" 被多个内核线程替代,这些线程可以称为 "writeback" 进程。这些进程的名称可能包含 "flush" 或 "writeback"。
/proc/sys/vm/dirty_ 参数*: 这些内核参数可以用来配置脏页面的行为,例如,控制写回的频率、阈值等。
https://lwn.net/Articles/648292/
xfsaild: XFS文件系统异步日志守护程序。
xfsalloc, xfs-buf, xfs-cil, xfs-conv, xfs-data: XFS 文件系统的组件。
xfs-eofblocks, xfs-log: XFS文件系统的额外组件。
xfs_mru_cache, xfs-reclaim: XFS文件系统的内存管理组件。
xprtiod: NFS传输层守护程序,用于处理RPC传输
Linux 下有 3 个特殊的进程:
idle 进程 (pid = 0);
init 进程 (pid = 1),Redhat/CentOS 中就是 systemd 进程;
kthreadd (pid = 2)。
idle 进程,pid = 0
由系统自动创建, 运行在内核态;
pid = 0,其前身是系统创建的第一个进程;
唯一一个没有通过 fork 或者 kernel_thread 产生的进程;
完成加载系统后,演变为进程调度、交换;
init 进程(pid = 1)
init 进程由 idle 通过 kernel_thread 创建,在内核空间完成初始化后, 加载 init 程序, 并最终用户空间;
由 0 进程创建,完成系统的初始化。它是系统中所有其它用户进程的祖先进程;
Linux 中的所有进程都是由 init 进程创建并运行的 - 首先 Linux 内核启动,然后在用户空间中启动 init 进程,再启动其他系统进程。在系统启动完成完成后,init 进程将变为守护进程,监视系统其他进程。
kthreadd 进程(pid = 2)
kthreadd 进程由 idle 通过 kernel_thread 创建,并始终运行在内核空间, 负责所有内核线程的调度和管理;
它的任务就是管理和调度其他内核线程 kernel_thread, 会循环执行一个 kthread 的函数,该函数的作用就是运行 kthread_create_list 全局链表中维护的 kthread, 当我们调用 kernel_thread 创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以 kthreadd 为父进程。
需求
为了更好掌握系统的运行情况,我们需要掌握系统上运行了哪些内核进程。
Show me the code
根据上面的原理可知,我们只需要获取所有kthreadd 创建的子进程即可, 处理逻辑:
内核进程的 ppid 都是 2;
与 CPU 或者设备相关的,类似[xfs-log/dm-127] 转换成 xfs-log;
[ipv6_addrconf] 转换成 ipv6_addrconf。
bash 脚本如下:
ps -e -o pid,ppid,cmd | awk '$2 == 2 && $1 != 1 {print $3}' | sort | uniq | sed 's/\[\([^/]*\)\/[^]]*\]/\1/;s/\[\([^]]*\)\]/\1/' | uniq
在如下内核版本的执行结果:
uname -r3.10.0-1160.105.1.el7.x86_64
输出
ata_sffbiosetcryptodeferwqdiodm_bufio_cachedm-thinedac-polleripv6_addrconfkaluadkauditdkblockdkcopydkdevtmpfskdmflushkhungtaskdkintegritydkipmi0kmpath_rdacdkpsmousedksmdksoftirqdkswapd0kswapd1kthrotldkvm-irqfd-cleankworkerlru-add-drainmdmigrationnetnsnfitnfsiodpoll_megasas0_srcu_bhrcu_schedrpciodscsi_eh_0scsi_eh_1scsi_eh_10scsi_eh_2scsi_eh_3scsi_eh_4scsi_eh_5scsi_eh_6scsi_eh_7scsi_eh_8scsi_eh_9scsi_tmf_0scsi_tmf_1scsi_tmf_10scsi_tmf_2scsi_tmf_3scsi_tmf_4scsi_tmf_5scsi_tmf_6scsi_tmf_7scsi_tmf_8scsi_tmf_9ttm_swapwatchdogwatchdogdwritebackxfsaildxfsallocxfs-bufxfs-cilxfs-convxfs-dataxfs-eofblocksxfs-logxfs_mru_cachexfs-reclaimxprtiod
通过 chatGPT 3.5 来看一下每个进程的解释(手工也做了一些整理,可能也不是太完善):
ata_sff: ATA Serial Framework - 处理ATA(Advanced Technology Attachment)硬盘驱动的核心组件。
bioset: 用于块 I/O 层的进程。
crypto: 处理加密相关的工作,可能涉及到加密算法和操作。
deferwq: 延迟工作队列,用于处理延迟执行的工作。
dio: 直接I/O,用于直接在用户空间和设备之间传递数据而无需通过内核缓冲区。
dm_bufio_cache: 设备映射层(Device Mapper)缓冲I/O cache。
dm-thin: 设备映射层中的 thin 目标,用于实现精简设备映射。
edac-poller: 故障注入用于内存错误检测和校正的内核组件。
ipv6_addrconf: IPv6 地址配置。
kaluad: KALU(Kernel Asynchronous Logging)守护程序,用于记录内核异步事件。
kauditd: 安全审计守护程序,负责记录系统的安全事件。
kblockd: 每个处理器核对应一个 kblockd 内核线程。用于管理系统的块设备,它会周期性地激活系统内的块设备驱动。
kcopyd: 设备映射层中的 copy 目标,用于实现块拷贝操作。
kdevtmpfs: 动态创建和管理 /dev 目录下的设备节点(使用 tmpfs)。
kdmflush: 设备映射层中的dm-flush-worker,用于刷新延迟写入的数据。
khungtaskd: 内核框架任务调度器。
kintegrityd: 文件完整性保护的内核组件。
kipmi0: IPMI驱动的内核组件。
kmpath_rdacd: 多路径RDAC Daemon,用于多路径存储设备的管理。
kpsmoused: 主要作用是支持ps/2接口的鼠标驱动。
ksmd: 全称为 Kernel Samepage Merging Daemon,主要功能是尝试合并相邻的内存页面,以减少内存占用。。
ksoftirqd: 内核软中断处理程序。
kswapd0, kswapd1: 内核交换空间守护程序,用于处理交换空间的页面交换。
kthrotld: 全称为 Kernel Thread Throttle Daemon,它用于限制与 I/O 调度相关的内核线程的执行速率。。
kvm-irqfd-clean: KVM虚拟机中的IRQfd清理程序。
kworker: 用于异步处理工作队列中的任务。这些任务包括处理硬件中断、文件系统事件、管理系统内存等。我们可能会看到多个 kworker 进程,每个进程的名称后面都有一个数字,例如 “kworker/0:1”等。这个数字表示了 kworker 是在哪个 CPU 核心上运行的以及任务的顺序。
lru-add-drain: 内核页面 LRU 添加守护程序,用于处理页面的 LRU 队列 - https://access.redhat.com/solutions/3681321。
md: 软 RAID(磁盘阵列)的内核组件。
migration: 每个处理器核对应一个migration内核线程,主要作用是作为相应CPU核的迁移进 程,用来执行进程迁移操作。
netns: 网络命名空间,用于创建隔离的网络环境。
nfit: NVDIMM(非易失性内存设备)的内核组件。
nfsiod: NFS I/O守护程序,用于处理NFS文件系统的异步I/O请求。
poll_megasas0_s: MegaRAID驱动的异步事件通知。
rcu_bh, rcu_sched: 内核RCU(Read-Copy Update)的后台和调度线程。
rpciod: 每个处理器核对应一个rpciod内核线程,主要作用是作为远过程调用服务的守护进程,用于从客 户端启动I/O服务,通常启动NFS服务时要用到它,。
scsi_eh_*: SCSI 错误处理线程,用于处理 SCSI 设备的错误事件。
scsi_tmf_*: SCSI 任务管理线程,用于处理 SCSI 任务管理函数。
ttm_swap: TTM(Translation Table Maps)交换调度器。
watchdog, watchdogd: 每个处理器核对应一个watchdog 内核线程,watchdog用于监视系统的运行,在系统出现故障时自动重新启动系统,包括一个内核 watchdog module 和一个用户空间的 watchdog 程序。在Linux 内核下, watchdog的基本工作原理是:当watchdog启动后(即/dev/watchdog设备被打开后),如果在某一设定的时间间隔(1分钟)内 /dev/watchdog没有被执行写操作, 硬件watchdog电路或软件定时器就会重新启动系统,每次写操作会导致重新设定定时器。
writeback: 在 Linux 中,"writeback" 进程通常指的是负责将脏页面(已修改但尚未写回磁盘)写回到磁盘的内核线程。这个进程的工作是确保文件系统中的数据与内存中的数据保持同步,以提供数据的持久性。以下是与 "writeback" 相关的一些概念:
pdflush: 在早期的内核版本中,"pdflush" 是负责将脏页面写回磁盘的内核线程。
kernel threads: 在较新的内核中,"pdflush" 被多个内核线程替代,这些线程可以称为 "writeback" 进程。这些进程的名称可能包含 "flush" 或 "writeback"。
/proc/sys/vm/dirty_ 参数*: 这些内核参数可以用来配置脏页面的行为,例如,控制写回的频率、阈值等。
https://lwn.net/Articles/648292/
xfsaild: XFS文件系统异步日志守护程序。
xfsalloc, xfs-buf, xfs-cil, xfs-conv, xfs-data: XFS 文件系统的组件。
xfs-eofblocks, xfs-log: XFS文件系统的额外组件。
xfs_mru_cache, xfs-reclaim: XFS文件系统的内存管理组件。
xprtiod: NFS传输层守护程序,用于处理RPC传输