如何在Linux中使用systemd启动时访问VirtualBox共享文件夹
如何在系统启动时使用systemd单元文件挂载Oracle VirtualBox共享文件夹?
从Vbox重新启动共享文件夹时如何执行脚本?
RequiresMountsFor不适用于Oracle VirtualBox共享文件夹功能。
在本教程中,我将共享在重新启动/启动阶段从Oracle VirtualBox访问共享文件夹所需的说明。
如果我们正在使用任何其他第三方网络服务器(例如AWS)来创建共享并在重新引导或者关闭阶段访问它们,也可以将本文用作参考。
实验室环境
我正在使用Oracle VirtualBox的共享文件夹功能,该功能允许将Windows Host的文件夹共享到虚拟机。
有趣的部分是VirtualBox还具有自动挂载的功能,其中它将在重新引导期间自动在VM上安装此共享,而无需Linux客户端上进行任何其他配置。
我们将创建一个脚本,该脚本应该在VM节点重启后启动时将一些数据写入此共享文件夹。
现在,此脚本将作为systemd服务的一部分执行,该服务将配置为仅在我们的共享文件夹处于挂载状态时才调用该脚本。
1.配置Oracle VirtualBox共享文件夹
我已经写了一篇描述性很强的文章来在VirtualBox中创建共享文件夹,因此在此不再赘述。
我的Windows主机上有一个共享文件夹D:\shared
,该文件夹将挂载在/media/linux_dir
上。
由于所有内容均已配置,因此以下是我的Linux VM中已挂载的共享的摘要:
# df -h /media/linux_dir/ Filesystem Size Used Avail Use% Mounted on shared 235G 117G 118G 50% /media/linux_dir
2.创建虚拟脚本(可选)
我假设我们已经有了计划在系统启动或者关闭时执行的脚本。
但是为了本文的方便,让我创建一个。
这将是一个简单的脚本,它仅需进行一些预检查,然后将带有时间戳的目录创建到此共享文件夹中。
挂载共享文件夹后在启动时执行的示例脚本
3.创建系统服务单元文件
接下来,我们将创建服务单元文件,该文件将在系统启动期间执行脚本。
从上一篇文章中我们知道RequiresMountsFor
将检查安装点,然后启动相应的服务。
另外,除非在指定单位中设置了" DefaultDependencies = no",否则目标单元将使用" After ="类型的依赖关系补充所有" Wants ="或者" Requires ="类型的已配置依赖性。
# cat /etc/systemd/system/access-share.service [Unit] Description=Access VBox shared folder DefaultDependencies=no RequiresMountsFor=/media/linux_dir [Service] Type=simple RemainAfterExit=yes ExecStart=/root/create_dir.sh [Install] WantedBy=multi-user.target
重新加载systemd守护程序以激活更改
# systemctl daemon-reload
在重启之前,让我们先启动服务,然后确保它能够执行脚本,这将在共享文件夹/media/linux_dir下进一步创建一个目录。
# systemctl start access-share
检查服务状态
验证目录是否正确创建:
# ls -l /media/linux_dir/ total 0 drwxrwx--- 1 root vboxsf 0 Aug 30 16:58 dir_30-08-2017_16-58-12
4.验证共享装入后是否执行了服务
因此,运行时服务将按预期运行,并在共享文件夹中创建了目录。
接下来,使服务在重新启动时自动启动:
# systemctl enable access-share Created symlink /etc/systemd/system/multi-user.target.wants/access-share.service → /etc/systemd/system/access-share.service.
重新启动节点,并验证/media/linux_dir /下是否存在另一个目录。
# ls -l /media/linux_dir/ total 0 drwxrwx--- 1 root vboxsf 0 Aug 30 16:58 dir_30-08-2017_16-58-12
Hu,我仍然只有一个目录。幸运的是我有安装调试日志
下面的输出来自我的日志,其中列出了可用的安装单元:
starting at Sun Aug 30 17:01:41 IST 2017 UNIT LOAD ACTIVE SUB JOB DESCRIPTION -.mount loaded active mounted Root Mount boot.mount loaded inactive dead start /boot dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File System proc-fs-nfsd.mount loaded activating mounting start NFSD configuration filesystem proc-sys-fs-binfmt_misc.mount loaded inactive dead Arbitrary Executable File Formats File System sys-fs-fuse-connections.mount loaded inactive dead FUSE Control File System sys-kernel-config.mount loaded active mounted Kernel Configuration File System sys-kernel-debug.mount loaded active mounted Kernel Debug File System ● sysroot.mount not-found inactive dead sysroot.mount tmp.mount loaded inactive dead Temporary Directory (/tmp) var-lib-nfs-rpc_pipefs.mount loaded inactive dead start RPC Pipe File System LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. JOB = Pending job for the unit. 13 loaded units listed. To show all installed unit files use 'systemctl list-unit-files'. /media/linux_dir dir not available
我在输出中找不到media-linux_dir.mount
。
让我们检查一下是否现在已加载此挂载文件。
# systemctl list-units --all | grep linux_dir media-linux_dir.mount loaded active mounted /media/linux_dir
是的,"此装载已装载",我也可以看到共享文件夹已装载
# df -h /media/linux_dir/ Filesystem Size Used Avail Use% Mounted on shared 235G 117G 118G 50% /media/linux_dir
5.为什么systemd在重新启动期间无法访问共享文件夹
我尝试了
After =
,Before =
,Requires =
,WantedBy =
的不同组合,但没有对Oracle VirtualBox共享文件夹起作用。然后我开始意识到问题是,该共享文件夹正在使用不受systemd控制的自动安装功能挂载到我的VM。
因此,与来自系统的所有其他安装文件不同,systemd无法确定安装文件是否已加载并处于活动状态。
因此,要解决此问题,我应该禁用
Auto-Mount
并使用/etc/fstab
或者systemd挂载文件来挂载此共享文件夹。然后,我们可以为此访问共享服务的此挂载文件添加依赖项,因此希望它应该可以工作
6.禁用VBox共享文件夹的自动挂载
让我们禁用此共享文件夹的自动安装功能。
打开机器的"设置"→"共享文件夹"。
选择共享文件夹,然后取消选中"自动挂载"选项。
点击"确定"保存更改。
在VirtualBox共享文件夹上禁用自动挂载
7.创建系统单元文件以挂载共享文件夹
我们也可以使用/etc/fstab
,但是我已经习惯了systemd,所以我更喜欢这种解决方案。
以下是我的示例systemd单元文件,用于挂载共享文件夹。
我更喜欢使用/etc/systemd/system
来创建我的自定义systemd单元文件。
[Unit] Description=VBox shared directory DefaultDependencies=no Conflicts=umount.target Before=local-fs.target umount.target After=swap.target [Mount] What=shared Where=/media/linux_dir Type=vboxsf Options=defaults,uid=root,gid=vboxsf,umask=007 [Install] WantedBy=multi-user.target
提示:
如果我们想使用fstab
,则在/etc/fstab
中追加以下条目(根据环境修改值)。
# SHARED_FOLDER_NAME /MOUNT_POINT_ON_CLIENT TYPE_OF_FS OPTIONS DUMP PASS shared /media/linux_dir vboxsf defaults,uid=root,gid=vboxsf,umask=007 0 0
其中我们必须显式提供UID,GID和umask,否则默认情况下,用户和组权限将分配给root用户,umask 000将会分配。
因此,创建的任何文件或者目录都将具有完全权限。
由于我们知道Virtual Box共享文件夹由root
和vboxsf
拥有,因此我们将对umask007
应用相同的权限。
下一步启动此单位文件以确保它可以挂载我们的共享文件夹(显然,如果已处于挂载状态,则应卸载该共享文件夹)
# systemctl start media-linux_dir.mount
使用systemd单元文件挂载VirtualBox共享文件夹
8.验证systemd挂载单元文件
验证是否已安装共享文件夹
# df -h /media/linux_dir/ Filesystem Size Used Avail Use% Mounted on /shared 235G 117G 118G 50% /media/linux_dir
因此单位文件正常工作
让我们启用单元文件并重新启动节点,以确保重新启动后相同的工作
# systemctl enable media-linux_dir.mount Created symlink /etc/systemd/system/multi-user.target.wants/media-linux_dir.mount → /etc/systemd/system/media-linux_dir.mount.
重新启动后,验证共享文件夹的安装点
# df -h /media/linux_dir/ Filesystem Size Used Avail Use% Mounted on /shared 235G 117G 118G 50% /media/linux_dir
"因此我们的systemd单位文件正在按预期方式工作。
"
9.创建系统服务单元文件
我们可以使用本教程第3章中现有的systemd服务单元文件。
我添加了一个额外的Conflicts =
参数来确保执行我们的服务时,umount.mount
已关闭。
# cat /etc/systemd/system/access-share.service [Unit] Description=Access VBox shared folder DefaultDependencies=no Conflicts=umount.target After=media-linux_dir.mount RequiresMountsFor=/media/linux_dir [Service] Type=simple RemainAfterExit=yes ExecStart=/root/create_dir.sh [Install] WantedBy=multi-user.target
重新加载systemd守护程序以激活更改
# systemctl daemon-reload
启动服务,并验证它是否按预期工作。
# systemctl start access-share
检查服务状态
access-share.service的系统服务状态
在/media/linux_dir下,我们还有一个新目录。
# ls -l /media/linux_dir/ total 0 drwxrwx--- 1 root vboxsf 0 Aug 30 16:58 dir_30-08-2017_16-58-12 drwxrwx--- 1 root vboxsf 0 Aug 30 20:53 dir_30-08-2017_20-53-33
10.验证共享挂载后是否执行了服务
现在,让我们重新启动节点并检查是否有第三个目录:
# ls -l /media/linux_dir/ total 0 drwxrwx--- 1 root vboxsf 0 Aug 30 16:58 dir_30-08-2017_16-58-12 drwxrwx--- 1 root vboxsf 0 Aug 30 20:53 dir_30-08-2017_20-53-33 drwxrwx--- 1 root vboxsf 0 Aug 30 20:55 dir_30-08-2017_20-55-56
最后,我们有了第三个目录,一切正常。