Compare commits

...

16 Commits

Author SHA1 Message Date
Yu Watanabe 74294ac92b
Merge dda1e98c04 into c946b13575 2024-11-22 21:09:58 +01:00
Christian Hesse c946b13575 link README.logs from tmpfiles.d/legacy.conf only if available
The file README.logs is installed only if SysVInit support is enabled.
Thus the link should depend on it as well.
2024-11-22 18:33:20 +00:00
Lennart Poettering e39cbb1442 varlink: apparently on old kernels SO_PEERPIDFD returns EINVAL 2024-11-23 03:09:49 +09:00
Marco Tomaschett bc4a027f9c
hwdb: add support for PineTab2 to 60-sensor.hwdb (#35304)
Add accelerometer support for PineTab2
2024-11-23 03:08:06 +09:00
Lennart Poettering d209e197f8
userdbctl: two trivial fixlets (#35296)
Fixes: #35294
2024-11-22 16:06:01 +01:00
Antonio Alvarez Feijoo 9ed090230e tpm2-util: fix parameter name 2024-11-22 16:04:16 +01:00
Lennart Poettering 47c5ca237b userdbctl: respect selected disposition also when showing gid boundaries
Follow-up for: ad5de3222f
2024-11-22 11:28:30 +01:00
Lennart Poettering 7f8a4f12df userdbctl: fix counting
Fixes: #35294
2024-11-22 11:28:28 +01:00
Lennart Poettering e412fc5e04 userbdctl: show 'mapped' user range only inside of userns
Outside of userns the concept makes no sense, there cannot be users
mapped from further outside.
2024-11-22 11:28:17 +01:00
Yu Watanabe dda1e98c04 network/nexthop: add one more assertion
This may help issue #35164.
2024-11-21 16:54:26 +09:00
Yu Watanabe 3d417da827 network: introduce address_forget() and friends and use it where applicable
No functional change, just refactoring.
2024-11-21 16:47:36 +09:00
Yu Watanabe 5209f43ad2 network/nexthop: drop outdated comment and add one debugging log
All NextHop objects are managed by Manager since
352eba2e49.
2024-11-21 16:47:36 +09:00
Yu Watanabe a16844ff60 network/ndisc: unref Route objects that depend on the nexthop
No functional change, as when this function is called, the set will be
freed and contained Route objects will be unref()ed anyway soon later
by nexthop_detach() -> nexthop_free().
Even though, when the routes are forgotten from the Manager, then it is
not necessary to keep them by the nexthop. Let's unref earlier.
2024-11-21 16:47:36 +09:00
Yu Watanabe 5344ee6c94 network/ndisc: constify several arguments and add several assertions
Follow-up for 0f8afaf94d.

No functional change, just for safety.
2024-11-21 16:47:36 +09:00
Yu Watanabe 3985e93dab network/nexthop: do not share NextHop.nexthops and NextHop.routes with duplicated object
Otherwise, these may be freed twice.
But, fortunately, when this function is called, both are NULL.
So, this should not change any behavior. But for safety.
2024-11-21 16:47:36 +09:00
Yu Watanabe c6f6f506fc network: drop outdated comment
All Route objects are managed by Manager since
8d01e44c1f.
2024-11-21 16:47:36 +09:00
12 changed files with 218 additions and 179 deletions

View File

@ -953,6 +953,15 @@ sensor:modalias:acpi:MXC6655*:dmi:*:svnDefaultstring*:pnP612F:*
sensor:modalias:acpi:SMO8500*:dmi:*:svnPEAQ:pnPEAQPMMC1010MD99187:* sensor:modalias:acpi:SMO8500*:dmi:*:svnPEAQ:pnPEAQPMMC1010MD99187:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
#########################################
# Pine64
#########################################
# PineTab2
sensor:modalias:of:NaccelerometerT_null_Csilan,sc7a20:*
ACCEL_MOUNT_MATRIX=0, 0, -1; 1, 0, 0; 0, -1, 0
######################################### #########################################
# Pipo # Pipo
######################################### #########################################

View File

@ -16,7 +16,7 @@ int varlink_get_peer_pidref(sd_varlink *v, PidRef *ret) {
int pidfd = sd_varlink_get_peer_pidfd(v); int pidfd = sd_varlink_get_peer_pidfd(v);
if (pidfd < 0) { if (pidfd < 0) {
if (!ERRNO_IS_NEG_NOT_SUPPORTED(pidfd)) if (!ERRNO_IS_NEG_NOT_SUPPORTED(pidfd) && pidfd != -EINVAL)
return pidfd; return pidfd;
pid_t pid; pid_t pid;

View File

@ -1129,6 +1129,23 @@ void log_address_debug(const Address *address, const char *str, const Link *link
address->family == AF_INET ? strna(address->label) : ""); address->family == AF_INET ? strna(address->label) : "");
} }
static void address_forget(Link *link, Address *address, bool removed_by_us, const char *msg) {
assert(link);
assert(address);
assert(msg);
Request *req;
if (address_get_request(link, address, &req) >= 0)
address_enter_removed(req->userdata);
if (!address->link && address_get(link, address, &address) < 0)
return;
address_enter_removed(address);
log_address_debug(address, msg, link);
(void) address_drop(address, removed_by_us);
}
static int address_set_netlink_message(const Address *address, sd_netlink_message *m, Link *link) { static int address_set_netlink_message(const Address *address, sd_netlink_message *m, Link *link) {
uint32_t flags; uint32_t flags;
int r; int r;
@ -1181,16 +1198,8 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remov
(r == -EADDRNOTAVAIL || !address->link) ? LOG_DEBUG : LOG_WARNING, (r == -EADDRNOTAVAIL || !address->link) ? LOG_DEBUG : LOG_WARNING,
r, "Could not drop address"); r, "Could not drop address");
if (address->link) {
/* If the address cannot be removed, then assume the address is already removed. */ /* If the address cannot be removed, then assume the address is already removed. */
log_address_debug(address, "Forgetting", link); address_forget(link, address, /* removed_by_us = */ true, "Forgetting");
Request *req;
if (address_get_request(link, address, &req) >= 0)
address_enter_removed(req->userdata);
(void) address_drop(address, /* removed_by_us = */ true);
}
} }
return 1; return 1;
@ -1775,14 +1784,7 @@ int link_request_static_addresses(Link *link) {
} }
int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
_cleanup_(address_unrefp) Address *tmp = NULL; int r;
struct ifa_cacheinfo cinfo;
Link *link;
uint16_t type;
Address *address = NULL;
Request *req = NULL;
bool is_new = false, update_dhcp4;
int ifindex, r;
assert(rtnl); assert(rtnl);
assert(message); assert(message);
@ -1796,6 +1798,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
uint16_t type;
r = sd_netlink_message_get_type(message, &type); r = sd_netlink_message_get_type(message, &type);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@ -1805,6 +1808,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
int ifindex;
r = sd_rtnl_message_addr_get_ifindex(message, &ifindex); r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m"); log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
@ -1814,6 +1818,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
Link *link;
r = link_get_by_index(m, ifindex, &link); r = link_get_by_index(m, ifindex, &link);
if (r < 0) { if (r < 0) {
/* when enumerating we might be out of sync, but we will get the address again, so just /* when enumerating we might be out of sync, but we will get the address again, so just
@ -1823,6 +1828,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
_cleanup_(address_unrefp) Address *tmp = NULL;
r = address_new(&tmp); r = address_new(&tmp);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -1890,28 +1896,22 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
assert_not_reached(); assert_not_reached();
} }
update_dhcp4 = tmp->family == AF_INET6; /* Then, find the managed Address object corresponding to the received address. */
Address *address = NULL;
/* Then, find the managed Address and Request objects corresponding to the received address. */
(void) address_get(link, tmp, &address); (void) address_get(link, tmp, &address);
(void) address_get_request(link, tmp, &req);
if (type == RTM_DELADDR) { if (type == RTM_DELADDR) {
if (address) { if (address)
bool removed_by_us = FLAGS_SET(address->state, NETWORK_CONFIG_STATE_REMOVING); address_forget(link, address,
/* removed_by_us = */ FLAGS_SET(address->state, NETWORK_CONFIG_STATE_REMOVING),
address_enter_removed(address); "Forgetting removed");
log_address_debug(address, "Forgetting removed", link); else
(void) address_drop(address, removed_by_us);
} else
log_address_debug(tmp, "Kernel removed unknown", link); log_address_debug(tmp, "Kernel removed unknown", link);
if (req)
address_enter_removed(req->userdata);
goto finalize; goto finalize;
} }
bool is_new = false;
if (!address) { if (!address) {
/* If we did not know the address, then save it. */ /* If we did not know the address, then save it. */
r = address_attach(link, tmp); r = address_attach(link, tmp);
@ -1931,6 +1931,8 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
} }
/* Also update information that cannot be obtained through netlink notification. */ /* Also update information that cannot be obtained through netlink notification. */
Request *req = NULL;
(void) address_get_request(link, tmp, &req);
if (req && req->waiting_reply) { if (req && req->waiting_reply) {
Address *a = ASSERT_PTR(req->userdata); Address *a = ASSERT_PTR(req->userdata);
@ -1978,6 +1980,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
} else if (r < 0) } else if (r < 0)
log_link_debug_errno(link, r, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m"); log_link_debug_errno(link, r, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m");
struct ifa_cacheinfo cinfo;
r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo); r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
if (r >= 0) if (r >= 0)
address_set_lifetime(m, address, &cinfo); address_set_lifetime(m, address, &cinfo);
@ -2000,7 +2003,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
link_enter_failed(link); link_enter_failed(link);
finalize: finalize:
if (update_dhcp4) { if (tmp->family == AF_INET6) {
r = dhcp4_update_ipv6_connectivity(link); r = dhcp4_update_ipv6_connectivity(link);
if (r < 0) { if (r < 0) {
log_link_warning_errno(link, r, "Failed to notify IPv6 connectivity to DHCPv4 client: %m"); log_link_warning_errno(link, r, "Failed to notify IPv6 connectivity to DHCPv4 client: %m");

View File

@ -705,10 +705,6 @@ Manager* manager_free(Manager *m) {
sd_netlink_unref(m->genl); sd_netlink_unref(m->genl);
sd_resolve_unref(m->resolve); sd_resolve_unref(m->resolve);
/* reject (e.g. unreachable) type routes are managed by Manager, but may be referenced by a
* link. E.g., DHCP6 with prefix delegation creates unreachable routes, and they are referenced
* by the upstream link. And the links may be referenced by netlink slots. Hence, two
* set_free() must be called after the above sd_netlink_unref(). */
m->routes = set_free(m->routes); m->routes = set_free(m->routes);
m->nexthops_by_id = hashmap_free(m->nexthops_by_id); m->nexthops_by_id = hashmap_free(m->nexthops_by_id);

View File

@ -215,7 +215,7 @@ static int ndisc_remove_unused_nexthops(Link *link) {
#define NDISC_NEXTHOP_APP_ID SD_ID128_MAKE(76,d2,0f,1f,76,1e,44,d1,97,3a,52,5c,05,68,b5,0d) #define NDISC_NEXTHOP_APP_ID SD_ID128_MAKE(76,d2,0f,1f,76,1e,44,d1,97,3a,52,5c,05,68,b5,0d)
static uint32_t ndisc_generate_nexthop_id(NextHop *nexthop, Link *link, sd_id128_t app_id, uint64_t trial) { static uint32_t ndisc_generate_nexthop_id(const NextHop *nexthop, Link *link, sd_id128_t app_id, uint64_t trial) {
assert(nexthop); assert(nexthop);
assert(link); assert(link);
@ -232,7 +232,7 @@ static uint32_t ndisc_generate_nexthop_id(NextHop *nexthop, Link *link, sd_id128
return (uint32_t) ((result & 0xffffffff) ^ (result >> 32)); return (uint32_t) ((result & 0xffffffff) ^ (result >> 32));
} }
static bool ndisc_nexthop_equal(NextHop *a, NextHop *b) { static bool ndisc_nexthop_equal(const NextHop *a, const NextHop *b) {
assert(a); assert(a);
assert(b); assert(b);
@ -250,9 +250,11 @@ static bool ndisc_nexthop_equal(NextHop *a, NextHop *b) {
return true; return true;
} }
static bool ndisc_take_nexthop_id(NextHop *nexthop, NextHop *existing, Manager *manager) { static bool ndisc_take_nexthop_id(NextHop *nexthop, const NextHop *existing, Manager *manager) {
assert(nexthop); assert(nexthop);
assert(nexthop->id == 0);
assert(existing); assert(existing);
assert(existing->id > 0);
assert(manager); assert(manager);
if (!ndisc_nexthop_equal(nexthop, existing)) if (!ndisc_nexthop_equal(nexthop, existing))
@ -300,7 +302,7 @@ static int ndisc_nexthop_find_id(NextHop *nexthop, Link *link) {
return false; return false;
} }
static int ndisc_nexthop_new(Route *route, Link *link, NextHop **ret) { static int ndisc_nexthop_new(const Route *route, Link *link, NextHop **ret) {
_cleanup_(nexthop_unrefp) NextHop *nexthop = NULL; _cleanup_(nexthop_unrefp) NextHop *nexthop = NULL;
int r; int r;

View File

@ -247,6 +247,23 @@ static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const
IN_ADDR_TO_STRING(neighbor->dst_addr.family, &neighbor->dst_addr.address)); IN_ADDR_TO_STRING(neighbor->dst_addr.family, &neighbor->dst_addr.address));
} }
static void neighbor_forget(Link *link, Neighbor *neighbor, const char *msg) {
assert(link);
assert(neighbor);
assert(msg);
Request *req;
if (neighbor_get_request(link, neighbor, &req) >= 0)
neighbor_enter_removed(req->userdata);
if (!neighbor->link && neighbor_get(link, neighbor, &neighbor) < 0)
return;
neighbor_enter_removed(neighbor);
log_neighbor_debug(neighbor, "Forgetting", link);
neighbor_detach(neighbor);
}
static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) { static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r; int r;
@ -421,16 +438,8 @@ static int neighbor_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remo
(r == -ESRCH || !neighbor->link) ? LOG_DEBUG : LOG_WARNING, (r == -ESRCH || !neighbor->link) ? LOG_DEBUG : LOG_WARNING,
r, "Could not remove neighbor"); r, "Could not remove neighbor");
if (neighbor->link) {
/* If the neighbor cannot be removed, then assume the neighbor is already removed. */ /* If the neighbor cannot be removed, then assume the neighbor is already removed. */
log_neighbor_debug(neighbor, "Forgetting", link); neighbor_forget(link, neighbor, "Forgetting");
Request *req;
if (neighbor_get_request(link, neighbor, &req) >= 0)
neighbor_enter_removed(req->userdata);
neighbor_detach(neighbor);
}
} }
return 1; return 1;
@ -529,13 +538,7 @@ int link_drop_static_neighbors(Link *link) {
} }
int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
_cleanup_(neighbor_unrefp) Neighbor *tmp = NULL; int r;
Neighbor *neighbor = NULL;
Request *req = NULL;
uint16_t type, state;
bool is_new = false;
int ifindex, r;
Link *link;
assert(rtnl); assert(rtnl);
assert(message); assert(message);
@ -549,6 +552,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
uint16_t type;
r = sd_netlink_message_get_type(message, &type); r = sd_netlink_message_get_type(message, &type);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@ -558,6 +562,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
uint16_t state;
r = sd_rtnl_message_neigh_get_state(message, &state); r = sd_rtnl_message_neigh_get_state(message, &state);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: received neighbor message with invalid state, ignoring: %m"); log_warning_errno(r, "rtnl: received neighbor message with invalid state, ignoring: %m");
@ -566,6 +571,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
/* Currently, we are interested in only static neighbors. */ /* Currently, we are interested in only static neighbors. */
return 0; return 0;
int ifindex;
r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex); r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m"); log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
@ -575,12 +581,14 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
Link *link;
r = link_get_by_index(m, ifindex, &link); r = link_get_by_index(m, ifindex, &link);
if (r < 0) if (r < 0)
/* when enumerating we might be out of sync, but we will get the neighbor again. Also, /* when enumerating we might be out of sync, but we will get the neighbor again. Also,
* kernel sends messages about neighbors after a link is removed. So, just ignore it. */ * kernel sends messages about neighbors after a link is removed. So, just ignore it. */
return 0; return 0;
_cleanup_(neighbor_unrefp) Neighbor *tmp = NULL;
r = neighbor_new(&tmp); r = neighbor_new(&tmp);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -604,25 +612,20 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
/* Then, find the managed Neighbor and Request objects corresponding to the netlink notification. */ /* Then, find the managed Neighbor object corresponding to the netlink notification. */
Neighbor *neighbor = NULL;
(void) neighbor_get(link, tmp, &neighbor); (void) neighbor_get(link, tmp, &neighbor);
(void) neighbor_get_request(link, tmp, &req);
if (type == RTM_DELNEIGH) { if (type == RTM_DELNEIGH) {
if (neighbor) { if (neighbor)
neighbor_enter_removed(neighbor); neighbor_forget(link, neighbor, "Forgetting removed");
log_neighbor_debug(neighbor, "Forgetting removed", link); else
neighbor_detach(neighbor);
} else
log_neighbor_debug(tmp, "Kernel removed unknown", link); log_neighbor_debug(tmp, "Kernel removed unknown", link);
if (req)
neighbor_enter_removed(req->userdata);
return 0; return 0;
} }
/* If we did not know the neighbor, then save it. */ /* If we did not know the neighbor, then save it. */
bool is_new = false;
if (!neighbor) { if (!neighbor) {
r = neighbor_attach(link, tmp); r = neighbor_attach(link, tmp);
if (r < 0) { if (r < 0) {
@ -634,6 +637,8 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
} }
/* Also update information that cannot be obtained through netlink notification. */ /* Also update information that cannot be obtained through netlink notification. */
Request *req = NULL;
(void) neighbor_get_request(link, tmp, &req);
if (req && req->waiting_reply) { if (req && req->waiting_reply) {
Neighbor *n = ASSERT_PTR(req->userdata); Neighbor *n = ASSERT_PTR(req->userdata);

View File

@ -78,7 +78,9 @@ static NextHop* nexthop_detach_impl(NextHop *nexthop) {
nexthop_detach_from_group_members(nexthop); nexthop_detach_from_group_members(nexthop);
hashmap_remove(nexthop->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id)); NextHop *n;
n = hashmap_remove(nexthop->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id));
assert(!n || n == nexthop);
nexthop->manager = NULL; nexthop->manager = NULL;
return nexthop; return nexthop;
} }
@ -261,6 +263,8 @@ static int nexthop_dup(const NextHop *src, NextHop **ret) {
dest->network = NULL; dest->network = NULL;
dest->section = NULL; dest->section = NULL;
dest->group = NULL; dest->group = NULL;
dest->nexthops = NULL;
dest->routes = NULL;
HASHMAP_FOREACH(nhg, src->group) { HASHMAP_FOREACH(nhg, src->group) {
_cleanup_free_ struct nexthop_grp *g = NULL; _cleanup_free_ struct nexthop_grp *g = NULL;
@ -491,8 +495,11 @@ static void nexthop_forget_dependents(NextHop *nexthop, Manager *manager) {
/* If a nexthop is removed, the kernel silently removes routes that depend on the removed nexthop. /* If a nexthop is removed, the kernel silently removes routes that depend on the removed nexthop.
* Let's forget them. */ * Let's forget them. */
Route *route; for (;;) {
SET_FOREACH(route, nexthop->routes) { _cleanup_(route_unrefp) Route *route = set_steal_first(nexthop->routes);
if (!route)
break;
Request *req; Request *req;
if (route_get_request(manager, route, &req) >= 0) if (route_get_request(manager, route, &req) >= 0)
route_enter_removed(req->userdata); route_enter_removed(req->userdata);
@ -501,6 +508,26 @@ static void nexthop_forget_dependents(NextHop *nexthop, Manager *manager) {
log_route_debug(route, "Forgetting silently removed", manager); log_route_debug(route, "Forgetting silently removed", manager);
route_detach(route); route_detach(route);
} }
nexthop->routes = set_free(nexthop->routes);
}
static void nexthop_forget(Manager *manager, NextHop *nexthop, const char *msg) {
assert(manager);
assert(nexthop);
assert(msg);
Request *req;
if (nexthop_get_request_by_id(manager, nexthop->id, &req) >= 0)
nexthop_enter_removed(req->userdata);
if (!nexthop->manager && nexthop_get_by_id(manager, nexthop->id, &nexthop) < 0)
return;
nexthop_enter_removed(nexthop);
log_nexthop_debug(nexthop, msg, manager);
nexthop_forget_dependents(nexthop, nexthop->manager);
nexthop_detach(nexthop);
} }
static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveRequest *rreq) { static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveRequest *rreq) {
@ -518,18 +545,8 @@ static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remov
(r == -ENOENT || !nexthop->manager) ? LOG_DEBUG : LOG_WARNING, (r == -ENOENT || !nexthop->manager) ? LOG_DEBUG : LOG_WARNING,
r, "Could not drop nexthop, ignoring"); r, "Could not drop nexthop, ignoring");
nexthop_forget_dependents(nexthop, manager);
if (nexthop->manager) {
/* If the nexthop cannot be removed, then assume the nexthop is already removed. */ /* If the nexthop cannot be removed, then assume the nexthop is already removed. */
log_nexthop_debug(nexthop, "Forgetting", manager); nexthop_forget(manager, nexthop, "Forgetting");
Request *req;
if (nexthop_get_request_by_id(manager, nexthop->id, &req) >= 0)
nexthop_enter_removed(req->userdata);
nexthop_detach(nexthop);
}
} }
return 1; return 1;
@ -962,20 +979,6 @@ int link_drop_nexthops(Link *link, bool only_static) {
return r; return r;
} }
static void nexthop_forget_one(NextHop *nexthop) {
assert(nexthop);
assert(nexthop->manager);
Request *req;
if (nexthop_get_request_by_id(nexthop->manager, nexthop->id, &req) >= 0)
nexthop_enter_removed(req->userdata);
nexthop_enter_removed(nexthop);
log_nexthop_debug(nexthop, "Forgetting silently removed", nexthop->manager);
nexthop_forget_dependents(nexthop, nexthop->manager);
nexthop_detach(nexthop);
}
void link_forget_nexthops(Link *link) { void link_forget_nexthops(Link *link) {
assert(link); assert(link);
assert(link->manager); assert(link->manager);
@ -992,7 +995,7 @@ void link_forget_nexthops(Link *link) {
if (nexthop->family != AF_INET) if (nexthop->family != AF_INET)
continue; continue;
nexthop_forget_one(nexthop); nexthop_forget(link->manager, nexthop, "Forgetting silently removed");
} }
/* Remove all group nexthops their all members are removed in the above. */ /* Remove all group nexthops their all members are removed in the above. */
@ -1013,7 +1016,7 @@ void link_forget_nexthops(Link *link) {
if (!hashmap_isempty(nexthop->group)) if (!hashmap_isempty(nexthop->group))
continue; /* At least one group member still exists. */ continue; /* At least one group member still exists. */
nexthop_forget_one(nexthop); nexthop_forget(link->manager, nexthop, "Forgetting silently removed");
} }
} }
@ -1077,11 +1080,6 @@ static int nexthop_update_group(NextHop *nexthop, sd_netlink_message *message) {
} }
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
uint16_t type;
uint32_t id, ifindex;
NextHop *nexthop = NULL;
Request *req = NULL;
bool is_new = false;
int r; int r;
assert(rtnl); assert(rtnl);
@ -1096,6 +1094,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
uint16_t type;
r = sd_netlink_message_get_type(message, &type); r = sd_netlink_message_get_type(message, &type);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@ -1105,6 +1104,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
uint32_t id;
r = sd_netlink_message_read_u32(message, NHA_ID, &id); r = sd_netlink_message_read_u32(message, NHA_ID, &id);
if (r == -ENODATA) { if (r == -ENODATA) {
log_warning_errno(r, "rtnl: received nexthop message without NHA_ID attribute, ignoring: %m"); log_warning_errno(r, "rtnl: received nexthop message without NHA_ID attribute, ignoring: %m");
@ -1117,25 +1117,20 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
return 0; return 0;
} }
NextHop *nexthop = NULL;
(void) nexthop_get_by_id(m, id, &nexthop); (void) nexthop_get_by_id(m, id, &nexthop);
(void) nexthop_get_request_by_id(m, id, &req);
if (type == RTM_DELNEXTHOP) { if (type == RTM_DELNEXTHOP) {
if (nexthop) { if (nexthop)
nexthop_enter_removed(nexthop); nexthop_forget(m, nexthop, "Forgetting removed");
log_nexthop_debug(nexthop, "Forgetting removed", m); else
nexthop_forget_dependents(nexthop, m);
nexthop_detach(nexthop);
} else
log_nexthop_debug(&(const NextHop) { .id = id }, "Kernel removed unknown", m); log_nexthop_debug(&(const NextHop) { .id = id }, "Kernel removed unknown", m);
if (req)
nexthop_enter_removed(req->userdata);
return 0; return 0;
} }
/* If we did not know the nexthop, then save it. */ /* If we did not know the nexthop, then save it. */
bool is_new = false;
if (!nexthop) { if (!nexthop) {
r = nexthop_add_new(m, id, &nexthop); r = nexthop_add_new(m, id, &nexthop);
if (r < 0) { if (r < 0) {
@ -1147,6 +1142,8 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
} }
/* Also update information that cannot be obtained through netlink notification. */ /* Also update information that cannot be obtained through netlink notification. */
Request *req = NULL;
(void) nexthop_get_request_by_id(m, id, &req);
if (req && req->waiting_reply) { if (req && req->waiting_reply) {
NextHop *n = ASSERT_PTR(req->userdata); NextHop *n = ASSERT_PTR(req->userdata);
@ -1182,6 +1179,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
else else
nexthop->blackhole = r; nexthop->blackhole = r;
uint32_t ifindex;
r = sd_netlink_message_read_u32(message, NHA_OIF, &ifindex); r = sd_netlink_message_read_u32(message, NHA_OIF, &ifindex);
if (r == -ENODATA) if (r == -ENODATA)
nexthop->ifindex = 0; nexthop->ifindex = 0;
@ -1192,10 +1190,12 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
else else
nexthop->ifindex = (int) ifindex; nexthop->ifindex = (int) ifindex;
/* All blackhole or group nexthops are managed by Manager. Note that the linux kernel does not /* The linux kernel does not set NHA_OID attribute when NHA_BLACKHOLE or NHA_GROUP is set.
* set NHA_OID attribute when NHA_BLACKHOLE or NHA_GROUP is set. Just for safety. */ * But let's check that for safety. */
if (!nexthop_bound_to_link(nexthop)) if (!nexthop_bound_to_link(nexthop) && nexthop->ifindex != 0) {
log_debug("rtnl: received blackhole or group nexthop with NHA_OIF attribute, ignoring the attribute.");
nexthop->ifindex = 0; nexthop->ifindex = 0;
}
nexthop_enter_configured(nexthop); nexthop_enter_configured(nexthop);
if (req) if (req)

View File

@ -460,6 +460,23 @@ void log_route_debug(const Route *route, const char *str, Manager *manager) {
strna(proto), strna(scope), strna(route_type_to_string(route->type)), strna(flags)); strna(proto), strna(scope), strna(route_type_to_string(route->type)), strna(flags));
} }
static void route_forget(Manager *manager, Route *route, const char *msg) {
assert(manager);
assert(route);
assert(msg);
Request *req;
if (route_get_request(manager, route, &req) >= 0)
route_enter_removed(req->userdata);
if (!route->manager && route_get(manager, route, &route) < 0)
return;
route_enter_removed(route);
log_route_debug(route, msg, manager);
route_detach(route);
}
static int route_set_netlink_message(const Route *route, sd_netlink_message *m) { static int route_set_netlink_message(const Route *route, sd_netlink_message *m) {
int r; int r;
@ -564,16 +581,8 @@ static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveR
LOG_DEBUG : LOG_WARNING, LOG_DEBUG : LOG_WARNING,
r, "Could not drop route, ignoring"); r, "Could not drop route, ignoring");
if (route->manager) {
/* If the route cannot be removed, then assume the route is already removed. */ /* If the route cannot be removed, then assume the route is already removed. */
log_route_debug(route, "Forgetting", manager); route_forget(manager, route, "Forgetting");
Request *req;
if (route_get_request(manager, route, &req) >= 0)
route_enter_removed(req->userdata);
route_detach(route);
}
} }
return 1; return 1;
@ -1088,7 +1097,6 @@ static int process_route_one(
Route *tmp, Route *tmp,
const struct rta_cacheinfo *cacheinfo) { const struct rta_cacheinfo *cacheinfo) {
Request *req = NULL;
Route *route = NULL; Route *route = NULL;
Link *link = NULL; Link *link = NULL;
bool is_new = false, update_dhcp4; bool is_new = false, update_dhcp4;
@ -1099,13 +1107,15 @@ static int process_route_one(
assert(IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)); assert(IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE));
(void) route_get(manager, tmp, &route); (void) route_get(manager, tmp, &route);
(void) route_get_request(manager, tmp, &req);
(void) route_get_link(manager, tmp, &link); (void) route_get_link(manager, tmp, &link);
update_dhcp4 = link && tmp->family == AF_INET6 && tmp->dst_prefixlen == 0; update_dhcp4 = link && tmp->family == AF_INET6 && tmp->dst_prefixlen == 0;
switch (type) { switch (type) {
case RTM_NEWROUTE: case RTM_NEWROUTE: {
Request *req = NULL;
(void) route_get_request(manager, tmp, &req);
if (!route) { if (!route) {
if (!manager->manage_foreign_routes && !(req && req->waiting_reply)) { if (!manager->manage_foreign_routes && !(req && req->waiting_reply)) {
route_enter_configured(tmp); route_enter_configured(tmp);
@ -1159,20 +1169,14 @@ static int process_route_one(
(void) route_setup_timer(route, cacheinfo); (void) route_setup_timer(route, cacheinfo);
break; break;
}
case RTM_DELROUTE: case RTM_DELROUTE:
if (route) { if (route)
route_enter_removed(route); route_forget(manager, route, "Forgetting removed");
log_route_debug(route, "Forgetting removed", manager); else
route_detach(route);
} else
log_route_debug(tmp, log_route_debug(tmp,
manager->manage_foreign_routes ? "Kernel removed unknown" : "Ignoring received", manager->manage_foreign_routes ? "Kernel removed unknown" : "Ignoring received",
manager); manager);
if (req)
route_enter_removed(req->userdata);
break; break;
default: default:
@ -1574,13 +1578,7 @@ void link_forget_routes(Link *link) {
if (!IN_SET(route->type, RTN_UNICAST, RTN_BROADCAST, RTN_ANYCAST, RTN_MULTICAST)) if (!IN_SET(route->type, RTN_UNICAST, RTN_BROADCAST, RTN_ANYCAST, RTN_MULTICAST))
continue; continue;
Request *req; route_forget(link->manager, route, "Forgetting silently removed");
if (route_get_request(link->manager, route, &req) >= 0)
route_enter_removed(req->userdata);
route_enter_removed(route);
log_route_debug(route, "Forgetting silently removed", link->manager);
route_detach(route);
} }
} }

View File

@ -550,6 +550,23 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const c
strna(rule->iif), strna(rule->oif), strna(table)); strna(rule->iif), strna(rule->oif), strna(table));
} }
static void routing_policy_rule_forget(Manager *manager, RoutingPolicyRule *rule, const char *msg) {
assert(manager);
assert(rule);
assert(msg);
Request *req;
if (routing_policy_rule_get_request(manager, rule, rule->family, &req) >= 0)
routing_policy_rule_enter_removed(req->userdata);
if (!rule->manager && routing_policy_rule_get(manager, rule, rule->family, &rule) < 0)
return;
routing_policy_rule_enter_removed(rule);
log_routing_policy_rule_debug(rule, "Forgetting", NULL, manager);
routing_policy_rule_detach(rule);
}
static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule, sd_netlink_message *m) { static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule, sd_netlink_message *m) {
int r; int r;
@ -708,16 +725,8 @@ static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_messa
(r == -ENOENT || !rule->manager) ? LOG_DEBUG : LOG_WARNING, (r == -ENOENT || !rule->manager) ? LOG_DEBUG : LOG_WARNING,
r, "Could not drop routing policy rule, ignoring"); r, "Could not drop routing policy rule, ignoring");
if (rule->manager) {
/* If the rule cannot be removed, then assume the rule is already removed. */ /* If the rule cannot be removed, then assume the rule is already removed. */
log_routing_policy_rule_debug(rule, "Forgetting", NULL, manager); routing_policy_rule_forget(manager, rule, "Forgetting");
Request *req;
if (routing_policy_rule_get_request(manager, rule, rule->family, &req) >= 0)
routing_policy_rule_enter_removed(req->userdata);
routing_policy_rule_detach(rule);
}
} }
return 1; return 1;
@ -1046,10 +1055,6 @@ static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *ru
} }
int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
_cleanup_(routing_policy_rule_unrefp) RoutingPolicyRule *tmp = NULL;
RoutingPolicyRule *rule = NULL;
Request *req = NULL;
uint16_t type;
int r; int r;
assert(rtnl); assert(rtnl);
@ -1063,6 +1068,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
return 0; return 0;
} }
uint16_t type;
r = sd_netlink_message_get_type(message, &type); r = sd_netlink_message_get_type(message, &type);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@ -1072,6 +1078,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
return 0; return 0;
} }
_cleanup_(routing_policy_rule_unrefp) RoutingPolicyRule *tmp = NULL;
r = routing_policy_rule_new(&tmp); r = routing_policy_rule_new(&tmp);
if (r < 0) { if (r < 0) {
log_oom(); log_oom();
@ -1240,23 +1247,20 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
return 0; return 0;
} }
RoutingPolicyRule *rule = NULL;
(void) routing_policy_rule_get(m, tmp, tmp->family, &rule); (void) routing_policy_rule_get(m, tmp, tmp->family, &rule);
(void) routing_policy_rule_get_request(m, tmp, tmp->family, &req);
if (type == RTM_DELRULE) { if (type == RTM_DELRULE) {
if (rule) { if (rule)
routing_policy_rule_enter_removed(rule); routing_policy_rule_forget(m, rule, "Forgetting removed");
log_routing_policy_rule_debug(rule, "Forgetting removed", NULL, m); else
routing_policy_rule_detach(rule);
} else
log_routing_policy_rule_debug(tmp, "Kernel removed unknown", NULL, m); log_routing_policy_rule_debug(tmp, "Kernel removed unknown", NULL, m);
if (req)
routing_policy_rule_enter_removed(req->userdata);
return 0; return 0;
} }
Request *req = NULL;
(void) routing_policy_rule_get_request(m, tmp, tmp->family, &req);
bool is_new = false; bool is_new = false;
if (!rule) { if (!rule) {
if (!req && !m->manage_foreign_rules) { if (!req && !m->manage_foreign_rules) {

View File

@ -392,7 +392,7 @@ int tpm2_make_pcr_json_array(uint32_t pcr_mask, sd_json_variant **ret);
int tpm2_parse_pcr_json_array(sd_json_variant *v, uint32_t *ret); int tpm2_parse_pcr_json_array(sd_json_variant *v, uint32_t *ret);
int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, const struct iovec *pubkey, uint32_t pubkey_pcr_mask, uint16_t primary_alg, const struct iovec blobs[], size_t n_blobs, const struct iovec policy_hash[], size_t n_policy_hash, const struct iovec *salt, const struct iovec *srk, const struct iovec *pcrlock_nv, TPM2Flags flags, sd_json_variant **ret); int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, const struct iovec *pubkey, uint32_t pubkey_pcr_mask, uint16_t primary_alg, const struct iovec blobs[], size_t n_blobs, const struct iovec policy_hash[], size_t n_policy_hash, const struct iovec *salt, const struct iovec *srk, const struct iovec *pcrlock_nv, TPM2Flags flags, sd_json_variant **ret);
int tpm2_parse_luks2_json(sd_json_variant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, struct iovec *ret_pubkey, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, struct iovec **ret_blobs, size_t *ret_n_blobs, struct iovec **ret_policy_hash, size_t *ret_n_policy_hash, struct iovec *ret_salt, struct iovec *ret_srk, struct iovec *pcrlock_nv, TPM2Flags *ret_flags); int tpm2_parse_luks2_json(sd_json_variant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, struct iovec *ret_pubkey, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, struct iovec **ret_blobs, size_t *ret_n_blobs, struct iovec **ret_policy_hash, size_t *ret_n_policy_hash, struct iovec *ret_salt, struct iovec *ret_srk, struct iovec *ret_pcrlock_nv, TPM2Flags *ret_flags);
/* Default to PCR 7 only */ /* Default to PCR 7 only */
#define TPM2_PCR_INDEX_DEFAULT UINT32_C(7) #define TPM2_PCR_INDEX_DEFAULT UINT32_C(7)

View File

@ -23,6 +23,7 @@
#include "user-util.h" #include "user-util.h"
#include "userdb.h" #include "userdb.h"
#include "verbs.h" #include "verbs.h"
#include "virt.h"
static enum { static enum {
OUTPUT_CLASSIC, OUTPUT_CLASSIC,
@ -139,10 +140,16 @@ static int show_user(UserRecord *ur, Table *table) {
return 0; return 0;
} }
static bool test_show_mapped(void) {
/* Show mapped user range only in environments where user mapping is a thing. */
return running_in_userns() > 0;
}
static const struct { static const struct {
uid_t first, last; uid_t first, last;
const char *name; const char *name;
UserDisposition disposition; UserDisposition disposition;
bool (*test)(void);
} uid_range_table[] = { } uid_range_table[] = {
{ {
.first = 1, .first = 1,
@ -175,11 +182,12 @@ static const struct {
.last = MAP_UID_MAX, .last = MAP_UID_MAX,
.name = "mapped", .name = "mapped",
.disposition = USER_REGULAR, .disposition = USER_REGULAR,
.test = test_show_mapped,
}, },
}; };
static int table_add_uid_boundaries(Table *table, const UIDRange *p) { static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
int r; int r, n_added = 0;
assert(table); assert(table);
@ -192,6 +200,9 @@ static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
if (!uid_range_covers(p, i->first, i->last - i->first + 1)) if (!uid_range_covers(p, i->first, i->last - i->first + 1))
continue; continue;
if (i->test && !i->test())
continue;
name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN),
" begin ", i->name, " users ", " begin ", i->name, " users ",
special_glyph(SPECIAL_GLYPH_ARROW_DOWN)); special_glyph(SPECIAL_GLYPH_ARROW_DOWN));
@ -249,9 +260,11 @@ static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
TABLE_INT, 1); /* sort after any other entry with the same UID */ TABLE_INT, 1); /* sort after any other entry with the same UID */
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
n_added += 2;
} }
return ELEMENTSOF(uid_range_table) * 2; return n_added;
} }
static int add_unavailable_uid(Table *table, uid_t start, uid_t end) { static int add_unavailable_uid(Table *table, uid_t start, uid_t end) {
@ -565,16 +578,22 @@ static int show_group(GroupRecord *gr, Table *table) {
} }
static int table_add_gid_boundaries(Table *table, const UIDRange *p) { static int table_add_gid_boundaries(Table *table, const UIDRange *p) {
int r; int r, n_added = 0;
assert(table); assert(table);
FOREACH_ELEMENT(i, uid_range_table) { FOREACH_ELEMENT(i, uid_range_table) {
_cleanup_free_ char *name = NULL, *comment = NULL; _cleanup_free_ char *name = NULL, *comment = NULL;
if (!FLAGS_SET(arg_disposition_mask, UINT64_C(1) << i->disposition))
continue;
if (!uid_range_covers(p, i->first, i->last - i->first + 1)) if (!uid_range_covers(p, i->first, i->last - i->first + 1))
continue; continue;
if (i->test && !i->test())
continue;
name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN),
" begin ", i->name, " groups ", " begin ", i->name, " groups ",
special_glyph(SPECIAL_GLYPH_ARROW_DOWN)); special_glyph(SPECIAL_GLYPH_ARROW_DOWN));
@ -626,9 +645,11 @@ static int table_add_gid_boundaries(Table *table, const UIDRange *p) {
TABLE_INT, 1); /* sort after any other entry with the same GID */ TABLE_INT, 1); /* sort after any other entry with the same GID */
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
n_added += 2;
} }
return ELEMENTSOF(uid_range_table) * 2; return n_added;
} }
static int add_unavailable_gid(Table *table, uid_t start, uid_t end) { static int add_unavailable_gid(Table *table, uid_t start, uid_t end) {

View File

@ -13,11 +13,12 @@
d /run/lock 0755 root root - d /run/lock 0755 root root -
L /var/lock - - - - ../run/lock L /var/lock - - - - ../run/lock
{% if HAVE_SYSV_COMPAT %}
{% if CREATE_LOG_DIRS %} {% if CREATE_LOG_DIRS %}
L$ /var/log/README - - - - ../..{{DOC_DIR}}/README.logs L$ /var/log/README - - - - ../..{{DOC_DIR}}/README.logs
{% endif %} {% endif %}
{% if HAVE_SYSV_COMPAT %}
# /run/lock/subsys is used for serializing SysV service execution, and # /run/lock/subsys is used for serializing SysV service execution, and
# hence without use on SysV-less systems. # hence without use on SysV-less systems.
d /run/lock/subsys 0755 root root - d /run/lock/subsys 0755 root root -