core: add a new sd_notify() message for removing fds from the FD store again
Currenly the only way to remove fds from the fdstore is to fully stop the service, or to somehow trigger POLLERR/POLLHUP on the fd, in which case systemd will remove the fd automatically. Let's add another way: a new message that can be sent to remove fds explicitly, given their name.
This commit is contained in:
parent
8d1ab18a46
commit
e78ee06de1
|
@ -234,25 +234,26 @@
|
|||
to send messages with <literal>FDSTORE=1</literal>, see below.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>FDSTOREREMOVE=1</term>
|
||||
|
||||
<listitem><para>Removes file descriptors from the file descriptor store. This field needs to be combined with
|
||||
<varname>FDNAME=</varname> to specify the name of the file descriptors to remove.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>FDNAME=…</term>
|
||||
|
||||
<listitem><para>When used in combination with
|
||||
<varname>FDSTORE=1</varname>, specifies a name for the
|
||||
submitted file descriptors. This name is passed to the service
|
||||
during activation, and may be queried using
|
||||
<listitem><para>When used in combination with <varname>FDSTORE=1</varname>, specifies a name for the submitted
|
||||
file descriptors. When used with <varname>FDSTOREREMOVE=1</varname>, specifies the name for the file
|
||||
descriptors to remove. This name is passed to the service during activation, and may be queried using
|
||||
<citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>. File
|
||||
descriptors submitted without this field set, will implicitly
|
||||
get the name <literal>stored</literal> assigned. Note that, if
|
||||
multiple file descriptors are submitted at once, the specified
|
||||
name will be assigned to all of them. In order to assign
|
||||
different names to submitted file descriptors, submit them in
|
||||
separate invocations of
|
||||
<function>sd_pid_notify_with_fds()</function>. The name may
|
||||
consist of any ASCII character, but must not contain control
|
||||
characters or <literal>:</literal>. It may not be longer than
|
||||
255 characters. If a submitted name does not follow these
|
||||
restrictions, it is ignored.</para></listitem>
|
||||
descriptors submitted without this field set, will implicitly get the name <literal>stored</literal>
|
||||
assigned. Note that, if multiple file descriptors are submitted at once, the specified name will be assigned to
|
||||
all of them. In order to assign different names to submitted file descriptors, submit them in separate
|
||||
invocations of <function>sd_pid_notify_with_fds()</function>. The name may consist of arbitrary ASCII
|
||||
characters except control characters or <literal>:</literal>. It may not be longer than 255 characters. If a
|
||||
submitted name does not follow these restrictions, it is ignored.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
|
|
@ -458,6 +458,21 @@ static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void service_remove_fd_store(Service *s, const char *name) {
|
||||
ServiceFDStore *fs, *n;
|
||||
|
||||
assert(s);
|
||||
assert(name);
|
||||
|
||||
LIST_FOREACH_SAFE(fd_store, fs, n, s->fd_store) {
|
||||
if (!streq(fs->fdname, name))
|
||||
continue;
|
||||
|
||||
log_unit_debug(UNIT(s), "Got explicit request to remove fd %i (%s), closing.", fs->fd, name);
|
||||
service_fd_store_unlink(fs);
|
||||
}
|
||||
}
|
||||
|
||||
static int service_arm_timer(Service *s, usec_t usec) {
|
||||
int r;
|
||||
|
||||
|
@ -3466,7 +3481,19 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
|
|||
service_reset_watchdog_timeout(s, watchdog_override_usec);
|
||||
}
|
||||
|
||||
if (strv_find(tags, "FDSTORE=1")) {
|
||||
/* Process FD store messages. Either FDSTOREREMOVE=1 for removal, or FDSTORE=1 for addition. In both cases,
|
||||
* process FDNAME= for picking the file descriptor name to use. Note that FDNAME= is required when removing
|
||||
* fds, but optional when pushing in new fds, for compatibility reasons. */
|
||||
if (strv_find(tags, "FDSTOREREMOVE=1")) {
|
||||
const char *name;
|
||||
|
||||
name = strv_find_startswith(tags, "FDNAME=");
|
||||
if (!name || !fdname_is_valid(name))
|
||||
log_unit_warning(u, "FDSTOREREMOVE=1 requested, but no valid file descriptor name passed, ignoring.");
|
||||
else
|
||||
service_remove_fd_store(s, name);
|
||||
|
||||
} else if (strv_find(tags, "FDSTORE=1")) {
|
||||
const char *name;
|
||||
|
||||
name = strv_find_startswith(tags, "FDNAME=");
|
||||
|
@ -3475,7 +3502,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
|
|||
name = NULL;
|
||||
}
|
||||
|
||||
service_add_fd_store_set(s, fds, name);
|
||||
(void) service_add_fd_store_set(s, fds, name);
|
||||
}
|
||||
|
||||
/* Notify clients about changed status or main pid */
|
||||
|
|
|
@ -222,6 +222,15 @@ int sd_is_mq(int fd, const char *path);
|
|||
invocation. This variable is only supported with
|
||||
sd_pid_notify_with_fds().
|
||||
|
||||
FDSTOREREMOVE=1
|
||||
Remove one or more file descriptors from the file
|
||||
descriptor store, identified by the name specified
|
||||
in FDNAME=, see below.
|
||||
|
||||
FDNAME= A name to assign to new file descriptors stored in the
|
||||
file descriptor store, or the name of the file descriptors
|
||||
to remove in case of FDSTOREREMOVE=1.
|
||||
|
||||
Daemons can choose to send additional variables. However, it is
|
||||
recommended to prefix variable names not listed above with X_.
|
||||
|
||||
|
|
Loading…
Reference in New Issue