0%

APUE学习笔记(第四章)

这一章将文件系统的相关操作,比如文件,目录,软硬链接等等。要深入的了解这些需要
了解linux内核的相关知识。

  1. 用户态和文件相关的基本数据结构是:struct stat
    可以用int stat(const char *pathname, struct stat *buf); 读出stat的内容。
    struct stat中的内容主要是对应文件的属性,一般从对应文件的inode节点得到这些
    内容。inode节点是文件系统的内容,下面的部分会提到。

  2. linux有多种文件类型。目录也是一种文件,其内容是目录中的文件名。另外符号链接,
    设备文件,管道也是文件。

  3. 各种ID: 每个进程相关的ID

    1
    2
    3
    4
    5
    6
    7
    +--------------+-----------+------------+
    | 实际用户ID | 实际组ID | |
    +--------------+-----------+------------+
    | 有效用户ID | 有效组ID | 附加组ID |
    +--------------+-----------+------------+
    | ... | ... | ... |
    +--------------+-----------+------------+

    一般决定文件访问权限的是第二行的有较,一般实际 = 有效***

    除了和进程相关的ID, 每个文件有它自己的所有者和所有组。执行文件操作时,会
    比较进程的有效***和文件的所有者和所有组,来判定是否可以执行。

    这里有个特殊的文件属性位,当设置该位的时候,执行该文件的进程会自动把自己
    的有效用户ID设置成文件的所有这ID。文件的这个位一般用来提升执行权限,完成
    一些功能。比如/usr/bin/passwd

    test@Latitude-D630:~$ ls -l which passwd
    -rwsr-xr-x 1 root root 45420 2月 17 2014 /usr/bin/passwd

    一般的用户可以用passwd去改自己的密码,但是修改密码要写/etc/shadow文件,

    test@Latitude-D630:~$ ls -l /etc/shadow
    -rw-r—– 1 root shadow 1513 12月 21 23:59 /etc/shadow

    可以看到/etc/shadow的所有者是root,且其他人不可以写。可以看到
    /usr/bin/passwd的可执行位是’s’, 这表示文件/usr/bin/passwd的特殊文件属性位
    被设定,这样当普通用户执行passwd命令时当前进程把自己的有效用户ID提升成
    root, 执行完后再恢复自己的ID。给文件加该属性要用chmod u+s file。

  4. umask.
    文件和目录创建时的默认属性一般是666和777。umask值可以去掉对应的读写执行
    权限,比如现在的umask值是:022,那么同组用户和其他用户没有了写权限。
    现在新建一个文件,得到的属性是644。使用umask命令可以查看当前shell的umask值,
    使用umask *** 可以修改当前的umask值。

  5. 文件系统[1]

有关文件系统的进一步介绍,可以参考[1]

1
2
3
4
5
6
7
8
9
10
11
12
+----------------+------------------+--------------------+
| 分区 | 分区 | 分区 |
+----------------+------------------+--------------------+

boot block
+--------+----------+-----------+-------------+--------------+
文件系统 | 自举块 | 超级块 | 柱面1 | 柱面2 | ... |
+--------+----------+-----------+-------------+--------------+

+-------------+-------------+------------+-----------+---------+----------+
| 超级块副本 | 配置信息 | i节点图 | 块位图 | i节点 | 数据块 |
+-------------+-------------+------------+-----------+---------+----------+

上图根据APUE插图得到,一个磁盘可以划分几个分区,每个分区上可以部署不同的
文件系统,文件系统的每个柱面中又有超级块副本,…,i节点,数据块等内容

主要关注i节点和数据块,i节点存放文件的属性,数据块存放文件的内容。

文件的根文件系统和磁盘上的根文件系统有说明区别?
只是存储数据的介质不同,在挂载文件系统的时候加入的数据读写的回调函数不同。

在ubuntu的根文件系统中有/boot/initrd.img-XXX, /boot/initrd.img-XXX是一个最小
根文件系统, 它基本作用是在内核起来之时挂载的第一个文件系统,在这个文件系统中
有必要的工具加载挂载磁盘文件系统需要的驱动。之后内核就可以挂载磁盘中真正的
根文件系统了。这样内核里一开始就不用放相关的驱动了,initrd.img文件系统里,
其实是使用的udev的机制,动态的识别系统外设,然后动态的加载所需要的内核驱动。
之前内核驱动都已经以模块的形式编译。有关initrd.img的内容可以参考内核文档[2]

制作一个文件上的文件系统, 相关的命令:
dd mkfs.ext4 mount cp umount

  1. 符号链接和硬链接

    创建一个B指向A的软连接, 可以建立指向文件和目录的软连接。软连接和硬连接的实质
    区别是,硬链接只有一个inode节点,软链接的文件/目录本身的inode和软链接本身的
    inode不同。

    ln -s A B /* A <– B */

  2. 文件的时间有:文件最后访问时间,文件最后修改时间,文件inode节点最后修改时间。

reference:
[1] Linux C编程一站式学习
[2] linux/Documentation/initrd.txt