ukui-search/ukui-search-service-dir-man.../dirwatcher/dir-watcher.cpp

709 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dir-watcher.h"
#include <QDebug>
#include <QDir>
#include <QDBusConnection>
#include <QDBusArgument>
#include <QThread>
#include <fstab.h>
#include <QMutexLocker>
#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;
}
void DirWatcher::initData()
{
//适配需求,可索引目录为用户指定。
// m_indexableDirList << "/data" << QDir::homePath();
/* boot里面存放Linux核心文件开机选单与开机所需配置文件等
* backup里面是系统备份文件
* bin放置的是在单人维护模式下还能够被操作的指令在bin底下的指令可以被root与一般账号所使用。
* dev里面存放设备文件
* etc里面存放了几乎所有的系统主要配置文件包括人员的账号密码文件各种服务的起始档等
* lib放置最基本的共享库和内核模块lib32lib64libx32分别面向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<QDBusObjectPath>();
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<QDBusObjectPath>();
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);
}
}