news 2026/9/26 9:45:24

Multipass `mount` 命令完全指南:共享目录、ID 映射与挂载类型解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Multipass `mount` 命令完全指南:共享目录、ID 映射与挂载类型解析
  • 虚拟化
  • 开发工具
  • 云原生

【免费下载链接】multipass

Multipass orchestrates virtual Ubuntu instances

项目地址:https://gitcode.com/gh_mirrors/mu/multipass
点击查看免费下载

multipass mount是 Multipass 中用于将宿主机本地目录映射到 Ubuntu 实例(instance)文件系统的核心命令,支持经典(classic)与原生(native)两种挂载类型,并可通过用户/组 ID 映射(UID/GID mapping)保持文件所有权的跨端一致性。本文基于仓库内 mount 命令参考文档 展开,结合 数据共享指南、Mount 原理文档、ID 映射文档 以及 CLI 与 daemon 源码实现,完整覆盖mount/umount的语法、全部选项、实际用例、底层工作原理与安全注意事项,帮助你高效地在宿主机与实例之间共享数据。

mount命令概览

multipass mount将宿主机上的一个本地目录映射到实例中,使目录内容及其后续变更在两端同时可见。你可以通过--type指定挂载类型,并通过-g/-u定义组 ID 或用户 ID 映射,使实例内文件与文件夹的所有权从宿主机 ID 映射到实例 ID。

基本语法如下(以 classic 挂载为例):

multipass mount --type=classic /host/path <instance name>:/instance/path

使用multipass umount命令可撤销映射。关于 classic 与 native 挂载的差异详见 Mount 原理;关于如何用mount在宿主机与实例间共享数据的完整示例见 How to share data with an instance。

完整命令行选项参考

以下内容即multipass help mount的完整输出,说明了该命令的全部可用选项:

Usage: multipass mount [options] <source> <target> [<target> ...] Mount a local directory inside the instance. If the instance is not currently running, the directory will be mounted automatically on next boot. Options: -h, --help Displays help on commandline options -v, --verbose Increase logging verbosity. Repeat the 'v' in the short option for more detail. Maximum verbosity is obtained with 4 (or more) v's, i.e. -vvvv. -g, --gid-map <host>:<instance> A mapping of group IDs for use in the mount. File and folder ownership will be mapped from <host> to <instance> inside the instance. Can be used multiple times. Mappings can only be specified as a one-to-one relationship. -u, --uid-map <host>:<instance> A mapping of user IDs for use in the mount. File and folder ownership will be mapped from <host> to <instance> inside the instance. Can be used multiple times. Mappings can only be specified as a one-to-one relationship. -t, --type <type> Specify the type of mount to use. Classic mounts use technology built into Multipass. Native mounts use hypervisor and/or platform specific mounts. Valid types are: 'classic' (default) and 'native' Arguments: source Path of the local directory to mount target Target mount points, in <name>[:<path>] format, where <name> is an instance name, and optional <path> is the mount point. If omitted, the mount point will be under /home/ubuntu/<source-dir>, where <source-dir> is the name of the <source> directory.

参数说明

  • source:本地要挂载的目录路径,必须是宿主机上真实存在、可读的目录(源码层面会对此进行校验,见下文)。
  • target:目标挂载点,格式为<name>[:<path>],其中<name>是实例名称,<path>是可选的挂载点路径。若省略<path>,挂载点默认为实例内/home/ubuntu/<source-dir>,其中<source-dir>为source目录的目录名。
  • -u/--uid-map <host>:<instance>:用户 ID 映射,将文件与文件夹的所有权从宿主机用户 ID 映射到实例内的用户 ID。可多次使用(多对映射),但每个映射必须是一对一关系。
  • -g/--gid-map <host>:<instance>:组 ID 映射,规则与 UID 映射相同。
  • -t/--type <type>:挂载类型,合法取值为classic(默认)与native。
  • -v/--verbose:增加日志详细程度,可重复v以获取更多细节,最大冗长度为-vvvv。

源码中的参数校验与默认行为

