Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Copyright: Curtis Gedak
License: GPL-2.0-or-later

#config
Files: service/assets/data/* application/assets/deepin-diskmanager.desktop application/assets/environments.h.in service/policy/com.deepin.diskmanager.policy service/udev/99-diskmanager.rules
Files: service/assets/data/* service/assets/dconfig/* application/assets/deepin-diskmanager.desktop application/assets/environments.h.in service/policy/com.deepin.diskmanager.policy service/udev/99-diskmanager.rules
Copyright: UnionTech Software Technology Co., Ltd.
License: CC0-1.0

Expand Down
4 changes: 4 additions & 0 deletions service/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ set(APP_USBREMOVE_FILES "${APP_EDEV_DIR}/USBremove.sh")
set(APP_DEEPIN_DISKMANAGER_SERVICE_BIN "${APP_EDEV_DIR}/deepin-diskmanager-authenticateProxy")
set(APP_POLICY_DIR "policy")
set(APP_POLICY_FILES "${APP_POLICY_DIR}/com.deepin.diskmanager.policy")
set(APP_DCONFIG_DIR "${APP_RES_DIR}/dconfig")
set(APP_DCONFIG_SCHEMA "${APP_DCONFIG_DIR}/com.deepin.diskmanager.storage.json")

# Find the library
find_package(PkgConfig REQUIRED)
find_package(DtkCore REQUIRED)
find_package(DtkGui REQUIRED)
find_package(Qt5 COMPONENTS
Core
Expand Down Expand Up @@ -79,4 +82,5 @@ install(PROGRAMS ${APP_USBADD_FILES} DESTINATION libexec/openconnect/)
install(PROGRAMS ${APP_USBREMOVE_FILES} DESTINATION libexec/openconnect/)
install(FILES ${APP_UDEV_FILES} DESTINATION /lib/udev/rules.d/)
install(FILES ${APP_POLICY_FILES} DESTINATION share/polkit-1/actions)
install(FILES ${APP_DCONFIG_SCHEMA} DESTINATION share/dsg/configs/com.deepin.diskmanager/)
install(PROGRAMS ${APP_DEEPIN_DISKMANAGER_SERVICE_BIN} DESTINATION bin/)
17 changes: 17 additions & 0 deletions service/assets/dconfig/com.deepin.diskmanager.storage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"magic": "dsg.config.meta",
"version": "1.0",
"contents": {
"ufsSpecVersions": {
"value": ["300", "310", "400", "410"],
"serial": 0,
"flags": ["global"],
"name": "UFS Spec Versions",
"name[zh_CN]": "UFS规范版本",
"description": "Substrings of the UFS spec version read from /sys/block/<dev>/device/spec_version that should be recognized as the UFS interface. Append new version strings here instead of modifying source code.",
"description[zh_CN]": "从 /sys/block/<dev>/device/spec_version 读取的UFS规范版本子串列表,匹配任一项即识别为UFS接口。新增UFS版本时只需在此配置中追加,无需修改源码。",
"permissions": "readonly",
"visibility": "private"
}
}
}
31 changes: 27 additions & 4 deletions service/diskoperation/DeviceStorage.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2022-2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-only

#include "DeviceStorage.h"
#include <QDebug>

Check warning on line 6 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDebug> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QFile>

Check warning on line 7 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QFile> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QRegularExpression>

Check warning on line 8 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QRegularExpression> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QScopedPointer>

Check warning on line 9 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QScopedPointer> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QVariant>

Check warning on line 10 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QVariant> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <DConfig>

Check warning on line 11 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DConfig> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include "utils.h"

Check warning on line 12 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "utils.h" not found.

namespace DiskManager {

Expand Down Expand Up @@ -583,7 +586,22 @@
return 1 == isPGUX;
}

// 从 DConfig 读取需要识别为 UFS 接口的 spec_version 子串列表,新增 UFS 版本时
// 只需在 com.deepin.diskmanager.storage 配置中追加,无需修改源码。
static QStringList ufsSpecVersions()
{
const QStringList fallback{"300", "310", "400", "410"};
QScopedPointer<Dtk::Core::DConfig> cfg(
Dtk::Core::DConfig::create("com.deepin.diskmanager", "com.deepin.diskmanager.storage"));
if (cfg && cfg->isValid()) {
QStringList versions = cfg->value("ufsSpecVersions", QVariant::fromValue(fallback)).toStringList();
if (!versions.isEmpty())
return versions;
}
return fallback;
}

void DeviceStorage::getDiskInfoInterface(const QString &devicePath, QString &interface, QString &model)

Check warning on line 604 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Parameter 'model' can be declared as reference to const
{
QString bootDevicePath("/proc/bootdevice/product_name");
QFile file(bootDevicePath);
Expand All @@ -592,8 +610,11 @@
if (model == file.readLine().simplified()) {
QString spec_version = Utils::readContent("/sys/block/sdd/device/spec_version").trimmed();
if (!spec_version.isEmpty()) {
if (spec_version.contains("300") || spec_version.contains("310") || spec_version.contains("400")) {
interface = "UFS";
foreach (const QString &version, ufsSpecVersions()) {
if (spec_version.contains(version)) {

Check warning on line 614 in service/diskoperation/DeviceStorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Consider using std::any_of algorithm instead of a raw loop.
interface = "UFS";
break;
}
}
}
}
Expand All @@ -606,7 +627,9 @@
proc.start(cmd);
proc.waitForFinished(-1);
QString outPut = proc.readAllStandardOutput().trimmed();
QStringList outPutList = outPut.split("(");
QMap<QString, QString> mapInfo;
getMapInfoFromInput(outPut, mapInfo);
QStringList outPutList = mapInfo.value("Attached to").split("(");
interface = outPutList[outPutList.size() - 1].split(" ")[0];
}
return;
Expand Down
4 changes: 3 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ LIST(APPEND SRC_LIST ${UT_DISKOPERATION})
file(GLOB ALL_HEADERS "../service/diskoperation/*.h" "../service/diskoperation/filesystems/*.h")
file(GLOB ALL_SOURCES "../service/diskoperation/*.cpp" "../service/diskoperation/filesystems/*.cpp")

find_package(DtkCore REQUIRED)

add_executable(${PROJECT_NAME_TEST} ${SRC_LIST} ${ALL_HEADERS} ${ALL_SOURCES})

target_link_libraries(${PROJECT_NAME_TEST} gmock gmock_main gtest gtest_main pthread Qt5::Core basestruct parted parted-fs-resize)
target_link_libraries(${PROJECT_NAME_TEST} gmock gmock_main gtest gtest_main pthread Qt5::Core ${DtkCore_LIBRARIES} basestruct parted parted-fs-resize)

# 添加 QTest 测试
add_test(${PROJECT_NAME_TEST} that-test-I-made COMMAND ${PROJECT_NAME_TEST})
Expand Down
85 changes: 85 additions & 0 deletions test/ut_diskoperation/ut_devicestorage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-only

#include "gtest/gtest.h"

Check warning on line 5 in test/ut_diskoperation/ut_devicestorage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "gtest/gtest.h" not found.

#include "../../service/diskoperation/DeviceStorage.h"

#include <QFile>
#include <QTemporaryDir>

using namespace DiskManager;

namespace {

class PathGuard
{
public:
explicit PathGuard(const QString &path)
: m_oldPath(qgetenv("PATH"))
{
qputenv("PATH", QString("%1:%2").arg(path, QString::fromLocal8Bit(m_oldPath)).toLocal8Bit());
}

~PathGuard()
{
qputenv("PATH", m_oldPath);
}

private:
QByteArray m_oldPath;
};

void writeExecutable(const QString &filePath, const QByteArray &content)
{
QFile file(filePath);
ASSERT_TRUE(file.open(QIODevice::WriteOnly | QIODevice::Truncate));
ASSERT_EQ(file.write(content), content.size());
file.close();
ASSERT_TRUE(file.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner));
}

} // namespace

class ut_devicestorage : public ::testing::Test
{
};

TEST_F(ut_devicestorage, getDiskInfoInterface_usesAttachedToWhenCapacityFollows)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
writeExecutable(dir.filePath("hwinfo"),
"#!/bin/sh\n"
"printf '%s\\n' '10: None 00.0: 10600 Disk' "
"' Attached to: #1 (UFS 3.1 Controller)' "
"' Capacity: 1 TB (1024626524160 bytes)'\n");
PathGuard guard(dir.path());

DeviceStorage storage;
QString interface;
QString model("__ut_nonexistent_model__");

storage.getDiskInfoInterface("/dev/__ut_nonexistent_pms372777_ufs__", interface, model);

EXPECT_EQ(interface, "UFS");
}

TEST_F(ut_devicestorage, getDiskInfoInterface_ignoresCapacityBytesWhenInterfaceMissing)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
writeExecutable(dir.filePath("hwinfo"),
"#!/bin/sh\n"
"printf '%s\\n' ' Capacity: 1 TB (1024626524160 bytes)'\n");
PathGuard guard(dir.path());

DeviceStorage storage;
QString interface;
QString model("__ut_nonexistent_model__");

storage.getDiskInfoInterface("/dev/__ut_nonexistent_pms372777_capacity__", interface, model);

EXPECT_TRUE(interface.isEmpty());
}
Loading