-
-
Notifications
You must be signed in to change notification settings - Fork 168
feat(loop-device):实现Dragonos对loop的支持 #1261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Vitus213
wants to merge
36
commits into
DragonOS-Community:master
Choose a base branch
from
Vitus213:feat/loop-device
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
5cbe962
完成loop_device的注册,能在/dev下看见8个loopdevice
Vitus213 be65aaa
fmt & 删除loopdevice中的devid字段
Vitus213 c9157f8
添加了driver和control device和manager,将注册逻辑移动至driver中
Vitus213 0867f83
- 将具体注册逻辑移动到loopdriver中,由loopmanager封装init函数,管理loopdevice信息
Vitus213 d8eb2e7
注册loop-control设备
Vitus213 521d819
复用linux中关于loop的ioctl魔数
Vitus213 327d166
- 往loop_control_device中加入loopmanager的arc实例
Vitus213 e7363e3
添加不对回环路由代理
Vitus213 a1f2a30
add test
Vitus213 9f5ebdf
Merge remote-tracking branch 'upstream/master' into feat/loop-device
Vitus213 89c7fb1
merge 主线,调整版本号和工具链
Vitus213 9ef8d3c
fmt
Vitus213 786c435
fix : function loop_add()
Vitus213 29c7679
- 增加read_async,write_async
Vitus213 e87dcd8
feat:增添删除设备逻辑和测试
Vitus213 0b43777
fmt
Vitus213 bd115d9
- feat: add loop_set_status and loop_get_status
Vitus213 9f9f246
Merge remote-tracking branch 'upstream/master' into feat/loop-device
Vitus213 293f529
- add ioctl change_fd and set_capacity
Vitus213 e4bde6b
Merge remote-tracking branch 'origin/master' into feat/loop-device
Vitus213 2715d3a
- 修改为枚举
Vitus213 6df9ba3
- 修改major管理
Vitus213 3431ff1
- add idallocator,把和id和minor解耦,减少遍历的次数
Vitus213 332dd9c
- fix docs
Vitus213 d224fbf
Merge branch 'master' into feat/loop-device
Vitus213 3386be3
Merge branch 'master' into feat/loop-device
Vitus213 0c5d02c
Merge remote-tracking branch 'refs/remotes/origin/feat/loop-device' i…
Vitus213 eda602a
修正clippy
Vitus213 87ba21d
copilot审查修正
Vitus213 2360c1b
- 改动loop_device的位置
Vitus213 2ebf533
- 添加回调函数,阻塞io,保证io结束后再回调释放资源
Vitus213 912bc23
- 添加回调函数,阻塞io,保证io结束后再回调释放资源
Vitus213 5ef7728
Merge remote-tracking branch 'refs/remotes/origin/feat/loop-device' i…
Vitus213 95c0444
Merge branch 'master' into feat/loop-device
Vitus213 126bc5a
- refactor: 调整loop_device位置
Vitus213 88877ca
Merge remote-tracking branch 'refs/remotes/origin/feat/loop-device' i…
Vitus213 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,3 +6,4 @@ Device | |
| :maxdepth: 1 | ||
|
|
||
| tty | ||
| loop_device | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| # Loop Device 架构设计 | ||
|
|
||
| 本文档阐述 DragonOS 中 loop 设备子系统的架构设计思路,用于指导开发和后续演进。 | ||
|
|
||
| ## 问题背景 | ||
|
|
||
| 在操作系统开发中,我们经常面临这样的需求: | ||
| - 如何将一个镜像文件当作块设备使用? | ||
| - 如何在不重启系统的情况下动态创建/删除虚拟块设备? | ||
|
|
||
| loop 设备正是解决这些问题的关键组件。 | ||
|
|
||
| ## 系统架构定位 | ||
|
|
||
| loop 设备在 DragonOS 架构中扮演着"虚拟化桥梁"的角色: | ||
|
|
||
| ``` | ||
| 用户态应用 | ||
| ↓ | ||
| loop-control 接口 (字符设备) | ||
| ↓ | ||
| LoopManager (设备生命周期管理) | ||
| ↓ | ||
| LoopDevice[] (虚拟块设备数组) | ||
| ↓ | ||
| 块设备层 ←→ 后端文件系统 | ||
| ``` | ||
|
|
||
| 这种分层设计的核心思想是:**将控制平面与数据平面分离**。 | ||
|
|
||
| ## 核心设计哲学 | ||
|
|
||
| ### 1. 状态驱动的设备管理 | ||
|
|
||
| 我们仿照linux设计引入状态机来管理设备生命周期 | ||
|
|
||
| ``` | ||
| Unbound → Bound → Rundown → Deleting | ||
| ↓ ↓ ↓ | ||
| Deleting Unbound Deleting | ||
| ``` | ||
|
|
||
| **设计考量**: | ||
| - 防止非法状态转换(如直接在 Bound 状态删除设备) | ||
| - 提供清晰的设备生命周期语义 | ||
| - 为未来的扩展(如设备热插拔)奠定基础 | ||
|
|
||
| ### 2. 双重接口策略 | ||
|
|
||
| 我们的设计刻意区分了两种接口: | ||
|
|
||
| **字符控制接口** (`/dev/loop-control`): | ||
| - 负责设备的生命周期管理 | ||
| - 提供用户友好的设备分配/回收机制 | ||
| - 与 Linux 标准接口保持兼容 | ||
|
|
||
| **块设备接口** (`/dev/loopX`): | ||
| - 专注于数据读写功能 | ||
| - 提供标准的块设备语义 | ||
| - 支持偏移、大小限制等高级功能 | ||
|
|
||
| **设计价值**:这种分离使得控制逻辑与数据路径互不干扰,提高了系统的可维护性。 | ||
|
|
||
| ### 3. 安全性优先 | ||
|
|
||
| 在与用户态交互时,我们采用了多重安全检查: | ||
|
|
||
| - **参数边界检查**:所有偏移和大小都必须 LBA 对齐 | ||
| - **内存安全**:使用 `UserBufferReader/Writer` 进行用户态数据拷贝 | ||
| - **权限验证**:只读设备拒绝写入操作 | ||
| - **状态验证**:每个操作前都检查当前设备状态是否允许 | ||
|
|
||
| ## 模块协作架构 | ||
|
|
||
| ### LoopManager 的定位 | ||
| LoopManager 不是简单的设备数组管理器,而是整个子系统的"调度中心": | ||
|
|
||
| - **设备分配策略**:采用"就近分配"原则,优先复用空闲设备 | ||
| - **资源池管理**:预注册 8 个设备,避免运行时分配开销 | ||
| - **并发安全**:所有设备操作都在锁保护下进行 | ||
|
|
||
| ### LoopDevice 的抽象设计 | ||
| LoopDevice 的核心抽象是"**后端文件的块设备视图**": | ||
|
|
||
| ``` | ||
| 用户视角 内部实现 | ||
| /dev/loop0 ←→ 文件偏移 + 大小限制 | ||
| 块0-100 文件偏移0-51200 | ||
| 块101-200 文件偏移51200-102400 | ||
| ``` | ||
|
|
||
| 这种设计允许用户将文件的任意部分映射为块设备,为容器等应用场景提供了极大的灵活性。 | ||
|
|
||
| ## 关键设计 | ||
|
|
||
| ### 为什么选择 256 个设备上限? | ||
| - 足够满足大多数应用场景需求 | ||
| - 避免无限制增长导致的资源耗尽 | ||
| - 与 Linux 系统默认上限保持一致,保证兼容性 | ||
|
|
||
| ### 为什么预注册 8 个设备? | ||
| - 覆盖常见的测试场景(通常不超过 4-5 个) | ||
| - 减少首次使用的等待时间 | ||
| - 提供一个合理的初始工作集 | ||
|
|
||
| ### 为什么使用 SpinLock 而不是其他锁? | ||
| - loop 设备操作大多是短时操作 | ||
| - 避免复杂的锁层级和死锁问题 | ||
| - 简化实现,提高性能 | ||
|
|
||
| ## 兼容性考量 | ||
|
|
||
| 我们的设计在很大程度上参考了 Linux loop 驱动的接口,这是有意的选择: | ||
|
|
||
| 1. **用户态软件兼容**:现有的 loop 工具无需修改即可使用 | ||
| 2. **API 契约一致性**:避免因接口差异导致的潜在问题 | ||
| 3. **社区知识复用**:开发者可以复用现有的 loop 设备知识 | ||
|
|
||
| ## 总结 | ||
|
|
||
| DragonOS 的 loop 设备设计遵循以下核心原则: | ||
| 1. **架构清晰**:控制平面与数据平面分离 | ||
| 2. **状态安全**:基于状态机的设备生命周期管理 | ||
| 3. **接口兼容**:与 Linux 标准接口保持兼容 | ||
| 4. **扩展友好**:为未来功能预留架构空间 | ||
| 5. **测试完备**:通过多层级测试保证质量 | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| use core::{fmt::Formatter, sync::atomic::AtomicU32}; | ||
|
|
||
| use alloc::sync::Arc; | ||
| use alloc::{sync::Arc, vec::Vec}; | ||
| use hashbrown::HashMap; | ||
| use system_error::SystemError; | ||
| use unified_init::macros::unified_init; | ||
|
|
@@ -11,7 +11,7 @@ use crate::{ | |
| device::{device_number::Major, DevName}, | ||
| }, | ||
| filesystem::{ | ||
| devfs::devfs_register, | ||
| devfs::{devfs_register, devfs_unregister}, | ||
| mbr::MbrDiskPartionTable, | ||
| vfs::{utils::DName, IndexNode}, | ||
| }, | ||
|
|
@@ -167,13 +167,24 @@ impl BlockDevManager { | |
|
|
||
| /// 卸载磁盘设备 | ||
| #[allow(dead_code)] | ||
| pub fn unregister(&self, dev: &Arc<dyn BlockDevice>) { | ||
| pub fn unregister(&self, dev: &Arc<dyn BlockDevice>) -> Result<(), SystemError> { | ||
| let mut inner = self.inner(); | ||
Vitus213 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| inner.disks.remove(dev.dev_name()); | ||
| // todo: 这里应该callback一下磁盘设备,但是现在还没实现热插拔,所以暂时没做这里 | ||
| todo!("BlockDevManager: unregister disk") | ||
| if inner.disks.remove(dev.dev_name()).is_none() { | ||
| return Err(SystemError::ENOENT); | ||
| } | ||
| let blk_meta = dev.blkdev_meta(); | ||
| let gendisks = { | ||
| let mut meta_inner = blk_meta.inner(); | ||
| let disks: Vec<Arc<GenDisk>> = meta_inner.gendisks.values().cloned().collect(); | ||
| meta_inner.gendisks.clear(); | ||
| disks | ||
| }; | ||
| for gendisk in gendisks { | ||
| let dname = gendisk.dname()?; | ||
| devfs_unregister(dname.as_ref(), gendisk)?; | ||
| } | ||
| Ok(()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| /// 通过路径查找gendisk | ||
| /// | ||
| /// # 参数 | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.

Uh oh!
There was an error while loading. Please reload this page.