胶合目录解释
在 Linux 内核的 **sysfs 文件系统** 中,**胶合目录(Glue Directory)** 是一种特殊的中间目录,主要用于解决不同类设备在 sysfs 层次结构中的命名冲突问题。它的核心作用是 **隔离不同类别的设备**,确保它们在 sysfs 中能够正确、安全地组织在一起,而不会因为文件名冲突导致混乱。
---
## **1. 为什么需要胶合目录?**
### **问题背景**
- **sysfs**(`/sys/`)是内核用于展示设备树结构的一个虚拟文件系统,设备按照其所属的 **类(Class)** 和 **父设备(Parent Device)** 进行组织。
- 但某些设备的 **父设备** 和 **自身** 属于不同的类别,例如:
- **USB 控制器**(属于 `usb` 类)挂载在 `/sys/devices/.../usb1/`。
- **USB 磁盘**(属于 `block` 类)如果直接挂载在 USB 控制器下,可能会和 USB 控制器本身的文件冲突(如 `power`、`uevent` 等)。
### **冲突示例**
如果直接把 USB 磁盘 `sdb` 放在 USB 控制器的目录下:
```
/sys/devices/.../usb1/
├── sdb/ ← 块设备(block class)
├── power ← USB 控制器的电源管理文件
└── uevent ← USB 控制器的事件文件
```
这里 `sdb/` 是一个块设备,而 `power` 和 `uevent` 是 USB 控制器的文件,如果块设备也有同名文件,就会冲突!
---
## **2. 胶合目录的作用**
为了避免这种冲突,内核会在父设备目录下 **创建一个中间目录**(即胶合目录),然后把设备挂载进去:
```
/sys/devices/.../usb1/
├── block/ ← 胶合目录(隔离块设备)
│ └── sdb/ ← 实际块设备
├── power ← USB 控制器的文件不受影响
└── uevent
```
这样:
- **块设备** 放在 `block/` 目录下,避免和 USB 控制器的文件冲突。
- **USB 控制器** 的文件仍然可以直接访问。
---
## **3. 胶合目录的实现**
### **数据结构**
- 每个设备类(`struct class`)维护一个 **胶合目录链表**(`glue_dirs`),记录已经创建的胶合目录。
- 当设备需要挂载到父设备下时,内核会:
1. **查找是否已有匹配的胶合目录**(通过 `list_for_each_entry` 遍历链表)。
2. **如果找到,直接复用**(避免重复创建)。
3. **如果没找到,创建新的胶合目录**(如 `block/`、`net/` 等)。
### **代码逻辑**
```c
list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry)
if (k->parent == parent_kobj) { // 检查是否已有匹配的胶合目录
kobj = kobject_get(k); // 增加引用计数,防止被释放
break;
}
```
- **`k->parent == parent_kobj`**:检查是否已经有一个胶合目录挂载在目标父设备下。
- **`kobject_get(k)`**:增加引用计数,确保目录不会被意外删除。
如果没找到匹配的胶合目录,内核会调用:
```c
k = class_dir_create_and_add(dev->class, parent_kobj);
```
创建一个新的胶合目录(如 `block/`),并添加到 `glue_dirs` 链表,供后续设备复用。
---
## **4. 实际应用场景**
### **场景 1:USB 磁盘**
- **设备**:`/dev/sdb`(块设备,`block_class`)。
- **父设备**:USB 控制器(`/sys/devices/.../usb1/`,属于 `usb` 类)。
- **胶合目录**:`block/`。
- **最终路径**:
```
/sys/devices/.../usb1/block/sdb/
```
### **场景 2:虚拟网络设备**
- **设备**:`veth0`(网络设备,`net_class`)。
- **父设备**:网络命名空间(`/sys/devices/virtual/net/`)。
- **胶合目录**:可能不需要(因为网络设备已经有专用目录)。
- **最终路径**:
```
/sys/devices/virtual/net/veth0/
```
---
## **5. 总结**
| **关键点** | **说明** |
|---------------------|-------------------------------------------------------------------------|
| **作用** | 隔离不同类设备,避免 sysfs 文件名冲突。 |
| **典型目录名** | `block/`(块设备)、`net/`(网络设备)等。 |
| **数据结构** | 每个设备类维护 `glue_dirs` 链表,记录已创建的胶合目录。 |
| **查找逻辑** | 遍历链表,匹配 `k->parent == parent_kobj`,找到则复用,否则创建新目录。 |
| **实际应用** | USB 磁盘、虚拟设备、网络设备等需要隔离的场景。 |
胶合目录是 Linux 设备模型中的一个重要机制,确保 sysfs 的层次结构清晰、无冲突,同时提高设备管理的灵活性。