Linux kernel 内核升级和降级的方法实践

2019-01-28 16:43:32 +08:00
 wsgzao

前言

相信现在很多公有云包括企业内部已经开始使用 Linux 内核热补丁 Livepatch,没人喜欢重启机器但现实是还得再等等。通常升级内核可能有多种原因,频率最高的比如修复安全漏洞,然而我们也会遇到需要降级内核的情况,比如向下兼容或者升级后产生新的严重 Bug 需要回退。本文主要以 CentOS 为例介绍内核的升级和降级方案,虽然官方一直坚持使用旧内核 3.10 版本,但这也是追求极致稳定的权衡结果,有高版本内核需求比如 4.10 以上我们可以手动升级也可以更换 Ubuntu 等其它操作系统,对线上生产环境始终保持一颗敬畏之心。

Linux kernel 内核升级和降级的方法实践

更新历史

2019 年 01 月 27 日 - 初稿

阅读原文 - https://wsgzao.github.io/post/linux-kernel-update/

扩展阅读

kernel - https://www.kernel.org/


Linux 内核简介

Linux 内核是一个整体的类 Unix 计算机操作系统内核。通常我们使用的 Linux 发行版,如 Red Hat、Debian、SUSE 等,这些都称为 Linux 的分发版。一个典型的分发版,是由 Linux 内核,以及支持的许多由 GNU 项目提供的应用程序、GNU 组件,C 标准库,CLI shell,X windows 等组成的一个完整操作系统。我们应该要知道的是,Linux 的定义仅仅是 Linux 内核,所有的” Linux ” 发行版实际上是以 Linux 为内核的 GNU 系统的版本。不同的 Linux 内核版本都有其生命周期,Linux 内核组织或 Linux 发行版厂商只在该日期提供错误或漏洞修复,我们可以从从内核的版本号区分辨别,比如版本 3.16.43 ,该数字 3.16 表示一个长期版本,43 则表示错误修订之后再发行的具体版本号,当然我这里描述的只是提供一个参考价值,更细致的版本还有可能是 3.16.43-1 这种。值得我们关注的是,任何内核版本错误修复后的再发布版本都应该是我们考虑升级使用的内核版本。

Linux 内核版本

Linux 内核版本分为主线、稳定和长期版本。所有内核版本都可以在内核开发官方网站 https://www.kernel.org 上获取,目前我们看到最新的稳定内核版本为 4.20.5。

主线版本代表整个 Linux 内核的一个树干,新的主线版本每 2-3 个月发布一次,所有的新功能及特性都将会包含主线版本中。稳定内核则是在主线版本中,被认为是” 稳定的” 得出。稳定内核的任何错误修复都将从主线树中返回,也就是主线内核出现的任何错误 (包括之前的任何旧版本内核的错误和 BUG) 在得到修复之后才会被指定为稳定内核,所以在通常情况下,稳定内核既有内核新功能,同时 BUG 也是最少的内核版本。稳定内核的更新发布依赖于主线内核 (直到下一个主线内核可用),稳定的内核更新是根据需要发布的,通常是每 3 个月。而对于长期内核版本,通常提供几个” 长期维护” 内核版本,用于较早的内核树错误修复返回的目的。这些内核只应用重要的错误修复,通常不会有非常频繁的更新。

主线、稳定和长期都是活动内核版本,由 Linus Torvalds 及 Linux 内核组织维护和释放。 而我们平时所使用的 Linux 发行版的内核都为分发内核,许多 Linux 发行版都提供自己的” 长期维护” 内核版本,这些内核可能是也可能不是基于内核开发人员维护的内核。因此分发版本的内核版本由发行版的厂商决定并有自己的维护周期,通常由分发版更新时一起发布。

安装 / 升级新内核的目的

