【问题标题】:Getting the name of the last mounted/unmounted filesystem获取最后安装/卸载的文件系统的名称
【发布时间】:2014-06-10 09:19:55
【问题描述】:

我知道我可以监视(使用pollselect)文件/proc/mount/etc/mtab 并找出何时 文件系统已安装或卸载。我也可以使用getmntent 获取已安装文件系统的列表。

我的应用旨在监控已挂载的文件系统并报告任何更改(挂载或卸载)。

我的解决方案:

  1. 检测/proc/mounts 中的一些变化。
  2. 使用getmntent 获取所有当前挂载的文件系统。
  3. 将获得的列表与之前的列表进行比较。
  4. 处理差异。

但我需要知道在从/proc/mounts/etc/mtab 轮询时是否有某种方法可以安装最后一个文件系统。只需读取文件或将数据轮询到某种结构中(例如 mntent。)

【问题讨论】:

  • 附带说明,如果您使用 systemd,您可以订阅单位更改通知(.mount 单位),您将轻松获得所需的信息。
  • 是的,我正在使用 systemd。你能在subscribe for unit change notifications (.mount units) 上解释一下吗?
  • systemd 通过其 dbus 公共接口通知单元中的任何更改,包括挂载点。我已经用 Python here 编写了一个类似于您需要的示例代码。也许您可以将其用作解决问题的基础。
  • 您的问题取得了进展?
  • 是的,但我不得不采用将 udev 与监控 /etc/mtab 结合使用的解决方案

标签: linux polling mount


【解决方案1】:

解决方案说明

实施的解决方案涉及udevpollsetmntentgetmntent

这个想法是保留所有已挂载文件系统的列表(这不会占用内存,因为设备数量通常很少)并且该列表只需要创建一次。

"/proc/mounts" 上使用 poll(),您可以了解 何时 文件系统被挂载或卸载。然后使用 udev 你可以得到当时挂载的设备列表。因此,您可以与已有的列表进行比较,这样您就可以知道文件系统是挂载还是卸载,以及哪个文件系统受到影响。

灵魂相关代码示例

获取挂载节点的函数。

vector<string> get_mounted_storage_nodes()
{
    vector<string> storage_nodes = get_storage_nodes(); // This uses udev.
    vector<string> mounted_nodes;
    struct mntent *mntent;

    FILE *file;
    file = setmntent("/etc/mtab", "r");

    while ((mntent = getmntent(file)))
    {
        string mounted_node(mntent->mnt_fsname);
        vector<string>::iterator it;
        it = find(storage_nodes.begin(), storage_nodes.end(), mounted_node);
        if (it != storage_nodes.end())
            mounted_nodes.push_back(mounted_node);
    }

    return mounted_nodes;
}

确定文件系统是挂载还是卸载

简单的只是比较两个灯的大小。

// event is a convenience struct that holds the name of the affected
// filesystem and the action (mounted or unmounted).

vector<string> new_mounted_nodes = get_mounted_storage_nodes();
int new_size = new_mounted_nodes.size();
int curr_size = mounted_nodes.size();

if (new_size == curr_size)
    event.action = NONE;    // No partition was mount or unmounted.
                            // This case is very common when the poll
                            // is working as non-blocking because the timeout.
else
    event.action = new_size > curr_size ? MOUNT : UMOUNT;

找出受影响的文件系统

vector<string> new_mounted_nodes = get_mounted_storage_nodes();

使用上一行,如果文件系统已挂载,您只需找到不在已挂载节点列表中的new_mounted nodes 元素。另一方面,如果文件系统被卸载,你必须找到你已经拥有但不在new_mounted_nodes的列表中的元素。

代码示例:

switch(event.action)
{
    case MOUNT:

        for (auto it = new_mounted_nodes.begin(); it != new_mounted_nodes.end(); ++it)
            if (find(mounted_nodes.begin(), mounted_nodes.end(), *it) == mounted_nodes.end())
            {
                event.node = *it;
                break;
            }
        break;

    case UMOUNT:
        for (auto it = mounted_nodes.begin(); it != mounted_nodes.end(); ++it)
            if (find(new_mounted_nodes.begin(), new_mounted_nodes.end(), *it) == new_mounted_nodes.end())
            {
                event.node = *it;
                break;
            }
        break;
    default:
        break;
}

重要提示:最新代码的复杂度是O(n^2),但是挂载设备的数量一般会(我不想absolute) 低于 20。因此,算法将运行得非常快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    相关资源
    最近更新 更多