有个老同事想快速查看不同版本的内核源码,问我有没有啥方法,当然有。大部分玩linux的小伙伴应该都知道从kernel/git/stable/linux.git - Linux kernel stable tree 可以查找下载linux内核源码。但是内核源码原版本繁多,如果想在多个内核版本之间查看内核更新日志changelog和源码,总不能在kernel/git/stable/linux.git - Linux kernel stable tree一个个内核源码点击查看吧?效率太低了!
比如现在怀疑发现3.10.107内核文件系统层有个bug,3.10.108内核解决了这个bug,相关源码C文件N多个,不确定修改哪个文件解决了这个bug。其实熟悉了git操作,就可以得到3.10.107到3.10.108内核的所有更新日志changelog,按照特定模块或者关键字查找changelog,大大缩小排查范围。
再者,可以用git checkout命名把源码从3.10.107快速切换到指定3.10.108,不用新下载3.10.108的源码,这样方便的查看多个版本的内核源码。还有其他git命令,熟悉之后对阅读内核源码有好处,本文做个总结。
首先 git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git 下载最新linux内核源码。下载速度慢很正常,只能等了,运气好下载速度可能达到M/s级别(我遇到过)。下载好后进入linux目录,执行ctags –R建立源码函数关系,之后就可以借助vim查看内核源码,同时支持函数跳转。
先执行git branch –a命令查看内核源码本地和远程所有分支
git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/linux-2.6.11.y
remotes/origin/linux-2.6.12.y
remotes/origin/linux-2.6.13.y
remotes/origin/linux-2.6.14.y
remotes/origin/linux-2.6.15.y
..........
remotes/origin/linux-3.18.y
remotes/origin/linux-3.19.y
remotes/origin/linux-3.2.y
.........
remotes/origin/linux-5.9.y
remotes/origin/linux-rolling-lts
remotes/origin/linux-rolling-stable
remotes/origin/master
打印出各个内核版本分支
执行git checkout linux-3.5.y把内核源码切换到linux-3.5.y,其他内核版本也可以按照该方法切换,然后再ctags –R就可以快速查看不同版本的内核源码,而不用单独下载每个内核版本的源码。
[root@localhost linux]# git checkout linux-3.5.y
M include/uapi/linux/netfilter/xt_CONNMARK.h
M include/uapi/linux/netfilter/xt_DSCP.h
M include/uapi/linux/netfilter/xt_MARK.h
M include/uapi/linux/netfilter/xt_RATEEST.h
M include/uapi/linux/netfilter/xt_TCPMSS.h
M include/uapi/linux/netfilter_ipv4/ipt_ECN.h
M include/uapi/linux/netfilter_ipv4/ipt_TTL.h
M include/uapi/linux/netfilter_ipv6/ip6t_HL.h
M net/netfilter/xt_DSCP.c
M net/netfilter/xt_HL.c
M net/netfilter/xt_RATEEST.c
M net/netfilter/xt_TCPMSS.c
M tools/memory-model/litmus-tests/Z6.0+pooncelock+poonceLock+pombonce.litmus
Switched to branch 'linux-3.5.y'
这是内核大版本号,要想获取内核小版本号怎么办?执行git tag命令
[root@localhost linux]# git tag
v2.6.11
v2.6.11-tree
........
v3.10.28
v3.10.29
.....
v4.2.5
v4.2.6
.....
v5.8.7
v5.8.8
v5.8.9
当然也可以执行git checkout v3.10.28把内核源码切换到指定内核小版本。
执行git status打印当前内核版本。有时执行git log -1打印最近一次更新日志时,也可以打印当前内核版本,git log -2打印最近两次更新日志。
[root@localhost linux]# git status
# On branch linux-3.5.y
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: include/uapi/linux/netfilter/xt_CONNMARK.h
# modified: include/uapi/linux/netfilter/xt_DSCP.h
# modified: include/uapi/linux/netfilter/xt_MARK.h
# modified: include/uapi/linux/netfilter/xt_RATEEST.h
# modified: include/uapi/linux/netfilter/xt_TCPMSS.h
# modified: include/uapi/linux/netfilter_ipv4/ipt_ECN.h
# modified: include/uapi/linux/netfilter_ipv4/ipt_TTL.h
# modified: include/uapi/linux/netfilter_ipv6/ip6t_HL.h
# modified: net/netfilter/xt_DSCP.c
# modified: net/netfilter/xt_HL.c
# modified: net/netfilter/xt_RATEEST.c
# modified: net/netfilter/xt_TCPMSS.c
# modified: tools/memory-model/litmus-
.............
执行 git log -p block/blk-core.c查看单个文件的修改日志,git blame block/blk-core.c也可以实现类似效果
[root@localhost linux]# git log -p block/blk-core.c
commit 3b629f8d6dc04d3af94429c18fe17239d6fbe2c3
Merge: c547d89 3d5b3fb
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon Aug 30 19:30:30 2021 -0700
Merge tag 'io_uring-bio-cache.5-2021-08-30' of git://git.kernel.dk/linux-block
Pull support for struct bio recycling from Jens Axboe:
"This adds bio recycling support for polled IO, allowing quick reuse of
a bio for high IOPS scenarios via a percpu bio_set list.
It's good for almost a 10% improvement in performance, bumping our
per-core IO limit from ~3.2M IOPS to ~3.5M IOPS"
* tag 'io_uring-bio-cache.5-2021-08-30' of git://git.kernel.dk/linux-block:
bio: improve kerneldoc documentation for bio_alloc_kiocb()
block: provide bio_clear_hipri() helper
block: use the percpu bio cache in __blkdev_direct_IO
io_uring: enable use of bio alloc cache
block: clear BIO_PERCPU_CACHE flag if polling isn't supported
bio: add allocation cache abstraction
fs: add kiocb alloc cache flag
bio: optimize initialization of a bio
commit 679369114e55f422dc593d0628cfde1d04ae59b3
Merge: 8596e58 1d1cf15
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon Aug 30 18:52:11 2021 -0700
Merge tag 'for-5.15/block-2021-08-30' of git://git.kernel.dk/linux-block
Pull block updates from Jens Axboe:
"Nothing major in here - lots of good cleanups and tech debt handling,
which is also evident in the diffstats. In particular:
- Add disk sequence numbers (Matteo)
..................
会打印commit id、作者、时间、修改日志等重要信息。还可以执行git log --oneline --graph block/blk-mq.c查看该文件所有简略的更新日志,查找bug时很有用。
如果我们想查看linux-3.5.y和linux-3.6.y这两个内核版本之间的所有修改日志,执行git log remotes/origin/linux-3.5.y..remotes/origin/linux-3.6.y 命令
[root@localhost linux]# git log remotes/origin/linux-3.5.y..remotes/origin/linux-3.6.y
commit b2824f4e0990716407b0c0e7acee75bb6353febf
Author: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Mon Dec 17 09:27:45 2012 -0800
Linux 3.6.11
commit 8647f31166b23f82f8ba33b3bf563e9f2bbd8956
Author: Tommi Rantala <tt.rantala@gmail.com>
Date: Thu Nov 22 03:23:16 2012 +0000
sctp: fix -ENOMEM result with invalid user space pointer in sendto() syscall
…………………………
如果linux-3.5.y内核有个ext4文件系统的bug,linux-3.6.y内核解决了。你想查看到底是linux-3.5.y内核哪次更新解决了这个bug,用这个命令很有用。因为可以从commit 日志里找到蛛丝马迹。但是git log remotes/origin/linux-3.5.y..remotes/origin/linux-3.6.y打印的信息太多太杂乱,能只查看每次更新的简略信息吗?可以,用git log --oneline remotes/origin/linux-3.5.y..remotes/origin/linux-3.6.y命令
[root@localhost linux]# git log --oneline remotes/origin/linux-3.5.y..remotes/origin/linux-3.6.y
b2824f4 Linux 3.6.11
8647f31 sctp: fix -ENOMEM result with invalid user space pointer in sendto() syscall
11b435b sctp: fix memory leak in sctp_datamsg_from_user() when copy from user space fails
c60fcb1 bonding: fix race condition in bonding_store_slaves_active
6ba4bca bonding: Bonding driver does not consider the gso_max_size/gso_max_segs setting of slave devices.
be59563 net: cdc_ncm: add Huawei devices
8e63550 usb/ipheth: Add iPhone 5 support
973e442 inet_diag: validate port comparison byte code to prevent unsafe reads
38a5e42 inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run()
2d9f468 inet_diag: validate byte code to prevent oops in inet_diag_bc_run()
72c4553 inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state
f410b53 ipv4: ip_check_defrag must not modify skb before unsharing
67e2485 ipv4: avoid passing NULL to inet_putpeer() in icmpv4_xrlim_allow()
1322cf6 ipv4: do not cache looped multicasts
0541e18 irda: sir_dev: Fix copy/paste typo
.......................
可以发现,加了个--oneline参数。这样可以每行的更新日志,只打印commit id和简略更新日志。git查看内核日志很多时候都可以加--oneline以过滤干扰打印。因为内核bug与ext4文件系统有关,还可以grep ext4搜索关键字,这样干扰信息能大大减少,如下:
[root@localhost linux]# git log --oneline remotes/origin/linux-3.5.y..remotes/origin/linux-3.6.y | grep ext4
5770e9e ext4: remove erroneous ext4_superblock_csum_set() in update_backups()
19dfc17 ext4: fix metadata checksum calculation for the superblock
dab43b7 ext4: fix unjournaled inode bitmap modification
b1f9e72 ext4: Avoid underflow in ext4_trim_fs()
462f4e6 ext4: Checksum the block bitmap properly with bigalloc enabled
e28b27b ext4: race-condition protection for ext4_convert_unwritten_extents_endio
92b7722 ext4: fix mtime update in nodelalloc mode
34414b2 ext4: fix fdatasync() for files with only i_size changes
12ebdf0 ext4: always set i_op in ext4_mknod()
22a5672 ext4: online defrag is not supported for journaled files
ba57d9e ext4: move_extent code cleanup
2fdb112 ext4: fix crash when accessing /proc/mounts concurrently
1638f1f ext4: fix potential deadlock in ext4_nonda_switch()
假设第一行的“5770e9e ext4: remove erroneous ext4_superblock_csum_set() in update_backups()”被判定很大可能解决了linux-3.5.y内核的这个ext4文件系统的bug,怎么查看这个更新的详细信息呢?执行git log commit id,如下:
[root@localhost linux]# git log 5770e9e
commit 5770e9ed8a5b8ae7204e6cfe52565f10395091e4
Author: Tao Ma <boyu.mt@taobao.com>
Date: Thu Sep 20 11:35:38 2012 -0400
ext4: remove erroneous ext4_superblock_csum_set() in update_backups()
commit bef53b01faeb791e27605cba1a71ba21364cb23e upstream.
The update_backups() function is used to backup all the metadata
blocks, so we should not take it for granted that 'data' is pointed to
a super block and use ext4_superblock_csum_set to calculate the
checksum there. In case where the data is a group descriptor block,
it will corrupt the last group descriptor, and then e2fsck will
complain about it it.
As all the metadata checksums should already be OK when we do the
backup, remove the wrong ext4_superblock_csum_set and it should be
just fine.
Reported-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
commit 5433889db1b04159054a9e6357f90c77970cf4ed
Author: Manuel Lauss <manuel.lauss@gmail.com>
Date: Thu Nov 22 11:58:22 2012 +0100
MPI: Fix compilation on MIPS with GCC 4.4 and newer
commit a3cea9894157c20a5b1ec08b7e0b5f2019740c10 upstream.
Since 4.4 GCC on MIPS no longer recognizes the "h" constraint,
leading to t
可以看到这个更新前后挨着的两次提交记录,5770e9ed8a5b8ae7204e6cfe52565f10395091e4是完整的commit id,5433889db1b04159054a9e6357f90c77970cf4ed是前一次的commit id ,再执行如下命令:git diff 5433889db1b04159054a9e6357f90c77970cf4ed 5770e9ed8a5b8ae7204e6cfe52565f10395091e4
[root@localhost linux]# git diff 5433889db1b04159054a9e6357f90c77970cf4ed 5770e9ed8a5b8ae7204e6cfe52565f10395091e4
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 101b41c..82e1fde3 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -979,8 +979,6 @@ static void update_backups(struct super_block *sb,
goto exit_err;
}
- ext4_superblock_csum_set(sb);
-
while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) {
struct buffer_head *bh;
git diff 前后两次的commit id就可以查看后一次的详细修改记录,如上修改正是commit id 5770e9ed8a5b8ae7204e6cfe52565f10395091e4的详细修改记录。
其他常用的git命令,git pull远程获取最新源码版本并合并到本地,如果你只想看看最新源码版修改了什么?可以借助git fetch命令。还有其他命令:
git 大多时候还可以用tig替代,tig用起来是交互模式。先介绍这么多,后续有机会在补充。