安装 / 升级的方法和建议

  1. 对于 CentOS/RHEL 系统,尽量使用 yum 方式或 RPM 包安装 / 升级内核,需要注意的是红帽的 Red Hat Linux 服务需要订阅。
  2. 使用安装新内核而不是直接升级内核,安装新内核不会覆盖旧内核,而升级会导致新内核直接替换旧内核,可能会导致系统无法启动,安装也可以让我们在升级后有回滚的选择。
  3. 一般地,对于大多数 Linux 分发版,使用 yum/dnf 和分发版布官方的存储库来升级内核,这种方式只能升级到该分发版的存储库提供的最新版本,而不是 Linux 内核组织发布的最新内核。
  4. 如果想迅速并且安全地使用最新内核,对于 CentOS/RHEL 系统并不支持 yum 的方式直接安装或升级。那么此时我们可以使用 ELRepo(第三方存储库) 进行内核安装升级。
  5. 下载新内核的源码包进行编译安装,这种方式有助于我们更细致地学习内核底层知识,但在生产环境中不推荐编译安装。
  6. 尽量使用最新的 Linux 发行版,新的 Liunx 发行版包含该发行版维护的新内核,如果有必要,那么请使用如 yum upgrade 或者 yum update 来更新你的系统。对于 Ubuntu、Debian 等发行版,使用 apt-get update 方式来更新。

内核软件包介绍

kernel Linux 内核软件包,包含单、多核和多处理器系统的内核,是任何 Linux 操作系统的核心,单处理器的系统仅需安装内核包。内核处理操作系统的基本功能: 内存分配、进程分配、设备输入和输出等

kernel-devel 包含提供足够的针对内核软件包构建模块的内核头文件和 makefile 文件

kernel-headers 包含指定 Linux 内核、用户空间库文件和程序之间指定接口的 C 头文件。头文件定义了构建大多数标准程序所需的结构和常量,也是重建 glibc 软件包所必需的

kernel-doc 包含来自内核源代码的文档文件。各种关于 Linux 内核和设备以及驱动程序的信息都记录在这些文件当中

kernel-firmware 包含对于某些设备及其操作的固件信息文件

kernel-debug 包含许多对于内核 debug 诊断和调试的启用选项,只有当我们需要尝试收集额外的内核错误信息时才应该安装它。它是以牺牲性能为代价

kernel-debug-devel 包含内核 debug 诊断和调试的启用选项,以牺牲性能为代价

在 CentOS 上安装 / 升级内核

Linux 内核升级通常有两种方式

  1. 下载新版内核到服务器上,进行编译安装,之后删除老内核, 优点是:可完全控制编译项, 缺点是:慢,且容易失败;
  2. 采用 yum 方式安装, 优点是:快捷方便,成功率高。

我这里采用第二种方式来安装, 采用 yum 安装最多也就三五分钟的事, 万一失败还能补救。

Linux OS version: CentOS Linux release 7.5.1804 (Core) Linux kernel 升级原因: CPU 性能优化 Linux kernel 当前版本: 3.10.0-862.el7.x86_64 Linux kernel 目标版本: 3.10.0-862.14.4.el7.x86_64

# 查看当前操作系统版本
cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

# 查看当前内核
uname -r
3.10.0-862.el7.x86_64

# 查看 yum 可升级的内核版本
yum list kernel --showduplicates

Installed Packages
kernel.x86_64                                                          3.10.0-862.el7                                                                @anaconda
kernel.x86_64                                                          3.10.0-862.11.6.el7                                                           @updates
Available Packages
kernel.x86_64                                                          3.10.0-862.el7                                                                base
kernel.x86_64                                                          3.10.0-862.2.3.el7                                                            updates
kernel.x86_64                                                          3.10.0-862.3.2.el7                                                            updates
kernel.x86_64                                                          3.10.0-862.3.3.el7                                                            updates
kernel.x86_64                                                          3.10.0-862.6.3.el7                                                            updates
kernel.x86_64                                                          3.10.0-862.9.1.el7                                                            updates
kernel.x86_64                                                          3.10.0-862.11.6.el7                                                           updates

# 如果 yum list 中有需要的版本可以直接执行 update 升级,但现在的问题是没有
yum update kernel-3.10.0-862.14.4.el7.x86_64

# 可以通过 Google 搜索所需 kernel 版本,下载后离线安装升级,建议使用 -i 保留原来的内核方便版本回退
ftp://ftp.riken.jp/Linux/cern/centos/7/updates/x86_64/repoview/kernel.html
wget ftp://ftp.riken.jp/Linux/cern/centos/7/updates/x86_64/Packages/kernel-3.10.0-862.14.4.el7.x86_64.rpm