上述选项并非仅是文档描述,mount.cpp 中的parse_args实现了完整的解析与校验逻辑,可作为实际行为依据:

  • source 校验:代码使用QFileInfo检查 source 路径,依次验证其存在(Source path ... does not exist)、是目录(Source path ... is not a directory)、可读(Source path ... is not readable),并通过QDir::absolutePath()规范为绝对路径后写入请求。
  • target 解析:每个 target 参数按:切分,前半部分作为实例名,后半部分作为目标路径;源码注释表明若省略路径,挂载点将位于home_in_instance(即/home/ubuntu)之下的<source-dir>。
  • ID 映射格式校验:通过正则表达式^([0-9]+[:][0-9]+)$校验-u/-g值必须是纯数字的host:instance形式,非法输入会报Invalid UID/GID map given。
  • 默认 ID 映射:当未显式指定-u/-g时,CLI 会添加默认映射——宿主机当前用户 UID/GID(mcp::getuid()/mcp::getgid())映射到实例内的default_id(在 client_platform.h 中定义为-1,由后端解释为默认用户,通常即ubuntu用户)。这一点解释了为何默认挂载后实例内文件归属于ubuntu用户。
  • 挂载类型校验:checked_mount_type只接受classic与native两个字符串(不区分大小写,toLower后比较),其他取值抛出ValidationException,提示Bad mount type '...' specified, please use 'classic' or 'native'。
  • 命令执行:解析成功后,Mount::run通过 gRPC 将MountRequest分发给 daemon,并使用旋转动画(spinner)反馈进度,失败时通过standard_failure_handler_for输出错误。

实际操作示例

基础共享:挂载宿主机目录到实例

将宿主机本地目录映射到实例,基本语法为:

multipass mount <local path> <instance name>

例如,在 Linux 系统上将本地家目录$HOME映射到名为keen-yak的实例:

multipass mount $HOME keen-yak

运行multipass info keen-yak可查看挂载结果:

... Mounts: /home/michal => /home/michal

此后,本地家目录/home/michal的内容在实例内即可见、可读写。挂载路径是持久的,会一直保持到被显式卸载(unmount)为止,即使实例关机重启后,挂载也会在下次启动时自动恢复(CLI 帮助文本与源码均说明了这一点:"If the instance is not currently running, the directory will be mounted automatically on next boot")。

挂载到指定路径

若希望将本地目录挂载到实例中的特定路径,可显式指定目标:

multipass mount $HOME keen-yak:/some/path

注意(覆盖语义):如果/some/path在实例文件系统中已存在,其原有内容会被挂载目录临时隐藏(overlay),但不会被覆盖或删除;卸载后原目录内容会重新出现。因此,不能将外部目录挂载到实例的$HOME目录之上——$HOME中包含访问实例所需的 SSH 密钥,一旦被隐藏将无法再通过 shell 登录该实例。

在创建实例时定义挂载

也可以在创建实例时直接指定挂载,使用launch命令的--mount选项:

multipass launch --mount /local/path:/instance/path

使用 ID 映射保持文件所有权

不同系统间用户 ID 往往不一致(如 macOS 用户 UID 为501,而 Ubuntu 实例内默认用户ubuntu的 UID 为1000)。通过-u/-g指定映射可让文件在两端保持正确的所有权。例如,将宿主机 UID501映射为实例内 UID1000:

multipass mount ~/Documents foo:Documents -u 501:1000

由于 ID 映射在宿主机与实例之间双向生效,它必须是一对一关系:宿主机上的每个用户/组 ID 只能映射到实例内的一个 ID,反之亦然。以下命令是非法的,因为它将宿主机两个不同 UID(501、502)映射到了实例内同一个 UID(1000),Multipass 将无法确定宿主机上 UID 为501的文件在实例内应归属哪个 ID:

multipass mount ~/Documents foo:Documents -u 501:1000 -u 502:1000

正确的多对映射写法应为:

multipass mount ~/Documents foo:Documents -u 501:1000 -u 502:1001

同样的规则也适用于反向场景:不能把实例内的一个 ID 映射到宿主机上的两个不同 ID。ID 映射的详细原理参见 ID mapping 文档。

卸载共享目录(umount)

使用umount命令卸载先前挂载的路径。可指定具体路径进行定向卸载:

multipass umount keen-yak:/home/michal

若不指定任何路径,则一次性卸载该实例的所有共享目录:

multipass umount keen-yak

umount的完整帮助输出如下:

Usage: multipass umount [options] <mount> [<mount> ...] Unmount a directory from an instance. Options: -h, --help Displays help on commandline options -v, --verbose Increase logging verbosity. Repeat the 'v' in the short option for more detail. Maximum verbosity is obtained with 4 (or more) v's, i.e. -vvvv. Arguments: mount Mount points, in <name>[:<path>] format, where <name> are instance names, and optional <path> are mount points. If omitted, all mounts will be removed from the named instances.

