Compare commits

...

17 Commits

Author SHA1 Message Date
Yuri Chornoivan d7b34e3841 all: fix minor typos
[thaller@redhat.com: original patch by Yuri, extracted from [1]]

[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/565
2020-07-07 18:52:49 +09:00
Lennart Poettering 5d043c9fdf update NEWS 2020-07-07 11:48:45 +02:00
Lennart Poettering cbe952fe1f update TODO 2020-07-07 11:33:44 +02:00
Luca Boccassi cda667722c core: refresh unit cache when building a transaction if UNIT_NOT_FOUND
When a command asks to load a unit directly and it is in state
UNIT_NOT_FOUND, and the cache is outdated, we refresh it and
attempto to load again.
Use the same logic when building up a transaction and a dependency in
UNIT_NOT_FOUND state is encountered.
Update the unit test to exercise this code path.
2020-07-07 10:09:24 +02:00
Zbigniew Jędrzejewski-Szmek 77ecc1aaa5
Merge pull request #16380 from yuwata/network-dhcp6-update-prefix-route
Network: update acquired dhcp6 prefix routes
2020-07-07 09:05:08 +02:00
Zbigniew Jędrzejewski-Szmek 9389a271b7
Merge pull request #16381 from yuwata/dhcp4-renewing
dhcp4: fixes around renewing address
2020-07-07 08:59:35 +02:00
Zbigniew Jędrzejewski-Szmek a240147bdc
Merge pull request #16383 from yuwata/network-dhcp6-radv-update-prefix
network: do not restart radv engine when adding prefix
2020-07-07 08:53:31 +02:00
satmandu 7f6e342c93
hwdb: Add Google Pixel Slate (nocturne) (#16377) 2020-07-07 08:45:31 +02:00
Yu Watanabe 58e6c62191 network: fix memleak
If init() is failed, the allocated memory was leaked.
2020-07-07 08:23:17 +02:00
Yu Watanabe 1d596fdec2 network: do not restart radv engine when adding prefix
Replaces d469cea3bd.
2020-07-07 11:20:35 +09:00
Yu Watanabe 8fc2a5dff4 network: fix indentation 2020-07-07 11:18:28 +09:00
Yu Watanabe 290696e512 Revert "network: Don't send RA with zero router lifetime when restarting radv"
This reverts commit d469cea3bd.
2020-07-07 11:06:08 +09:00
Yu Watanabe 921693a0f3 dhcp4: do not try to renew address when client has no lease 2020-07-07 10:18:58 +09:00
Yu Watanabe ceaec54a3c dhcp4: do not renew address if client is not running yet 2020-07-07 10:18:22 +09:00
Yu Watanabe f050c94df0 network: always update acquired prefix route
Otherwise, routes become lifetime 0.

Fixes #16356.
2020-07-07 09:20:44 +09:00
Yu Watanabe 1419ff0401 network: decrease indentation level 2020-07-07 09:14:21 +09:00
Yu Watanabe cecd68c70f network: fix indentation 2020-07-07 08:47:38 +09:00
22 changed files with 175 additions and 101 deletions

25
NEWS
View File

@ -91,6 +91,15 @@ CHANGES WITH 246 in spe:
from the documentation, but will now result in warnings when used,
and be converted to "journal" and "journal+console" automatically.
* If the service setting User= is set to the "nobody" user, a warning
message is now written to the logs (but the value is nonetheless
accepted). Setting User=nobody is unsafe, since the primary purpose
of the "nobody" user is to own all files whose owner cannot be mapped
locally. It's in particular used by the NFS subsystem and in user
namespacing. By running a service under this user's UID it might get
read and even write access to all these otherwise unmappable files,
which is quite likely a major security problem.
* A new kernel command line option systemd.hostname= has been added
that allows controlling the hostname that is initialized early during
boot.
@ -370,6 +379,21 @@ CHANGES WITH 246 in spe:
storage and file system may now be configured explicitly, too, via
the new /etc/systemd/homed.conf configuration file.
* systemd-homed now supports unlocking home directories with FIDO2
security tokens that support the 'hmac-secret' extension, in addition
to the existing support for PKCS#11 security token unlocking
support. Note that many recent hardware security tokens support both
interfaces. The FIDO2 support is accessible via homectl's
--fido2-device= option.
* homectl's --pkcs11-uri= setting now accepts two special parameters:
if "auto" is specified and only one suitable PKCS#11 security token
is plugged in, its URL is automatically determined and enrolled for
unlocking the home directory. If "list" is specified a brief table of
suitable PKCS#11 security tokens is shown. Similar, the new
--fido2-device= option also supports these two special values, for
automatically selecting and listing suitable FIDO2 devices.
* The /etc/crypttab tmp option now optionally takes an argument
selecting the file system to use. Moreover, the default is now
changed from ext2 to ext4.
@ -496,7 +520,6 @@ CHANGES WITH 246 in spe:
LogControl1 D-Bus API which allows clients to change log level +
target of the service during runtime.
CHANGES WITH 245:
* A new tool "systemd-repart" has been added, that operates as an

12
TODO
View File

@ -138,12 +138,12 @@ Features:
* homed: support new FS_IOC_ADD_ENCRYPTION_KEY ioctl for setting up fscrypt
* busctl: maybe expose a verb "ping" for pinging a dbus service to see if it
exists and responds.
* homed: maybe pre-create ~/.cache as subvol so that it can have separate quota
easily?
* busctl: maybe expose a verb "ping" for pinging a dbus service to see if it
exists and responds.
* when systemd-nspawn and suchlike dissect an OS image, and there are multiple
root partitions, do an strverscmp() on the partition label and boot
first. That is inspired how sd-boot figures out which kernel to boot, and
@ -343,7 +343,8 @@ Features:
beefing up logind to make pam session close hook synchronous and wait until
systemd --user is shut down.
- logind: maybe keep a "busy fd" as long as there's a non-released session around or the user@.service
- maybe make automatic, read-only, time-based reflink-copies of LUKS disk images (think: time machine)
- maybe make automatic, read-only, time-based reflink-copies of LUKS disk
images (and btrfs snapshots of subvolumes) (think: time machine)
- distinguish destroy / remove (i.e. currently we can unregister a user, unregister+remove their home directory, but not just remove their home directory)
- in systemd's PAMName= logic: query passwords with ssh-askpassword, so that we can make "loginctl set-linger" mode work
- fingerprint authentication, pattern authentication, …
@ -359,6 +360,9 @@ Features:
- make slice for users configurable (requires logind rework)
- logind: populate auto-login list bus property from PKCS#11 token
- when determining state of a LUKS home directory, check DM suspended sysfs file
- introduce API for "making room", that grows/shrinks home directory
according to elastic parameters, discards blocks, and removes additional snapshots. Call it
either from UI when disk space gets low
* introduce a new per-process uuid, similar to the boot id, the machine id, the
invocation id, that is derived from process creds, specifically a hashed

View File

@ -316,6 +316,10 @@ sensor:modalias:platform:cros-ec-accel:dmi:*:svnGoogle:pnCaroline*
sensor:modalias:platform:cros-ec-accel:dmi:*svnGoogle:pnVayne*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1
# nocturne board (Google Pixel Slate)
sensor:modalias:platform:cros-ec-accel:dmi:*Google_Nocturne*
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
#########################################
# GP-electronic
#########################################

View File

@ -1334,7 +1334,7 @@ int safe_fork_full(
ppid = getppid();
if (ppid == 0)
/* Parent is in a differn't PID namespace. */;
/* Parent is in a different PID namespace. */;
else if (ppid != original_pid) {
log_debug("Parent died early, raising SIGTERM.");
(void) raise(SIGTERM);

View File

@ -77,7 +77,7 @@ int rdrand(unsigned long *ret) {
* hash functions for its hash tables, with a seed generated randomly. The hash tables
* systemd employs watch the fill level closely and reseed if necessary. This allows use of
* a low quality RNG initially, as long as it improves should a hash table be under attack:
* the attacker after all needs to to trigger many collisions to exploit it for the purpose
* the attacker after all needs to trigger many collisions to exploit it for the purpose
* of DoS, but if doing so improves the seed the attack surface is reduced as the attack
* takes place.
*

View File

@ -105,7 +105,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
return -EINVAL;
} else {
/* If there's no embedded NUL byte, then then the size needs to match the whole
/* If there's no embedded NUL byte, then the size needs to match the whole
* structure or the structure with one extra NUL byte suffixed. (Yeah, Linux is awful,
* and considers both equivalent: getsockname() even extends sockaddr_un beyond its
* size if the path is non NUL terminated.)*/

View File

@ -1932,11 +1932,19 @@ unsigned manager_dispatch_load_queue(Manager *m) {
return n;
}
static bool manager_unit_cache_needs_refresh(Manager *m, Unit *u) {
assert(m);
bool manager_unit_file_maybe_loadable_from_cache(Unit *u) {
assert(u);
return m->unit_cache_mtime > 0 &&
(m->unit_cache_mtime > u->fragment_loadtime || !lookup_paths_mtime_good(&m->lookup_paths, m->unit_cache_mtime));
if (u->load_state != UNIT_NOT_FOUND)
return false;
if (u->manager->unit_cache_mtime == 0)
return false;
if (u->manager->unit_cache_mtime > u->fragment_loadtime)
return true;
return !lookup_paths_mtime_good(&u->manager->lookup_paths, u->manager->unit_cache_mtime);
}
int manager_load_unit_prepare(
@ -1988,7 +1996,7 @@ int manager_load_unit_prepare(
* we need to try again - even if the cache is current, it might have been
* updated in a different context before we had a chance to retry loading
* this particular unit. */
if (ret->load_state == UNIT_NOT_FOUND && manager_unit_cache_needs_refresh(m, ret))
if (manager_unit_file_maybe_loadable_from_cache(ret))
ret->load_state = UNIT_STUB;
else {
*_ret = ret;

View File

@ -463,6 +463,7 @@ Unit *manager_get_unit(Manager *m, const char *name);
int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
bool manager_unit_file_maybe_loadable_from_cache(Unit *u);
int manager_load_unit_prepare(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret);

View File

@ -954,6 +954,24 @@ int transaction_add_job_and_dependencies(
if (type != JOB_STOP) {
r = bus_unit_validate_load_state(unit, e);
/* The time-based cache allows to start new units without daemon-reload,
* but if they are already referenced (because of dependencies or ordering)
* then we have to force a load of the fragment. As an optimization, check
* first if anything in the usual paths was modified since the last time
* the cache was loaded. Also check if the last time an attempt to load the
* unit was made was before the most recent cache refresh, so that we know
* we need to try again - even if the cache is current, it might have been
* updated in a different context before we had a chance to retry loading
* this particular unit.
* Given building up the transaction is a synchronous operation, attempt
* to load the unit immediately. */
if (r < 0 && manager_unit_file_maybe_loadable_from_cache(unit)) {
unit->load_state = UNIT_STUB;
r = unit_load(unit);
if (r < 0 || unit->load_state == UNIT_STUB)
unit->load_state = UNIT_NOT_FOUND;
r = bus_unit_validate_load_state(unit, e);
}
if (r < 0)
return r;
}

View File

@ -376,7 +376,7 @@ int sd_dhcp_client_set_client_id(
/* For hardware types, log debug message about unexpected data length.
*
* Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
* last last 8 bytes of the address are stable and suitable to put into
* the last 8 bytes of the address are stable and suitable to put into
* the client-id. The caller is advised to account for that. */
if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) ||
(type == ARPHRD_INFINIBAND && data_len != 8))
@ -1441,7 +1441,10 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
client->state = DHCP_STATE_RENEWING;
if (client->lease)
client->state = DHCP_STATE_RENEWING;
else if (client->state != DHCP_STATE_INIT)
client->state = DHCP_STATE_INIT_REBOOT;
client->attempt = 0;
return client_initialize_time_events(client);
@ -2012,6 +2015,9 @@ int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
assert_return(client->fd >= 0, -EINVAL);
if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT, DHCP_STATE_STOPPED))
return 0;
client->start_delay = 0;
client->attempt = 1;
client->state = DHCP_STATE_RENEWING;

View File

@ -1489,7 +1489,7 @@ static int client_receive_message(
break;
}
_fallthrough_; /* for Soliciation Rapid Commit option check */
_fallthrough_; /* for Solicitation Rapid Commit option check */
case DHCP6_STATE_REQUEST:
case DHCP6_STATE_RENEW:
case DHCP6_STATE_REBIND:

View File

@ -339,12 +339,12 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
return 0;
fail:
sd_radv_stop(ra, true);
sd_radv_stop(ra);
return 0;
}
_public_ int sd_radv_stop(sd_radv *ra, bool zero_router_lifetime) {
_public_ int sd_radv_stop(sd_radv *ra) {
int r;
assert_return(ra, -EINVAL);
@ -354,15 +354,11 @@ _public_ int sd_radv_stop(sd_radv *ra, bool zero_router_lifetime) {
log_radv("Stopping IPv6 Router Advertisement daemon");
if (zero_router_lifetime) {
/* RFC 4861, Section 6.2.5, send at least one Router Advertisement
with zero lifetime */
r = radv_send(ra, NULL, 0);
if (r < 0)
log_radv_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
else
log_radv("Sent last Router Advertisement with router lifetime set to zero");
}
/* RFC 4861, Section 6.2.5, send at least one Router Advertisement
with zero lifetime */
r = radv_send(ra, NULL, 0);
if (r < 0)
log_radv_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
radv_reset(ra);
ra->fd = safe_close(ra->fd);

View File

@ -284,7 +284,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
return 0;
}
assert_se(sd_radv_stop(ra, true) >= 0);
assert_se(sd_radv_stop(ra) >= 0);
test_stopped = true;
return 0;

View File

@ -6,7 +6,6 @@
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include "sd-radv.h"
#include "sd-dhcp6-client.h"
@ -18,6 +17,7 @@
#include "networkd-dhcp6.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-radv.h"
#include "siphash24.h"
#include "string-table.h"
#include "string-util.h"
@ -28,7 +28,6 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
static Link *dhcp6_prefix_get(Manager *m, struct in6_addr *addr);
static int dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link);
static int dhcp6_prefix_remove_all(Manager *m, Link *link);
static bool dhcp6_link_has_dhcpv6_prefix(Link *link);
static int dhcp6_assign_delegated_prefix(Link *link, const struct in6_addr *prefix,
uint8_t prefix_len,
uint32_t lifetime_preferred,
@ -78,7 +77,7 @@ static int dhcp6_get_preferred_delegated_prefix(
if (subnet_id >= 0) {
/* If the link has a preference for a particular subnet id try to allocate that */
if ((uint64_t)subnet_id >= n_prefixes)
if ((uint64_t) subnet_id >= n_prefixes)
return log_link_debug_errno(link,
SYNTHETIC_ERRNO(ERANGE),
"subnet id %" PRIi64 " is out of range. Only have %" PRIu64 " subnets.",
@ -112,28 +111,24 @@ static int dhcp6_get_preferred_delegated_prefix(
log_link_debug(link, "The requested prefix %s is available. Using it.",
strnull(assigned_buf));
return 0;
} else {
for (uint64_t n = 0; n < n_prefixes; n++) {
/* if we do not have an allocation preference just iterate
* through the address space and return the first free prefix. */
Link* assigned_link = dhcp6_prefix_get(manager, &prefix.in6);
if (!assigned_link || assigned_link == link) {
*ret_addr = prefix.in6;
return 0;
}
r = in_addr_prefix_next(AF_INET6, &prefix, 64);
if (r < 0)
return log_link_error_errno(link,
r,
"Can't allocate another prefix. Out of address space?");
}
log_link_warning(link, "Couldn't find a suitable prefix. Ran out of address space.");
}
return -ERANGE;
for (uint64_t n = 0; n < n_prefixes; n++) {
/* if we do not have an allocation preference just iterate
* through the address space and return the first free prefix. */
Link* assigned_link = dhcp6_prefix_get(manager, &prefix.in6);
if (!assigned_link || assigned_link == link) {
*ret_addr = prefix.in6;
return 0;
}
r = in_addr_prefix_next(AF_INET6, &prefix, 64);
if (r < 0)
return log_link_error_errno(link, r, "Can't allocate another prefix. Out of address space?");
}
return log_link_warning_errno(link, SYNTHETIC_ERRNO(ERANGE), "Couldn't find a suitable prefix. Ran out of address space.");
}
static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) {
@ -159,8 +154,7 @@ static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) {
return false;
}
static int dhcp6_lease_information_acquired(sd_dhcp6_client *client,
Link *link) {
static int dhcp6_lease_information_acquired(sd_dhcp6_client *client, Link *link) {
return 0;
}
@ -168,34 +162,12 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
uint8_t prefix_len,
uint32_t lifetime_preferred,
uint32_t lifetime_valid) {
sd_radv *radv = link->radv;
int r;
_cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
r = sd_radv_prefix_new(&p);
r = radv_add_prefix(link, prefix, prefix_len, lifetime_preferred, lifetime_valid);
if (r < 0)
return r;
r = sd_radv_prefix_set_prefix(p, prefix, prefix_len);
if (r < 0)
return r;
r = sd_radv_prefix_set_preferred_lifetime(p, lifetime_preferred);
if (r < 0)
return r;
r = sd_radv_prefix_set_valid_lifetime(p, lifetime_valid);
if (r < 0)
return r;
r = sd_radv_stop(radv, false);
if (r < 0)
return r;
r = sd_radv_add_prefix(radv, p, true);
if (r < 0 && r != -EEXIST)
return r;
r = dhcp6_prefix_add(link->manager, prefix, link);
if (r < 0)
return r;
@ -206,7 +178,7 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
return r;
}
return sd_radv_start(radv);
return 0;
}
static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
@ -312,14 +284,11 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link,
if (!dhcp6_get_prefix_delegation(link))
continue;
if (dhcp6_link_has_dhcpv6_prefix(link))
continue;
if (assign_preferred_subnet_id != dhcp6_has_preferred_subnet_id(link))
continue;
r = dhcp6_get_preferred_delegated_prefix(manager, link, &prefix.in6, pd_prefix_len,
&assigned_prefix.in6);
&assigned_prefix.in6);
if (assign_preferred_subnet_id && r == -EAGAIN) {
/* A link has a preferred subnet_id but that one is
@ -1029,20 +998,6 @@ static int dhcp6_prefix_remove_all(Manager *m, Link *link) {
return 0;
}
static bool dhcp6_link_has_dhcpv6_prefix(Link *link) {
Iterator i;
Link *l;
assert(link);
assert(link->manager);
HASHMAP_FOREACH(l, link->manager->dhcp6_prefixes, i)
if (link == l)
return true;
return false;
}
static int dhcp6_assign_delegated_prefix(Link *link,
const struct in6_addr *prefix,
uint8_t prefix_len,

View File

@ -840,7 +840,7 @@ int link_stop_clients(Link *link, bool may_keep_dhcp) {
}
if (link->radv) {
k = sd_radv_stop(link->radv, true);
k = sd_radv_stop(link->radv);
if (k < 0)
r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
}

View File

@ -672,6 +672,37 @@ int radv_configure(Link *link) {
return 0;
}
int radv_add_prefix(Link *link, struct in6_addr *prefix, uint8_t prefix_len,
uint32_t lifetime_preferred, uint32_t lifetime_valid) {
_cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
int r;
assert(link);
assert(link->radv);
r = sd_radv_prefix_new(&p);
if (r < 0)
return r;
r = sd_radv_prefix_set_prefix(p, prefix, prefix_len);
if (r < 0)
return r;
r = sd_radv_prefix_set_preferred_lifetime(p, lifetime_preferred);
if (r < 0)
return r;
r = sd_radv_prefix_set_valid_lifetime(p, lifetime_valid);
if (r < 0)
return r;
r = sd_radv_add_prefix(link->radv, p, true);
if (r < 0 && r != -EEXIST)
return r;
return 0;
}
int config_parse_radv_dns(
const char *unit,
const char *filename,

View File

@ -52,6 +52,8 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(RoutePrefix, route_prefix_free);
int radv_emit_dns(Link *link);
int radv_configure(Link *link);
int radv_add_prefix(Link *link, struct in6_addr *prefix, uint8_t prefix_len,
uint32_t lifetime_preferred, uint32_t lifetime_valid);
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;

View File

@ -39,7 +39,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
};
static int qdisc_new(QDiscKind kind, QDisc **ret) {
QDisc *qdisc;
_cleanup_(qdisc_freep) QDisc *qdisc = NULL;
int r;
if (kind == _QDISC_KIND_INVALID) {

View File

@ -22,7 +22,7 @@ const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
};
static int tclass_new(TClassKind kind, TClass **ret) {
TClass *tclass;
_cleanup_(tclass_freep) TClass *tclass = NULL;
int r;
tclass = malloc0(tclass_vtable[kind]->object_size);

View File

@ -176,7 +176,7 @@ int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret);
int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
/* Low-level, iterative TLV access. This is for evertyhing else, it iteratively goes through all available TLVs
/* Low-level, iterative TLV access. This is for everything else, it iteratively goes through all available TLVs
* (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */
int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n);
int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n);

View File

@ -22,7 +22,6 @@
#include <inttypes.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <sys/types.h>
#include "_sd-common.h"
@ -50,7 +49,7 @@ int sd_radv_detach_event(sd_radv *nd);
sd_event *sd_radv_get_event(sd_radv *ra);
int sd_radv_start(sd_radv *ra);
int sd_radv_stop(sd_radv *ra, bool zero_router_lifetime);
int sd_radv_stop(sd_radv *ra);
int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);

View File

@ -53,6 +53,33 @@ systemctl start testservice-48.service
systemctl is-active testservice-48.service
# Stop and remove, and try again to exercise the transaction setup code path by
# having the target pull in the unloaded but available unit
systemctl stop testservice-48.service testservice-48.target
rm -f /run/systemd/system/testservice-48.service /run/systemd/system/testservice-48.target
systemctl daemon-reload
sleep 3.1
cat > /run/systemd/system/testservice-48.target <<EOF
[Unit]
Conflicts=shutdown.target
Wants=testservice-48.service
EOF
systemctl daemon-reload
systemctl start testservice-48.target
cat > /run/systemd/system/testservice-48.service <<EOF
[Service]
ExecStart=/bin/sleep infinity
EOF
systemctl restart testservice-48.target
systemctl is-active testservice-48.service
echo OK > /testok
exit 0