zoukankan      html  css  js  c++  java
  • 软件包管理

    软件包管理
    软件相关概念
    ABI
    ABI即 Application Binary Interface
    Windows与Linux不兼容
    ELF(Executable and Linkable Format)
    PE(Portable Executable)
    库级别的虚拟化:
    Linux: WINE
    Windows: Cygwin

    API
    API即Application Programming Interface,API可以在各种不同的操作系统上实现给应用程序提供完全
    相同的接口,而它们本身在这些系统上的实现却可能迥异,主流的操作系统有两种,一种是Windows系
    统,另一种是Linux系统。由于操作系统的不同,API又分为Windows API和Linux API。在Windows平
    台开发出来的软件在Linux上无法运行,在Linux上开发的软件在Windows上又无法运行,这就导致了软
    件移植困难,POSIX 标准的出现就是为了解决这个问题
    POSIX:Portable Operating System Interface 可移植操作系统接口,定义了操作系统应该为应用程序
    提供的接口标准,是IEEE为要在各种UNIX操作系统上运行的软件而定义的一系列API标准的总称。
    Linux和windows都要实现基本的posix标准,程序就在源代码级别可移植了

    开发语言
    系统级开发
    汇编语言
    C
    C++
    应用级开发
    java
    Python
    go
    php
    perl
    delphi
    basic
    ruby
    bash

    C语言程序的实现过程
    C 程序源代码 --> 预处理 --> 编译 --> 汇编 --> 链接
    C语言的程序编译主要经过四个过程:
    预处理(Pre-Processing)
    编译 (Compiling)
    汇编 (Assembling)
    链接 (Linking)

    gcc 编译过程
    #分步骤编译运行
    gcc -E hello.c -o hello.i 对hello.c文件进行预处理,生成了hello.i 文件
    gcc -S hello.i -o hello.s 对预处理文件进行编译,生成了汇编文件
    gcc -c hello.s -o hello.o 对汇编文件进行编译,生成了目标文件
    gcc hello.o -o hello      对目标文件进行链接,生成可执行文件
    #一步实现编译过程
    gcc hello.c -o hello      直接编译链接成可执行目标文件

    软件模块的静态和动态链接
    链接主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接,分为静态
    和动态链接
    静态链接
    把程序对应的依赖库复制一份到包
    生成模块文件libxxx.a
    嵌入程序包
    升级难,需重新编译
    占用较多空间,迁移容易

    动态链接
    只把依赖加做一个动态链接
    生成模块文件libxxx.so
    连接指向
    占用较少空间,升级方便

    模块(库)文件
    查看二进制程序所依赖的库文件
    ldd /PATH/TO/BINARY_FILE
    管理及查看本机装载的库文件
    #加载配置文件中指定的库文件
    ldconfig
    #显示本机已经缓存的所有可用库文件名及文件路径映射关系
    /sbin/ldconfig –p

    配置文件:
    /etc/ld.so.conf,
    /etc/ld.so.conf.d/*.conf

    缓存文件:
    /etc/ld.so.cache

    软件包和包管理器
    软件包介绍
    开源软件最初只提供了.tar.gz的打包的源码文件,用户必须自已编译每个想在GNU/Linux上运行的软
    件。用户急需系统能提供一种更加便利的方法来管理这些软件,当Debian诞生时,这样一个管理工具
    dpkg也就应运而生,可用来管理deb后缀的"包"文件。从而著名的“package”概念第一次出现在
    GNU/Linux系统中,稍后Red Hat才开发自己的rpm包管理系统

    软件包中的文件分类
    二进制文件
    库文件
    配置文件
    帮助文件
    利用 cpio工具查看包文件列表
    rpm2cpio 包文件|cpio –itv         预览包内文件
    rpm2cpio 包文件|cpio –id “*.conf” 释放包内文件

    程序包管理器
    软件包管理器功能
    将编译好的应用程序的各组成文件打包一个或几个程序包文件,利用包管理器可以方便快捷地实现程序
    包的安装、卸载、查询、升级和校验等管理操作

    主流的程序包管理器
    redhat:rpm文件, rpm 包管理器,rpm:Redhat Package Manager,RPM Package Manager 
    debian:deb文件, dpkg 包管理器

    包命名
    源代码打包文件命名:
    name-VERSION.tar.gz|bz2|xz
    VERSION: major.minor.release

    rpm包命名方式:
    name-VERSION-release.arch.rpm
    VERSION: major.minor.release
    release:release.OS

    常见的arch:
    x86: i386, i486, i586, i686
    x86_64: x64, x86_64, amd64
    powerpc: ppc
    跟平台无关:noarch

    分类和拆包
    软件包为了管理和使用的便利,会将一个大的软件分类,放在不同的子包中。

    包的分类
    Application-VERSION-ARCH.rpm: 主包
    Application-devel-VERSION-ARCH.rpm 开发子包
    Application-utils-VERSION-ARHC.rpm 其它子包
    Application-libs-VERSION-ARHC.rpm 其它子包

    包的依赖
    软件包之间可能存在依赖关系,甚至循环依赖,即:A包依赖B包,B包依赖C包,C包依赖A包
    安装软件包时,会因为缺少依赖的包,而导致安装包失败。

    解决依赖包管理工具:
    yum:   rpm包管理器的前端工具
    dnf:   Fedora 18+ rpm包管理器前端管理工具,CentOS 8 版代替 yum
    apt:   deb包管理器前端工具
    zypper:suse上的rpm前端管理工具

    程序包管理器相关文件
    包文件组成 (每个包独有)
    包内的文件
    元数据,如:包的名称,版本,依赖性,描述等
    可能会有包安装或卸载时运行的脚本

    数据库(公共):/var/lib/rpm
    程序包名称及版本
    依赖关系
    功能说明
    包安装后生成的各文件路径及校验码信息

    获取程序包的途径
    软件包需要事先将源码进行编译后打包形成,获取包的途径如下:
    系统发版的光盘或官方网站
    CentOS镜像:
    https://www.centos.org/download/
    http://mirrors.aliyun.com
    http://mirrors.sohu.com
    http://mirrors.163.com
    Ubuntu 镜像:
    http://cdimage.ubuntu.com/releases/
    http://releases.ubuntu.com
    第三方组织提供
    Fedora-EPEL:Extra Packages for Enterprise Linux
    https://fedoraproject.org/wiki/EPEL
    https://mirrors.aliyun.com/epel/?spm=a2c6h.13651104.0.0.3bc47dfaZpesAr
    Rpmforge:官网:http://repoforge.org/, RHEL推荐,包很全,即将关闭
    Community Enterprise Linux Repository:http://www.elrepo.org,支持最新的内核和硬件相关包
    软件项目官方站点
    http://yum.mariadb.org/10.4/centos8-amd64/rpms/
    http://repo.mysql.com/yum/mysql-8.0-community/el/8/x86_64/
    搜索引擎
    http://pkgs.org
    http://rpmfind.net
    http://rpm.pbone.net
    https://sourceforge.net/
    自己制作
    将源码文件,利用工具,如:rpmbuild,fpm等工具制作成rpm包文件

    包管理器rpm
    CentOS系统上使用rpm命令管理程序包
    功能
    安装、卸载、升级、查询、校验、数据库维护

    安装
    格式
    rpm {-i|--install} [install-options] PACKAGE_FILE…
    选项:
    -v: verbose
    -vv: 
    -h: 以#显示程序包管理执行进度
    常用组合:
    rpm -ivh PACKAGE_FILE ...

    rpm包安装[install-options]
    --test:    测试安装,但不真正执行安装,即dry run模式
    --nodeps: 忽略依赖关系
    --replacepkgs | replacefiles
    --nosignature: 不检查来源合法性
    --nodigest:   不检查包完整性
    --noscripts:  不执行程序包脚本
    %pre:     安装前脚本 --nopre
    %post:    安装后脚本 --nopost
    %preun:   卸载前脚本 --nopreun
    %postun:  卸载后脚本 --nopostun

    升级和降级
    rpm {-U|--upgrade} [install-options] PACKAGE_FILE...
    rpm {-F|--freshen} [install-options] PACKAGE_FILE...
    upgrade:安装有旧版程序包,则“升级”,如果不存在旧版程序包,则“安装”
    freshen:安装有旧版程序包,则“升级”, 如果不存在旧版程序包,则不执行升级操作
    --oldpackage:降级
    --force:      强制安装
    常用组合
    rpm -Uvh PACKAGE_FILE ...
    rpm -Fvh PACKAGE_FILE ...
    升级注意项:
    (1) 不要对内核做升级操作;Linux支持多内核版本并存,因此直接安装新版本内核
    (2) 如果原程序包的配置文件安装后曾被修改,升级时,新版本提供的同一个配置文件不会直接覆盖老
    版本的配置文件,而把新版本文件重命名(FILENAME.rpmnew)后保留

    包查询
    rpm {-q|--query} [select-options] [query-options]

    [select-options]
    -a:所有包
    -f:查看指定的文件由哪个程序包安装生成
    -p rpmfile:针对尚未安装的程序包文件做查询操作
    --whatprovides CAPABILITY:查询指定的CAPABILITY由哪个包所提供
    --whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖
    [query-options]
    --changelog:查询rpm包的changelog
    -c:查询程序的配置文件
    -d:查询程序的文档
    -i:information
    -l:查看指定的程序包安装后生成的所有文件
    --scripts:程序包自带的脚本
    --provides:列出指定程序包所提供的CAPABILITY
    -R:查询指定的程序包所依赖的CAPABILITY

    常用查询用法:
    -qa 
    -q  PACKAGE
    -qi PACKAGE
    -qc PACKAGE
    -ql PACKAGE
    -qd PACKAGE
    -q --scripts PACKAGE
    -qf  FILE
    -qpi PACKAGE_FILE
    -qpl PACKAGE_FILE, ...

    包卸载
    格式:
    rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] 
    PACKAGE_NAME ...
    注意:当包卸载时,对应的配置文件不会删除, 以FILENAME.rpmsave形式保留

    包校验
    在安装包时,系统也会检查包的来源是否是合法的
    检查包的完整性和签名
    rpm -K|checksig rpmfile  

    在检查包的来源和完整性前,必须导入所需要公钥
    /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
    rpm -qa “gpg-pubkey*”

    软件在安装时,会将包里的每个文件的元数据,如:大小,权限,所有者,时间等记录下来,可以用来
    检查包中的文件是否和当初安装时有所变化
    rpm {-V|--verify} [select-options] [verify-options]

    S file Size differs
    M Mode differs (includes permissions and file type)
    5 digest (formerly MD5 sum) differs
    D Device major/minor number mismatch
    L readLink(2) path mismatch
    U User ownership differs
    G Group ownership differs
    T mTime differs
    P capabilities differ

    数据库
    rpm包安装时生成的信息,都放在rpm数据库中
    /var/lib/rpm
    可以重建数据库
    rpm {--initdb|--rebuilddb}
    initdb: 初始化,如果事先不存在数据库,则新建之,否则,不执行任何操作
    rebuilddb:重建已安装的包头的数据库索引目录

    yum和dnf
    CentOS使用 yum, dnf 解决rpm的包依赖关系
    YUM: Yellowdog Update Modifier,rpm的前端程序,可解决软件包相关依赖性,可在多个库之间定位
    软件包,up2date的替代工具,CentOS 8 用dnf 代替了yum ,不过保留了和yum的兼容性,配置也是通
    用的

    yum/dnf 工作原理
    yum/dnf 是基于C/S 模式
    yum 服务器存放rpm包和相关包的元数据库
    yum 客户端访问yum服务器进行安装或查询等
    yum 实现过程
    先在yum服务器上创建 yum repository(仓库),在仓库中事先存储了众多rpm包,以及包的相关的
    元数据文件(放置于特定目录repodata下),当yum客户端利用yum/dnf工具进行安装时包时,会自动
    下载repodata中的元数据,查询远数据是否存在相关的包及依赖关系,自动从仓库中找到相关包下载并
    安装。
    yum服务器的仓库可以多种形式存在:
    file:// 本地路径
    http://
    https://
    ftp://
    注意:yum仓库指向的路径一定必须是repodata目录所在目录

    yum客户端配置
    yum客户端配置文件
    /etc/yum.conf #为所有仓库提供公共配置
    /etc/yum.repos.d/*.repo: #为每个仓库的提供配置文件

    相关变量
    yum的repo配置文件中可用的变量:
    $releasever: 当前OS的发行版的主版本号,如:8,7,6
    $arch: CPU架构,如:aarch64, i586, i686,x86_64等
    $basearch:  系统基础平台;i386, x86_64
    $contentdir:表示目录,比如:centos-8,centos-7
    $YUM0-$YUM9: 自定义变量

    repo仓库配置文件指向的定义:
    [repositoryID]
    name=Some name for this repository
    baseurl=url://path/to/repository/
    enabled={1|0}
    gpgcheck={1|0}
    gpgkey=URL
    enablegroups={1|0}
    failovermethod={roundrobin|priority}
         roundrobin:意为随机挑选,默认值
         priority:按顺序访问
    cost= 默认为1000

    其中baseurl指向的路径
    阿里云仓库路径:http://mirrors.aliyun.com/repo/
    CentOS系统的yum源
    阿里云
    https://mirrors.aliyun.com/centos/$releasever/os/x86_64/ 
    华为云 
    https://mirrors.huaweicloud.com/            
    清华大学
    https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/os/x86_64/

    EPEL的yum源
    阿里云
    https://mirrors.aliyun.com/epel/$releasever/x86_64
    阿里巴巴开源软件
    https://opsx.alibaba.com/

    yum-config-manager命令
    可以生成yum仓库的配置文件及启用或禁用仓库,来自于yum-utils包
    #增加仓库
    yum-config-manager --add-repo URL或file 
    #禁用仓库
    yum-config-manager --disable  “仓库名" 
    #启用仓库
    yum-config-manager --enable  “仓库名”

    yum命令
    yum [options] [command] [package ...]
    yum的命令行选项:
    -y   #自动回答为“yes”
    -q   #静默模式
    --nogpgcheck   #禁止进行gpg check
    --enablerepo=repoidglob    #临时启用此处指定的repo,支持通配符,如:”*“
    --disablerepo=repoidglob   #临时禁用此处指定的repo,和上面语句同时使用,放在后面的生效

    显示仓库列表
    yum repolist [all|enabled|disabled]
    显示程序包
    yum list
    yum list [all | glob_exp1] [glob_exp2] [...]
    yum list {available|installed|updates} [glob_exp1] [...]

    安装程序包
    yum install package1 [package2] [...]
    yum reinstall package1 [package2] [...] #重新安装

    卸载程序包
    yum remove | erase package1 [package2] [...]

    升级和降级
    yum update [package1] [package2] [...]
    yum downgrade package1 [package2] [...] (降级)
    检查可用升级:
    yum check-update

    查看程序包information:
    yum info [...]

    查看指定的特性(可以是某文件)是由哪个程序包所提供:
    yum provides | whatprovides feature1 [feature2] [...]

    以指定的关键字搜索程序包名及summary信息
    yum search string1 [string2] [...]

    查看指定包所依赖的capabilities:
    yum deplist package1 [package2] [...]

    仓库缓存
    清除目录/var/cache/yum/缓存
    yum clean [ packages | metadata | expire-cache | rpmdb | plugins | all ]
    构建缓存:
    yum makecache
    查看yum事务历史
    yum 执行安装卸载命令会记录到相关日志中
    日志 文件:
    #CentOS 7以前版本日志
    /var/log/yum.log
    #CentOS 8 版本日志
    /var/log/dnf.rpm.log
    /var/log/dnf.log

    日志命令
    yum history [info|list|packages-list|packages-info|summary|addon-
    info|redo|undo|rollback|new|sync|stats]

    安装及升级本地程序包
    yum localinstall|install rpmfile1 [rpmfile2] [...]
    yum localupdate|update rpmfile1 [rpmfile2] [...]

    包组管理的相关命令
    yum groupinstall group1 [group2] [...]
    yum groupupdate group1 [group2] [...]
    yum grouplist [hidden] [groupwildcard] [...]
    yum groupremove group1 [group2] [...]
    yum groupinfo group1 [...]

    实现 私用 yum仓库
    下载所有yum仓库的相关包和meta 数据
    #CentOS 8 dnf 工具集成
    dnf reposync  --repoid=REPOID --download-metadata -p /path 
    dnf reposync --help #查看帮助

    #CentOS 7 以前版本,reposync工具来自于yum-utils包
    reposync --repoid=REPOID --download-metadata -p /path  

    创建私有yum仓库:
    createrepo [options] <directory>

    DNF 介绍
    DNF,即DaNdiFied,是新一代的RPM软件包管理器。DNF 发行日期是2015年5月11日,DNF 包管理
    器采用Python 编写,发行许可为GPL v2,首先出现在Fedora 18 发行版中。在 RHEL 8.0 版本正式取代
    了 YUM,DNF包管理器克服了YUM包管理器的一些瓶颈,提升了包括用户体验,内存占用,依赖分
    析,运行速度等

    配置文件:/etc/dnf/dnf.conf  
    仓库文件:/etc/yum.repos.d/ *.repo
    日志:/var/log/dnf.rpm.log
         /var/log/dnf.log
    DNF 使用帮助:man dnf
    dnf 用法与yum一致

    yum Troubleshooting
    故障排错:yum 和 dnf 失败最主要原因:
             yum的配置文件格式或路径错误
               解决方法:检查/etc/yum.repos.d/*.repo文件格式
             yum cache
               解决方法:yum clean all
             网络不通:
               解决方法:网卡配置      

    程序包编译
    源码编译介绍
    程序包编译安装:
    源代码-->预处理-->编译-->汇编-->链接-->执行
    多文件:文件中的代码之间,很可能存在跨文件依赖关系
    虽然有很多开源软件将软件打成包,供人们使用,但并不是所有源代码都打成包,如果想使用开源软件,可能需要自已下载源码,进行编译安装。另外即使提供了包,但是生产中需要用于软件的某些特性,仍然需要自行编译安装。但是利用源代码编译安装是比较繁琐的,庆幸的是有相关的项目管理工具可以大大减少编译过程的复杂度

    开源程序源代码的获取
    项目官方自建站点:
    apache.org (ASF:Apache Software Foundation)
    mariadb.org
    代码托管:
    Github.com
    gitee.com
    SourceForge.net
    code.google.com

    编译源码的项目工具
    C、C++的源码编译:使用 make 项目管理器
    configure脚本 --> Makefile.in --> Makefile
    相关开发工具:
    autoconf: 生成configure脚本
    automake:生成Makefile.in
    java的源码编译: 使用 maven

    C语言源代码编译安装过程
    利用编译工具,通常只需要三个大的步骤
    ./configure
    (1) 通过选项传递参数,指定安装路径、启用特性等;执行时会参考用户的指定以及Makefile.in文件生成Makefile
    (2) 检查依赖到的外部环境,如依赖的软件包
    make 根据Makefile文件,会检测依赖的环境,进行构建应用程序,
    make install 复制文件到相应路径
    注意:安装前可以通过查看README,INSTALL获取帮助

    编译安装准备
    准备:安装相关的依赖包
    开发工具:make, gcc (c/c++编译器GNU C Complier)
    开发环境:开发库(glibc:标准库),头文件,可安装开发包组 Development Tools
    软件相关依赖包
    生产实践:基于最小化安装的系统建议安装下面相关包
    yum install  gcc make autoconf gcc-c++ glibc glibc-devel pcre pcre-devel openssl 
    openssl-devel systemd-devel zlib-devel  vim lrzsz tree tmux lsof tcpdump wget 
    net-tools iotop bc bzip2 zip unzip nfs-utils man-pages

    编译安装
    1.第一步:运行 configure 脚本,生成Makefile 文件
    其选项主要功能:可以指定安装位置,指定启用的特性
    获取其支持使用的选项:./configure --help
    选项分类:
    安装路径设定:
    --prefix=/PATH:    指定默认安装位置,默认为/usr/local/
    --sysconfdir=/PATH:配置文件安装位置
    System types: 支持交叉编译
    软件特性和相关指定:
    Optional Features:    可选特性
     --disable-FEATURE
     --enable-FEATURE[=ARG]
    Optional Packages:    可选包
     --with-PACKAGE[=ARG] 依赖包
     --without-PACKAGE    禁用依赖关系
    注意:通常被编译操作依赖的程序包,需要安装此程序包的“开发”组件,其包名一般类似于name-devel-VERSION

    2.第二步:make
    3.第三步:make install

    安装后的配置
    1.二进制程序目录导入至PATH环境变量中
    编辑文件/etc/profile.d/NAME.sh
    export PATH=/PATH/TO/BIN:$PATH
    2.相关用户及文件
    有些开源软件编译完成后,还需要创建相关的用户及文件
    3.导入帮助手册
    编辑/etc/man.config|man_db.conf文件,添加一个MANPATH

    Ubuntu 软件管理
    Debian软件包通常为预编译的二进制格式的扩展名“.deb”,类似rpm文件,因此安装快速,无需编译软件。包文件包括特定功能或软件所必需的文件、元数据和指令
    dpkg:package manager for Debian,类似于rpm, dpkg是基于Debian的系统的包管理器。可以安装,删除和构建软件包,但无法自动下载和安装软件包或其依赖项
    apt:Advanced Packaging Tool,功能强大的软件管理工具,甚至可升级整个Ubuntu的系统,基于客户/服务器架构,类似于yum

    APT工作原理
    在服务器上先复制所有DEB包,然后用APT的分析工具genbasedir根据每个DEB 包的包头(Header)信息对所有的DEB包进行分析,并将该分析结果记录在文件夹base内的一个DEB 索引清单文件中,一旦APT 服务器内的DEB有所变动,要使用genbasedir产生新的DEB索引清单。客户端在进行安装或升级时先要查询DEB索引清单,从而获知所有具有依赖关系的软件包,并一同下载到客户端以便安装。当客户端需要安装、升级或删除某个软件包时,客户端计算机取得DEB索引清单压缩文件后,会将其解压置放于 /var/cache/apt/,而客户端使用apt-get install或apt-get upgrade命令的时候,就会将这个文件夹内的数据和客户端计算机内的DEB数据库比对,知道哪些DEB已安装、未安装或是可以升级的

    dpkg 包管理器
    帮助参看:man dpkg
    dpkg 常见用法
    #安装包
    dpkg -i package.deb 
    #删除包,不建议,不自动卸载依赖于它的包
    dpkg -r package 
    #删除包(包括配置文件)
    dpkg -P package 
    #列出当前已安装的包,类似rpm -qa
    dpkg -l
    #显示该包的简要说明,类似rpm –qi
    dpkg -l package 
    #列出该包的状态,包括详细信息,类似rpm –qi
    dpkg -s package 
    #列出该包中所包含的文件,类似rpm –ql 
    dpkg -L package 
    #搜索包含pattern的包,类似rpm –qf
    dpkg -S <pattern> 
    #配置包,-a 使用,配置所有没有配置的软件包
    dpkg --configure package 
    #列出 deb 包的内容,类似rpm –qpl 
    dpkg -c package.deb 
    #解开 deb 包的内容
    dpkg --unpack package.deb
    注意:一般建议不要使用dpkg卸载软件包。因为删除包时,其它依赖它的包不会卸载,并且可能无法再正常运行

    apt
    查看帮助:apt help
    apt install  安装软件包
    apt remove   移除软件包
    apt purge    移除软件包及配置文件
    apt update   刷新存储库索引
    apt upgrade  升级所有可升级的软件包
    apt autoremove    自动删除不需要的包
    apt full-upgrade  在升级软件包时自动处理依赖关系
    apt search   搜索应用程序
    apt show     显示安装细节

    apt 特有的命令
    apt list    列出包含条件的包(已安装,可升级等)
    apt edit-sources 编辑源列表

    APT包索引配置文件
    /etc/apt/sources.list
    /etc/apt/sources.list.d
    (可以修改上面文件为国内的安装源,提高速度)

    apt命令操作(如安装和删除软件包)日志文件
    /var/log/dpkg.log

    ubuntu建议安装的常用包
    apt purge ufw lxd lxd-client lxcfs liblxc-common
    apt install iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfscommon lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev gcc 
    openssh-server iotop unzip zip
  • 相关阅读:
    使用 Python 编码和解码 JSON 对象
    搞定github下载加速
    git错误:fatal: Could not read from remote repository.解决
    webstorm安装配置
    node.js下载安装
    IDEA安装小配置
    JAVA软件安装
    关于升级一般软件的一些想法
    linux 的 逻辑卷管理
    记一次内核升级。
  • 原文地址:https://www.cnblogs.com/llliuhuiii/p/12826132.html
Copyright © 2011-2022 走看看