简体   繁体   English

获取最后一个已挂载/未挂载文件系统的名称

[英]Getting the name of the last mounted/unmounted filesystem

I know I can monitor (using poll , or select ) on the files /proc/mount or /etc/mtab and findout WHEN a filesystem is mounted or unmounted. 我知道我可以监视(使用轮询选择 )上的文件/proc/mount/etc/mtab和findout 文件系统被安装或卸载。 Also I can use getmntent for getting a list of mounted filesystems. 我也可以使用getmntent获取已挂载文件系统的列表。

My app is intended to monitor the mounted filesystem and report any change (mount or unmount). 我的应用旨在监视已挂载的文件系统并报告任何更改(已安装或已卸载)。

My solution: 我的解决方案:

  1. Detect some change in /proc/mounts . 检测/proc/mounts某些更改。
  2. Get all currently mounted filesystem with getmntent . 使用getmntent获取当前所有已挂载的文件系统。
  3. Compare the obtained list with some previous list. 将获得的列表与先前的列表进行比较。
  4. Process the difference. 处理差异。

But I need to know if there are some way to get the last filesystem mounted when polling from /proc/mounts or /etc/mtab . 但是我需要知道从/proc/mounts/etc/mtab轮询时是否有某种方法可以挂载最后一个文件系统。 Just reading the file or polling data into some structure (like mntent for instance.) 只需读取文件或将数据轮询为某种结构(例如mntent )。

Solution description 解决方案说明

The implemented solution involve udev , poll , setmntent and getmntent . 实现的解决方案涉及udevpollsetmntentgetmntent

The idea is to keep a list of all the mounted file systems (this is not memory-expensive, since the number of devices is generally low) and the list has to be created only once. 这个想法是保留所有已挂载文件系统的列表(由于设备数量通常很少,因此不会占用大量内存),并且该列表只需创建一次即可。

Using poll() over "/proc/mounts" you can find out when a filesystem is mounted or unmounted. “ / proc / mounts”上使用poll()可以发现文件系统何时被挂载或卸载。 And then using udev you can get the list of devices mounted at that time. 然后,使用udev可以获取当时安装的设备列表。 So you can compare with the list you already have and that way you will know if the filesystem was mounted or unmounted and which filesystem is the affected. 因此,您可以将其与已经拥有的列表进行比较,这样您将知道文件系统是已安装还是已卸载,以及哪个文件系统受到了影响。

Relevant code samples of the soultion 灵魂的相关代码示例

Function to get the mounted nodes. 获取已安装节点的功能。

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;
}

Finding out if the filesystem was mounted or unmounted 查找文件系统是否已挂载

Simple just compare the size of both 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;

Finding out if the affected filesystem 找出受影响的文件系统

vector<string> new_mounted_nodes = get_mounted_storage_nodes();

Using the previous line, if the filesystem was mounted, you only have to find the element of new_mounted nodes that is not in the list of mounted nodes you already have. 使用上一行,如果已挂载文件系统,则只需要查找new_mounted nodes的元素,该元素不在您已经拥有的已挂载节点的列表中。 On the other hand, if the filesystem was unmounted you have to find the element that is in the list you already have but not in new_mounted_nodes . 另一方面,如果文件系统已卸载,则必须在列表中找到已存在但在new_mounted_nodes没有的new_mounted_nodes

Code sample: 代码示例:

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;
}

IMPORTANT NOTE: The complexity of the latest code is O(n^2) , but the number of mounted devices will generally (I don't want to be absolute) be lower that 20. So, the algorithm will run very fast. 重要说明:最新代码的复杂度为O(n ^ 2) ,但已安装设备的数量通常(我不想绝对)小于20。因此,该算法将运行得非常快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM