我需要收集本地文件系统可以访问的所有已安装“挂载点”的列表 .
这包括:
-
/Volumes
下任何通常安装的卷 . -
当前在
/net
下安装的任何NFS卷 . -
使用"mount"命令安装的任何本地或远程文件系统,或以某种方式自动安装 .
但我需要避免访问任何可以自动挂载但当前未挂载的文件系统 . 即,我不想引起任何自动计费 .
我目前的方法如下:
-
在循环中调用
FSGetVolumeInfo()
以收集所有已知卷 . 这将为我提供/Volumes
下的所有本地驱动器以及/net, /home
,以及/net
下的NFS安装 . -
调用
FSGetVolumeParms()
以获取每个卷的"device ID"(这结果是网络卷的装载路径) . -
如果ID是POSIX路径(即它以"/"开头),我在其路径的父节点上使用
readdir()
来检查父目录是否实际包含挂载点项(例如,如果ID是/net/MyNetShare
,那么我读取/net
) . 如果它不可用,我认为这是一个具有尚未卸载的卷的自动挂载点,因此将其从我的挂载卷列表中排除 . -
最后,如果卷显示已挂载,我会检查它是否包含任何项目 . 如果是,我将它添加到我的列表中 .
步骤3是必要的,以查看路径是否实际安装 . 如果我在完整路径上调用 lstat()
,它会尝试自动挂载文件系统,我需要避免 .
现在,即使上述工作大部分时间都有效,但仍存在一些问题:
-
对BSD和Carbon API的混合调用,以及"device ID"值的特殊套管,是相当不洁净的 .
-
FSGetVolumeInfo()
调用给出了挂载点,如"/net"和"/home",即使这些挂载点似乎不是实际挂载点 - 挂载点也会出现在这些挂载点内 . 例如,如果我_14727380_d收集了"/net"点和"/net/MyNFSVolume",但"/net"点不是实际音量 . -
最糟糕的是,有时上述过程仍会导致主动尝试联系离线服务器,从而导致长时间超时 .
那么,谁能告诉我更好的方法来找到所有实际安装的卷?
1 回答
通过使用BSD级别函数
getattrlist()
,要求ATTR_DIR_MOUNTSTATUS
属性,可以测试DIR_MNTSTATUS_TRIGGER
标志 .仅当自动挂载的共享点当前无法访问时,才会设置此标志 . 此标志的状态似乎与管理重新安装此类挂载点的
automountd
守护程序维护的挂载状态直接相关:只要automountd
报告挂载点不可用,由于服务器没有响应, "trigger"标志已设置 .但请注意,一旦网络共享无法访问,就不会立即设置此状态 . 考虑这种情况:
文件
/etc/auto_master
在最后添加了这一行:文件
/etc/auto_mymounts
具有以下内容:这意味着
/mymounts/MYSERVER1
将有一个自动挂载目录,可以访问myserver1导出的NFS共享的根目录 .我们假设服务器最初是可以访问的 . 然后我们可以浏览/ mymounts / MYSERVER1目录,并清除
DIR_MNTSTATUS_TRIGGER
标志 .接下来,让's make the server become unreachable by simply killing the network connection (such as removing the ethernet cable to turning off Wi-Fi). At this point, when trying to access /mymounts/MYSERVER1 again, we' ll得到延迟和超时,我们甚至可能得到看似有效的结果,例如非空目录列表,尽管服务器不可用 . 此时
DIR_MNTSTATUS_TRIGGER
标志将保持清除状态 .现在让电脑进入睡眠状态并再次唤醒它 . 此时,
automountd
尝试再次重新连接所有自动安装的卷 . 它会注意到服务器处于脱机状态并将挂载点置于"trigger"状态 . 现在DIR_MNTSTATUS_TRIGGER
标志将根据需要设置 .因此,虽然这个触发标志不是告诉远程服务器何时无法访问的完美指示器,但它足以告诉服务器何时离线较长时间,因为通常在不同网络之间移动客户端计算机时会发生这种情况,例如在工作和家庭之间,计算机在两者之间进入睡眠状态,从而导致automountd守护程序检测NFS服务器的可达性 .