获取上次挂载/卸载的文件系统的名称

时间:2014-04-24 21:11:35

标签: linux polling mount

我知道我可以对文件/proc/mount/etc/mtab进行监控(使用pollselect),然后找出 WHEN 文件系统安装或未安装。此外,我可以使用getmntent获取已安装文件系统的列表。

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

我的解决方案:

  1. 检测/proc/mounts
  2. 中的某些更改
  3. 使用getmntent获取当前挂载的所有文件系统。
  4. 将获得的列表与之前的列表进行比较。
  5. 处理差异。
  6. 但是我需要知道在从/proc/mounts/etc/mtab进行轮询时是否有某种方法可以安装最后一个文件系统。只需读取文件或将数据轮询到某个结构(例如mntent)。

1 个答案:

答案 0 :(得分:0)

解决方案说明

已实施的解决方案涉及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;
}

确定文件系统是已安装还是未安装

简单地比较两个lits的大小。

// 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),但安装设备的数量一般(我不想要)绝对)低于20.因此,算法将运行得非常快。