Skip to content

Release/2500 - #1222

Closed
fly602 wants to merge 1 commit into
linuxdeepin:release/2500from
fly602:release/2500
Closed

Release/2500#1222
fly602 wants to merge 1 commit into
linuxdeepin:release/2500from
fly602:release/2500

Conversation

@fly602

@fly602 fly602 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Make touchpad udev rule restoration reliable across restarts and unexpected shutdowns.

Bug Fixes:

  • Restore touchpad udev rules during startup so they are recreated after forced shutdowns or power loss.
  • Ensure udev rule file updates are durably persisted, including file data and newly created directory entries.

Enhancements:

  • Make udev rule management atomic, permission-safe, and efficient by skipping unchanged content and refreshing devices only when rules change.

Build:

  • Update the go-dbus-factory dependency.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: fly602

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions

Copy link
Copy Markdown

TAG Bot

TAG: 6.1.99.1
EXISTED: no
DISTRIBUTION: unstable

@sourcery-ai

sourcery-ai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Reviewer's Guide

This release fixes touchpad udev-rule recovery and durability: startup now explicitly rebuilds the rule from dconfig even when no logical state change is detected, while rule writes are synced to storage and errors are propagated before completion.

Sequence diagram for durable touchpad udev-rule recovery

sequenceDiagram
    participant InputDevices
    participant Touchpad
    participant DConfig
    participant UdevRuleFile
    participant Storage

    InputDevices->>DConfig: Value()
    DConfig-->>InputDevices: enabled
    InputDevices->>Touchpad: setTouchpadEnableViaUdev(enabled)
    Touchpad->>UdevRuleFile: os.Create()
    Touchpad->>UdevRuleFile: Write()
    Touchpad->>UdevRuleFile: Sync()
    UdevRuleFile->>Storage: persist rule data
    Storage-->>UdevRuleFile: synced
    Touchpad->>UdevRuleFile: Close()
    UdevRuleFile-->>Touchpad: error or success
    Touchpad-->>InputDevices: error or success
Loading

File-Level Changes

Change Details Files
Rebuild the touchpad udev rule during initialization directly from the persisted configuration.
  • Read the configured enabled state and invoke the udev-specific update path during startup.
  • Avoid the state-change guard in the regular setter so rules are recreated even when the in-memory state already matches configuration.
system/inputdevices1/inputdevices.go
Make udev rule creation durable across abrupt shutdowns.
  • Write the rule through an open file, call fsync before closing, and propagate write, sync, and close errors.
system/inputdevices1/touchpad.go
Record the release changes in Debian packaging metadata.
  • Add the Release/2500 entry to the Debian changelog.
