From 8eef68661ac05d566d6ea35184e23d45afb561b3 Mon Sep 17 00:00:00 2001 From: xujin Date: Thu, 25 Jun 2026 16:45:53 +0800 Subject: [PATCH] fix: detect scripts and set Type=forking for systemd services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a program is a script that forks child processes (e.g., deepin- security-loader-exec), systemd under Type=simple may incorrectly terminate the service and kill child processes. By detecting script files and setting Type=forking, we ensure the service manager waits for the forking process to complete properly. Log: Fixed script execution handling with proper systemd service type Influence: 1. Test executing script files that fork child processes 2. Verify that scripts with shebang (#!) are correctly identified 3. Ensure non-script executables still use default Type=simple 4. Check that child processes survive parent script exit 5. Validate systemd service lifecycle with forking scripts 6. Test backward compatibility for existing binary executables fix: 检测脚本并为 systemd 服务设置 Type=forking 当程序是一个会 fork 子进程的脚本(如 deepin-security-loader-exec)时,使用 Type=simple 的 systemd 可能错误地终止服务并杀掉子进程。通过检测脚本文件并设置 Type=forking,确保服务管理器正确等待 fork 进程完成。 Log: 修复了脚本执行时 systemd 服务类型的处理 Influence: 1. 测试执行会 fork 子进程的脚本文件 2. 验证带 shebang (#!) 的脚本能被正确识别 3. 确保非脚本可执行文件仍使用默认的 Type=simple 4. 检查子进程在父脚本退出后是否正常存活 5. 验证 systemd 服务生命周期对 fork 脚本的处理 6. 测试对现有二进制可执行文件的向后兼容性 PMS: BUG-366983 --- src/dbus/applicationmanager1service.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/dbus/applicationmanager1service.cpp b/src/dbus/applicationmanager1service.cpp index b3978c77..e3f45735 100644 --- a/src/dbus/applicationmanager1service.cpp +++ b/src/dbus/applicationmanager1service.cpp @@ -996,7 +996,19 @@ QDBusObjectPath ApplicationManager1Service::executeCommand(const QString &progra // 1. Property: Description properties.append({"Description", QDBusVariant(QString("Run: %1").arg(program))}); - // 2. Property: ExecStart (Type: a(sasb)) + // 2. Property: Type (Type: s) + // 脚本中可能调用会 fork 的子进程(如 deepin-security-loader-exec),导致主进程提前退出, + // systemd 在 Type=simple 下会误判服务结束并杀掉子进程,因此脚本使用 Type=forking + QFile programFile(program); + if (programFile.open(QIODevice::ReadOnly)) { + if (programFile.readLine().startsWith("#!")) { + properties.append({"Type", QDBusVariant(QStringLiteral("forking"))}); + qInfo() << "Detected script, using Type=forking for systemd service"; + } + programFile.close(); + } + + // 3. Property: ExecStart (Type: a(sasb)) // Systemd 要求 ExecStart 是一个结构体数组,因为一个服务可以有多个 ExecStart 命令 SystemdExecCommand execCmd; execCmd.path = program; // 二进制路径 @@ -1007,10 +1019,10 @@ QDBusObjectPath ApplicationManager1Service::executeCommand(const QString &progra execStartList << execCmd; properties.append({"ExecStart", QDBusVariant(QVariant::fromValue(execStartList))}); - // 3. Property: Environment (Type: as) + // 4. Property: Environment (Type: as) properties.append({"Environment", QDBusVariant(environment)}); - // 4. Property: WorkingDirectory (Type: s) + // 5. Property: WorkingDirectory (Type: s) if (!workdir.isEmpty()) { properties.append({"WorkingDirectory", QDBusVariant(workdir)}); }