返回资讯中心
外部精选
软件工程
#开发者实时流

Systemd Inhibitor Locks

systemd 183 and newer include a logic to inhibit system shutdowns and sleep states. This is implemented as part of systemd-logind.daemon(8) There are a couple of different use cases for this:

Hacker News 最新ankitg122026/10/29 · 2 天前12 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

systemd 183 and newer include a logic to inhibit system shutdowns and sleep states. This is implemented as part of systemd-logind.daemon(8) There are a couple of different use cases for this:

A CD burning application wants to ensure that the system is not turned off or suspended while the burn process is in progress.

A package manager wants to ensure that the system is not turned off while a package upgrade is in progress.

An office suite wants to be notified before system suspend in order to save all data to disk, and delay the suspend logic until all data is written.

A web browser wants to be notified before system hibernation in order to free its cache to minimize the amount of memory that needs to be virtualized.

A screen lock tool wants to bring up the screen lock right before suspend, and delay the suspend until that’s complete.

Applications which want to make use of the inhibition logic shall take an inhibitor lock via the logind D-Bus API.

Seven distinct inhibitor lock types may be taken, or a combination of them:

Three different modes of locks are supported:

block inhibits operations entirely until the lock is released. If such a lock is taken the operation will fail (but still may be overridden if the user possesses the necessary privileges).

delay inhibits operations only temporarily, either until the lock is released or up to a certain amount of time. The InhibitDelayMaxSec= setting in logind.conf(5) controls the timeout for this. This is intended to be used by applications which need a synchronous way to execute actions before system suspend but shall not be allowed to block suspend indefinitely. This mode is only available for sleep and shutdown locks.

block-weak is identical to block, but has no effect on operations requested by root or by the user owning the inhibitor lock.

Inhibitor locks are taken via the Inhibit() D-Bus call on the logind Manager object:

$ gdbus introspect --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 node /org/freedesktop/login1 { interface org.freedesktop.login1.Manager { methods: Inhibit(in s what, in s who, in s why, in s mode, out h fd); ListInhibitors(out a(ssssuu) inhibitors); ... signals: PrepareForShutdown(b active); PrepareForSleep(b active); ... properties: readonly s BlockInhibited = ''; readonly s DelayInhibited = ''; readonly t InhibitDelayMaxUSec = 5000000; readonly b PreparingForShutdown = false; readonly b PreparingForSleep = false; ... }; ... };

Inhibit() is the only API necessary to take a lock. It takes four arguments:

Inhibit() returns a single value, a file descriptor that encapsulates the lock. As soon as the file descriptor is closed (and all its duplicates) the lock is automatically released. If the client dies while the lock is taken the kernel automatically closes the file descriptor so that the lock is automatically released.

A delay lock taken this way should be released ASAP on reception of PrepareForShutdown(true) (see below), but of course only after execution of the actions the application wanted to delay the operation for in the first place.

ListInhibitors() lists all currently active inhibitor locks. It returns an array of structs, each consisting of What, Who, Why, Mode as above, plus the PID and UID of the process that requested the lock.

The PrepareForShutdown() and PrepareForSleep() signals are emitted when a system suspend or shutdown has been requested and is about to be executed, as well as after the suspend/shutdown was completed (or failed).

The signals carry a boolean argument. If True the shutdown/sleep has been requested, and the preparation phase for it begins, if False the operation has finished completion (or failed).

If True, this should be used as indication for applications to quickly execute the operations they wanted to execute before suspend/shutdown and then release any delay lock taken. If False the suspend/shutdown operation is over, either successfully or unsuccessfully (of course, this signal will never be sent if a shutdown request was successful).

The signal with False is generally delivered only after the system comes back from suspend, the signal with True possibly as well, for example when no delay lock was taken in the first place, and the system suspend hence executed without any delay.

The signal with False is usually the signal on which applications request a new delay lock in order to be synchronously notified about the next suspend/shutdown cycle.

Note that watching PrepareForShutdown(true)/PrepareForSleep(true) without taking a delay lock is racy and should not be done, as any code that an application might want to execute on this signal might not actually finish before the suspend/shutdown cycle is executed.

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →