mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
udevadm-wait: add --notify option to send notifications
With this, 'udevadm wait' can be used in a Type=notify service, and the caller can know when it has started watching the devices.
This commit is contained in:
1 parent
5f53c52fa2
commit
07111a11ed
4 files changed
+52
-3
No files matched your search
@@ -1178,6 +1178,19 @@
|
||||
<xi:include href="version-info.xml" xpointer="v251"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--notify</option></term>
|
||||
<listitem>
|
||||
<para>When specified, udevadm notifies the calling service manager with a
|
||||
<literal>READY=1</literal> message when it is ready to wait for devices to be initialized (or
|
||||
added when <option>--initialized=no</option>, or removed when <option>--removed</option>), and
|
||||
notifies with a <literal>STOPPING=1</literal> message when all devices are initialized. This may
|
||||
be useful when the command is called in a service with <varname>Type=notify</varname>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v263"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ _udevadm() {
|
||||
[VERIFY_ARG]='-N --resolve-names --root'
|
||||
[CAT_STANDALONE]='--tldr --config'
|
||||
[CAT_ARG]='--root'
|
||||
[WAIT]='-t --timeout --initialized=no --removed --settle'
|
||||
[WAIT]='-t --timeout --initialized=no --removed --settle --notify'
|
||||
[LOCK]='-t --timeout -d --device -b --backing -p --print'
|
||||
)
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ _udevadm_wait(){
|
||||
'--initialized=[Wait for devices being initialized by systemd-udevd.]:boolean:(yes no)' \
|
||||
'--removed[Wait for devices being removed.]' \
|
||||
'--settle[Also wait for udev queue being empty.]' \
|
||||
'--notify[Send notifications to service manager.]' \
|
||||
'*::devpath:_files -W /dev'
|
||||
}
|
||||
|
||||
|
||||
+37
-2
@@ -7,6 +7,7 @@
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "build.h"
|
||||
#include "daemon-util.h"
|
||||
#include "device-monitor-private.h"
|
||||
#include "device-util.h"
|
||||
#include "event-util.h"
|
||||
@@ -15,6 +16,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "static-destruct.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -35,6 +37,7 @@ static WaitUntil arg_wait_until = WAIT_UNTIL_INITIALIZED;
|
||||
static usec_t arg_timeout_usec = USEC_INFINITY;
|
||||
static bool arg_removed = false;
|
||||
static bool arg_settle = false;
|
||||
static bool arg_notify = false;
|
||||
static char **arg_devices = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_devices, strv_freep);
|
||||
@@ -340,6 +343,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_settle = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("notify", NULL, "Send notifications to service manager"):
|
||||
arg_notify = true;
|
||||
break;
|
||||
|
||||
OPTION_COMMON_INTROSPECT_CLI:
|
||||
return introspect_cli(SD_JSON_FORMAT_OFF);
|
||||
}
|
||||
@@ -380,9 +387,31 @@ int verb_wait_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
"Specified path \"%s\" does not start with \"/dev/\" or \"/sys/\".", *p);
|
||||
}
|
||||
|
||||
_cleanup_free_ char *notify_message_start = NULL, *notify_message_stop = NULL, *notify_message_fail = NULL;
|
||||
if (arg_notify) {
|
||||
notify_message_start = asprintf_safe(
|
||||
"READY=1\n"
|
||||
"STATUS=Waiting for devices to be %s...",
|
||||
wait_until_to_string(arg_wait_until));
|
||||
notify_message_stop = asprintf_safe(
|
||||
"STOPPING=1\n"
|
||||
"STATUS=All devices are %s.",
|
||||
wait_until_to_string(arg_wait_until));
|
||||
notify_message_fail = asprintf_safe(
|
||||
"STATUS=Failed to wait for devices to be %s.",
|
||||
wait_until_to_string(arg_wait_until));
|
||||
if (!notify_message_start || !notify_message_stop || !notify_message_fail)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
/* Check before configuring event sources, as devices may be already initialized. */
|
||||
if (check())
|
||||
if (check()) {
|
||||
if (arg_notify) {
|
||||
(void) sd_notify(/* unset_environment= */ false, notify_message_start);
|
||||
(void) sd_notify(/* unset_environment= */ false, notify_message_stop);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_event_default(&event);
|
||||
if (r < 0)
|
||||
@@ -423,9 +452,13 @@ int verb_wait_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return log_error_errno(r, "Failed to set up periodic timer: %m");
|
||||
}
|
||||
|
||||
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
|
||||
if (arg_notify)
|
||||
notify_message = notify_start(notify_message_start, notify_message_fail);
|
||||
|
||||
/* Check before entering the event loop, as devices may be initialized during setting up event sources. */
|
||||
if (check())
|
||||
return 0;
|
||||
goto success;
|
||||
|
||||
r = sd_event_loop(event);
|
||||
if (r == -ETIMEDOUT)
|
||||
@@ -434,5 +467,7 @@ int verb_wait_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Event loop failed: %m");
|
||||
|
||||
success:
|
||||
notify_message = notify_message_stop;
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user