在 OSX 中确定实际安装的卷和远程文件系统
Determine actually mounted volumes and remote file systems in OSX
我需要收集本地文件系统可以访问的所有已挂载 "mount points" 的列表。
这包括:
/Volumes
. 下任何普通安装的卷
- 当前安装在
/net
下的任何 NFS 卷。
- 使用 "mount" 命令挂载或以某种方式自动挂载的任何本地或远程文件系统。
但我需要避免访问任何可以自动挂载但当前未挂载的文件系统。也就是说,我不想导致任何自动数量。
我目前的方法如下:
- 在循环中调用
FSGetVolumeInfo()
以收集所有已知的体积。这将为我提供 /Volumes
和 /net, /home
下的所有本地驱动器以及 /net
. 下的 NFS 挂载
- 调用
FSGetVolumeParms()
获取每个卷的"device ID"(原来是网络卷的挂载路径)
- 如果 ID 是 POSIX 路径(即它以“/”开头),我在其路径的父级上使用
readdir()
来检查父级目录是否实际包含挂载点项(例如,如果 ID 是 /net/MyNetShare
,那么我 readdir /net
)。如果它不可用,我假设这是一个带有尚未卸载的卷的自动安装点,因此将其从我的已安装卷列表中排除。
- 最后,如果该卷显示为已安装,我会检查它是否包含任何项目。如果是,我将其添加到我的列表中。
第 3 步是必要的,以查看该路径是否已实际挂载。如果我改为在完整路径上调用 lstat()
,它会尝试自动挂载文件系统,我需要避免这种情况。
现在,尽管上面的大部分时间都有效,但仍然存在一些问题:
- 混合调用 BSD 和 Carbon API,以及 "device ID" 值的特殊大小写,相当不干净。
FSGetVolumeInfo()
调用为我提供了诸如“/net”和“/home”之类的挂载点,尽管这些似乎不是实际的挂载点 - 挂载点宁愿出现 里面这些。例如,如果我在“/net/MyNFSVolume”挂载 NFS 共享,我会同时收集“/net”点和“/net/MyNFSVolume”,但“/net”点没有实际体积。
- 最糟糕的是,有时上述过程仍然会导致主动尝试联系离线服务器,从而导致长时间超时。
那么,谁能告诉我找到所有实际安装的卷的更好方法?
通过使用 BSD 级别函数 getattrlist()
,请求 ATTR_DIR_MOUNTSTATUS
属性,可以测试 DIR_MNTSTATUS_TRIGGER
标志。
此标志似乎仅在当前无法访问自动挂载的共享点时设置。此标志的状态似乎与管理重新安装此类安装点的 automountd
守护程序维护的安装状态直接相关:只要 automountd
报告安装点不可用,由于服务器没有响应,设置了 "trigger" 标志。
但是请注意,一旦网络共享变得不可访问,此状态不会立即设置。考虑这种情况:
文件 /etc/auto_master
在末尾添加了这一行:
/- auto_mymounts
文件/etc/auto_mymounts
具有以下内容:
/mymounts/MYSERVER1 -nfs,soft,bg,intr,net myserver1:/
这意味着在 /mymounts/MYSERVER1
将有一个自动挂载目录,允许访问 myserver1 导出的 NFS 共享的根目录。
让我们假设服务器最初是可访问的。然后我们可以浏览/mymounts/MYSERVER1处的目录,DIR_MNTSTATUS_TRIGGER
标志将被清除。
接下来,让我们通过简单地终止网络连接(例如移除以太网电缆以关闭 Wi-Fi)来使服务器变得无法访问。此时,当再次尝试访问 /mymounts/MYSERVER1 时,我们会遇到延迟和超时,甚至可能会在服务器不可用的情况下得到看似有效的结果,例如非空目录列表。此时 DIR_MNTSTATUS_TRIGGER
标志将保持清除状态。
现在让计算机进入睡眠状态,然后再将其唤醒。此时,automountd
再次尝试重新连接所有自动安装的卷。它会注意到服务器离线并将挂载点置于 "trigger" 状态。现在 DIR_MNTSTATUS_TRIGGER
标志将根据需要设置。
因此,虽然此触发标志不是判断远程服务器何时无法访问的完美指标,但它足以判断服务器何时离线较长时间,因为移动客户端计算机时通常会发生这种情况在不同的网络之间,例如在工作和家庭之间,计算机在两者之间进入睡眠状态,从而导致 automountd 守护进程检测 NFS 服务器的可达性。
我需要收集本地文件系统可以访问的所有已挂载 "mount points" 的列表。
这包括:
/Volumes
. 下任何普通安装的卷
- 当前安装在
/net
下的任何 NFS 卷。 - 使用 "mount" 命令挂载或以某种方式自动挂载的任何本地或远程文件系统。
但我需要避免访问任何可以自动挂载但当前未挂载的文件系统。也就是说,我不想导致任何自动数量。
我目前的方法如下:
- 在循环中调用
FSGetVolumeInfo()
以收集所有已知的体积。这将为我提供/Volumes
和/net, /home
下的所有本地驱动器以及/net
. 下的 NFS 挂载
- 调用
FSGetVolumeParms()
获取每个卷的"device ID"(原来是网络卷的挂载路径) - 如果 ID 是 POSIX 路径(即它以“/”开头),我在其路径的父级上使用
readdir()
来检查父级目录是否实际包含挂载点项(例如,如果 ID 是/net/MyNetShare
,那么我 readdir/net
)。如果它不可用,我假设这是一个带有尚未卸载的卷的自动安装点,因此将其从我的已安装卷列表中排除。 - 最后,如果该卷显示为已安装,我会检查它是否包含任何项目。如果是,我将其添加到我的列表中。
第 3 步是必要的,以查看该路径是否已实际挂载。如果我改为在完整路径上调用 lstat()
,它会尝试自动挂载文件系统,我需要避免这种情况。
现在,尽管上面的大部分时间都有效,但仍然存在一些问题:
- 混合调用 BSD 和 Carbon API,以及 "device ID" 值的特殊大小写,相当不干净。
FSGetVolumeInfo()
调用为我提供了诸如“/net”和“/home”之类的挂载点,尽管这些似乎不是实际的挂载点 - 挂载点宁愿出现 里面这些。例如,如果我在“/net/MyNFSVolume”挂载 NFS 共享,我会同时收集“/net”点和“/net/MyNFSVolume”,但“/net”点没有实际体积。- 最糟糕的是,有时上述过程仍然会导致主动尝试联系离线服务器,从而导致长时间超时。
那么,谁能告诉我找到所有实际安装的卷的更好方法?
通过使用 BSD 级别函数 getattrlist()
,请求 ATTR_DIR_MOUNTSTATUS
属性,可以测试 DIR_MNTSTATUS_TRIGGER
标志。
此标志似乎仅在当前无法访问自动挂载的共享点时设置。此标志的状态似乎与管理重新安装此类安装点的 automountd
守护程序维护的安装状态直接相关:只要 automountd
报告安装点不可用,由于服务器没有响应,设置了 "trigger" 标志。
但是请注意,一旦网络共享变得不可访问,此状态不会立即设置。考虑这种情况:
文件 /etc/auto_master
在末尾添加了这一行:
/- auto_mymounts
文件/etc/auto_mymounts
具有以下内容:
/mymounts/MYSERVER1 -nfs,soft,bg,intr,net myserver1:/
这意味着在 /mymounts/MYSERVER1
将有一个自动挂载目录,允许访问 myserver1 导出的 NFS 共享的根目录。
让我们假设服务器最初是可访问的。然后我们可以浏览/mymounts/MYSERVER1处的目录,DIR_MNTSTATUS_TRIGGER
标志将被清除。
接下来,让我们通过简单地终止网络连接(例如移除以太网电缆以关闭 Wi-Fi)来使服务器变得无法访问。此时,当再次尝试访问 /mymounts/MYSERVER1 时,我们会遇到延迟和超时,甚至可能会在服务器不可用的情况下得到看似有效的结果,例如非空目录列表。此时 DIR_MNTSTATUS_TRIGGER
标志将保持清除状态。
现在让计算机进入睡眠状态,然后再将其唤醒。此时,automountd
再次尝试重新连接所有自动安装的卷。它会注意到服务器离线并将挂载点置于 "trigger" 状态。现在 DIR_MNTSTATUS_TRIGGER
标志将根据需要设置。
因此,虽然此触发标志不是判断远程服务器何时无法访问的完美指标,但它足以判断服务器何时离线较长时间,因为移动客户端计算机时通常会发生这种情况在不同的网络之间,例如在工作和家庭之间,计算机在两者之间进入睡眠状态,从而导致 automountd 守护进程检测 NFS 服务器的可达性。