# 安装完成之后重启会自动修改启动项切换至新内核
rpm -ivh kernel-3.10.0-862.14.4.el7.x86_64.rpm
init 6

在 CentOS 上降级内核

和之前 Kernel 升级的原因一样,降级也是因为 CPU 性能优化,建议各位仔细评估线上环境所需的版本

Linux OS version: CentOS Linux release 7.6.1810 (Core) Linux kernel 降级原因: CPU 性能优化 Linux kernel 当前版本: 3.10.0-957.1.3.el7.x86_64 Linux kernel 目标版本: 3.10.0-862.6.3.el7.x86_64

# 查看当前操作系统版本
cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

# 查看当前内核
uname -r
3.10.0-957.1.3.el7.x86_64

# 下载制定版本内核覆盖安装
wget ftp://ftp.riken.jp/Linux/cern/centos/7/updates/x86_64/Packages/kernel-3.10.0-862.6.3.el7.x86_64.rpm
rpm -ivh kernel-3.10.0-862.6.3.el7.x86_64.rpm

# 禁止 yum 自动升级 kernel (可选)
vim /etc/yum.conf 
exclude=kernel*

Kernel Change Log

最后给大家分享下官方的 Kernel Change Log,方便各位了解自己目前所用的版本是否合理

The kernel package contains the Linux kernel (vmlinuz), the core of any Linux operating system. The kernel handles the basic functions of the operating system: memory allocation, process allocation, device input and output, etc.

Architecture: x86_64

Version: 3.10.0-957.el7[系列]

2018-11-15 Jan Stancek <jstancek@redhat.com> [3.10.0-957.1.3.el7]
- [x86] Mark Intel Cascade Lake supported (Steve Best) [1650213 1639980]

2018-11-01 Jan Stancek <jstancek@redhat.com> [3.10.0-957.1.1.el7]
- [x86] boot: Fix kexec booting failure in the SEV bit detection code (Kairui Song) [1644990 1628828] 
- [net] 8021q: create device with all possible features in wanted_features (Davide Caratti) [1644675 1640645] 
- [mm] memcontrol: fix high scheduling latency source in mem_cgroup_reparent_charges (Andrea Arcangeli) [1644673 1632898] 
- [kernel] cpuset: use trialcs->mems_allowed as a temp variable (Aristeu Rozanski) [1644236 1613248] 
- [kernel] cpuset: fix a warning when clearing configured masks in old hierarchy (Aristeu Rozanski) [1644236 1613248] 
- [kernel] cpuset: initialize effective masks when clone_children is enabled (Aristeu Rozanski) [1644236 1613248] 
- [x86] efi: Only load initrd above 4g on second try (Lenny Szubowicz) [1643359 1608955] 
- [x86] efi: Support initrd loaded above 4G (Lenny Szubowicz) [1643359 1608955] 
- [x86] efi: Generalize handle_ramdisks() and rename to handle_cmdline_files() (Lenny Szubowicz) [1643359 1608955] 
- [kernel] sched/fair: Fix throttle_list starvation with low CFS quota (Phil Auld) [1640675 1601153] 
- [target] scsi: iscsi: Use bin2hex instead of a re-implementation (Maurizio Lombardi) [1634711 1627034] {CVE-2018-14633} 
- [target] scsi: iscsi: Use hex2bin instead of a re-implementation (Maurizio Lombardi) [1634711 1627034] {CVE-2018-14633}

2018-11-01 Jan Stancek <jstancek@redhat.com> [3.10.0-957.1.2.el7]
- [net] rtnetlink: give a user socket to get_target_net() (Jiri Benc) [1639635 1630694] {CVE-2018-14646} 
- [net] Add variants of capable for use on on sockets (Jiri Benc) [1639635 1630694] {CVE-2018-14646}

2018-10-04 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-957.el7]
- [mm] mlock: avoid increase mm->locked_vm on mlock() when already mlock2(, MLOCK_ONFAULT) (Rafael Aquini) [1633059]

2018-10-03 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-955.el7]
- [netdrv] net/mlx5e: IPoIB, Set the netdevice sw mtu in ipoib enhanced flow (Alaa Hleihel) [1633652] 
- [netdrv] net/mlx5e: Fix traffic between VF and representor (Alaa Hleihel) [1633652] 
- [mm] vmscan: do not loop on too_many_isolated for ever (Waiman Long) [1632050]

