如何在Linux中使用systemd启动时访问VirtualBox共享文件夹

时间:2020-02-23 14:40:39  来源:igfitidea点击:

如何在系统启动时使用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共享文件夹由rootvboxsf拥有,因此我们将对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

最后,我们有了第三个目录,一切正常。