从源码看,umount.cpp 中umount命令还注册了别名unmount,其解析逻辑与mount的 target 解析一致:按:切分<name>[:<path>],仅给定实例名而不给路径时,即表示移除该实例上的全部挂载。

挂载类型:classic 与 native

Multipass 提供两种挂载类型,可通过--type选择:

  • classic(默认):基于 Multipass 内置技术(SSHFS,SSH 文件系统)实现,在所有后端上均可用,兼容性更高,但因 SSH 加密通信而略有性能开销。
  • native:使用驱动相关的高性能挂载技术,仅在特定后端可用:
    • Hyper-V上通过 SMB/CIFS 实现;
    • QEMU上通过 9P 协议实现。

从源码看,挂载类型的分派发生在 daemon 侧:daemon.cpp 中mount请求处理逻辑将请求中的MountType(CLASSIC/NATIVE)转换为VMMount::MountType(定义见 vm_mount.h),随后make_mount据此分派:

return mount.get_mount_type() == VMMount::MountType::Classic ? std::make_unique<SSHFSMountHandler>(vm, config->ssh_key_provider.get(), target, mount) : vm->make_native_mount_handler(target, mount);

即 classic 挂载由SSHFSMountHandler处理(相关实现见 sshfs_mount_handler.cpp 及sftp_server相关文件),而 native 挂载则委托给具体虚拟化后端实现(例如 QEMU 的 qemu_mount_handler.cpp 与 Windows 的 smb_mount_handler.cpp)。若挂载目录时实例正在运行,daemon 会立即激活挂载;否则挂载将在实例下次启动时自动建立,这一行为在 test_daemon_mount.cpp 等测试中有覆盖验证。

安全注意事项

由于挂载以高权限身份执行,使用时需留意以下安全边界(详见 Mount 文档的安全小节):

  • Linux:挂载以root身份执行(snap 安装除外),因此对宿主机整个操作系统具有写权限。但由于只有特权用户(sudo、wheel、admin组成员)能使用 Multipass,这通常不构成问题。若通过 snap 安装,snap 的 confinement 会限制挂载范围在/home目录内(且不能挂载/home中的隐藏文件/文件夹),并根据所连接的接口限制可移动介质。即便如此,拥有 Multipass 访问权的用户 A 仍可能访问另一用户 B 在其家目录中建立的挂载。
  • macOS:同样以root身份挂载、对整个操作系统有写权限;同样因仅特权用户可用 Multipass 而无虞。
  • Windows:挂载以特权用户(SYSTEM)身份执行,对整个操作系统有写权限。出于历史原因,Windows 上挂载默认被禁用;如需启用,可设置local.privileged-mounts键。该设置项在 Linux 和 macOS 上默认为true,Windows 上默认为false(见 local-privileged-mounts 文档),可通过multipass set local.privileged-mounts=Yes等命令修改(支持on/off、yes/no、1/0、true/false及大小写变体)。

延伸阅读

  • How to share data with an instance:完整的宿主机与实例数据共享实操,包含transfer命令的用法。
  • Mount 原理:classic 与 native 挂载的详细对比与安全说明。
  • ID mapping:ID 映射的机制与一对一约束。
  • umount参考:卸载挂载的命令参考。
  • launch参考:在创建实例时通过--mount定义挂载。
  • local.privileged-mounts:控制mount是否被允许的设置项。
  • 虚拟化
  • 开发工具
  • 云原生

【免费下载链接】multipass

Multipass orchestrates virtual Ubuntu instances

项目地址:https://gitcode.com/gh_mirrors/mu/multipass
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 9:44:25

数据结构课设与实验.zip:从代码到报告的可复现交付指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 9:44:24

Claude Code 终极实战指南:从入门到精通 TaoToken 配置与 MCP 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 9:43:58

轴向电机电磁仿真与实测对标:3D有限元精度提升实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 9:43:54

CodeBuddy规则加载机制详解:CODEBUDDY.md与rules目录的正确用法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 9:43:52

OpenHarmony驱动AD9833实战:HCS配置、SPI时序与HDF服务调用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 9:43:52

堡盒TV内置源与本地多仓配置全攻略:从部署到维护

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华