2018-10-03 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-956.el7]
- [block] blk-mq: fix hctx debugfs entry related race between update hw queues and cpu hotplug (Ming Lei) [1619988] 
- [nvme] nvme-pci: unquiesce dead controller queues (Ming Lei) [1632424]

2018-09-24 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-954.el7]
- [fs] exec: Limit arg stack to at most 75 of _STK_LIM (Yauheni Kaliuta) [1625991] {CVE-2018-14634} 
- [fs] exec: account for argv/envp pointers (Yauheni Kaliuta) [1625991] {CVE-2018-14634} 
- [kernel] revert "sched/topology: Introduce NUMA identity node sched domain" (Gustavo Duarte) [1620031] 
- [powerpc] revert "powernv: Add a virtual irqchip for opal events" (Gustavo Duarte) [1617966] 
- [powerpc] revert "powernv: Reorder OPAL subsystem initialisation" (Gustavo Duarte) [1617966] 
- [char] revert "ipmi/powernv: Convert to irq event interface" (Gustavo Duarte) [1617966] 
- [tty] revert "hvc: Convert to using interrupts instead of opal events" (Gustavo Duarte) [1617966] 
- [powerpc] revert "powernv/eeh: Update the EEH code to use the opal irq domain" (Gustavo Duarte) [1617966] 
- [powerpc] revert "powernv/opal: Convert opal message events to opal irq domain" (Gustavo Duarte) [1617966] 
- [powerpc] revert "powernv/elog: Convert elog to opal irq domain" (Gustavo Duarte) [1617966] 
- [powerpc] revert "powernv/opal-dump: Convert to irq domain" (Gustavo Duarte) [1617966] 
- [powerpc] revert "opal: Remove events notifier" (Gustavo Duarte) [1617966] 
- [powerpc] revert "powernv: Increase opal-irqchip initcall priority" (Gustavo Duarte) [1617966] 
- [powerpc] revert "opal-irqchip: Fix double endian conversion" (Gustavo Duarte) [1617966] 
- [powerpc] revert "opal-irqchip: Fix deadlock introduced by"Fix double endian conversion"" (Gustavo Duarte) [1617966] 
- [sound] alsa: hda/realtek - two more lenovo models need fixup of MIC_LOCATION (Jaroslav Kysela) [1611958] 
- [sound] alsa: hda/realtek - Fix the problem of two front mics on more machines (Jaroslav Kysela) [1611958] 
- [sound] alsa: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs (Jaroslav Kysela) [1611958]

2018-09-21 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-953.el7]
- [cdrom] information leak in cdrom_ioctl_media_changed() (Sanskriti Sharma) [1578207] {CVE-2018-10940} 
- [mm] mlock: remove lru_add_drain_all() (Oleksandr Natalenko) [1624765] 
- [block] blk-mq: fix race between updating nr_hw_queues and switching io sched (Ming Lei) [1619988] 
- [block] blk-mq: avoid to map CPU into stale hw queue (Ming Lei) [1619988] 
- [block] blk-mq: fix sysfs inflight counter (Ming Lei) [1548261] 
- [block] blk-mq: count allocated but not started requests in iostats inflight (Ming Lei) [1548261] 
- [block] fix a crash caused by wrong API (Ming Lei) [1548261] 
- [block] blk-mq: enable checking two part inflight counts at the same time (Ming Lei) [1548261] 
- [block] blk-mq: provide internal in-flight variant (Ming Lei) [1548261] 
- [block] make part_in_flight() take an array of two ints (Ming Lei) [1548261] 
- [block] pass in queue to inflight accounting (Ming Lei) [1548261] 
- [x86] Mark Intel Cascade Lake supported (Steve Best) [1584343]

