From 49c13f943e077fa5e8741b433e90758bc843a534 Mon Sep 17 00:00:00 2001 From: ComixHe Date: Mon, 11 Sep 2023 14:56:28 +0800 Subject: [PATCH] feat: support cgroup v1 and v2 Signed-off-by: ComixHe --- src/cgroupsidentifier.cpp | 36 +++++++++++++++++++++++++++++------- src/cgroupsidentifier.h | 3 ++- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/cgroupsidentifier.cpp b/src/cgroupsidentifier.cpp index dfb3d4f..ab434ff 100644 --- a/src/cgroupsidentifier.cpp +++ b/src/cgroupsidentifier.cpp @@ -16,21 +16,43 @@ IdentifyRet CGroupsIdentifier::Identify(pid_t pid) qWarning() << "open " << AppCgroupPath << "failed: " << AppCgroupFile.errorString(); return {}; } - auto UnitStr = parseCGroupsPath(QString::fromLocal8Bit(AppCgroupFile.readAll()) - .split(':', Qt::SkipEmptyParts) - .last() - .trimmed()); // FIXME: support CGroup version detection and multi-line parsing + + auto UnitStr = parseCGroupsPath(AppCgroupFile); auto [appId, InstanceId] = processUnitName(UnitStr); return {std::move(appId), std::move(InstanceId)}; } -QString CGroupsIdentifier::parseCGroupsPath(const QString &CGP) noexcept +QString CGroupsIdentifier::parseCGroupsPath(QFile &cgroupFile) noexcept { - if (CGP.isEmpty()) { - qWarning() << "CGroupPath is empty."; + QTextStream stream{&cgroupFile}; + + if (stream.atEnd()) { + qWarning() << "read from cgroup file failed:" << stream.status(); return {}; } + stream.setEncoding(QStringConverter::Utf8); + QString CGP; + while (!stream.atEnd()) { + auto line = stream.readLine(); + auto firstColon = line.indexOf(':'); + auto secondColon = line.indexOf(':', firstColon + 1); + auto subSystemd = QStringView(line.constBegin() + firstColon + 1, secondColon - firstColon - 1); + if (subSystemd.isEmpty()) { // cgroup v2 + CGP = line.last(line.size() - secondColon - 1); + break; + } + + if (subSystemd == QString{"name=systemd"}) { // cgroup v1 + CGP = line.last(line.size() - secondColon - 1); // shouldn't break, maybe v1 and v2 exists at the same time. + } + } + + if (CGP.isEmpty()) { + qWarning() << "no systemd informations found."; + return {}; + } + auto CGPSlices = CGP.split('/', Qt::SkipEmptyParts); if (CGPSlices.first() != "user.slice") { diff --git a/src/cgroupsidentifier.h b/src/cgroupsidentifier.h index 6db7ecf..6f091aa 100644 --- a/src/cgroupsidentifier.h +++ b/src/cgroupsidentifier.h @@ -6,6 +6,7 @@ #define CGROUPSIDENTIFIER_H #include "identifier.h" +#include class CGroupsIdentifier : public Identifier { @@ -13,7 +14,7 @@ public: IdentifyRet Identify(pid_t pid) override; private: - [[nodiscard]] static QString parseCGroupsPath(const QString &CGP) noexcept; + [[nodiscard]] static QString parseCGroupsPath(QFile &file) noexcept; }; #endif