1
0
mirror of https://github.com/systemd/systemd synced 2026-02-25 08:44:45 +01:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Mike Yuan
3c47dc76be systemctl-start-unit: drop redundant check for enqueue-marked-jobs --wait
Follow-up for c008f88dede789ce4572c21a2bca16ff7eede193

The check at the beginning of the function already covers this.
2026-02-25 05:09:38 +09:00
Luca Boccassi
a851c5118b test: avoid hanging forever waiting for udev if not a booted system
test_sd_device_enumerator_filter_subsystem hangs forever in OBS builds,
as it waits for the udev queue to be drained. But this is not a booted
system, with systemd and udev, so nothing will do that.
Skip the test in that case.
2026-02-25 04:53:20 +09:00
Daan De Meyer
e4f72956b6
network: several follow-ups for new varlink methods (#40808) 2026-02-24 19:59:01 +01:00
Luca Boccassi
882cf2d943 core: check selinux/polkit access on varlink SetProperty
Reported on yeswehack.com as:
YWH-PGM9780-92

Follow-up for 0e1c4de235908dfe507fbbddb06ad49b53ccb86b
2026-02-24 18:54:44 +00:00
Luca Boccassi
c556a2ad15
tree-wide: a small number of small fixlets all over the place (#40797) 2026-02-24 18:53:17 +00:00
Yu Watanabe
ab2bc40dcd bash-completion/systemctl: add enqueue-marked-jobs and deprecate --marked
Follow-up for #40810.
2026-02-24 17:53:53 +00:00
Mike Yuan
21fd534ae8
systemctl: introduce enqueue-marked-jobs verb (#40810) 2026-02-24 18:08:22 +01:00
Yu Watanabe
93e1b0f328
man: coredump: KeepFree/MaxUse clarification of default values (#40796)
On sd-coredump for both `MaxUse` and `KeepFree` defaults has a caveat,
it may set it differently if not explicit configured.
On `MaxUse` it'll cap to 4GiB as seem
[here](d39b103719/src/coredump/coredump-vacuum.c (L82)).
Similar for `KeepFree`
[here](d39b103719/src/coredump/coredump-vacuum.c (L98))

Also show that `MaxUse` takes precedence.

Making this clear at the man page
2026-02-25 01:35:38 +09:00
Antonio Alvarez Feijoo
8ea1ae25ab import/pull-oci: fix several OOM checks
Follow-up for a9f6ba04969d6eb2e629e30299fab7538ef42a57
2026-02-24 17:34:09 +01:00
Lennart Poettering
35e4cb2189 update TODO 2026-02-24 17:11:54 +01:00
Lennart Poettering
3601697b2d analyzer: remove spurious empty line 2026-02-24 17:11:54 +01:00
Lennart Poettering
a69dffbf4f sd-varlink: add a bit of debug logging indicating when exit-on-idle triggers 2026-02-24 17:11:54 +01:00
Lennart Poettering
a0276f6e12 sd-varlink: use correct error variable 2026-02-24 17:09:33 +01:00
Lennart Poettering
332ecf40f2 sd-netlink: pin reply slot while we execute callback
The callback might drop the last ref to the slot object, and we still
want to access it. Hence do what we usually do in these cases: keep an
extra reference while processing the callback.
2026-02-24 17:09:33 +01:00
Lennart Poettering
c8aa7b152f network: enable LLDP for links that use only link-local addressing
Links with link-local-only communication are typically peer-to-peer
links between two laptops or similar. In such cases it makes sense to be
able to see which device one is specifically connected to, hence let's
just enable LLDP for it. This doesn't leak any data really, given that
this is inherently local, and typically only used between isolated
systems that are under the same user's possession.

Background: I recently connected multiple laptops via thunderbolt networking
and was kinda annoyed not being able to see what system I was actually
talking to.

(Also, the file touched here is an example only anyway, so even if this
would leak too much info, it's not in effect by default)
2026-02-24 17:09:33 +01:00
Mike Yuan
81f31dccb8
man/systemctl: deprecate --marked 2026-02-24 16:00:05 +01:00
Mike Yuan
c008f88ded
systemctl: introduce enqueue-marked-jobs verb, stop lumping it with distinct verbs 2026-02-24 16:00:05 +01:00
Yu Watanabe
da7374b2ae varlink-idl: allow to pass polkit arguments to io.systemd.service.Reload()
Then, varlink interfaces with unprivileged access can be implement the
method.
2026-02-24 23:59:08 +09:00
Yu Watanabe
27f1bf5cde network: rename dispatch_interface() and make it take flags
No functional change. Just refactoring and preparation for later change.
2026-02-24 23:57:15 +09:00
Yu Watanabe
b6919c737a network: rename io.systemd.Network.LinkUp()/LinkDown()
Then, this also moves their implementations to networkd-link-varlink.c.
2026-02-24 23:56:20 +09:00
Mike Yuan
a8ceed0000
Revert "systemctl: allow --marker with start/stop too"
This reverts commit 351b4dd123f89f7f8491239b2d3f77bef5d00797.

I'm pretty sure we should not create more of these multiplexer
interfaces, which in this specific also leads to a fair bit of
confusion: start/stop/reload-or-restart --marked all enqueue
all job types.

Instead, a dedicated verb will be introduced in later commits.
2026-02-24 15:48:53 +01:00
André Paiusco
cbd7b9033b man: coredump: MaxUse takes precedence 2026-02-23 16:43:09 +00:00
André Paiusco
1e2c2a04fc man: coredump: KeepFree/MaxUse clarification of default values 2026-02-23 16:22:32 +00:00
26 changed files with 253 additions and 167 deletions

7
NEWS
View File

@ -172,9 +172,10 @@ CHANGES WITH 260 in spe:
RouteMetric=, and UseGateway= settings. This allows systemd-networkd
to establish a cellular modem connection to a broadband network.
* systemd-networkd gained a pair of varlink methods LinkUp()/LinkDown().
networkctl up/down now utilizes the new varlink interfaces in place
of direct RTNL message for better interaction with networkd.
* systemd-networkd gained a pair of varlink methods
io.systemd.Network.Link.Up()/Down(). networkctl up/down now utilizes
the new varlink interfaces in place of direct RTNL message for better
interaction with networkd.
Changes in systemd-boot and the stub:

3
TODO
View File

@ -121,6 +121,9 @@ Deprecations and removals:
Features:
* sd-lldp: pick up 802.3 maximum frame size/mtu, to be able to detect jumbo
frame capable networks
* networkd: maintain a file in /run/ that can be symlinked into /run/issue.d/
that always shows the current primary IP address

View File

@ -168,11 +168,13 @@
<option>MaxUse=</option> makes
sure that old core dumps are removed as soon as the total disk
space taken up by core dumps grows beyond this limit (defaults
to 10% of the total disk size). <option>KeepFree=</option>
controls how much disk space to keep free at least (defaults
to 15% of the total disk size). Note that the disk space used
to 10% of the total disk size, capped at 4GiB, minimum 1MiB).
<option>KeepFree=</option> controls how much disk space to keep
free at least (defaults to 15% of the total disk size, limited
to a maximum of 4GiB). Note that the disk space used
by core dumps might temporarily exceed these limits while
core dumps are processed. Note that old core dumps are also
core dumps are processed. <option>MaxUse=</option> takes precedence.
Note that old core dumps are also
removed based on time via
<citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
Set either value to 0 to turn off size-based cleanup.</para>

View File

@ -499,6 +499,20 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
do not document that. -->
</listitem>
</varlistentry>
<varlistentry>
<term><command>enqueue-marked-jobs</command></term>
<listitem><para>Enqueue start/stop/restart/reload jobs for all units that have the respective
<literal>needs-*</literal> markers set. When a unit marked for reload does not support reload,
restart will be queued. Those properties can be set using <command>set-property Markers=…</command>.</para>
<para>Unless <option>--no-block</option> is used, <command>systemctl</command> will wait for the
queued jobs to finish.</para>
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
</varlistentry>
<varlistentry>
<term><command>reload-or-restart <replaceable>PATTERN</replaceable></command></term>
@ -506,8 +520,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>Reload one or more units if they support it. If not, stop and then start them instead. If the units
are not running yet, they will be started.</para>
<para>This has a slightly differing functionality when used in combination with <option>--marked</option>,
see below.</para>
<para>When used in combination with <option>--marked</option>, it is a deprecated alias of
<command>enqueue-marked-jobs</command>.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -2852,20 +2866,6 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--marked</option></term>
<listitem><para>Only allowed with <command>reload-or-restart</command>, <command>start</command>, or
<command>stop</command>. Enqueues jobs for all units that are marked. When a unit marked for reload
does not support reload, restart will be queued. Those properties can be set using
<command>set-property Markers=…</command>.</para>
<para>Unless <option>--no-block</option> is used, <command>systemctl</command> will wait for the
queued jobs to finish.</para>
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--read-only</option></term>

View File

@ -18,3 +18,5 @@ Property=ID_NET_AUTO_LINK_LOCAL_ONLY=1
LinkLocalAddressing=yes
IPv6AcceptRA=no
MulticastDNS=yes
LLDP=yes
EmitLLDP=yes

View File

@ -134,7 +134,7 @@ _systemctl () {
--help -h --no-ask-password --no-block --legend=no --no-pager --no-reload --no-wall --now
--quiet -q --system --user --version --runtime --recursive -r --firmware-setup
--show-types --plain --failed --value --fail --dry-run --wait --no-warn --with-dependencies
--show-transaction -T --mkdir --marked --read-only'
--show-transaction -T --mkdir --read-only'
[ARG]='--host -H --kill-whom --property -p -P --signal -s --type -t --state --job-mode --root
--preset-mode -n --lines -o --output -M --machine --message --timestamp --check-inhibitors --what
--image --boot-loader-menu --boot-loader-entry --reboot-argument --drop-in'
@ -233,7 +233,8 @@ _systemctl () {
suspend-then-hibernate kexec soft-reboot list-jobs list-sockets
list-timers list-units list-unit-files poweroff
reboot rescue show-environment suspend get-default
is-system-running preset-all list-automounts list-paths'
is-system-running preset-all list-automounts list-paths
enqueue-marked-jobs'
[FILE]='link switch-root'
[TARGETS]='set-default'
[MACHINES]='list-machines'

View File

@ -310,7 +310,6 @@ static int help(int argc, char *argv[], void *userdata) {
" --debugger=DEBUGGER Use the given debugger\n"
" -A --debugger-arguments=ARGS\n"
" Pass the given arguments to the debugger\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,

View File

@ -3,6 +3,7 @@
#include "sd-json.h"
#include "bitfield.h"
#include "bus-polkit.h"
#include "cgroup.h"
#include "condition.h"
#include "dbus-job.h"
@ -667,6 +668,19 @@ int vl_method_set_unit_properties(sd_varlink *link, sd_json_variant *parameters,
if (r < 0)
return r;
r = mac_selinux_unit_access_check_varlink(unit, link, "start");
if (r < 0)
return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL);
r = varlink_verify_polkit_async(
link,
manager->system_bus,
"org.freedesktop.systemd1.manage-units",
/* details= */ NULL,
&manager->polkit_registry);
if (r <= 0)
return r;
if (p.markers_found)
unit->markers = unit_normalize_markers((unit->markers & ~p.markers_mask), p.markers);

View File

@ -997,7 +997,7 @@ static int oci_pull_save_nspawn_settings(OciPull *i) {
return log_oom();
_cleanup_free_ char *j = path_join(i->image_root, fn);
if (!fn)
if (!j)
return log_oom();
_cleanup_fclose_ FILE *f = NULL;
@ -1085,7 +1085,7 @@ static int oci_pull_save_oci_config(OciPull *i) {
return log_oom();
_cleanup_free_ char *j = path_join(i->image_root, fn);
if (!fn)
if (!j)
return log_oom();
_cleanup_close_ int fd = -EBADF;
@ -1116,7 +1116,7 @@ static int oci_pull_save_mstack(OciPull *i) {
return log_oom();
_cleanup_free_ char *j = path_join(i->image_root, dn);
if (!dn)
if (!j)
return log_oom();
log_notice("Creating '%s'", j);

View File

@ -3,6 +3,7 @@
#include <fcntl.h>
#include <unistd.h>
#include "sd-daemon.h"
#include "sd-event.h"
#include "capability-util.h"
@ -466,6 +467,10 @@ TEST(sd_device_enumerator_filter_subsystem) {
return;
}
/* The rest of this test depends on a full booted system with a working udev and so on */
if (!sd_booted())
return (void) log_tests_skipped("Test requires fully booted system with udev/etc, skipping to avoid hanging forever.");
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
ASSERT_OK(sd_event_default(&event));
ASSERT_OK(sd_event_add_inotify(event, NULL, "/run/udev" , IN_DELETE, on_inotify, NULL));

View File

@ -331,7 +331,6 @@ static int process_timeout(sd_netlink *nl) {
static int process_reply(sd_netlink *nl, sd_netlink_message *m) {
struct reply_callback *c;
sd_netlink_slot *slot;
uint32_t serial;
uint16_t type;
int r;
@ -354,7 +353,8 @@ static int process_reply(sd_netlink *nl, sd_netlink_message *m) {
if (type == NLMSG_DONE)
m = NULL;
slot = container_of(c, sd_netlink_slot, reply_callback);
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot =
sd_netlink_slot_ref(container_of(c, sd_netlink_slot, reply_callback));
r = c->callback(nl, m, slot->userdata);
if (r < 0)

View File

@ -280,7 +280,7 @@ _public_ int sd_varlink_connect_exec(sd_varlink **ret, const char *_command, cha
}
execvp(command, argv);
log_debug_errno(r, "Failed to invoke process '%s': %m", command);
log_debug_errno(errno, "Failed to invoke process '%s': %m", command);
_exit(EXIT_FAILURE);
}
@ -4055,8 +4055,10 @@ _public_ int sd_varlink_server_shutdown(sd_varlink_server *s) {
static void varlink_server_test_exit_on_idle(sd_varlink_server *s) {
assert(s);
if (s->exit_on_idle && s->event && s->n_connections == 0)
if (s->exit_on_idle && s->event && s->n_connections == 0) {
varlink_server_log(s, "Exit-on-idle triggered.");
(void) sd_event_exit(s->event, 0);
}
}
_public_ int sd_varlink_server_set_exit_on_idle(sd_varlink_server *s, int b) {

View File

@ -59,6 +59,7 @@ systemd_networkd_extract_sources = files(
'networkd-ipv6ll.c',
'networkd-json.c',
'networkd-link-bus.c',
'networkd-link-varlink.c',
'networkd-link.c',
'networkd-lldp-rx.c',
'networkd-lldp-tx.c',

View File

@ -67,7 +67,7 @@ int link_up_down(int argc, char *argv[], void *userdata) {
ORDERED_SET_FOREACH(p, indexes)
RET_GATHER(ret, varlink_callbo_and_log(
vl,
up ? "io.systemd.Network.LinkUp" : "io.systemd.Network.LinkDown",
up ? "io.systemd.Network.Link.Up" : "io.systemd.Network.Link.Down",
/* reply= */ NULL,
SD_JSON_BUILD_PAIR_INTEGER("InterfaceIndex", PTR_TO_INT(p)),
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)));

View File

@ -0,0 +1,102 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-varlink.h"
#include "bus-polkit.h"
#include "json-util.h"
#include "networkd-link.h"
#include "networkd-link-varlink.h"
#include "networkd-manager.h"
#include "networkd-setlink.h"
int dispatch_link(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, DispatchLinkFlag flags, Link **ret) {
struct {
int ifindex;
const char *ifname;
} info = {};
Link *link = NULL;
int r;
static const sd_json_dispatch_field dispatch_table[] = {
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
{}
}, dispatch_polkit_table[] = {
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
assert(vlink);
assert(manager);
assert(ret);
r = sd_varlink_dispatch(
vlink,
parameters,
FLAGS_SET(flags, DISPATCH_LINK_POLKIT) ? dispatch_polkit_table : dispatch_table,
&info);
if (r != 0)
return r;
if (info.ifindex < 0)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
if (info.ifindex > 0 && link_get_by_index(manager, info.ifindex, &link) < 0)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
if (info.ifname) {
Link *link_by_name;
if (link_get_by_name(manager, info.ifname, &link_by_name) < 0)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
if (link && link_by_name != link)
/* If both arguments are specified, then these must be consistent. */
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
link = link_by_name;
}
if (!link && FLAGS_SET(flags, DISPATCH_LINK_MANDATORY))
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
/* If the DISPATCH_LINK_MANDATORY flag is not set, this function may return NULL. */
*ret = link;
return 0;
}
static int vl_method_link_up_or_down(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool up) {
Link *link;
int r;
assert(vlink);
assert(manager);
r = dispatch_link(vlink, parameters, manager, DISPATCH_LINK_POLKIT | DISPATCH_LINK_MANDATORY, &link);
if (r != 0)
return r;
r = varlink_verify_polkit_async(
vlink,
manager->bus,
"org.freedesktop.network1.manage-links",
/* details= */ NULL,
&manager->polkit_registry);
if (r <= 0)
return r;
if (!up)
/* Stop all network engines while interface is still up to allow proper cleanup,
* e.g. sending IPv6 shutdown RA messages before the interface is brought down. */
(void) link_stop_engines(link, /* may_keep_dynamic = */ false);
return link_up_or_down_now_by_varlink(link, up, vlink);
}
int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ true);
}
int vl_method_link_down(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ false);
}

View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "networkd-forward.h"
typedef enum DispatchLinkFlag {
DISPATCH_LINK_POLKIT = 1 << 0,
DISPATCH_LINK_MANDATORY = 1 << 1,
} DispatchLinkFlag;
int dispatch_link(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, DispatchLinkFlag flags, Link **ret);
int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_link_down(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);

View File

@ -14,11 +14,12 @@
#include "networkd-dhcp-server.h"
#include "networkd-json.h"
#include "networkd-link.h"
#include "networkd-link-varlink.h"
#include "networkd-manager.h"
#include "networkd-manager-varlink.h"
#include "networkd-setlink.h"
#include "stat-util.h"
#include "varlink-io.systemd.Network.h"
#include "varlink-io.systemd.Network.Link.h"
#include "varlink-io.systemd.service.h"
#include "varlink-util.h"
@ -93,55 +94,6 @@ static int vl_method_get_namespace_id(sd_varlink *link, sd_json_variant *paramet
SD_JSON_BUILD_PAIR_CONDITION(nsid != UINT32_MAX, "NamespaceNSID", SD_JSON_BUILD_UNSIGNED(nsid)));
}
static int dispatch_interface(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool polkit, Link **ret) {
struct {
int ifindex;
const char *ifname;
} info = {};
Link *link = NULL;
int r;
static const sd_json_dispatch_field dispatch_table[] = {
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
{}
}, dispatch_polkit_table[] = {
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
assert(vlink);
assert(manager);
assert(ret);
r = sd_varlink_dispatch(vlink, parameters, polkit ? dispatch_polkit_table : dispatch_table, &info);
if (r != 0)
return r;
if (info.ifindex < 0)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
if (info.ifindex > 0 && link_get_by_index(manager, info.ifindex, &link) < 0)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
if (info.ifname) {
Link *link_by_name;
if (link_get_by_name(manager, info.ifname, &link_by_name) < 0)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
if (link && link_by_name != link)
/* If both arguments are specified, then these must be consistent. */
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
link = link_by_name;
}
/* If neither InterfaceIndex nor InterfaceName specified, this function returns NULL. */
*ret = link;
return 0;
}
static int link_append_lldp_neighbors(Link *link, sd_json_variant *v, sd_json_variant **array) {
assert(link);
assert(array);
@ -163,7 +115,7 @@ static int vl_method_get_lldp_neighbors(sd_varlink *vlink, sd_json_variant *para
assert(vlink);
assert(manager);
r = dispatch_interface(vlink, parameters, manager, /* polkit= */ false, &link);
r = dispatch_link(vlink, parameters, manager, /* flags= */ 0, &link);
if (r != 0)
return r;
@ -284,46 +236,6 @@ static int vl_method_set_persistent_storage(sd_varlink *vlink, sd_json_variant *
return sd_varlink_reply(vlink, NULL);
}
static int vl_method_link_up_or_down(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool up) {
Link *link;
int r;
assert(vlink);
assert(manager);
r = dispatch_interface(vlink, parameters, manager, /* polkit= */ true, &link);
if (r != 0)
return r;
/* Require a specific link to be specified. */
if (!link)
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
r = varlink_verify_polkit_async(
vlink,
manager->bus,
"org.freedesktop.network1.manage-links",
/* details= */ NULL,
&manager->polkit_registry);
if (r <= 0)
return r;
if (!up)
/* Stop all network engines while interface is still up to allow proper cleanup,
* e.g. sending IPv6 shutdown RA messages before the interface is brought down. */
(void) link_stop_engines(link, /* may_keep_dynamic = */ false);
return link_up_or_down_now_by_varlink(link, up, vlink);
}
static int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ true);
}
static int vl_method_link_down(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ false);
}
int manager_varlink_init(Manager *m, int fd) {
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
_unused_ _cleanup_close_ int fd_close = fd; /* take possession */
@ -347,6 +259,7 @@ int manager_varlink_init(Manager *m, int fd) {
r = sd_varlink_server_add_interface_many(
s,
&vl_interface_io_systemd_Network,
&vl_interface_io_systemd_Network_Link,
&vl_interface_io_systemd_service);
if (r < 0)
return log_error_errno(r, "Failed to add Network interface to varlink server: %m");
@ -358,8 +271,8 @@ int manager_varlink_init(Manager *m, int fd) {
"io.systemd.Network.GetNamespaceId", vl_method_get_namespace_id,
"io.systemd.Network.GetLLDPNeighbors", vl_method_get_lldp_neighbors,
"io.systemd.Network.SetPersistentStorage", vl_method_set_persistent_storage,
"io.systemd.Network.LinkUp", vl_method_link_up,
"io.systemd.Network.LinkDown", vl_method_link_down,
"io.systemd.Network.Link.Up", vl_method_link_up,
"io.systemd.Network.Link.Down", vl_method_link_down,
"io.systemd.service.Ping", varlink_method_ping,
"io.systemd.service.SetLogLevel", varlink_method_set_log_level,
"io.systemd.service.GetEnvironment", varlink_method_get_environment);

View File

@ -216,6 +216,7 @@ shared_sources = files(
'varlink-io.systemd.MuteConsole.c',
'varlink-io.systemd.NamespaceResource.c',
'varlink-io.systemd.Network.c',
'varlink-io.systemd.Network.Link.c',
'varlink-io.systemd.PCRExtend.c',
'varlink-io.systemd.PCRLock.c',
'varlink-io.systemd.Repart.c',

View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "bus-polkit.h"
#include "varlink-io.systemd.Network.Link.h"
#define VARLINK_NETWORK_INTERFACE_INPUTS \
SD_VARLINK_FIELD_COMMENT("Index of the interface. If specified together with InterfaceName, both must reference the same link."), \
SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), \
SD_VARLINK_FIELD_COMMENT("Name of the interface. If specified together with InterfaceIndex, both must reference the same link."), \
SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)
static SD_VARLINK_DEFINE_METHOD(
Up,
VARLINK_NETWORK_INTERFACE_INPUTS,
VARLINK_DEFINE_POLKIT_INPUT);
static SD_VARLINK_DEFINE_METHOD(
Down,
VARLINK_NETWORK_INTERFACE_INPUTS,
VARLINK_DEFINE_POLKIT_INPUT);
SD_VARLINK_DEFINE_INTERFACE(
io_systemd_Network_Link,
"io.systemd.Network.Link",
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link up."),
&vl_method_Up,
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link down."),
&vl_method_Down);

View File

@ -0,0 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "sd-varlink-idl.h"
extern const sd_varlink_interface vl_interface_io_systemd_Network_Link;

View File

@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "bus-polkit.h"
#include "varlink-io.systemd.Network.h"
/* Helper macro to define address fields with both binary and string representation */
@ -594,22 +593,6 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_FIELD_COMMENT("Whether persistent storage is ready and writable"),
SD_VARLINK_DEFINE_INPUT(Ready, SD_VARLINK_BOOL, 0));
static SD_VARLINK_DEFINE_METHOD(
LinkUp,
SD_VARLINK_FIELD_COMMENT("Index of the interface. If specified together with InterfaceName, both must reference the same link."),
SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Name of the interface. If specified together with InterfaceIndex, both must reference the same link."),
SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
VARLINK_DEFINE_POLKIT_INPUT);
static SD_VARLINK_DEFINE_METHOD(
LinkDown,
SD_VARLINK_FIELD_COMMENT("Index of the interface. If specified together with InterfaceName, both must reference the same link."),
SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Name of the interface. If specified together with InterfaceIndex, both must reference the same link."),
SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
VARLINK_DEFINE_POLKIT_INPUT);
static SD_VARLINK_DEFINE_ERROR(StorageReadOnly);
SD_VARLINK_DEFINE_INTERFACE(
@ -620,10 +603,6 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_method_GetNamespaceId,
&vl_method_GetLLDPNeighbors,
&vl_method_SetPersistentStorage,
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link up."),
&vl_method_LinkUp,
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link down."),
&vl_method_LinkDown,
&vl_type_Address,
&vl_type_DHCPLease,
&vl_type_DHCPServer,

View File

@ -2,6 +2,7 @@
#include <unistd.h>
#include "bus-polkit.h"
#include "env-util.h"
#include "json-util.h"
#include "log.h"
@ -11,7 +12,9 @@
static SD_VARLINK_DEFINE_METHOD(Ping);
static SD_VARLINK_DEFINE_METHOD(Reload);
static SD_VARLINK_DEFINE_METHOD(
Reload,
VARLINK_DEFINE_POLKIT_INPUT);
static SD_VARLINK_DEFINE_METHOD(
SetLogLevel,

View File

@ -59,12 +59,13 @@ static int systemctl_main(int argc, char *argv[]) {
{ "list-machines", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_machines },
{ "clear-jobs", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_trivial_method },
{ "cancel", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_cancel },
{ "start", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "stop", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "start", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "stop", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "condstop", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with ALTLinux */
{ "reload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "enqueue-marked-jobs", 1, 1, VERB_ONLINE_ONLY, verb_start },
{ "reload-or-restart", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_start },
{ "reload-or-try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with old systemctl <= 228 */
{ "try-reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start },

View File

@ -295,6 +295,7 @@ int verb_start(int argc, char *argv[], void *userdata) {
const char *method, *job_type, *mode, *one_name, *suffix = NULL;
_cleanup_free_ char **stopped_units = NULL; /* Do not use _cleanup_strv_free_ */
_cleanup_strv_free_ char **names = NULL;
bool is_enqueue_marked_jobs = false;
int r, ret = EXIT_SUCCESS;
sd_bus *bus;
@ -331,13 +332,23 @@ int verb_start(int argc, char *argv[], void *userdata) {
job_type = "start";
mode = "isolate";
suffix = ".target";
} else if (!arg_marked) {
} else if (streq(argv[0], "enqueue-marked-jobs") || arg_marked) {
is_enqueue_marked_jobs = true;
method = job_type = mode = NULL;
if (arg_show_transaction)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--show-transaction is not supported for enqueue-marked-jobs.");
if (arg_marked)
log_warning("--marked is deprecated. Please use systemctl enqueue-marked-jobs instead.");
} else {
/* A command in style of "systemctl start <unit1> <unit2> …", "systemctl stop <unit1> <unit2> …" and so on */
method = verb_to_method(argv[0]);
job_type = verb_to_job_type(argv[0]);
mode = arg_job_mode();
} else
method = job_type = mode = NULL;
}
one_name = NULL;
}
@ -357,7 +368,7 @@ int verb_start(int argc, char *argv[], void *userdata) {
names = strv_new(one_name);
if (!names)
return log_oom();
} else if (!arg_marked) {
} else if (!is_enqueue_marked_jobs) {
bool expanded;
r = expand_unit_names(bus, strv_skip(argv, 1), suffix, &names, &expanded);
@ -387,7 +398,7 @@ int verb_start(int argc, char *argv[], void *userdata) {
}
_cleanup_(fork_notify_terminate) PidRef journal_pid = PIDREF_NULL;
if (arg_marked)
if (is_enqueue_marked_jobs)
ret = enqueue_marked_jobs(bus, w);
else {
if (arg_verbose)

View File

@ -143,6 +143,7 @@ static int systemctl_help(void) {
" reload UNIT... Reload one or more units\n"
" restart UNIT... Start or restart one or more units\n"
" try-restart UNIT... Restart one or more units if active\n"
" enqueue-marked-jobs Enqueue all marked unit jobs\n"
" reload-or-restart UNIT... Reload one or more units if possible,\n"
" otherwise start or restart\n"
" try-reload-or-restart UNIT... If active, reload one or more units,\n"
@ -1069,24 +1070,19 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--wait may not be combined with --no-block.");
bool do_reload_or_restart = streq_ptr(argv[optind], "reload-or-restart");
if (arg_marked) {
if (!STRPTR_IN_SET(argv[optind], "reload-or-restart", "start", "stop"))
if (!do_reload_or_restart)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--marked may only be used with 'reload-or-restart', 'start', or 'stop'.");
"--marked may only be used with 'reload-or-restart'.");
if (optind + 1 < argc)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"No additional arguments allowed with '%s --marked'.", strna(argv[optind]));
if (arg_wait)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--marked --wait is not supported.");
if (arg_show_transaction)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--marked --show-transaction is not supported.");
"No additional arguments allowed with 'reload-or-restart --marked'.");
} else if (STRPTR_IN_SET(argv[optind], "reload-or-restart", "start", "stop")) {
} else if (do_reload_or_restart) {
if (optind + 1 >= argc)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"List of units to %s is required.", strna(argv[optind]));
"List of units to restart/reload is required.");
}
if (arg_image && arg_root)

View File

@ -34,6 +34,7 @@
#include "varlink-io.systemd.MuteConsole.h"
#include "varlink-io.systemd.NamespaceResource.h"
#include "varlink-io.systemd.Network.h"
#include "varlink-io.systemd.Network.Link.h"
#include "varlink-io.systemd.PCRExtend.h"
#include "varlink-io.systemd.PCRLock.h"
#include "varlink-io.systemd.Repart.h"
@ -199,6 +200,7 @@ TEST(parse_format) {
&vl_interface_io_systemd_MuteConsole,
&vl_interface_io_systemd_NamespaceResource,
&vl_interface_io_systemd_Network,
&vl_interface_io_systemd_Network_Link,
&vl_interface_io_systemd_PCRExtend,
&vl_interface_io_systemd_PCRLock,
&vl_interface_io_systemd_Repart,