2018-09-18 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-952.el7]
- [netdrv] mlx5e: IPoIB, Use priv stats in completion rx flow (Alaa Hleihel) [1618609] 
- [netdrv] mlx5e: IPoIB, Add ndo stats support for IPoIB child devices (Alaa Hleihel) [1618609] 
- [netdrv] mlx5e: IPoIB, Add ndo stats support for IPoIB netdevices (Alaa Hleihel) [1618609] 
- [netdrv] mlx5e: IPoIB, Initialize max_opened_tc in mlx5i_init flow (Alaa Hleihel) [1618609] 
- [netdrv] mlx5e: Present SW stats when state is not opened (Alaa Hleihel) [1618609] 
- [netdrv] mlx5e: Avoid reset netdev stats on configuration changes (Alaa Hleihel) [1618609] 
- [netdrv] mlx5e: Use bool as return type for mlx5e_xdp_handle (Alaa Hleihel) [1618609] 
- [netdrv] net: aquantia: memory corruption on jumbo frames (Igor Russkikh) [1628238] 
- [kernel] revert "platform/uv: Add adjustable set memory block size function" (Baoquan He) [1625143] 
- [x86] revert "mm: probe memory block size for generic x86 64bit" (Baoquan He) [1625143] 
- [x86] revert "mm: Use 2GB memory block size on large-memory x86-64 systems" (Baoquan He) [1625143] 
- [x86] revert "mm: Streamline and restore probe_memory_block_size()" (Baoquan He) [1625143] 
- [x86] revert "mm/memory_hotplug: determine block size based on the end of boot memory" (Baoquan He) [1625143] 
- [mm] revert "memory_hotplug: do not fail offlining too early" (Baoquan He) [1625143] 
- [mm] revert "memory_hotplug: remove timeout from __offline_memory" (Baoquan He) [1625143] 
- [kernel] revert "x86/platform/uv: Add adjustable set memory block size function" (Baoquan He) [1625143]

