#include "dir-watcher.h" #include #include #include #include #include #include #include #include "config.h" #define CURRENT_INDEXABLE_DIR_SETTINGS QDir::homePath() + "/.config/org.ukui/ukui-search/ukui-search-current-indexable-dir.conf" #define INDEXABLE_DIR_VALUE "IndexableDir" #define DEFAULT_INDEXABLE_DIR QDir::homePath() static std::once_flag flag; static DirWatcher *global_intance = nullptr; QMutex DirWatcher::s_mutex; DirWatcher::DirWatcher(QObject *parent) : QObject(parent) { m_qSettings = new QSettings(CURRENT_INDEXABLE_DIR_SETTINGS, QSettings::IniFormat); this->currentIndexableDir(); if (m_indexableDirList.isEmpty()) { qDebug() << QString("use the path: %1 as default indexable dir.").arg(DEFAULT_INDEXABLE_DIR); m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); m_qSettings->setValue(INDEXABLE_DIR_VALUE, DEFAULT_INDEXABLE_DIR); m_qSettings->endGroup(); } initDiskWatcher(); initData(); m_adaptor = new DirWatcherAdaptor(this); } DirWatcher::~DirWatcher() { if (m_volumeMonitor) { g_signal_handler_disconnect(m_volumeMonitor, m_mountAddHandle); g_signal_handler_disconnect(m_volumeMonitor, m_mountRemoveHandle); m_volumeMonitor = nullptr; } if(m_qSettings){ delete m_qSettings; } m_qSettings = nullptr; } DirWatcher *DirWatcher::getDirWatcher() { std::call_once(flag, [ & ] { global_intance = new DirWatcher(); }); return global_intance; } QStringList DirWatcher::currentIndexableDir() { QMutexLocker locker(&s_mutex); this->updateIndexableDirs(); return m_indexableDirList; } void DirWatcher::updateIndexableDirs() { m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); m_indexableDirList = m_qSettings->value(INDEXABLE_DIR_VALUE).toStringList(); m_qSettings->endGroup(); QStringList indexableDirs = m_indexableDirList; bool changed(false); for (const QString& dir : m_indexableDirList) { if (!QFileInfo(dir).isDir()) { indexableDirs.removeAll(dir); changed = true; } } if (changed) { m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); m_qSettings->setValue(INDEXABLE_DIR_VALUE, indexableDirs); m_qSettings->endGroup(); m_indexableDirList = indexableDirs; Q_EMIT this->indexDirsChanged(); } } QStringList DirWatcher::currentBlackListOfIndex() { QMutexLocker locker(&s_mutex); QStringList blackListOfIndex = m_blackListOfIndex; return blackListOfIndex; } bool DirWatcher::handleIndexItemAppend(const QString &path, QStringList &blackList) { //排除要添加的路径已被索引的情况 if (m_indexableDirList.contains(path)) { qDebug() << QString("index path %1 is already added.").arg(path); return false; } //处理添加路径非根目录时,要添加索引的路径与已索引路径为父子关系的情况 if (path != "/") { QString indexablePath; QStringList tmp = m_indexableDirList; for (int i = 0; i < m_indexableDirList.length(); i++) { indexablePath = m_indexableDirList.at(i); if (path.startsWith(indexablePath + "/")) { qCritical() << QString("The parent of the path:%1 has been added.").arg(path); return false; } if (indexablePath.startsWith(path + "/")) { tmp.removeAll(indexablePath); blackList.append(indexablePath); } } m_indexableDirList = tmp; } m_indexableDirList << path; m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); m_qSettings->setValue(INDEXABLE_DIR_VALUE, m_indexableDirList); m_qSettings->endGroup(); blackList.removeDuplicates(); Q_EMIT this->appendIndexItem(path, blackList); qDebug() << "index path:" << path << "blacklist:" << blackList; return true; } bool DirWatcher::handleIndexItemRemove(const QString &path) { this->currentIndexableDir(); QMutexLocker locker(&s_mutex); if (!m_indexableDirList.contains(path)) { qWarning() << QString("The path: %1 is not indexed").arg(path); return false; } m_indexableDirList.removeAll(path); m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); m_qSettings->setValue(INDEXABLE_DIR_VALUE, m_indexableDirList); m_qSettings->endGroup(); return true; } /** * @brief DirWatcher::blackListOfDir 根据传入目录返回当前目录下的所有不可搜索目录,没有则返回空列表 * @param dirPath 要搜索的目录 */ QStringList DirWatcher::blackListOfDir(const QString &dirPath) { //new TODO: Optimize the search algorithm. //There is no processing for the subvolumes.May be a bug. QStringList blackListOfDir; QMutexLocker locker(&s_mutex); for (auto t = m_repeatedlyMountedDeviceInfo.constBegin(); t != m_repeatedlyMountedDeviceInfo.constEnd(); t++) { QString topRepeatedMountPoint; for (QString mountPoint: t.value()) { if (mountPoint.startsWith(dirPath)) { if (topRepeatedMountPoint.isEmpty()) { topRepeatedMountPoint = mountPoint; continue; } else if (topRepeatedMountPoint.startsWith(mountPoint)) { blackListOfDir.append(topRepeatedMountPoint); topRepeatedMountPoint = mountPoint; } else { blackListOfDir.append(mountPoint); } } } } for (auto i = m_infoOfSubvolume.constBegin(); i != m_infoOfSubvolume.constEnd(); i++) { QString mountPoint = i.value(); QString spec = i.key(); //排除搜索列表指定多个目录时子卷会重复包含的情况,比如同时指定/home和/data/home QString tmp = dirPath; if (dirPath.startsWith(mountPoint)) { blackListOfDir.append(tmp.replace(0, mountPoint.length(), spec)); } if (dirPath.startsWith(spec)) { blackListOfDir.append(tmp.replace(0, spec.length(), mountPoint)); } } return blackListOfDir; } void DirWatcher::appendBlackListItemOfIndex(const QString &path) { QMutexLocker locker(&s_mutex); m_blackListOfIndex.append(path); m_blackListOfIndex = m_blackListOfIndex.toSet().toList(); } void DirWatcher::appendBlackListItemOfIndex(const QStringList &pathList) { QMutexLocker locker(&s_mutex); m_blackListOfIndex.append(pathList); m_blackListOfIndex = m_blackListOfIndex.toSet().toList(); } void DirWatcher::removeBlackListItemOfIndex(const QString &path) { QMutexLocker locker(&s_mutex); m_blackListOfIndex.removeAll(path); } void DirWatcher::removeBlackListItemOfIndex(const QStringList &pathList) { QMutexLocker locker(&s_mutex); for (QString path: pathList) { m_blackListOfIndex.removeAll(path); } } void DirWatcher::initDbusService() { QDBusConnection sessionBus = QDBusConnection::sessionBus(); if (!sessionBus.registerObject("/org/ukui/search/fileindex", this, QDBusConnection::ExportAdaptors)){ qWarning() << "ukui-search-fileindex dbus register object failed reason:" << sessionBus.lastError(); } } QStringList DirWatcher::currentSearchableDir() { QMutexLocker locker(&s_mutex); return m_searchableDirList; } QStringList DirWatcher::searchableDirForSearchApplication() { QMutexLocker locker(&s_mutex); return m_searchableListForApplication; } void DirWatcher::mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis) { qDebug() << "Mount Added"; GMount* mount = (GMount*)g_object_ref(gmount); GVolume* volume = g_mount_get_volume(mount); if (volume) { bool canEject = g_volume_can_eject(volume); QString devName = g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); if (canEject and devName.contains(QRegExp("/nvme[0-9]+n[0-9]+p[0-9]+|/sd[a-z][0-9]+"))) { QMutexLocker locker(&s_mutex); pThis->m_currentUDiskDeviceList.append(devName.section("/", -1)); } qDebug() << "added device name:" << devName.section("/", -1); g_object_unref(volume); } else { qWarning() << "GVolume(add) is NULL."; } pThis->handleDisk(); } void DirWatcher::mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis) { qDebug() << "Mount Removed"; pThis->handleDisk(); QMutexLocker locker(&s_mutex); //处理u盘设备 if (pThis->m_removedUDiskDevice != NULL) { pThis->updateIndexableDirs();//更新索引名单,排除失效目录 pThis->m_currentUDiskDeviceInfo.remove(pThis->m_removedUDiskDevice); qDebug() << "m_currentUDiskDeviceInfo(after remove):" << pThis->m_currentUDiskDeviceInfo; pThis->m_removedUDiskDevice = ""; return; } GMount* mount = (GMount*)g_object_ref(gmount); GFile* rootFile; rootFile = g_mount_get_root(mount); if (!rootFile) { return; } QString removedUri = g_file_get_uri(rootFile); if (removedUri.isEmpty()) { return; } //处理uri转码 if (removedUri.startsWith("file:///")) { QString removedMountPoint = g_filename_from_uri(removedUri.toUtf8().constData(), nullptr, nullptr); pThis->m_blackListOfIndex.removeAll(removedMountPoint); locker.unlock(); QStringList indexableDirList = pThis->currentIndexableDir(); //卸载目录下存在已索引目录时,通知索引服务删除对应目录 for (const QString &indexableDir : indexableDirList) { if (indexableDir.startsWith(removedMountPoint + "/") or !indexableDir.compare(removedMountPoint)) { Q_EMIT pThis->removeIndexItem(indexableDir); } } //处理子卷情况 locker.relock(); for (auto t = pThis->m_infoOfSubvolume.constBegin(); t != pThis->m_infoOfSubvolume.constEnd(); t++) { if (removedMountPoint.startsWith(t.value() + "/")) { pThis->m_blackListOfIndex.removeAll(removedMountPoint.replace(t.value(), t.key())); } if (removedMountPoint.startsWith(t.key() + "/")) { pThis->m_blackListOfIndex.removeAll(removedMountPoint.replace(t.key(), t.value())); } } qDebug() << "m_blackListOfIndex(after remove):" << pThis->m_blackListOfIndex; } else { qWarning() << QString("Removed uri:%1 is not starts with 'file:///', there's no handling of it.").arg(removedUri); } g_object_unref(rootFile); } int DirWatcher::appendIndexableListItem(const QString &path) { int resultCode = 1; /* code: * 1: successful * -1: path or its parent dir has been added * -2: path is or under blacklist * -3: path is in repeat mounted devices and another path which is in the same device has been indexed * -4: another path which is in the same device has been indexed * -5: path is not exists */ //排除path不存在的情况 QFile file(path); if (!file.exists()) { qWarning() << QString("target path:%1 is not exists!").arg(path); resultCode = -5; return resultCode; } //同步配置文件中的已索引目录 this->currentIndexableDir(); qDebug() << "current indexable dirs:" << m_indexableDirList; QStringList blackList; QMutexLocker locker(&s_mutex); //根目录特殊处理 if (path == "/") { if (!this->handleIndexItemAppend(path, m_blackListOfIndex)) { resultCode = -1; } return resultCode; } //处理要添加索引的路径与索引黑名单中路径为父子关系的情况 for (const QString& blackListPath : m_blackListOfIndex) { if (path.startsWith(blackListPath + "/") or path == blackListPath) { qCritical() << QString("path:%1 is or under the blacklistpath:%2.").arg(path, blackListPath); resultCode = -2; return resultCode; } if (blackListPath.startsWith(path + "/")) { blackList.append(blackListPath); } } //排除要添加的目录为某设备的重复挂载目录,并且之前已索引过该设备其他挂载目录或其父目录的情况 for (auto i = m_repeatedlyMountedDeviceInfo.constBegin(); i != m_repeatedlyMountedDeviceInfo.constEnd(); i++) { bool pathToBeAddedIsRepeatedDevice = false; bool pathToBeAddedHasRepeatedDevice = false; bool addedPathIsRepeatedDevice = false; bool addedPathHasRepeatedDevice = false; QString addedRelativeDir; QString repeatedDir; for (const QString &addedPath : m_indexableDirList) { for (const QString &mountPoint : i.value()) { //要添加索引路径在重复挂载设备路径下(1) if (path.startsWith(mountPoint + "/") or mountPoint == path) { repeatedDir = mountPoint; pathToBeAddedIsRepeatedDevice = true; } //重复挂载设备路径在要添加索引路径下(2) if (mountPoint.startsWith(path + "/")) { repeatedDir = mountPoint; pathToBeAddedHasRepeatedDevice = true; } //已索引路径在重复挂载设备路径下(3) if (addedPath.startsWith(mountPoint + "/") or mountPoint == addedPath) { addedRelativeDir = addedPath; addedRelativeDir.remove(mountPoint); addedPathIsRepeatedDevice = true; } //重复挂载设备路径在已索引路径下(4) if (mountPoint.startsWith(addedPath + "/")) { addedPathHasRepeatedDevice = true; } //(1)(4)直接返回 if (pathToBeAddedIsRepeatedDevice and addedPathHasRepeatedDevice) { qCritical() << "current path is in repeat mounted devices and another path which is in the same device has been indexed!"; resultCode = -3; return resultCode; } //(2)(4)将要添加索引目录相应的重复挂载路径添加到黑名单 if (pathToBeAddedHasRepeatedDevice and addedPathHasRepeatedDevice) { blackList.append(repeatedDir); break; } //(1)(3)将已索引路径的前缀替换为要添加路径的前缀(前缀为mountPoint),判断替换后路径是否在要索引路径下,如果是则返回,否则将替换后路径添加到黑名单 if (pathToBeAddedIsRepeatedDevice and addedPathIsRepeatedDevice) { QString pathAfterReplace = repeatedDir + addedRelativeDir; if (path.startsWith(pathAfterReplace) or path == pathAfterReplace) { qCritical() << QString("another path:%1 which is in the same device has been indexed").arg(pathAfterReplace); resultCode = -4; return resultCode; } else { blackList.append(pathAfterReplace); break; } } //(2)(3)将替换前缀后的已索引路径添加到黑名单 if (pathToBeAddedHasRepeatedDevice and addedPathIsRepeatedDevice) { blackList.append(repeatedDir + addedRelativeDir); break; } } } } //排除重复挂载设备的目录 for (auto i = m_repeatedlyMountedDeviceInfo.constBegin(); i != m_repeatedlyMountedDeviceInfo.constEnd(); i++) { QString topRepeatedMountPoint; for (const QString &mountPoint : i.value()) { if (mountPoint.startsWith(path + "/") or mountPoint == path) { if (topRepeatedMountPoint.isEmpty()) { topRepeatedMountPoint = mountPoint; continue; } else if (topRepeatedMountPoint.startsWith(mountPoint)) { blackList.append(topRepeatedMountPoint); topRepeatedMountPoint = mountPoint; } else { blackList.append(mountPoint); } } } } //处理自动挂载子卷下的目录 for (auto t = m_infoOfSubvolume.constBegin(); t != m_infoOfSubvolume.constEnd(); t++) { QString mountPoint = t.value(); QString spec = t.key(); //要添加目录下存在子卷(要添加/data,但挂到/home的/data/home是子卷),若添加了/home则将/data/home排除 if (spec.startsWith(path + "/")) { for (QString &indexDir : m_indexableDirList) { if (indexDir == mountPoint || mountPoint.startsWith(indexDir + "/")) { blackList << spec; } if (indexDir.startsWith(mountPoint + "/")) { blackList << indexDir.replace(0, mountPoint.length(), spec); } } } //要添加目录下存在子卷挂载点,同上 if (mountPoint.startsWith(path + "/")) { for (QString &indexDir : m_indexableDirList) { if (indexDir == spec || spec.startsWith(indexDir + "/")) { blackList << mountPoint; } if (indexDir.startsWith(spec + "/")) { blackList << indexDir.replace(0, spec.length(), mountPoint); } } } //要添加的目录是子卷或在子卷下(/data/home or /data/home/xxx) if (path.startsWith(spec + "/") || path == spec) { for (QString &indexDir : m_indexableDirList) { //已添加挂载点或其上层目录 if (mountPoint.startsWith(indexDir + "/") || indexDir == mountPoint) { qCritical() << "Fail to add" << path << "The mount point or its father:" << indexDir << "has been added"; resultCode = -3; return resultCode; } //已添加挂载点下其他目录 if (indexDir.startsWith(mountPoint + "/")) { QString tmp = indexDir; tmp.replace(0, mountPoint.length(), spec); if (tmp == path) { qCritical() << "Fail to add" << path << "The same path which is in the subvolume has been added."; resultCode = -4; return resultCode; } else if (tmp.startsWith(path + "/")) {//已添加的子卷子目录替换前缀后在要添加目录下 blackList << tmp; } } } } //要添加的目录是挂载点或在挂载点下(/home or /home/xxx) if (path.startsWith(mountPoint + "/") || path == mountPoint) { for (QString &indexDir : m_indexableDirList) { //已添加子卷或其上层目录 if (spec.startsWith(indexDir + "/") || indexDir == spec) { qCritical() << "Fail to add" << path << "The subvolume or its father:" << indexDir << "has been added"; resultCode = -3; return resultCode; } //已添加子卷下其他目录 if (indexDir.startsWith(spec + "/")) { QString tmp = indexDir; tmp.replace(0, spec.length(), mountPoint); if (tmp == path) { qCritical() << "Fail to add" << path << "The same path which is in the mount point has been added."; resultCode = -4; return resultCode; } else if (tmp.startsWith(path + "/")) {//已添加的子卷子目录替换前缀后在要添加目录下 blackList << tmp; } } } } } if (!this->handleIndexItemAppend(path, blackList)) { resultCode = -1; } return resultCode; } bool DirWatcher::removeIndexableListItem(const QString &path) { bool res = this->handleIndexItemRemove(path); Q_EMIT this->removeIndexItem(path); return res; } int DirWatcher::appendSearchDir(const QString &path) { SearchDir dir(path); Config::self()->addDir(dir); return 0; } void DirWatcher::removeSearchDir(const QString &path) { SearchDir dir(path, false); Config::self()->removeDir(dir); return; } QStringList DirWatcher::currentSearchDirs() { return Config::self()->searchDirs(); } QStringList DirWatcher::currentBlackList() { return Config::self()->blackDirs(); } void DirWatcher::initData() { //适配需求,可索引目录为用户指定。 // m_indexableDirList << "/data" << QDir::homePath(); /* boot里面存放Linux核心文件,开机选单与开机所需配置文件等 * backup里面是系统备份文件 * bin放置的是在单人维护模式下还能够被操作的指令,在bin底下的指令可以被root与一般账号所使用。 * dev里面存放设备文件 * etc里面存放了几乎所有的系统主要配置文件,包括人员的账号密码文件,各种服务的起始档等 * lib放置最基本的共享库和内核模块,lib32,lib64,libx32分别面向32位,64位以及x32 ABI。他们都分别连接到usr下的lib*中 * media一般放置可移除的装置,包括软盘,光盘和一些移动存储设备都自动挂载到这里 * mnt原本和media用途相同,现用来放置暂时挂载一些额外装置 * usr是Unix操作系统软件资源所放置的目录,所有系统默认的软件(distribution发布者提供的软件)都会放置到usr底下 * var目录主要针对常态性变动的文件,包括缓存(cache)、登录档(log file)以及某些软件运作所产生的文件,包括程序文件(lock file, run file),或者如MySQL数据库的文件等 */ //将磁盘分区后其他分区都会挂载到media下,多块硬盘也会挂到media,因此media放开,mnt同理; //backup是备份文件,tmp是临时文件,也都放开 // m_blackListOfIndex << "/boot" << "/bin" << "/dev" << "/etc" << "/usr" << "/var" // << "/lib" << "/lib32" << "/lib64" << "/libx32" << "/cdrom" // << "/sys" << "/proc" << "/srv" << "/sbin" << "/run" << "/opt"; //专用机需求:只屏蔽/proc, /sys, /dev, /tmp, /run m_blackListOfIndex << "/proc" << "/sys" << "/dev" << "/tmp" << "/run"; //目前方案:可搜索目录(服务)默认根目录,可搜索目录(应用)默认家目录和/data目录 QDir dir("/data"); if (dir.exists()) { m_searchableListForApplication << "/data"; } m_searchableListForApplication << QDir::homePath(); m_searchableDirList << "/"; //init auto mounted device list setfsent(); while (1) { fstab *myFstab = getfsent(); if (!myFstab) { endfsent(); break; } QString automaticMountPoint = myFstab->fs_file; QString spec = myFstab->fs_spec; //目前只索引data和home,因此只存这两个文件夹下的挂载点 if (automaticMountPoint.contains("/data") || automaticMountPoint.contains("/home")) { m_autoMountList.append(automaticMountPoint); } //存储所有子卷自动挂载 if (!spec.startsWith("UUID")) { m_infoOfSubvolume.insert(spec, automaticMountPoint); } } GList *list = g_volume_monitor_get_volumes(m_volumeMonitor); if (!list) { qDebug() << "Fail to init glist of volume monitor!"; handleDisk(); return; } for (guint i = 0; i < g_list_length(list); i++) { GVolume *volume = (GVolume*)g_list_nth_data(list, i); QString udiskDevName = g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); bool canEject = g_volume_can_eject(volume); if (canEject and udiskDevName.contains(QRegExp("/nvme[0-9]+n[0-9]+p[0-9]+|/sd[a-z][0-9]+"))) { qDebug() << "udiskDevName:" << udiskDevName.section("/",-1); m_currentUDiskDeviceList.append(udiskDevName.section("/",-1)); } } //init disk data, refresh the black list handleDisk(); } void DirWatcher::initDiskWatcher() { //use Dbus to monitor the hot plug of Udisk. QDBusConnection dbc = QDBusConnection::systemBus(); qDebug() << "Connect The Signal:InterfacesAdded" << dbc.connect("org.freedesktop.UDisks2", "/org/freedesktop/UDisks2", "org.freedesktop.DBus.ObjectManager", "InterfacesAdded", this, SLOT(handleAddedUDiskDevice(QDBusMessage))); qDebug() << dbc.lastError(); qDebug() << "Connect The Signal:InterfacesRemove" << dbc.connect("org.freedesktop.UDisks2", "/org/freedesktop/UDisks2", "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved", this, SLOT(handleRemovedUDiskDevice(QDBusMessage))); m_volumeMonitor = g_volume_monitor_get(); if (!m_volumeMonitor) { qDebug() << "Fail to init volume monitor"; return; } m_mountAddHandle = g_signal_connect(m_volumeMonitor, "mount-added", G_CALLBACK(mountAddCallback), this); m_mountRemoveHandle = g_signal_connect(m_volumeMonitor, "mount-removed", G_CALLBACK(mountRemoveCallback), this); } void DirWatcher::handleDisk() { //init current mounted device info QMutexLocker locker(&s_mutex); m_currentMountedDeviceInfo.clear(); m_repeatedlyMountedDeviceInfo.clear(); for (QStorageInfo &storage: QStorageInfo::mountedVolumes()) { //遍历当前系统所有挂载的,且以sd*和nvme开头的存储设备 if (storage.isValid() and storage.isReady() and QString(storage.device()).contains(QRegExp("/nvme[0-9]+n[0-9]+p[0-9]+|/sd[a-z][0-9]+"))) { m_currentMountedDeviceInfo[storage.device()].append(storage.rootPath()); //存储非子卷的重复挂载设备 if (m_currentMountedDeviceInfo.value(storage.device()).length() > 1 and storage.subvolume().isEmpty()) { m_repeatedlyMountedDeviceInfo.insert(storage.device(), m_currentMountedDeviceInfo.value(storage.device())); } //排除挂载到data和home下挂载的所有其他设备,后面需要修改 // if (storage.rootPath().startsWith("/data") || storage.rootPath().startsWith("/home")) { // m_blackListOfIndex.append(storage.rootPath()); // } } } //根据设备号(key)更新u盘信息 if (!m_currentUDiskDeviceList.isEmpty()) { for (const QString &udiskDevice: m_currentUDiskDeviceList) { QStringList udiskMountPointList = m_currentMountedDeviceInfo.value("/dev/" + udiskDevice); if (udiskMountPointList.isEmpty()) { m_currentUDiskDeviceInfo.remove(udiskDevice); } else { m_currentUDiskDeviceInfo.insert(udiskDevice, udiskMountPointList); } } } //将u盘设备添加到索引黑名单 if (!m_currentUDiskDeviceInfo.isEmpty()) { for (auto t = m_currentUDiskDeviceInfo.constBegin(); t != m_currentUDiskDeviceInfo.constEnd(); t++) { for (QString udiskDevice: t.value()) { // if (udiskDevice.startsWith("/data") || udiskDevice.startsWith("/home")) { // m_blackListOfIndex.append(udiskDevice); // } } } } //从索引黑名单中移除所有自动挂载设备(目前只包含自动挂载到/data和/home目录下的设备),m_infoOfSubvolume存储全部fstab文件中的子卷自动挂载 for (const QString &autoMountDevice: m_autoMountList) { m_blackListOfIndex.removeAll(autoMountDevice); } m_blackListOfIndex.removeDuplicates(); qDebug() << "m_infoOfSubvolume" << m_infoOfSubvolume; qDebug() << "m_currentMountedDeviceInfo:" << m_currentMountedDeviceInfo; qDebug() << "m_repeatedlyMountedDeviceInfo:" << m_repeatedlyMountedDeviceInfo; qDebug() << "m_currentUDiskDeviceInfo:" << m_currentUDiskDeviceInfo; qDebug() << "m_blackListOfIndex:" << m_blackListOfIndex; } void DirWatcher::handleAddedUDiskDevice(QDBusMessage msg) { QDBusObjectPath objPath = msg.arguments().at(0).value(); if (objPath.path().contains(QRegExp("/nvme[0-9]+n[0-9]+p[0-9]+|/sd[a-z][0-9]+"))) { QMutexLocker locker(&s_mutex); m_currentUDiskDeviceList.append(objPath.path().section("/",-1)); qDebug() << "Add Udisk:" << m_currentUDiskDeviceList; } } void DirWatcher::handleRemovedUDiskDevice(QDBusMessage msg) { Q_EMIT this->udiskRemoved(); QDBusObjectPath objPath = msg.arguments().at(0).value(); if (objPath.path().contains(QRegExp("/nvme[0-9]+n[0-9]+p[0-9]+|/sd[a-z][0-9]+"))) { QMutexLocker locker(&s_mutex); m_removedUDiskDevice = objPath.path().section("/",-1); m_currentUDiskDeviceList.removeAll(m_removedUDiskDevice); } }