debian/changelog

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="system/inputdevices1/touchpad.go" line_range="154" />
<code_context>
+			f.Close()
+			return err
+		}
+		err = f.Sync()
+		if err != nil {
+			f.Close()
</code_context>
<issue_to_address>
**issue (broader_impact):** `f.Sync()` flushes the file contents but does not flush the parent directory metadata, so after creating a previously missing rule file, a forced power loss can still lose the directory entry and leave the touchpad enabled after reboot.

**Triggers:** When `udevRuleFile` does not exist and power is lost before the parent directory is synchronized.

**Suggested fix:** Open and sync the parent directory after creating the rule file, or use an atomic replacement followed by a directory `fsync`.
</issue_to_address>

### Comment 2
<location path="system/inputdevices1/touchpad.go" line_range="145" />
<code_context>
-		if err := os.WriteFile(udevRuleFile, []byte(udevRuleContent), 0644); err != nil {
+		// 创建或覆盖 udev 规则文件,使用 fsync 确保落盘,
+		// 防止强制关机(断电)时 page cache 丢失导致规则文件丢失
+		f, err := os.Create(udevRuleFile)
+		if err != nil {
+			return err
</code_context>
<issue_to_address>
**🚨 issue (security):** `os.Create` creates a new rule file with mode `0666` subject to the process umask, whereas the previous `os.WriteFile` explicitly requested `0644`; with a permissive umask, the udev rule becomes group- or world-writable.

**Triggers:** When the rule file is newly created on a system whose service umask does not remove group/world write permissions.

**Suggested fix:** Use `os.OpenFile(udevRuleFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)` and explicitly enforce the mode for existing files if needed.

```suggestion
		f, err := os.OpenFile(udevRuleFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
		if err != nil {
			return err
		}
		if err := f.Chmod(0644); err != nil {
			f.Close()
			return err
		}
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread system/inputdevices1/touchpad.go Outdated
Comment thread system/inputdevices1/touchpad.go Outdated
@fly602
fly602 force-pushed the release/2500 branch 2 times, most recently from b96960c to 92117d2 Compare August 26, 2026 06:43
1. Replace os.WriteFile with os.Create + f.Sync() to ensure
   the udev rule file is flushed to disk before close
2. On startup, call setTouchpadEnableViaUdev directly instead
   of setTouchpadEnable to avoid skipped udev rebuild when
   changed=false due to pre-initialized Enable field
3. Prevents touchpad disable state loss after forced power-off

Log: fix touchpad disabled state lost after forced power-off
because udev rule file write was not fsynced and startup rebuild
was skipped by changed=false check

Influence:
1. Disable touchpad, force power off, reboot and verify it
   stays disabled
2. Disable touchpad, normal reboot and verify it stays disabled
3. Enable touchpad, force power off, reboot and verify it stays
   enabled

fix(inputdevices): 修复强制关机后触控板禁用状态丢失

1. 将 os.WriteFile 改为 os.Create + f.Sync() 确保写入 udev
   规则文件时强制刷盘,防止断电丢失
2. 启动恢复时直接调用 setTouchpadEnableViaUdev 重建 udev 规
   则,避免 changed=false 导致跳过写入
3. 修复强制关机后触控板禁用失效的问题

Log: 修复强制关机后触控板禁用状态丢失,原因是 udev 规则文件
写入未调用 fsync 导致断电丢失,且启动恢复逻辑因 changed=false
跳过了 udev 规则重建

Influence:
1. 禁用触控板后强制关机,重启后确认触控板仍为禁用状态
2. 禁用触控板后正常重启,确认触控板仍为禁用状态
3. 启用触控板后强制关机,重启后确认触控板仍为启用状态

PMS: BUG-374789
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 95 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 代码质量优秀,修复逻辑清晰,安全无漏洞。fsync和原子写入的实现规范,注释详尽。仅存少量轻微代码质量改进建议。
Commit 目的 修复强制关机后触控板禁用状态丢失问题(PMS: BUG-374789)

📋 变更概览

文件 类型 说明
go.mod / go.sum 依赖更新 更新 go-dbus-factory 依赖版本(2026-06-04 → 2026-08-04),常规升级
system/inputdevices1/inputdevices.go Bug修复 启动恢复时直接调用 setTouchpadEnableViaUdev 重建 udev 规则,绕过 changed=false 优化
system/inputdevices1/touchpad.go 重构+Bug修复 提取 writeUdevRuleFile 函数,使用原子写入+fsync 确保数据持久性

🔍 详细分析

1. 语法逻辑 ✅

评分: 23/25 ✓

评价: 语法正确,逻辑清晰

潜在问题:

  1. system/inputdevices1/inputdevices.go,第96行,init 函数:v.Value().(bool) 使用了未检查的类型断言,若 dconfig 返回非 bool 类型将导致 panic。此问题在原始代码中已存在,本次 PR 未引入新风险,但建议使用 comma-ok 模式增强健壮性。

建议: 建议对 dconfig 返回值使用 comma-ok 类型断言,防止异常类型导致 panic


2. 代码质量 ✅

评分: 24/25 ✓

评价: 代码结构清晰,注释完整

潜在问题:

  1. system/inputdevices1/touchpad.go,第214行,writeUdevRuleFile 函数:logger.Info("created udev rule file:", udevRuleFile) 日志消息在文件内容更新(非首次创建)时也会输出 "created",略有不准确。当文件已存在但内容被更新时,"created" 消息可能误导排查。

建议: 建议根据 isNew 标志输出不同日志:if isNew { logger.Info("created udev rule file:", udevRuleFile) } else { logger.Info("updated udev rule file:", udevRuleFile) },提高日志准确性


3. 代码性能 ✅

评分: 20/20 ✓

评价: 性能良好,资源使用合理

潜在问题:

建议: fsync 调用带来的 I/O 延迟是修复断电数据丢失的必要代价,设计合理。fast path 在内容未变时跳过写入和 fsync,性能表现良好。O_EXCL 方式避免了额外的 Stat 调用,syncDirBestEffort 仅在需要时调用。


4. 代码安全 🔒

评分: 30/30 ✓

评价: 存在0个安全漏洞

🔐 发现 0 个安全漏洞

安全漏洞详情:
无安全漏洞

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个

安全分析:
代码在安全性方面表现优秀,具体体现在以下方面:

  1. 使用 O_EXCL 原子创建文件,避免 Stat/OpenFile 之间的 TOCTOU 竞态条件
  2. ChmodTruncate 的操作顺序,避免权限修改失败时 O_TRUNC 已清空原内容导致规则丢失
  3. f.Sync() 确保文件数据落盘,防止强制关机时 page cache 丢失
  4. 首次创建文件时 fsync 父目录,保证目录项断电不丢
  5. fast path 仍执行 Chmod(0644) 收窄权限,防止外部改宽的 0666 等遗留
  6. udevRuleFile 为常量路径 /etc/udev/rules.d/90-dde-touchpad.rules,无路径遍历风险
  7. 无硬编码密钥、无命令注入、无敏感信息泄露

💡 改进建议代码示例

// inputdevices.go - 建议使用 comma-ok 类型断言
enabled, ok := v.Value().(bool)
if !ok {
    logger.Warning("invalid type for touchpadEnabled config")
    return
}
err = m.touchpad.setTouchpadEnableViaUdev(enabled)

// touchpad.go - 建议区分日志消息
if isNew {
    logger.Info("created udev rule file:", udevRuleFile)
} else {
    logger.Info("updated udev rule file:", udevRuleFile)
}

📝 审查结论

本次 PR 旨在修复强制关机后触控板禁用状态丢失问题(PMS: BUG-374789),代码实现与 commit 目的完全一致:

  1. fsync 修复:将 os.WriteFile 替换为原子文件写入 + f.Sync(),确保 udev 规则文件数据落盘,防止断电丢失 —— 符合修复目的
  2. 启动恢复修复:启动时直接调用 setTouchpadEnableViaUdev 重建 udev 规则,绕过 changed=false 优化 —— 符合修复目的
  3. 目录项持久化:首次创建文件时 fsync 父目录,确保目录项落盘 —— 增强修复完整性

代码质量优秀,注释详尽,安全无漏洞,建议合并。


本报告由 AI 代码审查工具自动生成

@fly602 fly602 closed this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants