登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
轻量养虾,开箱即用!低 Token + 稳定算力,Gitee & 模力方舟联合出品的 PocketClaw 正式开售!点击了解详情
代码拉取完成,页面将自动刷新
仓库状态说明
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
15
Star
11
Fork
109
src-openEuler
/
systemd
关闭
代码
Issues
9
Pull Requests
2
Wiki
统计
流水线
服务
JavaDoc
PHPDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
开发画像分析
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
【systemd】【systemd-logind】执行systemctl poweroff/systemctl halt/systemctl reboot命令,当前所有登录用户未收到提示消息
已完成
#I92W27
缺陷
吴宇
创建于
2024-02-22 14:32
**【标题描述】** 在多个用户在线登录场景下,某一个用户执行systemctl reboot或systemctl halt或systemctl poweroff,其余用户未能收到_**The system is going down for xxxx NOW**_ 的提示信息。 **一、缺陷信息** **内核信息:** 5.10.0-136.12.0.86.4.aarch64 **缺陷归属组件:** systemd **缺陷归属的版本:** version:249 **缺陷简述:** 【现象】: systemd当前版本缺少多用户在线场景下,某个用户systemctl reboot/halt/poweroff后对其他用户广播提示消息的功能。 【代码分析】 :logind-dbus.c源码中,method_do_shutdown_or_sleep函数,缺少消息提示的逻辑功能实现。 **【环境信息】** 硬件信息 - 无特殊要求 软件信息 - OS版本:22.03-LTS - 内核信息 - 发现问题的组件版本信息: - Name: systemd - version: 249 - release: 66 网络信息 - 无特殊要求 **【问题复现步骤】** 1)步骤1:用户A ssh远程登录; 2)步骤2:用户B ssh远程登录并保持会话; 3)步骤3:用户A执行systemctl reboot命令; 4)步骤4:用户B查看终端上是否显示reboot重启的提示信息; **【预期结果】** 多用户同时现在场景下,单个用户执行systemctl `<action>`命令,其中`<action>`为reboot、poweroff或halt,其余用户收到广播的提示消息: ```shell The system is going down for <action> NOW ``` 举例如下:  **【实际结果】** 没有收到reboot/halt/poweroff等相关的提示消息。 **【问题出现概率】** 必现 **【其他相关附件信息】** **缺陷详情参考链接:** **缺陷分析指导链接:** 经个人分析,systemd version < 251的版本均会出现该问题,高版本社区解决问题可能涉及到至少以下两个commit: fix-wall-message: https://github.com/systemd/systemd/commit/90b1ec03b2ce939f589239133a32f4429f2ad6a6 logind-refactor: https://github.com/systemd/systemd/commit/5ed73478e1b1560274038ef30ec6f89022b4d8f6 其中后者主要是对涉及hardcoded字符串代码的重构,问题解决的关键在于第一个commit。 考虑到重构代码部分较多,目前仅对核心消息提示部分做了测试,测试用补丁如下: ```patch src/login/logind-dbus.c | 64 ++++++++++++++++++++++++++++++----------- src/login/logind-utmp.c | 4 +-- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 1d0cf90..cf2a724 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -29,6 +29,7 @@ #include "fileio.h" #include "format-util.h" #include "fs-util.h" +#include "logind-action.h" #include "logind-dbus.h" #include "logind-polkit.h" #include "logind-seat-dbus.h" @@ -53,6 +54,8 @@ #include "utmp-wtmp.h" #include "virt.h" +static void reset_scheduled_shutdown(Manager *m); + static int get_sender_session( Manager *m, sd_bus_message *message, @@ -1838,6 +1841,29 @@ static int verify_shutdown_creds( return 0; } +static int setup_wall_message_timer(Manager *m, sd_bus_message* message) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + int r; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds); + if (r >= 0) { + const char *tty = NULL; + + (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid); + (void) sd_bus_creds_get_tty(creds, &tty); + + r = free_and_strdup(&m->scheduled_shutdown_tty, tty); + if (r < 0) + return log_oom(); + } + + r = manager_setup_wall_message_timer(m); + if (r < 0) + return r; + + return 0; +} + static int method_do_shutdown_or_sleep( Manager *m, sd_bus_message *message, @@ -1848,6 +1874,7 @@ static int method_do_shutdown_or_sleep( const char *action_ignore_inhibit, SleepOperation sleep_operation, bool with_flags, + HandleAction handle_action, sd_bus_error *error) { uint64_t flags; @@ -1906,6 +1933,15 @@ static int method_do_shutdown_or_sleep( if (r != 0) return r; + /* reset case we're shorting a scheduled shutdown */ + m->unlink_nologin = false; + reset_scheduled_shutdown(m); + + m->scheduled_shutdown_timeout = 0; + m->scheduled_shutdown_type = handle_action_to_string(handle_action); + + (void) setup_wall_message_timer(m, message); + r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error); if (r < 0) return r; @@ -1925,6 +1961,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error "org.freedesktop.login1.power-off-ignore-inhibit", _SLEEP_OPERATION_INVALID, sd_bus_message_is_method_call(message, NULL, "PowerOffWithFlags"), + HANDLE_POWEROFF, error); } @@ -1940,6 +1977,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error * "org.freedesktop.login1.reboot-ignore-inhibit", _SLEEP_OPERATION_INVALID, sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"), + HANDLE_REBOOT, error); } @@ -1955,6 +1993,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er "org.freedesktop.login1.halt-ignore-inhibit", _SLEEP_OPERATION_INVALID, sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"), + HANDLE_HALT, error); } @@ -1970,6 +2009,7 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error "org.freedesktop.login1.suspend-ignore-inhibit", SLEEP_SUSPEND, sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"), + HANDLE_SUSPEND, error); } @@ -1985,6 +2025,7 @@ static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_erro "org.freedesktop.login1.hibernate-ignore-inhibit", SLEEP_HIBERNATE, sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"), + HANDLE_HIBERNATE, error); } @@ -2000,6 +2041,7 @@ static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_e "org.freedesktop.login1.hibernate-ignore-inhibit", SLEEP_HYBRID_SLEEP, sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"), + HANDLE_HYBRID_SLEEP, error); } @@ -2015,6 +2057,7 @@ static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata "org.freedesktop.login1.hibernate-ignore-inhibit", SLEEP_SUSPEND_THEN_HIBERNATE, sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"), + HANDLE_SUSPEND_THEN_HIBERNATE, error); } @@ -2173,7 +2216,6 @@ error: static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) { Manager *m = userdata; - _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; const char *action_multiple_sessions = NULL; const char *action_ignore_inhibit = NULL; const char *action = NULL; @@ -2254,23 +2296,11 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_ m->scheduled_shutdown_timeout = elapse; - r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds); - if (r >= 0) { - const char *tty = NULL; - - (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid); - (void) sd_bus_creds_get_tty(creds, &tty); - - r = free_and_strdup(&m->scheduled_shutdown_tty, tty); - if (r < 0) { - m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source); - return log_oom(); - } - } - - r = manager_setup_wall_message_timer(m); - if (r < 0) + r = setup_wall_message_timer(m, message); + if (r < 0) { + m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source); return r; + } r = update_schedule_file(m); if (r < 0) diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c index dfbbb64..afdec1a 100644 --- a/src/login/logind-utmp.c +++ b/src/login/logind-utmp.c @@ -136,11 +136,11 @@ int manager_setup_wall_message_timer(Manager *m) { return 0; } - if (elapse < n) + if (elapse > 0 && elapse < n) return 0; /* Warn immediately if less than 15 minutes are left */ - if (elapse - n < 15 * USEC_PER_MINUTE) { + if (elapse == 0 || elapse - n < 15 * USEC_PER_MINUTE) { r = warn_wall(m, n); if (r == 0) return 0; -- 2.33.0 ``` 合入后可以解决reboot/halt/poweroff的消息提示问题。
**【标题描述】** 在多个用户在线登录场景下,某一个用户执行systemctl reboot或systemctl halt或systemctl poweroff,其余用户未能收到_**The system is going down for xxxx NOW**_ 的提示信息。 **一、缺陷信息** **内核信息:** 5.10.0-136.12.0.86.4.aarch64 **缺陷归属组件:** systemd **缺陷归属的版本:** version:249 **缺陷简述:** 【现象】: systemd当前版本缺少多用户在线场景下,某个用户systemctl reboot/halt/poweroff后对其他用户广播提示消息的功能。 【代码分析】 :logind-dbus.c源码中,method_do_shutdown_or_sleep函数,缺少消息提示的逻辑功能实现。 **【环境信息】** 硬件信息 - 无特殊要求 软件信息 - OS版本:22.03-LTS - 内核信息 - 发现问题的组件版本信息: - Name: systemd - version: 249 - release: 66 网络信息 - 无特殊要求 **【问题复现步骤】** 1)步骤1:用户A ssh远程登录; 2)步骤2:用户B ssh远程登录并保持会话; 3)步骤3:用户A执行systemctl reboot命令; 4)步骤4:用户B查看终端上是否显示reboot重启的提示信息; **【预期结果】** 多用户同时现在场景下,单个用户执行systemctl `<action>`命令,其中`<action>`为reboot、poweroff或halt,其余用户收到广播的提示消息: ```shell The system is going down for <action> NOW ``` 举例如下:  **【实际结果】** 没有收到reboot/halt/poweroff等相关的提示消息。 **【问题出现概率】** 必现 **【其他相关附件信息】** **缺陷详情参考链接:** **缺陷分析指导链接:** 经个人分析,systemd version < 251的版本均会出现该问题,高版本社区解决问题可能涉及到至少以下两个commit: fix-wall-message: https://github.com/systemd/systemd/commit/90b1ec03b2ce939f589239133a32f4429f2ad6a6 logind-refactor: https://github.com/systemd/systemd/commit/5ed73478e1b1560274038ef30ec6f89022b4d8f6 其中后者主要是对涉及hardcoded字符串代码的重构,问题解决的关键在于第一个commit。 考虑到重构代码部分较多,目前仅对核心消息提示部分做了测试,测试用补丁如下: ```patch src/login/logind-dbus.c | 64 ++++++++++++++++++++++++++++++----------- src/login/logind-utmp.c | 4 +-- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 1d0cf90..cf2a724 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -29,6 +29,7 @@ #include "fileio.h" #include "format-util.h" #include "fs-util.h" +#include "logind-action.h" #include "logind-dbus.h" #include "logind-polkit.h" #include "logind-seat-dbus.h" @@ -53,6 +54,8 @@ #include "utmp-wtmp.h" #include "virt.h" +static void reset_scheduled_shutdown(Manager *m); + static int get_sender_session( Manager *m, sd_bus_message *message, @@ -1838,6 +1841,29 @@ static int verify_shutdown_creds( return 0; } +static int setup_wall_message_timer(Manager *m, sd_bus_message* message) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + int r; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds); + if (r >= 0) { + const char *tty = NULL; + + (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid); + (void) sd_bus_creds_get_tty(creds, &tty); + + r = free_and_strdup(&m->scheduled_shutdown_tty, tty); + if (r < 0) + return log_oom(); + } + + r = manager_setup_wall_message_timer(m); + if (r < 0) + return r; + + return 0; +} + static int method_do_shutdown_or_sleep( Manager *m, sd_bus_message *message, @@ -1848,6 +1874,7 @@ static int method_do_shutdown_or_sleep( const char *action_ignore_inhibit, SleepOperation sleep_operation, bool with_flags, + HandleAction handle_action, sd_bus_error *error) { uint64_t flags; @@ -1906,6 +1933,15 @@ static int method_do_shutdown_or_sleep( if (r != 0) return r; + /* reset case we're shorting a scheduled shutdown */ + m->unlink_nologin = false; + reset_scheduled_shutdown(m); + + m->scheduled_shutdown_timeout = 0; + m->scheduled_shutdown_type = handle_action_to_string(handle_action); + + (void) setup_wall_message_timer(m, message); + r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error); if (r < 0) return r; @@ -1925,6 +1961,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error "org.freedesktop.login1.power-off-ignore-inhibit", _SLEEP_OPERATION_INVALID, sd_bus_message_is_method_call(message, NULL, "PowerOffWithFlags"), + HANDLE_POWEROFF, error); } @@ -1940,6 +1977,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error * "org.freedesktop.login1.reboot-ignore-inhibit", _SLEEP_OPERATION_INVALID, sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"), + HANDLE_REBOOT, error); } @@ -1955,6 +1993,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er "org.freedesktop.login1.halt-ignore-inhibit", _SLEEP_OPERATION_INVALID, sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"), + HANDLE_HALT, error); } @@ -1970,6 +2009,7 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error "org.freedesktop.login1.suspend-ignore-inhibit", SLEEP_SUSPEND, sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"), + HANDLE_SUSPEND, error); } @@ -1985,6 +2025,7 @@ static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_erro "org.freedesktop.login1.hibernate-ignore-inhibit", SLEEP_HIBERNATE, sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"), + HANDLE_HIBERNATE, error); } @@ -2000,6 +2041,7 @@ static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_e "org.freedesktop.login1.hibernate-ignore-inhibit", SLEEP_HYBRID_SLEEP, sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"), + HANDLE_HYBRID_SLEEP, error); } @@ -2015,6 +2057,7 @@ static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata "org.freedesktop.login1.hibernate-ignore-inhibit", SLEEP_SUSPEND_THEN_HIBERNATE, sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"), + HANDLE_SUSPEND_THEN_HIBERNATE, error); } @@ -2173,7 +2216,6 @@ error: static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) { Manager *m = userdata; - _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; const char *action_multiple_sessions = NULL; const char *action_ignore_inhibit = NULL; const char *action = NULL; @@ -2254,23 +2296,11 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_ m->scheduled_shutdown_timeout = elapse; - r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds); - if (r >= 0) { - const char *tty = NULL; - - (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid); - (void) sd_bus_creds_get_tty(creds, &tty); - - r = free_and_strdup(&m->scheduled_shutdown_tty, tty); - if (r < 0) { - m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source); - return log_oom(); - } - } - - r = manager_setup_wall_message_timer(m); - if (r < 0) + r = setup_wall_message_timer(m, message); + if (r < 0) { + m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source); return r; + } r = update_schedule_file(m); if (r < 0) diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c index dfbbb64..afdec1a 100644 --- a/src/login/logind-utmp.c +++ b/src/login/logind-utmp.c @@ -136,11 +136,11 @@ int manager_setup_wall_message_timer(Manager *m) { return 0; } - if (elapse < n) + if (elapse > 0 && elapse < n) return 0; /* Warn immediately if less than 15 minutes are left */ - if (elapse - n < 15 * USEC_PER_MINUTE) { + if (elapse == 0 || elapse - n < 15 * USEC_PER_MINUTE) { r = warn_wall(m, n); if (r == 0) return 0; -- 2.33.0 ``` 合入后可以解决reboot/halt/poweroff的消息提示问题。
评论 (
3
)
登录
后才可以发表评论
状态
已完成
待办的
已挂起
修复中
已确认
已完成
已验收
已取消
负责人
未设置
wangyuhang
wangyuhang27
负责人
协作者
+负责人
+协作者
胡宇彪
huyubiao
负责人
协作者
+负责人
+协作者
标签
sig/Base-service
未设置
项目
未立项任务
未立项任务
里程碑
openEuler-22.03-LTS-Dailybuild
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
分支 (
-
)
标签 (
-
)
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
预计工期
(小时)
参与者(3)
1
https://gitee.com/src-openeuler/systemd.git
git@gitee.com:src-openeuler/systemd.git
src-openeuler
systemd
systemd
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册