精华内容
下载资源
问答
  • 挂载
    千次阅读
    2017-03-15 13:50:54

    1. 简介

    挂载:Linux中所有的可读取设备(硬盘、光盘、U盘、软盘、移动硬盘等)都必须挂载之后才可以使用,系统硬盘分区是Linux系统开机自动挂载的,所有的可读取设备都有一个设备文件名,挂载指的就是将设备文件名和挂载点(任意一个空目录)连接起来。

    2. 查询挂载和自动挂载

    mount   
    或
    mount -l
    查询Linux系统中已经挂载的设备文件名、挂载点、文件系统
    
    mount -a        
    依据配置文件/etc/fstab的内容,自动进行挂载

    3. 挂载命令

    命令格式:mount [-t 文件系统] [-L 卷标名] [-o 特殊选项] 设备文件名 挂载点

    作用:执行挂载操作,将设备文件名和挂载点连接起来。

    选项:

    • -t 文件系统类型:手工指定挂载的文件系统类型(ext4、iso9660),一般无需手动指定。因为对于磁盘分区,默认的文件系统是ext4;对于光盘,默认的文件系统是iso9660。
    • -L 卷标名:相当于分区的别名,意义不大。
    • -o 特殊选项:可指定挂载的额外选项,多个特殊选项之间用逗号分隔。

    常用的特殊选项有以下几个:

    特殊选项说明
    remount重新挂载已挂载的文件系统。
    exec允许执行文件系统中的可执行文件,默认值。
    noexec不允许执行文件系统中的可执行文件。
    rw文件系统挂载时,权限设置为读写,默认值。
    ro文件系统挂载时,权限设置为只读。

    4. 挂载光盘

    具体可参考:http://blog.csdn.net/lamp_yang_3533/article/details/53284290

    5. 解挂命令

    命令格式:umount 设备文件名或挂载点

    作用:解除挂载

    注意:不能在当前目录中解除挂载,故必须先切换到其他目录。

    6. 挂载U盘

    挂载U盘之前,必须先知道U盘的设备文件名。

    注意:如果用的是虚拟机Linux系统,必须先将鼠标点进虚拟机Linux系统界面,再来插入U盘,否则,U盘会被真实机所识别。

    [root@localhost ~]# fdisk -l
    
    Disk /dev/sda: 10.7 GB, 10737418240 bytes
    255 heads, 63 sectors/track, 1305 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x000dbaad
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          26      204800   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              26         157     1048576   82  Linux swap / Solaris
    Partition 2 does not end on cylinder boundary.
    /dev/sda3             157        1306     9231360   83  Linux
    
    Disk /dev/sdb: 32.0 GB, 32018268160 bytes
    255 heads, 63 sectors/track, 3892 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1               1        3893    31267824    c  W95 FAT32 (LBA)
    
    查看系统中所有已连接的存储设备的设备文件名

    可发现,在该Linux系统中,将U盘的设备文件名识别为/dev/sdb1。

    然后,创建一个空目录作为U盘的挂载点。

    mkdir /mnt/usb

    最后,执行挂载命令。

    mount -t vfat /dev/sdb1 /mnt/usb

    注意:Linux系统默认是不支持NTFS文件系统,而且,它把FAT16识别为fat,把FAT32识别为vfat。

    之后,就可以浏览U盘中的文件了。

    cd /mnt/usb
    ll

    想要安全退出U盘,先解除挂载,再拔出U盘即可。

    cd
    umount /mnt/usb

    7. 挂载移动硬盘

    通常,移动硬盘的文件系统是NTFS格式的,而Linux系统默认不支持NTFS文件系统。

    为了能让Linux系统可以挂载移动硬盘,我们必须使Linux系统支持NTFS文件系统。

    具体的解决方案请参考下一讲

    更多相关内容
  • mount/umount命令挂载及卸载指定的文件系统 挂载: mount [选项] [-L<标签>] [-o<选项>] [-t<文件系统类型>] [设备名] [挂载点] 取消挂载: umount [挂载点]
  • 手把手教你挂载

    2021-01-09 10:25:07
    文章目录挂载是什么,我们为什么要挂载一步步演示挂载演示环境一些知识点挂载步骤Parted命令挂载 挂载是什么,我们为什么要挂载 在我看来,Linux下的硬盘挂载,相当于是windows的分配盘符。 Linux下一切皆文件,所以...
  • 查看nginx容器一直都是退出状态
  • 使用 RaiDrive 实现挂载阿里云盘到本地 并且 开机自启动
  • 1. 手动挂载 cat /proc/partitions 识别U盘在系统中的设备号 mount /dev/sdb1 /mnt/udisk 在/mnt/udisk目录下挂载sdb1,如果没有udisk则手动创建一个 umount /mnt/udisk 卸载u盘 2. 自动挂载 禁止自动挂载: $ ...
  • 文章目录1 查询与自动挂载2 挂载命令格式3 挂载光盘4 卸载命令5 挂载U盘 注:转载请标明原文出处链接:https://xiongyiming.blog.csdn.net/article/details/105874664 1 查询与自动挂载 Linux挂载称为分配挂载点,...
  • android 新增分区以及挂载方法
  • Ubuntu 添加新分区并设置自动挂载
  • 挂载:指的就是将设备文件中的顶级目录连接到Linux根目录下的某一目录,访问此目录就等同于访问设备文件。 Linux系统中"一切皆文件",所有文件都放置在以根目录为树根的树形目录结构中。 在Linux看来,任何硬件...

    目录

    一、Linux的挂载原理

    1、概念

    2、举例

    3、补充

    4、LINUX文件结构和WINDOWS的不同

    5、挂载文件系统

    6、mount结构与原理 

     7、mount 和umount命令

    二、Linux 如何挂载NAS盘 

    三、错误记录 


    一、Linux的挂载原理

    1、概念

    挂载:指的就是将设备文件中的顶级目录连接到Linux根目录下的某一目录,访问此目录就等同于访问设备文件

    Linux系统中"一切皆文件",所有文件都放置在以根目录为树根的树形目录结构中。

    在Linux看来,任何硬件设备也都是文件,它们各有自己的一套文件系统。

    当在Linux系统中使用这些硬件设备时,只有将硬件设备的文件目录  嫁接到Linux本身的文件目录,硬件设备才能为我们所用。这里的嫁接过程我们称之为"挂载"。

    既将一个文件系统的顶层目录挂到另一个文件系统的子目录上,使它们成为一个整体,称为挂载;

    注意:纠正一个误区,并不是根目录下任何一个目录都可以作为挂载点,由于挂载操作会使得原有目录中文件被隐藏,因此根目录以及系统原有目录都不要作为挂载点,会造成系统异常甚至崩溃,挂载点最好是新建的空目录。

    2、举例

    (摘抄自:http://c.biancheng.net/view/2859.html
    举个例子,我们想通过命令行访问某个 U 盘中的数据,图 1 所示为 U 盘文件目录结构和 Linux 系统中的文件目录结构。


    图 1 U 盘和 Linux 系统文件目录结构


    图 1 中可以看到,目前 U 盘和 Linux 系统文件分属两个文件系统,还无法使用命令行找到 U 盘文件,需要将两个文件系统进行挂载。

    接下来,我们在根目录下新建一个目录 /sdb-u,通过挂载命令将 U 盘文件系统挂载到此目录,

    mount /dev/sdb1      /sdb-u

    挂载效果如图 2 所示。


    图 2 文件系统挂载


    可以看到,U 盘文件系统已经成为 Linux 文件系统目录的一部分,此时访问 /sdb-u/ 就等同于访问 U 盘。

    前面讲过,根目录下的 /dev/ 目录文件负责所有的硬件设备文件,事实上,当 U 盘插入 Linux 后,系统也确实会给 U 盘分配一个目录文件(比如 sdb1),就位于 /dev/ 目录下(/dev/sdb1),但无法通过 /dev/sdb1/ 直接访问 U 盘数据,访问此目录只会提供给你此设备的一些基本信息(比如容量)。

    总之,Linux 系统使用任何硬件设备,都必须将设备文件与已有目录文件进行挂载。

    3、补充

    前面讲过,根目录下的/dev/目录文件负责所有的硬件设备文件。

    事实上,当U盘插入Linux后,系统也确实会给U盘分配一个目录文件(比如:sdb4)。

    位于/dev/sdb4,但是无法通过/dev/sdb4/直接访问U盘数据。

    我们只要执行mount操作后就可以访问U盘数据了。

    总之,Linux系统使用任何硬件设备,都必须将设备文件与已有目录文件进行挂载。

    4、LINUX文件结构和WINDOWS的不同

    摘自:https://www.freesion.com/article/4836457591/

    Linux是多用户操作系统,所以制定一个固定的目录规划有助于对系统文件和不同的用户文件进行统一管理——Linux采用标准的树状目录结构

    Windows不同的是,在最顶层的文件目录不是唯一的(多个盘符)


    5、挂载文件系统

    linux系统中每个分区都是一个文件系统,都有自己的目录层次结构。linux会将这些分属不同分区的、单独的文件系统按一定的方式形成一个系统的总的目录层次结构;这里所说“按一定方式”就是指的挂载

    通俗的说,将一个文件系统的顶层目录挂到另一个文件系统的子目录上,使它们成为一个整体,称为挂载;我们把这个子目录叫“挂载点”

    注意几点:
    1. 挂载点必须是一个目录
    2. 一个分区挂载在一个已存在的目录上,这个目录可以不为空,但挂载后这个目录下以前的内容将不可用;对于其他操作系统建立的文件系统的挂载也是这样
    挂载前要了解linux是否支持所要挂载的文件系统格式

    6、mount结构与原理 

    摘自:https://blog.csdn.net/jinking01/article/details/105683360

    在 Kernel 世界里,挂载是一项很了不起的特性,它可以将不同类型的文件系统组合成一个有机的整体,从使用者角度来看不同的文件系统并没有什么区别,那么 Kernel 是怎么做到呢?

    首先,Kernel 会为每个文件系统准备一个 mount 结构,然后再把这个结构加入到 vfs 这颗大树上就好了。

    这么一个小小的 mount 结构就这么神奇?

    请看图,一个 mount 中有三个很重要的成员,他们分别指向父 mount 结构(6)、本文件系统自己的根目录(7)和本文件系统的挂载点(8)。

    前两个很好理解,那么挂载点是什么呢?简单地说挂载点就是父级文件系统的某个目录(父级文件系统中的目录表示),一旦将某个文件系统efs挂载到某个目录上/home/a/,这个目录/home/a/就成了该文件系统efs的根目录了。并且该目录/home/a/的标志位 DCACHE_MOUNTED 将被置位,这将表明这个目录已经是一个挂载点了,如果要访问这个目录/home/a/的话就要顺着 mount 结构访问另一个文件系统了(因为efs能力处理/home/a/以下的内容,之上的内容就是另一个文件系统里的内容了),原来的内容将变得不可访问。
        现在我们从图的左边讲起,带你一窥 mount 的风采。一个进程有一个叫 root 的 path 结构,它就是本进程的根目录(大多数情况下它就是系统根目录),root 中两个成员分别指向某个文件系统的 mount 结构(其实是指向 mount.mnt 但这样理解没问题)(1)(rootfs文件系统的mount结构)和该文件系统的根目录(2)(就是/目录),这个文件系统就是所谓根文件系统(在图中就是 rootfs)。由于它是根文件系统,所以它的父 mount 结构就是它自己(4)它的挂载点就是它自己的根目录(5)。

    但是 rootfs 只是一个临时的根文件系统,在 Kernel 的启动过程中加载完 rootfs 之后会紧接着解压缩 initramfs 到 rootfs 中,这里面包括了驱动以及加载真正的根文件系统的工具,Kernel 通过加载这些驱动、使用这些工具实现了挂载真正的根文件系统。之后 rootfs 将退出历史舞台,但作为文件系统的总根 rootfs 并不会被卸载(注)。图中 fs1 就是所谓的真正的根文件系统,Kernel 把它挂载到了 rootfs 的根目录上(8),并且将它的父 mount 结构指向了 rootfs(6)。这时访问根目录的话就会直接访问到 fs1 的根目录,而 rootfs 就好像不存在了一样。
        再看 fs1,他有一个子目录“mnt/”,以及“mnt/”的子目录“a”,此时路径“/mnt/a/”是可访问的。但现在我们还有另一个文件系统 fs2,我们把它挂载到“/mnt/”上会发生什么呢?首先 fs2 的父 mount 将指向 fs1(9),然后 fs2 的挂载点将指向 “/mnt/”(10),同时“mnt/”的 DCACHE_MOUNTED 将被置位。此时路径“/mnt/a/”就不可访问了,取而代之的是“/mnt/b/”。本着不怕麻烦的精神我们再折腾一下,把 fs3 也挂载到“/mnt/”上,这时和挂载 fs2 一样父 mount 将指向 fs2(11),但是挂载点应该指向哪里呢?答案是 fs2 的根目录(12)。这时“/mnt/b/”也消失了,我们只能看见“/mnt/c”了。这样整个结构就形成了一个挂载的序列,最后挂载的在序列末尾,Kernel 可以很容易的通过这个序列找到最初的挂载点和最终的文件系统。
        在顺序查找的情景下,当遇到一个目录时 Kernel 会判断这个目录是不是挂载点(检查 DCACHE_MOUNTED 标志位),如果是就要找到挂载到这个目录的文件系统,继而找到该文件系统的根目录,然后在判断这个根目录是不是挂载点,如果是那就再往下找直到某个文件系统的根目录不再是挂载点。
        反向查找也和顺序查找类似。

     7、mount 和umount命令

    挂载:把分区和目录对应的过程   建立映射 

    挂载点:挂载在文件树中的位置

    mount 参数 设备名称 挂载点

    -a 安装在/etc/fstab文件中列出的所有文件系统.

    -l 列出当前已挂载的设备,文件系统名称和挂载点

    -o 指定挂载选项,

    -t 文件系统类型,指定设备的文件系统类型,

    ext2 

    Msdos

    Vfat

    Nfs

    iso9660

    Audo 自动检测文件系统

    参考文献

    linux 挂载_图解Linux中的挂载原理 https://blog.csdn.net/weixin_39573598/article/details/110810698

    二、Linux 如何挂载NAS盘 

    linux下需要将nas盘挂在到系统中;
    方法:
    首先本地创建一个挂载目录:

        mkdir /mnt/nas

    挂载目录:

    mount  -o  username=flt,password=r9SDy,iocharset=utf8   //192.168.2.90/产品部   /mnt/nas
     

    参数说明:

            username=flt                        [nas用户名]
            password=a^6r9dSDy                  [nas密码]     
            iocharset=utf8                      [路径中如有中文则添加此项,支持中文路径] 
            //192.168.2.90/产品部                [nas路径]
            /mnt/nas                            [挂载路径]

    参数之间用,(逗号)分隔。

    如果密码中有,号,则以上命令无法执行完成,因为需要参数之间用“,”逗号分隔,导致会认为提前结束了。
    所以可以用下面方法,创建一个环境变量:

    export PASSWD='!3\5g6,B'

    mount -o username=mkx,iocharset=utf8 //192.168.10.90/产品部 /mnt/nas

    注:shell会自动查找PASSWD

    使用完成后将其卸载:

    umount -l /mnt/nas

    原文链接:https://blog.csdn.net/xiaominggunchuqu/article/details/78912330

    三、错误记录 

    FS-Cache: Netfs 'nfs' registered for caching

    问题原因是在服务器上没有安装nfs。使用如下命令安装

    yum -y install nfs-utils

    https://blog.csdn.net/w892824196/article/details/103934696

    展开全文
  • docker 的具名挂载与匿名挂载

    千次阅读 2022-03-08 20:22:21
    大家好,今天我们分享一下docker 的具名挂载与匿名挂载 以这条命令举例 [root@localhost ~]# docker run -d -P --name nginx02 -v /etc/nginx/ nginx d8e9b9084cf884e7e0d11c560c3f50d94f2d4a2d9c77fccb3f52b5cfd8e...

    大家好,今天我们分享一下docker 的具名挂载与匿名挂载

    以这条命令举例

    [root@localhost ~]# docker run -d -P --name nginx02  -v /etc/nginx/  nginx
    d8e9b9084cf884e7e0d11c560c3f50d94f2d4a2d9c77fccb3f52b5cfd8e55392
    [root@localhost ~]# 
    

    这里我们就没有给它指定端口: 它对应的外网端口是随即的

    查看一下正在运行的容器:

    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                     NAMES
    d8e9b9084cf8   nginx          "/docker-entrypoint.…"   11 minutes ago   Up 11 minutes   0.0.0.0:49153->80/tcp, :::49153->80/tcp   nginx02
    6d6fa6a4c6d7   5d0da3dc9764   "/bin/bash"              32 hours ago     Up 32 hours                                               nice_panini
    [root@localhost ~]# 
    

    对应的外网端口是49153

    我们可以使用浏览器上访问:http://192.168.1.12:49153

    在这里插入图片描述

    这是docker数据卷命令的帮助:

    [root@localhost ~]# docker  volume  --help 
    
    Usage:  docker volume COMMAND
    
    Manage volumes
    
    Commands:
      create      Create a volume
      inspect     Display detailed information on one or more volumes
      ls          List volumes
      prune       Remove all unused local volumes
      rm          Remove one or more volumes
    
    Run 'docker volume COMMAND --help' for more information on a command.
    

    这些都是匿名的挂载 ,因为没有给它起名字

    DRIVER    VOLUME NAME
    local     3f0cc224bb62dceae38c25d6eaee76512b39ec786590099f4b2930674640756f
    local     8e16818bb95e740e59e5ef920e54751eb64db44f4cf43841a9c45aa6ad6646cc
    local     686e9b7764c19581aea3107940fc28c68121759ce28b31fabc0fce00659ff7ca
    local     882c0d1810e3ac6fddabcff2c65f1022605f450a6c49504edf57e78de14da1e5
    local     1490f17c760b935d926fb1fedc7de4e0e07f1084fcf8c769c672d50f43757f8f
    local     471762be4837d40ad175b7cfe74b81a51b4b3e752cb6f15e7e79d09ffc5f65fc
    local     af4dc486d8335ec0e524c0e30a0ae037ef05dfa7a4ed3e4e0dd59954c5084a9e
    local     c26b0f08ebdb140d91cb450313e9e314239c1c3553a612e6534154006aa19744
    local     c52728c97a7ee672216ccb2d4392fa83bc480dd9646ddb5577e1124eb98e15b6
    

    这里写一个具名挂载

    [root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx 
    

    看最后的一行,就是具名挂载

    [root@localhost ~]# docker volume ls
    DRIVER    VOLUME NAME
    local     3f0cc224bb62dceae38c25d6eaee76512b39ec786590099f4b2930674640756f
    local     8e16818bb95e740e59e5ef920e54751eb64db44f4cf43841a9c45aa6ad6646cc
    local     686e9b7764c19581aea3107940fc28c68121759ce28b31fabc0fce00659ff7ca
    local     882c0d1810e3ac6fddabcff2c65f1022605f450a6c49504edf57e78de14da1e5
    local     1490f17c760b935d926fb1fedc7de4e0e07f1084fcf8c769c672d50f43757f8f
    local     471762be4837d40ad175b7cfe74b81a51b4b3e752cb6f15e7e79d09ffc5f65fc
    local     af4dc486d8335ec0e524c0e30a0ae037ef05dfa7a4ed3e4e0dd59954c5084a9e
    local     c26b0f08ebdb140d91cb450313e9e314239c1c3553a612e6534154006aa19744
    local     c52728c97a7ee672216ccb2d4392fa83bc480dd9646ddb5577e1124eb98e15b6
    local     juming-nginx
    

    显示数据卷的具体信息

    [root@localhost ~]# docker volume inspect juming-nginx 
    [
        {
            "CreatedAt": "2022-03-05T18:16:53+08:00",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
            "Name": "juming-nginx",
            "Options": null,
            "Scope": "local"
        }
    ]
    

    docker 容器中所有的卷,在没有指定目录的情况下,都在var/lib/docker/volumes/juming-nginx/_data",

    我们可以通过具名挂载找到卷的位置,大多数情况下,我们使用具名挂载

    关于docker的挂载问题,有三个比较容易混淆的概念: (区分的方式)

    1.具名挂载:-v 参数 卷名:容器内路径

    2.匿名挂载:-v 参数后面 没有写上容器之外的地址, docker 自己会在docker内部给你找个位置

    3.指定路径挂载: -v /宿主机路径::容器内路径

    这里有一个权限问题:

    [root@localhost ~]# docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx:rw  nginx 
    6590da464b6ea5cecf58f1cfcdfe2df35092383adb7aaddac4ca5d463367c979
    

    rw :可读可写的权限
    ro : 可读权限

    [root@localhost ~]# docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx:ro  nginx 
    

    这个会对我们挂载出来的内容进行限定

    ro 权限说明命令只可以被宿主机操作,容器的内部将无法进行操作

    平时不需要动它

    好了,有关于docker 的具名挂载与匿名挂载就到这里了,谢谢大家

    展开全文
  • 到底什么是挂载

    千次阅读 2022-01-20 12:23:54
    在 LinuxLinuxLinux 的文件系统中,有个很重要的概念就是挂载挂载大家应该都很熟悉,除了根文件系统,其他所有文件系统都要先挂载到根文件系统中的某个目录之后才能访问。 所谓的根文件系统就是系统启动的时候安装...
    • 首发公号:Rand_cs

    L i n u x Linux Linux 的文件系统中,有个很重要的概念就是挂载,挂载大家应该都很熟悉,除了根文件系统,其他所有文件系统都要先挂载到根文件系统中的某个目录之后才能访问。

    所谓的根文件系统就是系统启动的时候安装的第一个文件系统,它也是内核映像所在的文件系统。而 挂载到某个目录某个目录 就是所谓的挂载点。

    L i n u x Linux Linux 中有专门的命令来挂载文件系统,mount device dir d e v i c e device device 为要挂载的设备文件名, d i r dir dir 为挂载点。这里所说的设备不是真的指单个实体设备,而是其上的逻辑设备,比如说一个磁盘上的不同分区都可以看作是不同的设备。

    每个设备都有一个设备号来标识,设备号可以分为两部分,一部分叫做主设备号 M a j o r Major Major N u m b e r Number Number,它用来标识某一类型的设备,比如说磁盘。另一部分叫做次设备号 M i n o r Minor Minor N u m b e r Number Number,它来标识某一具体设备,比如说磁盘上的某一具体分区。

    当文件系统挂载到某个目录后,我们就可以通过这个目录来访问该文件系统,很多地方就只是简单的这样讲了一下,但其实这只能说是挂载的作用,那到底什么是挂载,要想解决这个问题还是只能从源码着手。下面我将根据 L i n u x Linux Linux 0.11 0.11 0.11 的代码来讲述挂载,涉及的东西比较多,我们只讨论相关的部分。

    数据结构

    m_inode,内存中的 inode

    struct m_inode {
        /********略*********/
    	unsigned short i_mode;   //文件类型和属性
    	unsigned char i_mount;   //是否有文件系统挂载到这儿
        unsigned short i_zone[9]; //索引取,如果是块/字符设备文件i_zone[0]是设备号
        /********略*********/
    };
    

    super_block,内存中的超级块

    struct super_block {
        /********略*********/
    	unsigned short s_magic;    //文件系统魔数
        /********略*********/
    	unsigned short s_dev;      //设备号
        /********略*********/
        struct m_inode * s_isup;   //被挂载的文件系统的根目录inode
    	struct m_inode * s_imount; //该文件系统被安装到此inode
    };
    

    所谓的内存中的超级块和 i n o d e inode inode 指的是两者在内存中的缓存:

    struct super_block super_block[NR_SUPER];
    #define NR_SUPER 8
    struct m_inode inode_table[NR_INODE];
    #define NR_INODE 32
    

    可以看出在 L i n u x Linux Linux 0.11 0.11 0.11 里面内存中最多同时存在 8 个超级块和 32 个文件的 i n o d e inode inode。这个缓存与我们平时所说的缓存差不多,当系统要想获取一个 i n o d e inode inode 时,会先在 i n o d e _ t a b l e inode\_table inode_table 中寻找有没有该 i n o d e inode inode,如果有的话就直接返回,如果没有,就从设备上将 i n o d e inode inode 读到 i n o d e _ t a b l e inode\_table inode_table 之后再返回。

    相关操作

    在看 m o u n t mount mount 挂载之前,先来看看一些操作函数。

    static struct super_block * read_super(int dev);
    

    如果缓存区中没有该设备的超级块,则先找一个空闲的超级块槽,然后从设备上读取超级块到找到的空闲超级块槽。如果该设备的超级块已经在缓存区中且数据有效,则直接返回该超级块的指针。

    struct super_block * get_super(int dev);
    

    根据设备号 d e v dev dev 从超级块数组当中获取超级块。

    void put_super(int dev);
    

    释放指定的设备超级块,也就是将超级块的 s _ d e v s\_dev s_dev 字段清 0,如此使得该超级块槽空闲出来。

    struct m_inode * namei(const char * pathname);
    

    n a m e i namei namei 函数根据路径 p a t h n a m e pathname pathname 获取末尾文件的 i n o d e inode inode,这个函数应该是有印象的吧,在 x v 6 xv6 xv6 中也有类似的函数。如果不太清楚的话,我这里举个例子:如果参数路径是 /a/b/c,调用 n a m e i namei namei 之后就会返回文件 c c c i n o d e inode inode

    挂载

    挂载的实现还是挺简单的,来看代码

    int sys_mount(char * dev_name, char * dir_name, int rw_flag) //将名称为dev_name的设备上的文件系统挂载到目录dir_name上
    {
    	struct m_inode * dev_i, * dir_i;
    	struct super_block * sb;
    	int dev;
    
    	if (!(dev_i=namei(dev_name))) //没有找到该设备
    		return -ENOENT;
    	dev = dev_i->i_zone[0];
    	if (!S_ISBLK(dev_i->i_mode)) { //不是块设备
    		iput(dev_i);
    		return -EPERM;
    	}
    	iput(dev_i);   //释放该设备的inode
    	if (!(dir_i=namei(dir_name)))  //解析获取挂载点的inode
    		return -ENOENT;
    	if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) { //如果挂载点的引用数不等于1获取挂载点为根目录
    		iput(dir_i);
    		return -EBUSY;
    	}
    	if (!S_ISDIR(dir_i->i_mode)) {  //挂载点不是目录
    		iput(dir_i);
    		return -EPERM;
    	}
    	if (!(sb=read_super(dev))) {  //将设备上的文件系统的超级块读取到内存中
    		iput(dir_i);
    		return -EBUSY;
    	}
    	if (sb->s_imount) {  //如果该文件系统已挂载
    		iput(dir_i);
    		return -EBUSY;
    	}
    	if (dir_i->i_mount) {  //如果挂载点已经挂载了其他文件系统
    		iput(dir_i);
    		return -EPERM;
    	}
    	sb->s_imount=dir_i;   //将挂载点的inode记录到设备的超级块中
    	dir_i->i_mount=1;     //表示该挂载点已经挂载了该文件系统
    	dir_i->i_dirt=1;		/* NOTE! we don't iput(dir_i) */ //我们不会释放挂载点的inode
    	return 0;			/* we do that in umount */ //我们在umount卸载文件系统时释放
    }
    

    其流程图为:

    上图为 m o u n t mount mount 的实现过程,除了各种检查之外, m o u n t mount mount 实际上只做了两件事:

    1. 将要挂载的文件系统的超级块读到内存里的超级块槽
    2. 设置该超级块的 s b → s _ i m o u n t sb \rightarrow s\_imount sbs_imount 字段为 挂载点的 i n o d e inode inode,表示文件系统挂载到这个目录上,设置挂载点 i n o d e inode inode i _ m o u n t i\_mount i_mount 字段为 1 表示该目录上挂载的有文件系统

    另外再解释几点:

    1. 字符设备,提供连续的数据流,应用程序可以顺序读取数据,通常不支持随机存取,像前面提到过的键盘串口都属于字符设备。块设备,应用程序能够随机访问设备的数据,程序可以自行确定数据的位置,比如说硬盘就是典型的块设备。很明显地文件系统只能存放在块设备上
    2. 挂载点只能是个目录文件,文件系统都是挂载到目录上的
    3. 挂载文件系统时,挂载点这个目录文件只能在当前引用,也就是说在挂载文件系统的时候,还有其他地方正在使用挂载点目录的话就不对

    这就是挂载的本质,有没有感觉简单的同时又还是模模糊糊的?为什么将文件系统挂载到某个目录之后,这个目录就能表示被挂载的文件系统。解决这个问题还是要再来捋捋文件系统是如何寻找一个文件的,也就是 n a m e i namei namei 函数,比如说给定一个路径 /a/b,这是一个绝对路径,如何从最开始的根目录寻到文件 b b b 的呢?

    这个问题我在 x v 6 xv6 xv6 文件系统里面也详细说过, L i n u x Linux Linux 里也类似。这里我们假设 a a a 文件都是目录文件, b b b 是一个普通文件。首先根目录文件就是一个个目录项,在其中寻找文件名为 a a a 的目录项,从中获取 a a a 目录文件的 i n o d e _ a inode\_a inode_a,根据 i n o d e _ a inode\_a inode_a 的索引字段找到 a a a 目录文件的数据,也是一个个目录项,在其中寻找文件名为 b b b 的目录项,从中获取普通文件 b b b i n o d e _ b inode\_b inode_b 然后返回。

    上述所说的获取某个 i n o d e inode inode,使用的函数是, i g e t ( d e v , n r ) iget(dev, nr) iget(dev,nr),其意为从设备 d e v dev dev 中获取编号为 n r nr nr i n o d e inode inode。这个函数就会判断编号为 n r nr nr i n o d e inode inode 上是否挂载的有文件系统,来看相关代码:

    struct m_inode * iget(int dev, int nr){
        /*********略**********/
        inode = inode_table;    //从inode表中第一个元素开始
    	while (inode < NR_INODE+inode_table) {  //扫描内存里缓存的inode表
    		if (inode->i_dev != dev || inode->i_num != nr) { //如果设备号对不上或者inode编号对不上
    			inode++;   //下一个
    			continue;
    		}
    		wait_on_inode(inode);   //等待该inode解锁
    		if (inode->i_dev != dev || inode->i_num != nr) { //因为等待过程中inode可能会发生变化,所以再次判断
    			inode = inode_table;
    			continue;
    		}
    		inode->i_count++;  //找到了该inode,将其引用数加1
    		if (inode->i_mount) {   //如果该inode上挂载的有文件系统
    			int i;
    
    			for (i = 0 ; i<NR_SUPER ; i++)   //在内存中缓存的超级块中寻找挂载点为当前inode的超级块
    				if (super_block[i].s_imount==inode)  //找到了,break
    					break;
    			if (i >= NR_SUPER) {  //没找到,返回
    				printk("Mounted inode hasn't got sb\n");
    				if (empty) 
    					iput(empty);
    				return inode;
    			}
    			iput(inode);   //释放当前inode
    			dev = super_block[i].s_dev;  //将设备号重新设置为被挂载的文件系统所在的设备号
    			nr = ROOT_INO;    //将要寻找的inode编号重新设置为根目录的inode编号
    			inode = inode_table;   //从内存的inode表第一个元素重新开始寻找inode
    			continue;
    		}
    		if (empty)  //释放临时找的空闲inode
    			iput(empty);  
    		return inode;   //返回获取到的inode
    	}
    }
    

    其完整的流程图如下:

    这是我根据赵炯画的图改编,因为没有详细讲述 i g e t iget iget 的代码,所以主要关注虚线方框里面的就行。

    如果在 i n o d e _ t a b l e inode\_table inode_table 中找到相应的 i n o d e inode inode,就判断 i n o d e → i _ m o u n t = = 1 inode \rightarrow i\_mount == 1 inodei_mount==1,如果为真,表示该 $inode $表示的目录文件上面挂载的有文件系统。此时这个目录应该表示被挂载的文件系统的根目录,所以设置 d e v = 超 级 块 表 示 的 设 备 dev = 超级块表示的设备 dev= n r = 1 nr = 1 nr=1,原目录就被隐藏掉了。举个例子再说明一下,假如调用 i g e t ( 1 , 99 ) iget(1, 99) iget(1,99),本来我是要获取 1 号设备的第 99 个 i n o d e inode inode,然后发现这个 i n o d e inode inode 指向的目录上面挂载的有 2 号设备的文件系统,那么我们就去寻找 2 号设备的根目录 i n o d e inode inode 然后返回。所以看起来调用 i g e t ( 1 , 99 ) iget(1, 99) iget(1,99) 实则调用的 i g e t ( 2 , 1 ) iget(2, 1) iget(2,1),这也就是为什么说将文件系统挂载到某个目录之后,这个目录就被屏蔽了的原因所在

    到此,对文件系统的挂载应该有个很清晰的认识呢,最后来看看文件系统的卸载,基本上就是挂载的逆操作,来简单看看:

    int sys_umount(char * dev_name)
    {
    	struct m_inode * inode;
    	struct super_block * sb;
    	int dev;
    
    	if (!(inode=namei(dev_name)))  //解析获取设备文件的inode
    		return -ENOENT;
    	dev = inode->i_zone[0];   //对于块/字符设备,设备号记录在i_zone[0]
    	if (!S_ISBLK(inode->i_mode)) {  //如果不是块设备
    		iput(inode);
    		return -ENOTBLK;
    	}
    	iput(inode);  //释放设备文件的inode
    	if (dev==ROOT_DEV)  //如果要卸载的是根文件系统
    		return -EBUSY;
    	if (!(sb=get_super(dev)) || !(sb->s_imount)) //如果没有获取到设备的超级块或者如果挂载点为空
    		return -ENOENT;
    	if (!sb->s_imount->i_mount) //如果挂载点的挂载标识为空
    		printk("Mounted inode has i_mount=0\n");
        //检查是否有进程在使用将要卸载文件系统上的文件
    	for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++) 
    		if (inode->i_dev==dev && inode->i_count)
    				return -EBUSY;
    	sb->s_imount->i_mount=0;  //挂载标识设为0
    	iput(sb->s_imount);   //释放挂载点的inode
    	sb->s_imount = NULL;  //超级块的挂载点字段设为空
    	iput(sb->s_isup);    //释放被卸载的文件系统的根目录inode
    	sb->s_isup = NULL;   //根目录inode字段清0
    	put_super(dev);    //释放设备超级块
    	sync_dev(dev);     //更新的信息同步到设备
    	return 0;
    }
    

    文件系统的卸载主要就是释放超级块,然后将一些字段值复原,具体见上面注释就不细说了。

    好了本文关于文件系统的挂载就这么多,所以回到开头什么是挂载,但从实现上来说,就是将超级块加载到内存里面,因为超级块就是一个文件系统的元信息集合,超级块就能代表一个文件系统,所以将超级块加载到内存里面,我们就可以认为挂载了相应的文件系统。当然挂载这个机制不可能就只是靠超级块是否在内存里面来决定实现,还需要其他的函数来辅助,就比如说获取 i n o d e inode inode i g e t iget iget 函数,这个函数就会来判断当前获取的这个 i n o d e inode inode 是否为挂载点,如果是,那就需要屏蔽当前这个 i n o d e inode inode 指向的目录文件,然后将其替换为被挂载的文件系统的根目录。这些总总加起来应该才算是挂载这个机制的实现,而不是说单靠一个 m o u n t mount mount 函数就实现了挂载的机制。

    O K OK OK 本文就到这里了,有什么问题还请批评指正,也欢迎大家来同我探讨交流一起学习一起进步。

    • 首发公号:Rand_cs
    展开全文
  • Docker容器挂载

    千次阅读 2022-04-06 20:34:31
    docker的理念:将应用和环境打包成一个镜像!通过镜像启动容器运行 ...这就是卷技术,也就是目录的挂载,将容器内的目录挂载到linux上 总结:容器的持久化和同步操作!容器间也可以实现数据共享! 使
  • Linux挂载

    千次阅读 2022-03-21 15:42:52
    1、挂载的定义 挂载是一个非常重要的功能,它将一个设备(通常是存储设备,可以挂载光盘、硬盘、磁带、光盘镜像文件等)挂接到一个已存在的目录上(这个目录可以不为空,但挂载后这个目录下以前的内容将不可用。 ...
  • docker目录挂载、文件挂载问题集锦

    千次阅读 2021-02-20 17:04:26
    docker目录挂载、文件挂载问题集锦 docker提供服务时,为了保证宿主机与容器内部的数据同步,经常需要将需要的文件挂载到容器。docker启动时可以用-v完成,或在编排docker-compose的yml文件的volumes中添加挂载文件...
  • Linux硬盘分区挂载1

    千次阅读 2021-11-16 11:15:23
    本篇主要涉及分区涉及到的分区和挂载的概念,目的,常用分区工具(parted和fdisk),MBR分区表和GPT的区别与涉及到的相关挂载、分区、格式化、激活/关闭分区,取消挂载的命令的格式及使用,依次分概念及常用命令...
  • Linux通过UUID挂载和卸载硬盘

    千次阅读 2021-11-14 21:06:52
    本文介绍下Linux系统如何通过UUID的方式挂载硬盘,以及相关的注意事项。 注意事项: 挂载前一定想好挂载位置,不能是系统盘 挂载路径如果已经有文件或者文件夹,挂载新硬盘后将全部清空 基于上述两点,推荐硬盘挂载...
  • Ubuntu 配置磁盘挂载到指定目录

    千次阅读 2022-04-11 11:58:03
    最近在工作中,需要将磁盘挂载到自己指定的目录下,特此记录便于日后查阅。 1、查看当前所有的磁盘信息 首先查看当前服务器所有磁盘信息,命令如下: $ sudo fdisk -l 从列出的信息中可以看出,电脑内两个...
  • Ubuntu 磁盘挂载——开机自动挂载

    千次阅读 2022-01-20 12:29:42
    Ubuntu 磁盘挂载 1.使用命令查看分区 sudo fdisk -l 2.创建挂载目录 sudo mkdir /mnt/data 3.开始挂载 sudo mount /dev/sda/ /mnt/data/ 4.设置开机自动挂载 4.1查询挂载硬盘UUID sudo blkid /dev/sda2 返回信息...
  • 什么是挂载,Linux挂载如何实现详解

    千次阅读 多人点赞 2020-04-28 21:28:07
    挂载指的就是将设备文件中的顶级目录连接到 Linux 根目录下的某一目录(最好是空目录),访问此目录就等同于访问设备文件。Linux 系统中“一切皆文件”,所有文件都放置在以根目录为树根...
  • 数据卷挂载2.目录挂载3.文件挂载4.总结 1.数据卷挂载 数据卷挂载是将 宿主机的数据卷 挂载到 Docker容器中的目录 中,数据卷目录由Docker管理,位置在 /var/lib/docker/volumes 中 举例↓ docker run --name <...
  • LVM管理,扩容和挂载

    千次阅读 2022-04-02 15:41:45
    LVM管理 文章目录LVM管理1.基本概念2.LVM基本组成块2.1....查看磁盘信息3.2磁盘初始化3.3创建PV(物理卷):3.3创建LV(逻辑卷)3.4格式化LV3.5挂载3.5.1自动挂载4.磁盘扩容4.1 初始化磁盘创建PV4.2
  • 硬盘分区挂载和取消挂载

    千次阅读 2022-02-23 22:36:13
    一:挂载 fdisk -l |grep sd 查看分区情况 或者fdisk -l mkdir -p /data/disk1 创建数据存储目录 mkdir -p /data/disk2 mkdir -p /data/disk3 … mkfs.xfs /dev/sdb 格式化sdb磁盘 mkfs.xfs /dev/sdc 格式化...
  • 1.挂载命令(mount) 首先,介绍一下挂载(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的。 命令格式:mount [-t vfstype] [-o options] device dir 1、-t vfstype 指定文件系统的类型,...
  • 【Linux】磁盘分区和挂载

    千次阅读 多人点赞 2022-03-21 16:10:06
    Linux磁盘分区和挂载 linux分区 查看所有设备挂载情况 挂载案例 步骤1:新建一块硬盘 操作步骤2: 虚拟机硬盘分区 步骤3:虚拟机硬盘分区格式化 步骤4:将磁盘挂载到根目录下newdisk目录下 mount挂载 ...
  • 09Dcoker容器数据卷 命令-v挂载

    千次阅读 2022-03-20 20:50:49
    本地挂载使用命令的方式来挂载 -v 容器停止,此时Linux修改文件,docker 容器在启动的时候,会更新过去 举例: 测试:(本地能否链接成功) ​​ 好处:我们修改只需在本地修改即可,容器内会自动同步! 假设...
  • 2、具名挂载 匿名挂载 匿名挂载是没有对外部的数据文件进行起名的。 直接在 -v 后面添加容器内部的路径。 #匿名挂载 1 docker run -d -p -v /etc/nginx nginx #还有一种是绑定了主机地址 ;指定路径挂载 docker run ...
  • Linux中挂载详解以及mount命令用法

    千次阅读 2021-07-01 10:59:38
    挂载概念 Linux中的根目录以外的文件要想被访问,需要将其“关联”到根目录下的某个目录来实现,这种关联操作就是“挂载”,这个目录就是“挂载点”,解除次关联关系的过程称之为“卸载”。 注意:“挂载点”的...
  • k8s数据挂载

    千次阅读 2022-03-15 10:00:33
    nfs挂载 将mysql-data挂载到/data/dev/mysql, 采用nfs的形式: volumes: - name: mysql-data nfs: server: localhost path: /data/dev/mysql - name: mysql-dev-conf configMap: name: my.cnf pvc挂载 ...
  • NAS存储挂载

    千次阅读 2022-03-24 10:48:19
    然后在57和58上格式化分区,配置好之后由客户端挂载使用: 一、在SC9000上分配空间:(如果使用之前已分配的空间则跳过此步骤) 1、使用Dell存储管理软件Dell storage manager,登陆地址:,用户名,密码 2、在卷...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 615,689
精华内容 246,275
关键字:

挂载

友情链接: classproject.rar