2018-09-17 Bruno E. O. Meneguele <bmeneg@redhat.com> [3.10.0-951.el7]
- [fs] fanotify: fix logic of events on child (Miklos Szeredi) [1597738] 
- [fs] cifs: add a check for session expiry (Leif Sahlberg) [1626358] 
- [fs] xfs: completely disable per-inode DAX behavior (Eric Sandeen) [1623150] 
- [fs] fs: get_rock_ridge_filename(): handle malformed NM entries (Bill O'Donnell) [1340778] {CVE-2016-4913} 
- [md] fix 'allow faster resync only on non-rotational media' underneath dm (Nigel Croxon) [1561162] 
- [md] Revert "allow faster resync only on non-rotational media" (Nigel Croxon) [1561162] 
- [mm] madvise: fix madvise() infinite loop under special circumstances (Rafael Aquini) [1552982] {CVE-2017-18208} 
- [infiniband] srpt: Support HCAs with more than two ports (Don Dutile) [1616192] 
- [infiniband] overflow.h: Add allocation size calculation helpers (Don Dutile) [1616192] 
- [net] ip_tunnel: clean the GSO bits properly (Flavio Leitner) [1607907] 
- [kernel] revert cpuset: fix a warning when clearing configured masks in old hierarchy (Aristeu Rozanski) [1626943] 
- [s390] sclp: Change SCLP console default buffer-full behavior (Hendrik Brueckner) [1625350] 
- [x86] kvm: Take out __exit annotation in vmx_exit() (Waiman Long) [1626560] 
- [x86] mark coffeelake-s 8+2 as supported (David Arcari) [1575457] 
- [x86] kvm: vmx: fixes for vmentry_l1d_flush module parameter (Marcelo Tosatti) [1619602] 
- [x86] speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry (Marcelo Tosatti) [1619602]

Version: 3.10.0-862.el7[系列]

2018-09-21 Rado Vrbovsky <rvrbovsk@redhat.com> [3.10.0-862.14.4.el7]
- [scsi] Revert: lpfc: Fix port initialization failure (Radomir Vrbovsky) [1605235 1584377] 
- [scsi] Revert: qla2xxx: Fix NULL pointer access for fcport structure (Radomir Vrbovsky) [1597546 1547714]

2018-09-13 Rado Vrbovsky <rvrbovsk@redhat.com> [3.10.0-862.14.3.el7]
- [fs] exec: Limit arg stack to at most 75 of _STK_LIM (Yauheni Kaliuta) [1625980 1625991] {CVE-2018-14634} 
- [fs] exec: account for argv/envp pointers (Yauheni Kaliuta) [1625980 1625991] {CVE-2018-14634}

2018-09-10 Jan Stancek <jstancek@redhat.com> [3.10.0-862.14.2.el7]
- [uio] fix possible circular locking dependency (Xiubo Li) [1608677 1560418] 
- [scsi] tcmu: Don't pass KERN_ERR to pr_err (Xiubo Li) [1608677 1560418] 
- [scsi] tcmu: add module wide block/reset_netlink support (Xiubo Li) [1608677 1560418] 
- [scsi] tcmu: simplify nl interface (Xiubo Li) [1608677 1560418] 
- [scsi] tcmu: track nl commands (Xiubo Li) [1608677 1560418] 
- [scsi] tcmu: delete unused __wait (Xiubo Li) [1608677 1560418] 
- [uio] fix crash after the device is unregistered (Xiubo Li) [1608677 1560418] 
- [uio] change to use the mutex lock instead of the spin lock (Xiubo Li) [1608677 1560418] 
- [uio] Prevent device destruction while fds are open (Xiubo Li) [1608677 1560418] 
- [uio] Reduce return paths from uio_write() (Xiubo Li) [1608677 1560418] 
- [uio] fix incorrect memory leak cleanup (Xiubo Li) [1608677 1560418] 
- [uio] add missing error codes (Xiubo Li) [1608677 1560418] 
- [uio] fix false positive __might_sleep warning splat (Xiubo Li) [1608677 1560418] 
- [uio] Destroy uio_idr on module exit (Xiubo Li) [1608677 1560418] 
- [uio] don't free irq that was not requested (Xiubo Li) [1608677 1560418] 
- [uio] support memory sizes larger than 32 bits (Xiubo Li) [1608677 1560418] 
- [uio] we cannot mmap unaligned page contents (Xiubo Li) [1608677 1560418] 
- [uio] Pass pointers to virt_to_page(), not integers (Xiubo Li) [1608677 1560418] 
- [uio] fix memory leak (Xiubo Li) [1608677 1560418] 
- [uio] Request/free irq separate from dev lifecycle (Xiubo Li) [1608677 1560418] 
- [uio] Simplify uio error path by using devres functions (Xiubo Li) [1608677 1560418]

2018-08-22 Rado Vrbovsky <rvrbovsk@redhat.com> [3.10.0-862.14.1.el7]
- [x86] microcode: Allow late microcode loading with SMT disabled (Josh Poimboeuf) [1619622 1614515] 
- [infiniband] core: Fix nospec regression (Josh Poimboeuf) [1619624 1616346] 
- [x86] microcode/amd: Do not load when running on a hypervisor (Vitaly Kuznetsov) [1618390 1607899]

11934 次点击
所在节点    程序员
4 条回复
msg7086
2019-01-28 17:00:39 +08:00
> 虽然官方一直坚持使用旧内核 3.10 版本,但这也是追求极致稳定的权衡结果

官方并不是坚持使用旧内核。我觉得正确的说法是,官方在 RHEL 7 制作和发布时,决定使用 3.10 版本。因为就算官方要使用新版本,在发布之时那些版本也还未诞生。还未诞生的内核,如何能去使用。

> 比如版本 3.16.43 ,该数字 3.16 表示一个长期版本,43 则表示错误修订之后再发行的具体版本号

3.16 这个数字本身没有什么特别的,只是 3.16 恰好是 LTS 长期版本。很多其他版本的内核,比如 3.13 4.4 4.9 4.14 4.15 4.19 等,也都是 LTS 的。

> 如果想迅速并且安全地使用最新内核,(略……)那么此时我们可以使用 ELRepo(第三方存储库) 进行内核安装升级。

ELRepo 中的 mt 版本是主线版,稳定性是比不上稳定版的。lt 版本( 4.4 )是稳定版 LTS,质量相对较好。但是值得注意的是 ELRepo 作为第三方库,质量和安全响应速度都是比不上官方 Repo 的,安全性上还要再考量。

其他的部分都写得挺好的。
sunnyday123
2019-01-28 17:06:38 +08:00
收藏一下,以备后用,多谢
wsgzao
2019-01-28 17:19:33 +08:00
@msg7086 #1 感谢反馈
exkernel
2019-01-29 10:29:02 +08:00
竟然还推荐第三方的 ELRepo, 官方维护的 centos-release-xen 表示不服

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/531295

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX