mirror of
https://github.com/systemd/systemd
synced 2025-10-07 20:54:45 +02:00
Compare commits
19 Commits
993eb00016
...
6634a39469
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6634a39469 | ||
![]() |
c68ede3952 | ||
![]() |
a2b1572ce4 | ||
![]() |
c7cbe25d11 | ||
![]() |
70448bb1c1 | ||
![]() |
6dc4531d16 | ||
![]() |
bbea881312 | ||
![]() |
8430841b5e | ||
![]() |
86ae2d69a3 | ||
![]() |
84031b5d6e | ||
![]() |
4544002cae | ||
![]() |
ea539ad297 | ||
![]() |
70ad107bdf | ||
![]() |
f794098356 | ||
![]() |
3882526798 | ||
![]() |
084575ff91 | ||
![]() |
3fe23a96d6 | ||
![]() |
d94dfe7053 | ||
![]() |
6bfadad9bb |
@ -62,12 +62,24 @@
|
|||||||
If <varname>SpeedMeter=no</varname>, the value is ignored. Defaults to 10sec.</para></listitem>
|
If <varname>SpeedMeter=no</varname>, the value is ignored. Defaults to 10sec.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ManageForeignRoutingPolicyRules=</varname></term>
|
||||||
|
<listitem><para>A boolean. When true, <command>systemd-networkd</command> will remove rules
|
||||||
|
that are not configured in .network files (except for rules with protocol
|
||||||
|
<literal>kernel</literal>). When false, it will not remove any foreign rules, keeping them even
|
||||||
|
if they are not configured in a .network file. Defaults to yes.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>ManageForeignRoutes=</varname></term>
|
<term><varname>ManageForeignRoutes=</varname></term>
|
||||||
<listitem><para>A boolean. When true, <command>systemd-networkd</command> will store any routes
|
<listitem><para>A boolean. When true, <command>systemd-networkd</command> will remove routes
|
||||||
configured by other tools in its memory. When false, <command>systemd-networkd</command> will
|
that are not configured in .network files (except for routes with protocol
|
||||||
not manage the foreign routes, thus they are kept even if <varname>KeepConfiguration=</varname>
|
<literal>kernel</literal>, <literal>dhcp</literal> when <varname>KeepConfiguration=</varname>
|
||||||
is false. Defaults to yes.</para></listitem>
|
is true or <literal>dhcp</literal>, and <literal>static</literal> when
|
||||||
|
<varname>KeepConfiguration=</varname> is true or <literal>static</literal>). When false, it will
|
||||||
|
not remove any foreign routes, keeping them even if they are not configured in a .network file.
|
||||||
|
Defaults to yes.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -85,6 +85,34 @@
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-4</option></term>
|
||||||
|
<term><option>--ipv4</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Waiting for an IPv4 address of each network interface to be configured. If this
|
||||||
|
option is specified with <option>--any</option>, then
|
||||||
|
<command>systemd-networkd-wait-online</command> exits with success when at least one interface
|
||||||
|
becomes online and has an IPv4 address. The option is applied only for the operational state
|
||||||
|
<literal>degraded</literal> or above. If neither <option>--ipv4</option> nor
|
||||||
|
<option>--ipv6</option> is specified, then the value from
|
||||||
|
<varname>RequiredFamilyForOnline=</varname> in the corresponding <filename>.network</filename>
|
||||||
|
file is used if present.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-6</option></term>
|
||||||
|
<term><option>--ipv6</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Waiting for an IPv6 address of each network interface to be configured. If this
|
||||||
|
option is specified with <option>--any</option>, then
|
||||||
|
<command>systemd-networkd-wait-online</command> exits with success when at least one interface
|
||||||
|
becomes online and has an IPv6 address. The option is applied only for the operational state
|
||||||
|
<literal>degraded</literal> or above. If neither <option>--ipv4</option> nor
|
||||||
|
<option>--ipv6</option> is specified, then the value from
|
||||||
|
<varname>RequiredFamilyForOnline=</varname> in the corresponding <filename>.network</filename>
|
||||||
|
file is used if present.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--any</option></term>
|
<term><option>--any</option></term>
|
||||||
|
|
||||||
|
@ -229,6 +229,18 @@
|
|||||||
if <literal>RequiredForOnline=no</literal>.</para>
|
if <literal>RequiredForOnline=no</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>RequiredFamilyForOnline=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Specifies an address family. When specified,
|
||||||
|
<command>systemd-networkd-wait-online</command> waits for at least one routable or link-local
|
||||||
|
IP address in the family should be configured on the link. Takes one of
|
||||||
|
<literal>ipv4</literal>, <literal>ipv6</literal>, <literal>both</literal>, or
|
||||||
|
<literal>any</literal>. Defaults to <literal>any</literal>. Note that this will be used only
|
||||||
|
when <varname>RequiredForOnline=</varname> is true, or its minimum operational state is
|
||||||
|
<literal>degraded</literal> or above. Otherwise, it will be ignored.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>ActivationPolicy=</varname></term>
|
<term><varname>ActivationPolicy=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -8,15 +8,12 @@
|
|||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
|
||||||
int allow_listed_char_for_devnode(char c, const char *white) {
|
int allow_listed_char_for_devnode(char c, const char *white) {
|
||||||
|
return
|
||||||
if ((c >= '0' && c <= '9') ||
|
(c >= '0' && c <= '9') ||
|
||||||
(c >= 'A' && c <= 'Z') ||
|
(c >= 'A' && c <= 'Z') ||
|
||||||
(c >= 'a' && c <= 'z') ||
|
(c >= 'a' && c <= 'z') ||
|
||||||
strchr("#+-.:=@_", c) != NULL ||
|
strchr("#+-.:=@_", c) ||
|
||||||
(white != NULL && strchr(white, c) != NULL))
|
(white && strchr(white, c));
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode_devnode_name(const char *str, char *str_enc, size_t len) {
|
int encode_devnode_name(const char *str, char *str_enc, size_t len) {
|
||||||
@ -31,7 +28,7 @@ int encode_devnode_name(const char *str, char *str_enc, size_t len) {
|
|||||||
seqlen = utf8_encoded_valid_unichar(str + i, SIZE_MAX);
|
seqlen = utf8_encoded_valid_unichar(str + i, SIZE_MAX);
|
||||||
if (seqlen > 1) {
|
if (seqlen > 1) {
|
||||||
|
|
||||||
if (len-j < (size_t)seqlen)
|
if (len-j < (size_t) seqlen)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
memcpy(&str_enc[j], &str[i], seqlen);
|
memcpy(&str_enc[j], &str[i], seqlen);
|
||||||
|
@ -56,6 +56,15 @@ static const char* const link_carrier_state_table[_LINK_CARRIER_STATE_MAX] = {
|
|||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(link_carrier_state, LinkCarrierState);
|
DEFINE_STRING_TABLE_LOOKUP(link_carrier_state, LinkCarrierState);
|
||||||
|
|
||||||
|
static const char* const link_required_address_family_table[_ADDRESS_FAMILY_MAX] = {
|
||||||
|
[ADDRESS_FAMILY_NO] = "any",
|
||||||
|
[ADDRESS_FAMILY_IPV4] = "ipv4",
|
||||||
|
[ADDRESS_FAMILY_IPV6] = "ipv6",
|
||||||
|
[ADDRESS_FAMILY_YES] = "both",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(link_required_address_family, AddressFamily);
|
||||||
|
|
||||||
static const char* const link_address_state_table[_LINK_ADDRESS_STATE_MAX] = {
|
static const char* const link_address_state_table[_LINK_ADDRESS_STATE_MAX] = {
|
||||||
[LINK_ADDRESS_STATE_OFF] = "off",
|
[LINK_ADDRESS_STATE_OFF] = "off",
|
||||||
[LINK_ADDRESS_STATE_DEGRADED] = "degraded",
|
[LINK_ADDRESS_STATE_DEGRADED] = "degraded",
|
||||||
|
@ -11,6 +11,16 @@
|
|||||||
|
|
||||||
bool network_is_online(void);
|
bool network_is_online(void);
|
||||||
|
|
||||||
|
typedef enum AddressFamily {
|
||||||
|
/* This is a bitmask, though it usually doesn't feel that way! */
|
||||||
|
ADDRESS_FAMILY_NO = 0,
|
||||||
|
ADDRESS_FAMILY_IPV4 = 1 << 0,
|
||||||
|
ADDRESS_FAMILY_IPV6 = 1 << 1,
|
||||||
|
ADDRESS_FAMILY_YES = ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_IPV6,
|
||||||
|
_ADDRESS_FAMILY_MAX,
|
||||||
|
_ADDRESS_FAMILY_INVALID = -EINVAL,
|
||||||
|
} AddressFamily;
|
||||||
|
|
||||||
typedef enum LinkOperationalState {
|
typedef enum LinkOperationalState {
|
||||||
LINK_OPERSTATE_MISSING,
|
LINK_OPERSTATE_MISSING,
|
||||||
LINK_OPERSTATE_OFF,
|
LINK_OPERSTATE_OFF,
|
||||||
@ -50,6 +60,9 @@ LinkOperationalState link_operstate_from_string(const char *s) _pure_;
|
|||||||
const char* link_carrier_state_to_string(LinkCarrierState s) _const_;
|
const char* link_carrier_state_to_string(LinkCarrierState s) _const_;
|
||||||
LinkCarrierState link_carrier_state_from_string(const char *s) _pure_;
|
LinkCarrierState link_carrier_state_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
const char* link_required_address_family_to_string(AddressFamily s) _const_;
|
||||||
|
AddressFamily link_required_address_family_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
const char* link_address_state_to_string(LinkAddressState s) _const_;
|
const char* link_address_state_to_string(LinkAddressState s) _const_;
|
||||||
LinkAddressState link_address_state_from_string(const char *s) _pure_;
|
LinkAddressState link_address_state_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
@ -48,6 +48,14 @@ _public_ int sd_network_get_address_state(char **state) {
|
|||||||
return network_get_string("ADDRESS_STATE", state);
|
return network_get_string("ADDRESS_STATE", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_network_get_ipv4_address_state(char **state) {
|
||||||
|
return network_get_string("IPV4_ADDRESS_STATE", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_public_ int sd_network_get_ipv6_address_state(char **state) {
|
||||||
|
return network_get_string("IPV6_ADDRESS_STATE", state);
|
||||||
|
}
|
||||||
|
|
||||||
static int network_get_strv(const char *key, char ***ret) {
|
static int network_get_strv(const char *key, char ***ret) {
|
||||||
_cleanup_strv_free_ char **a = NULL;
|
_cleanup_strv_free_ char **a = NULL;
|
||||||
_cleanup_free_ char *s = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
@ -160,6 +168,26 @@ _public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
|
|||||||
return network_link_get_string(ifindex, "OPER_STATE", state);
|
return network_link_get_string(ifindex, "OPER_STATE", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_network_link_get_required_family_for_online(int ifindex, char **state) {
|
||||||
|
_cleanup_free_ char *s = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert_return(state, -EINVAL);
|
||||||
|
|
||||||
|
r = network_link_get_string(ifindex, "REQUIRED_FAMILY_FOR_ONLINE", &s);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r != -ENODATA)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
s = strdup("any");
|
||||||
|
if (!s)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*state = TAKE_PTR(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
_public_ int sd_network_link_get_carrier_state(int ifindex, char **state) {
|
_public_ int sd_network_link_get_carrier_state(int ifindex, char **state) {
|
||||||
return network_link_get_string(ifindex, "CARRIER_STATE", state);
|
return network_link_get_string(ifindex, "CARRIER_STATE", state);
|
||||||
}
|
}
|
||||||
@ -168,6 +196,14 @@ _public_ int sd_network_link_get_address_state(int ifindex, char **state) {
|
|||||||
return network_link_get_string(ifindex, "ADDRESS_STATE", state);
|
return network_link_get_string(ifindex, "ADDRESS_STATE", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_network_link_get_ipv4_address_state(int ifindex, char **state) {
|
||||||
|
return network_link_get_string(ifindex, "IPV4_ADDRESS_STATE", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_public_ int sd_network_link_get_ipv6_address_state(int ifindex, char **state) {
|
||||||
|
return network_link_get_string(ifindex, "IPV6_ADDRESS_STATE", state);
|
||||||
|
}
|
||||||
|
|
||||||
_public_ int sd_network_link_get_dhcp6_client_iaid_string(int ifindex, char **iaid) {
|
_public_ int sd_network_link_get_dhcp6_client_iaid_string(int ifindex, char **iaid) {
|
||||||
return network_link_get_string(ifindex, "DHCP6_CLIENT_IAID", iaid);
|
return network_link_get_string(ifindex, "DHCP6_CLIENT_IAID", iaid);
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,10 @@ struct ConfigPerfItem;
|
|||||||
%struct-type
|
%struct-type
|
||||||
%includes
|
%includes
|
||||||
%%
|
%%
|
||||||
Network.SpeedMeter, config_parse_bool, 0, offsetof(Manager, use_speed_meter)
|
Network.SpeedMeter, config_parse_bool, 0, offsetof(Manager, use_speed_meter)
|
||||||
Network.SpeedMeterIntervalSec, config_parse_sec, 0, offsetof(Manager, speed_meter_interval_usec)
|
Network.SpeedMeterIntervalSec, config_parse_sec, 0, offsetof(Manager, speed_meter_interval_usec)
|
||||||
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
|
Network.ManageForeignRoutingPolicyRules, config_parse_bool, 0, offsetof(Manager, manage_foreign_rules)
|
||||||
Network.RouteTable, config_parse_route_table_names, 0, 0
|
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
|
||||||
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid)
|
Network.RouteTable, config_parse_route_table_names, 0, 0
|
||||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
|
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid)
|
||||||
|
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
|
||||||
|
@ -684,6 +684,8 @@ const sd_bus_vtable link_vtable[] = {
|
|||||||
SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Link, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Link, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Link, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Link, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state, offsetof(Link, ipv4_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state, offsetof(Link, ipv6_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("BitRates", "(tt)", property_get_bit_rates, 0, 0),
|
SD_BUS_PROPERTY("BitRates", "(tt)", property_get_bit_rates, 0, 0),
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <linux/if_arp.h>
|
#include <linux/if_arp.h>
|
||||||
#include <linux/if_link.h>
|
#include <linux/if_link.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
@ -163,12 +164,25 @@ static void link_update_master_operstate(Link *link, NetDev *netdev) {
|
|||||||
link_update_operstate(master, true);
|
link_update_operstate(master, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LinkAddressState address_state_from_scope(uint8_t scope) {
|
||||||
|
if (scope < RT_SCOPE_SITE)
|
||||||
|
/* universally accessible addresses found */
|
||||||
|
return LINK_ADDRESS_STATE_ROUTABLE;
|
||||||
|
|
||||||
|
if (scope < RT_SCOPE_HOST)
|
||||||
|
/* only link or site local addresses found */
|
||||||
|
return LINK_ADDRESS_STATE_DEGRADED;
|
||||||
|
|
||||||
|
/* no useful addresses found */
|
||||||
|
return LINK_ADDRESS_STATE_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
void link_update_operstate(Link *link, bool also_update_master) {
|
void link_update_operstate(Link *link, bool also_update_master) {
|
||||||
LinkOperationalState operstate;
|
LinkOperationalState operstate;
|
||||||
LinkCarrierState carrier_state;
|
LinkCarrierState carrier_state;
|
||||||
LinkAddressState address_state;
|
LinkAddressState ipv4_address_state, ipv6_address_state, address_state;
|
||||||
_cleanup_strv_free_ char **p = NULL;
|
_cleanup_strv_free_ char **p = NULL;
|
||||||
uint8_t scope = RT_SCOPE_NOWHERE;
|
uint8_t ipv4_scope = RT_SCOPE_NOWHERE, ipv6_scope = RT_SCOPE_NOWHERE, scope;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
Address *address;
|
Address *address;
|
||||||
|
|
||||||
@ -201,8 +215,11 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
|||||||
if (!address_is_ready(address))
|
if (!address_is_ready(address))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (address->scope < scope)
|
if (address->family == AF_INET && address->scope < ipv4_scope)
|
||||||
scope = address->scope;
|
ipv4_scope = address->scope;
|
||||||
|
|
||||||
|
if (address->family == AF_INET6 && address->scope < ipv6_scope)
|
||||||
|
ipv6_scope = address->scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for operstate we also take foreign addresses into account */
|
/* for operstate we also take foreign addresses into account */
|
||||||
@ -210,19 +227,18 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
|||||||
if (!address_is_ready(address))
|
if (!address_is_ready(address))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (address->scope < scope)
|
if (address->family == AF_INET && address->scope < ipv4_scope)
|
||||||
scope = address->scope;
|
ipv4_scope = address->scope;
|
||||||
|
|
||||||
|
if (address->family == AF_INET6 && address->scope < ipv6_scope)
|
||||||
|
ipv6_scope = address->scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope < RT_SCOPE_SITE)
|
ipv4_address_state = address_state_from_scope(ipv4_scope);
|
||||||
/* universally accessible addresses found */
|
ipv6_address_state = address_state_from_scope(ipv6_scope);
|
||||||
address_state = LINK_ADDRESS_STATE_ROUTABLE;
|
|
||||||
else if (scope < RT_SCOPE_HOST)
|
scope = MIN(ipv4_scope, ipv6_scope);
|
||||||
/* only link or site local addresses found */
|
address_state = address_state_from_scope(scope);
|
||||||
address_state = LINK_ADDRESS_STATE_DEGRADED;
|
|
||||||
else
|
|
||||||
/* no useful addresses found */
|
|
||||||
address_state = LINK_ADDRESS_STATE_OFF;
|
|
||||||
|
|
||||||
/* Mapping of address and carrier state vs operational state
|
/* Mapping of address and carrier state vs operational state
|
||||||
* carrier state
|
* carrier state
|
||||||
@ -256,6 +272,20 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
|||||||
log_oom();
|
log_oom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link->ipv4_address_state != ipv4_address_state) {
|
||||||
|
link->ipv4_address_state = ipv4_address_state;
|
||||||
|
changed = true;
|
||||||
|
if (strv_extend(&p, "IPv4AddressState") < 0)
|
||||||
|
log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->ipv6_address_state != ipv6_address_state) {
|
||||||
|
link->ipv6_address_state = ipv6_address_state;
|
||||||
|
changed = true;
|
||||||
|
if (strv_extend(&p, "IPv6AddressState") < 0)
|
||||||
|
log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
if (link->operstate != operstate) {
|
if (link->operstate != operstate) {
|
||||||
link->operstate = operstate;
|
link->operstate = operstate;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -75,6 +75,8 @@ typedef struct Link {
|
|||||||
LinkOperationalState operstate;
|
LinkOperationalState operstate;
|
||||||
LinkCarrierState carrier_state;
|
LinkCarrierState carrier_state;
|
||||||
LinkAddressState address_state;
|
LinkAddressState address_state;
|
||||||
|
LinkAddressState ipv4_address_state;
|
||||||
|
LinkAddressState ipv6_address_state;
|
||||||
|
|
||||||
unsigned address_messages;
|
unsigned address_messages;
|
||||||
unsigned address_remove_messages;
|
unsigned address_remove_messages;
|
||||||
|
@ -235,6 +235,8 @@ const sd_bus_vtable manager_vtable[] = {
|
|||||||
SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Manager, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Manager, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state, offsetof(Manager, ipv4_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state, offsetof(Manager, ipv6_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
|
||||||
SD_BUS_METHOD_WITH_ARGS("ListLinks",
|
SD_BUS_METHOD_WITH_ARGS("ListLinks",
|
||||||
SD_BUS_NO_ARGS,
|
SD_BUS_NO_ARGS,
|
||||||
|
@ -380,6 +380,7 @@ int manager_new(Manager **ret) {
|
|||||||
*m = (Manager) {
|
*m = (Manager) {
|
||||||
.speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
|
.speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
|
||||||
.manage_foreign_routes = true,
|
.manage_foreign_routes = true,
|
||||||
|
.manage_foreign_rules = true,
|
||||||
.ethtool_fd = -1,
|
.ethtool_fd = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -655,6 +656,9 @@ static int manager_enumerate_rules(Manager *m) {
|
|||||||
assert(m);
|
assert(m);
|
||||||
assert(m->rtnl);
|
assert(m->rtnl);
|
||||||
|
|
||||||
|
if (!m->manage_foreign_rules)
|
||||||
|
return 0;
|
||||||
|
|
||||||
r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
|
r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -32,6 +32,7 @@ struct Manager {
|
|||||||
bool dirty;
|
bool dirty;
|
||||||
bool restarting;
|
bool restarting;
|
||||||
bool manage_foreign_routes;
|
bool manage_foreign_routes;
|
||||||
|
bool manage_foreign_rules;
|
||||||
|
|
||||||
Set *dirty_links;
|
Set *dirty_links;
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ struct Manager {
|
|||||||
LinkOperationalState operational_state;
|
LinkOperationalState operational_state;
|
||||||
LinkCarrierState carrier_state;
|
LinkCarrierState carrier_state;
|
||||||
LinkAddressState address_state;
|
LinkAddressState address_state;
|
||||||
|
LinkAddressState ipv4_address_state;
|
||||||
|
LinkAddressState ipv6_address_state;
|
||||||
|
|
||||||
Hashmap *links;
|
Hashmap *links;
|
||||||
Hashmap *netdevs;
|
Hashmap *netdevs;
|
||||||
|
@ -67,6 +67,7 @@ Link.Promiscuous, config_parse_tristate,
|
|||||||
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
|
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
|
||||||
Link.ActivationPolicy, config_parse_activation_policy, 0, offsetof(Network, activation_policy)
|
Link.ActivationPolicy, config_parse_activation_policy, 0, offsetof(Network, activation_policy)
|
||||||
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
|
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
|
||||||
|
Link.RequiredFamilyForOnline, config_parse_required_family_for_online, 0, offsetof(Network, required_family_for_online)
|
||||||
SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0
|
SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0
|
||||||
SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0
|
SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0
|
||||||
SR-IOV.QualityOfService, config_parse_sr_iov_uint32, 0, 0
|
SR-IOV.QualityOfService, config_parse_sr_iov_uint32, 0, 0
|
||||||
|
@ -1196,6 +1196,9 @@ int config_parse_required_for_online(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online, link_required_address_family, AddressFamily,
|
||||||
|
"Failed to parse RequiredFamilyForOnline= setting");
|
||||||
|
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
|
||||||
"Failed to parse KeepConfiguration= setting");
|
"Failed to parse KeepConfiguration= setting");
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ struct Network {
|
|||||||
bool unmanaged;
|
bool unmanaged;
|
||||||
bool required_for_online; /* Is this network required to be considered online? */
|
bool required_for_online; /* Is this network required to be considered online? */
|
||||||
LinkOperationalStateRange required_operstate_for_online;
|
LinkOperationalStateRange required_operstate_for_online;
|
||||||
|
AddressFamily required_family_for_online;
|
||||||
ActivationPolicy activation_policy;
|
ActivationPolicy activation_policy;
|
||||||
|
|
||||||
/* misc settings */
|
/* misc settings */
|
||||||
@ -348,6 +349,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_timezone);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
|
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_required_family_for_online);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
|
CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
|
CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
|
||||||
|
@ -977,6 +977,8 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
|
|||||||
case RTM_NEWRULE:
|
case RTM_NEWRULE:
|
||||||
if (rule)
|
if (rule)
|
||||||
log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL, m);
|
log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL, m);
|
||||||
|
else if (!m->manage_foreign_routes)
|
||||||
|
log_routing_policy_rule_debug(tmp, tmp->family, "Ignoring received foreign", NULL, m);
|
||||||
else {
|
else {
|
||||||
log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL, m);
|
log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL, m);
|
||||||
r = routing_policy_rule_consume_foreign(m, TAKE_PTR(tmp));
|
r = routing_policy_rule_consume_foreign(m, TAKE_PTR(tmp));
|
||||||
|
@ -105,10 +105,11 @@ static int ordered_set_put_in4_addrv(
|
|||||||
|
|
||||||
int manager_save(Manager *m) {
|
int manager_save(Manager *m) {
|
||||||
_cleanup_ordered_set_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
|
_cleanup_ordered_set_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
|
||||||
const char *operstate_str, *carrier_state_str, *address_state_str;
|
const char *operstate_str, *carrier_state_str, *address_state_str, *ipv4_address_state_str, *ipv6_address_state_str;
|
||||||
LinkOperationalState operstate = LINK_OPERSTATE_OFF;
|
LinkOperationalState operstate = LINK_OPERSTATE_OFF;
|
||||||
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
|
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
|
||||||
LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
|
LinkAddressState ipv4_address_state = LINK_ADDRESS_STATE_OFF, ipv6_address_state = LINK_ADDRESS_STATE_OFF,
|
||||||
|
address_state = LINK_ADDRESS_STATE_OFF;
|
||||||
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||||
_cleanup_strv_free_ char **p = NULL;
|
_cleanup_strv_free_ char **p = NULL;
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
@ -133,6 +134,12 @@ int manager_save(Manager *m) {
|
|||||||
if (link->address_state > address_state)
|
if (link->address_state > address_state)
|
||||||
address_state = link->address_state;
|
address_state = link->address_state;
|
||||||
|
|
||||||
|
if (link->ipv4_address_state > ipv4_address_state)
|
||||||
|
ipv4_address_state = link->ipv4_address_state;
|
||||||
|
|
||||||
|
if (link->ipv6_address_state > ipv6_address_state)
|
||||||
|
ipv6_address_state = link->ipv6_address_state;
|
||||||
|
|
||||||
if (!link->network)
|
if (!link->network)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -226,6 +233,12 @@ int manager_save(Manager *m) {
|
|||||||
address_state_str = link_address_state_to_string(address_state);
|
address_state_str = link_address_state_to_string(address_state);
|
||||||
assert(address_state_str);
|
assert(address_state_str);
|
||||||
|
|
||||||
|
ipv4_address_state_str = link_address_state_to_string(ipv4_address_state);
|
||||||
|
assert(ipv4_address_state_str);
|
||||||
|
|
||||||
|
ipv6_address_state_str = link_address_state_to_string(ipv6_address_state);
|
||||||
|
assert(ipv6_address_state_str);
|
||||||
|
|
||||||
r = fopen_temporary(m->state_file, &f, &temp_path);
|
r = fopen_temporary(m->state_file, &f, &temp_path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -236,8 +249,10 @@ int manager_save(Manager *m) {
|
|||||||
"# This is private data. Do not parse.\n"
|
"# This is private data. Do not parse.\n"
|
||||||
"OPER_STATE=%s\n"
|
"OPER_STATE=%s\n"
|
||||||
"CARRIER_STATE=%s\n"
|
"CARRIER_STATE=%s\n"
|
||||||
"ADDRESS_STATE=%s\n",
|
"ADDRESS_STATE=%s\n"
|
||||||
operstate_str, carrier_state_str, address_state_str);
|
"IPV4_ADDRESS_STATE=%s\n"
|
||||||
|
"IPV6_ADDRESS_STATE=%s\n",
|
||||||
|
operstate_str, carrier_state_str, address_state_str, ipv4_address_state_str, ipv6_address_state_str);
|
||||||
|
|
||||||
ordered_set_print(f, "DNS=", dns);
|
ordered_set_print(f, "DNS=", dns);
|
||||||
ordered_set_print(f, "NTP=", ntp);
|
ordered_set_print(f, "NTP=", ntp);
|
||||||
@ -273,6 +288,18 @@ int manager_save(Manager *m) {
|
|||||||
log_oom();
|
log_oom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m->ipv4_address_state != ipv4_address_state) {
|
||||||
|
m->ipv4_address_state = ipv4_address_state;
|
||||||
|
if (strv_extend(&p, "IPv4AddressState") < 0)
|
||||||
|
log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->ipv6_address_state != ipv6_address_state) {
|
||||||
|
m->ipv6_address_state = ipv6_address_state;
|
||||||
|
if (strv_extend(&p, "IPv6AddressState") < 0)
|
||||||
|
log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
r = manager_send_changed_strv(m, p);
|
r = manager_send_changed_strv(m, p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -376,7 +403,7 @@ static void serialize_addresses(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int link_save(Link *link) {
|
int link_save(Link *link) {
|
||||||
const char *admin_state, *oper_state, *carrier_state, *address_state;
|
const char *admin_state, *oper_state, *carrier_state, *address_state, *ipv4_address_state, *ipv6_address_state;
|
||||||
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -403,6 +430,12 @@ int link_save(Link *link) {
|
|||||||
address_state = link_address_state_to_string(link->address_state);
|
address_state = link_address_state_to_string(link->address_state);
|
||||||
assert(address_state);
|
assert(address_state);
|
||||||
|
|
||||||
|
ipv4_address_state = link_address_state_to_string(link->ipv4_address_state);
|
||||||
|
assert(ipv4_address_state);
|
||||||
|
|
||||||
|
ipv6_address_state = link_address_state_to_string(link->ipv6_address_state);
|
||||||
|
assert(ipv6_address_state);
|
||||||
|
|
||||||
r = fopen_temporary(link->state_file, &f, &temp_path);
|
r = fopen_temporary(link->state_file, &f, &temp_path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -414,8 +447,10 @@ int link_save(Link *link) {
|
|||||||
"ADMIN_STATE=%s\n"
|
"ADMIN_STATE=%s\n"
|
||||||
"OPER_STATE=%s\n"
|
"OPER_STATE=%s\n"
|
||||||
"CARRIER_STATE=%s\n"
|
"CARRIER_STATE=%s\n"
|
||||||
"ADDRESS_STATE=%s\n",
|
"ADDRESS_STATE=%s\n"
|
||||||
admin_state, oper_state, carrier_state, address_state);
|
"IPV4_ADDRESS_STATE=%s\n"
|
||||||
|
"IPV6_ADDRESS_STATE=%s\n",
|
||||||
|
admin_state, oper_state, carrier_state, address_state, ipv4_address_state, ipv6_address_state);
|
||||||
|
|
||||||
if (link->network) {
|
if (link->network) {
|
||||||
char **dhcp6_domains = NULL, **dhcp_domains = NULL;
|
char **dhcp6_domains = NULL, **dhcp_domains = NULL;
|
||||||
@ -431,6 +466,9 @@ int link_save(Link *link) {
|
|||||||
st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "",
|
st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "",
|
||||||
st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : "");
|
st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : "");
|
||||||
|
|
||||||
|
fprintf(f, "REQUIRED_FAMILY_FOR_ONLINE=%s\n",
|
||||||
|
link_required_address_family_to_string(link->network->required_family_for_online));
|
||||||
|
|
||||||
fprintf(f, "ACTIVATION_POLICY=%s\n",
|
fprintf(f, "ACTIVATION_POLICY=%s\n",
|
||||||
activation_policy_to_string(link->network->activation_policy));
|
activation_policy_to_string(link->network->activation_policy));
|
||||||
|
|
||||||
|
@ -8,18 +8,9 @@
|
|||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "network-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
|
||||||
typedef enum AddressFamily {
|
|
||||||
/* This is a bitmask, though it usually doesn't feel that way! */
|
|
||||||
ADDRESS_FAMILY_NO = 0,
|
|
||||||
ADDRESS_FAMILY_IPV4 = 1 << 0,
|
|
||||||
ADDRESS_FAMILY_IPV6 = 1 << 1,
|
|
||||||
ADDRESS_FAMILY_YES = ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_IPV6,
|
|
||||||
_ADDRESS_FAMILY_MAX,
|
|
||||||
_ADDRESS_FAMILY_INVALID = -EINVAL,
|
|
||||||
} AddressFamily;
|
|
||||||
|
|
||||||
typedef struct NetworkConfigSection {
|
typedef struct NetworkConfigSection {
|
||||||
unsigned line;
|
unsigned line;
|
||||||
bool invalid;
|
bool invalid;
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
[Network]
|
[Network]
|
||||||
#SpeedMeter=no
|
#SpeedMeter=no
|
||||||
#SpeedMeterIntervalSec=10sec
|
#SpeedMeterIntervalSec=10sec
|
||||||
|
#ManageForeignRoutingPolicyRules=yes
|
||||||
#ManageForeignRoutes=yes
|
#ManageForeignRoutes=yes
|
||||||
|
#RouteTable=
|
||||||
|
|
||||||
[DHCP]
|
[DHCP]
|
||||||
#DUIDType=vendor
|
#DUIDType=vendor
|
||||||
|
@ -97,7 +97,8 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int link_update_monitor(Link *l) {
|
int link_update_monitor(Link *l) {
|
||||||
_cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
|
_cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *required_family = NULL,
|
||||||
|
*ipv4_address_state = NULL, *ipv6_address_state = NULL, *state = NULL;
|
||||||
int r, ret = 0;
|
int r, ret = 0;
|
||||||
|
|
||||||
assert(l);
|
assert(l);
|
||||||
@ -135,6 +136,47 @@ int link_update_monitor(Link *l) {
|
|||||||
l->operational_state = s;
|
l->operational_state = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = sd_network_link_get_required_family_for_online(l->ifindex, &required_family);
|
||||||
|
if (r < 0)
|
||||||
|
ret = log_link_debug_errno(l, r, "Failed to get required address family, ignoring: %m");
|
||||||
|
else if (isempty(required_family))
|
||||||
|
l->required_family = ADDRESS_FAMILY_NO;
|
||||||
|
else {
|
||||||
|
AddressFamily f;
|
||||||
|
|
||||||
|
f = link_required_address_family_from_string(required_family);
|
||||||
|
if (f < 0)
|
||||||
|
ret = log_link_debug_errno(l, f, "Failed to parse required address family, ignoring: %m");
|
||||||
|
else
|
||||||
|
l->required_family = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_network_link_get_ipv4_address_state(l->ifindex, &ipv4_address_state);
|
||||||
|
if (r < 0)
|
||||||
|
ret = log_link_debug_errno(l, r, "Failed to get IPv4 address state, ignoring: %m");
|
||||||
|
else {
|
||||||
|
LinkAddressState s;
|
||||||
|
|
||||||
|
s = link_address_state_from_string(ipv4_address_state);
|
||||||
|
if (s < 0)
|
||||||
|
ret = log_link_debug_errno(l, s, "Failed to parse IPv4 address state, ignoring: %m");
|
||||||
|
else
|
||||||
|
l->ipv4_address_state = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_network_link_get_ipv6_address_state(l->ifindex, &ipv6_address_state);
|
||||||
|
if (r < 0)
|
||||||
|
ret = log_link_debug_errno(l, r, "Failed to get IPv6 address state, ignoring: %m");
|
||||||
|
else {
|
||||||
|
LinkAddressState s;
|
||||||
|
|
||||||
|
s = link_address_state_from_string(ipv6_address_state);
|
||||||
|
if (s < 0)
|
||||||
|
ret = log_link_debug_errno(l, s, "Failed to parse IPv6 address state, ignoring: %m");
|
||||||
|
else
|
||||||
|
l->ipv6_address_state = s;
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_network_link_get_setup_state(l->ifindex, &state);
|
r = sd_network_link_get_setup_state(l->ifindex, &state);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
|
ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
|
||||||
|
@ -19,6 +19,9 @@ struct Link {
|
|||||||
bool required_for_online;
|
bool required_for_online;
|
||||||
LinkOperationalStateRange required_operstate;
|
LinkOperationalStateRange required_operstate;
|
||||||
LinkOperationalState operational_state;
|
LinkOperationalState operational_state;
|
||||||
|
AddressFamily required_family;
|
||||||
|
LinkAddressState ipv4_address_state;
|
||||||
|
LinkAddressState ipv6_address_state;
|
||||||
char *state;
|
char *state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,6 +32,13 @@ static bool manager_ignore_link(Manager *m, Link *link) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange s) {
|
static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange s) {
|
||||||
|
AddressFamily required_family;
|
||||||
|
bool needs_ipv4;
|
||||||
|
bool needs_ipv6;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
assert(l);
|
||||||
|
|
||||||
/* This returns the following:
|
/* This returns the following:
|
||||||
* -EAGAIN: not processed by udev or networkd
|
* -EAGAIN: not processed by udev or networkd
|
||||||
* 0: operstate is not enough
|
* 0: operstate is not enough
|
||||||
@ -60,7 +67,35 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required_family = m->required_family > 0 ? m->required_family : l->required_family;
|
||||||
|
needs_ipv4 = required_family & ADDRESS_FAMILY_IPV4;
|
||||||
|
needs_ipv6 = required_family & ADDRESS_FAMILY_IPV6;
|
||||||
|
|
||||||
|
if (s.min >= LINK_OPERSTATE_DEGRADED) {
|
||||||
|
if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_DEGRADED)
|
||||||
|
goto ipv4_not_ready;
|
||||||
|
|
||||||
|
if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_DEGRADED)
|
||||||
|
goto ipv6_not_ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.min >= LINK_OPERSTATE_ROUTABLE) {
|
||||||
|
if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_ROUTABLE)
|
||||||
|
goto ipv4_not_ready;
|
||||||
|
|
||||||
|
if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_ROUTABLE)
|
||||||
|
goto ipv6_not_ready;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
ipv4_not_ready:
|
||||||
|
log_link_debug(l, "No routable or link-local IPv4 address is configured.");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ipv6_not_ready:
|
||||||
|
log_link_debug(l, "No routable or link-local IPv6 address is configured.");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool manager_configured(Manager *m) {
|
bool manager_configured(Manager *m) {
|
||||||
@ -298,6 +333,7 @@ static int manager_network_monitor_listen(Manager *m) {
|
|||||||
|
|
||||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||||
LinkOperationalStateRange required_operstate,
|
LinkOperationalStateRange required_operstate,
|
||||||
|
AddressFamily required_family,
|
||||||
bool any, usec_t timeout) {
|
bool any, usec_t timeout) {
|
||||||
_cleanup_(manager_freep) Manager *m = NULL;
|
_cleanup_(manager_freep) Manager *m = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -312,6 +348,7 @@ int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
|||||||
.interfaces = interfaces,
|
.interfaces = interfaces,
|
||||||
.ignore = ignore,
|
.ignore = ignore,
|
||||||
.required_operstate = required_operstate,
|
.required_operstate = required_operstate,
|
||||||
|
.required_family = required_family,
|
||||||
.any = any,
|
.any = any,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ struct Manager {
|
|||||||
char **ignore;
|
char **ignore;
|
||||||
|
|
||||||
LinkOperationalStateRange required_operstate;
|
LinkOperationalStateRange required_operstate;
|
||||||
|
AddressFamily required_family;
|
||||||
bool any;
|
bool any;
|
||||||
|
|
||||||
sd_netlink *rtnl;
|
sd_netlink *rtnl;
|
||||||
@ -35,6 +36,7 @@ struct Manager {
|
|||||||
Manager* manager_free(Manager *m);
|
Manager* manager_free(Manager *m);
|
||||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||||
LinkOperationalStateRange required_operstate,
|
LinkOperationalStateRange required_operstate,
|
||||||
|
AddressFamily required_family,
|
||||||
bool any, usec_t timeout);
|
bool any, usec_t timeout);
|
||||||
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||||
|
@ -19,6 +19,7 @@ static usec_t arg_timeout = 120 * USEC_PER_SEC;
|
|||||||
static Hashmap *arg_interfaces = NULL;
|
static Hashmap *arg_interfaces = NULL;
|
||||||
static char **arg_ignore = NULL;
|
static char **arg_ignore = NULL;
|
||||||
static LinkOperationalStateRange arg_required_operstate = { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID };
|
static LinkOperationalStateRange arg_required_operstate = { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID };
|
||||||
|
static AddressFamily arg_required_family = ADDRESS_FAMILY_NO;
|
||||||
static bool arg_any = false;
|
static bool arg_any = false;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_freep);
|
||||||
@ -42,6 +43,8 @@ static int help(void) {
|
|||||||
" --ignore=INTERFACE Don't take these interfaces into account\n"
|
" --ignore=INTERFACE Don't take these interfaces into account\n"
|
||||||
" -o --operational-state=MIN_OPERSTATE[:MAX_OPERSTATE]\n"
|
" -o --operational-state=MIN_OPERSTATE[:MAX_OPERSTATE]\n"
|
||||||
" Required operational state\n"
|
" Required operational state\n"
|
||||||
|
" -4 --ipv4 Requires at least one IPv4 address\n"
|
||||||
|
" -6 --ipv6 Requires at least one IPv6 address\n"
|
||||||
" --any Wait until at least one of the interfaces is online\n"
|
" --any Wait until at least one of the interfaces is online\n"
|
||||||
" --timeout=SECS Maximum time to wait for network connectivity\n"
|
" --timeout=SECS Maximum time to wait for network connectivity\n"
|
||||||
"\nSee the %s for details.\n",
|
"\nSee the %s for details.\n",
|
||||||
@ -111,6 +114,8 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "interface", required_argument, NULL, 'i' },
|
{ "interface", required_argument, NULL, 'i' },
|
||||||
{ "ignore", required_argument, NULL, ARG_IGNORE },
|
{ "ignore", required_argument, NULL, ARG_IGNORE },
|
||||||
{ "operational-state", required_argument, NULL, 'o' },
|
{ "operational-state", required_argument, NULL, 'o' },
|
||||||
|
{ "ipv4", no_argument, NULL, '4' },
|
||||||
|
{ "ipv6", no_argument, NULL, '6' },
|
||||||
{ "any", no_argument, NULL, ARG_ANY },
|
{ "any", no_argument, NULL, ARG_ANY },
|
||||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||||
{}
|
{}
|
||||||
@ -121,7 +126,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "hi:qo:", options, NULL)) >= 0)
|
while ((c = getopt_long(argc, argv, "hi:qo:46", options, NULL)) >= 0)
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
@ -159,6 +164,15 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case '4':
|
||||||
|
arg_required_family |= ADDRESS_FAMILY_IPV4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '6':
|
||||||
|
arg_required_family |= ADDRESS_FAMILY_IPV6;
|
||||||
|
break;
|
||||||
|
|
||||||
case ARG_ANY:
|
case ARG_ANY:
|
||||||
arg_any = true;
|
arg_any = true;
|
||||||
break;
|
break;
|
||||||
@ -197,7 +211,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
|
|
||||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||||
|
|
||||||
r = manager_new(&m, arg_interfaces, arg_ignore, arg_required_operstate, arg_any, arg_timeout);
|
r = manager_new(&m, arg_interfaces, arg_ignore, arg_required_operstate, arg_required_family, arg_any, arg_timeout);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not create manager: %m");
|
return log_error_errno(r, "Could not create manager: %m");
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ _SD_BEGIN_DECLARATIONS;
|
|||||||
int sd_network_get_operational_state(char **state);
|
int sd_network_get_operational_state(char **state);
|
||||||
int sd_network_get_carrier_state(char **state);
|
int sd_network_get_carrier_state(char **state);
|
||||||
int sd_network_get_address_state(char **state);
|
int sd_network_get_address_state(char **state);
|
||||||
|
int sd_network_get_ipv4_address_state(char **state);
|
||||||
|
int sd_network_get_ipv6_address_state(char **state);
|
||||||
|
|
||||||
/* Get DNS entries for all links. These are string representations of
|
/* Get DNS entries for all links. These are string representations of
|
||||||
* IP addresses */
|
* IP addresses */
|
||||||
@ -92,8 +94,11 @@ int sd_network_link_get_setup_state(int ifindex, char **state);
|
|||||||
*/
|
*/
|
||||||
int sd_network_link_get_operational_state(int ifindex, char **state);
|
int sd_network_link_get_operational_state(int ifindex, char **state);
|
||||||
int sd_network_link_get_required_operstate_for_online(int ifindex, char **state);
|
int sd_network_link_get_required_operstate_for_online(int ifindex, char **state);
|
||||||
|
int sd_network_link_get_required_family_for_online(int ifindex, char **state);
|
||||||
int sd_network_link_get_carrier_state(int ifindex, char **state);
|
int sd_network_link_get_carrier_state(int ifindex, char **state);
|
||||||
int sd_network_link_get_address_state(int ifindex, char **state);
|
int sd_network_link_get_address_state(int ifindex, char **state);
|
||||||
|
int sd_network_link_get_ipv4_address_state(int ifindex, char **state);
|
||||||
|
int sd_network_link_get_ipv6_address_state(int ifindex, char **state);
|
||||||
|
|
||||||
/* Indicates whether the network is relevant to being online.
|
/* Indicates whether the network is relevant to being online.
|
||||||
* Possible return codes:
|
* Possible return codes:
|
||||||
|
@ -23,6 +23,7 @@ test_append_files() {
|
|||||||
install_dmevent
|
install_dmevent
|
||||||
generate_module_dependencies
|
generate_module_dependencies
|
||||||
inst_binary losetup
|
inst_binary losetup
|
||||||
|
inst_binary wc
|
||||||
install_verity_minimal
|
install_verity_minimal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ PermanentMACAddress=
|
|||||||
[Link]
|
[Link]
|
||||||
ActivationPolicy=
|
ActivationPolicy=
|
||||||
RequiredForOnline=
|
RequiredForOnline=
|
||||||
|
RequiredFamilyForOnline=
|
||||||
ARP=
|
ARP=
|
||||||
AllMulticast=
|
AllMulticast=
|
||||||
Unmanaged=
|
Unmanaged=
|
||||||
|
@ -545,6 +545,7 @@ RemoteChecksumRx=
|
|||||||
RemoteChecksumTx=
|
RemoteChecksumTx=
|
||||||
ReorderHeader=
|
ReorderHeader=
|
||||||
RequestBroadcast=
|
RequestBroadcast=
|
||||||
|
RequiredFamilyForOnline=
|
||||||
RequiredForOnline=
|
RequiredForOnline=
|
||||||
ResendIGMP=
|
ResendIGMP=
|
||||||
RootDistanceMaxSec=
|
RootDistanceMaxSec=
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
[Match]
|
||||||
|
Name=veth99
|
||||||
|
|
||||||
|
[NetworkEmulator]
|
||||||
|
DelaySec=9
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
DHCP=ipv4
|
||||||
|
IPv6AcceptRA=true
|
11
test/test-network/conf/dhcp-server-with-ipv6-prefix.network
Normal file
11
test/test-network/conf/dhcp-server-with-ipv6-prefix.network
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[Match]
|
||||||
|
Name=veth-peer
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
Address=192.168.5.1/24
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
DHCPServer=yes
|
||||||
|
IPv6SendRA=yes
|
||||||
|
|
||||||
|
[IPv6Prefix]
|
||||||
|
Prefix=2002:da8:1:0::/64
|
12
test/test-network/conf/ipv6-prefix-with-delay.network
Normal file
12
test/test-network/conf/ipv6-prefix-with-delay.network
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Match]
|
||||||
|
Name=veth-peer
|
||||||
|
|
||||||
|
[NetworkEmulator]
|
||||||
|
DelaySec=15
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
IPv6SendRA=yes
|
||||||
|
|
||||||
|
[IPv6Prefix]
|
||||||
|
Prefix=2002:da8:1:0::/64
|
@ -0,0 +1,6 @@
|
|||||||
|
[Match]
|
||||||
|
Name=veth99
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=true
|
||||||
|
Address=192.168.5.1/24
|
@ -3,6 +3,7 @@ Name=dummy98
|
|||||||
|
|
||||||
[Link]
|
[Link]
|
||||||
RequiredForOnline=routable
|
RequiredForOnline=routable
|
||||||
|
RequiredFamilyForOnline=both
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
IPv6AcceptRA=no
|
IPv6AcceptRA=no
|
||||||
@ -14,3 +15,4 @@ MulticastDNS=yes
|
|||||||
DNSSEC=no
|
DNSSEC=no
|
||||||
Address=192.168.10.10/24
|
Address=192.168.10.10/24
|
||||||
Address=192.168.12.12/24
|
Address=192.168.12.12/24
|
||||||
|
Address=2002:da8:1:0:1034:56ff:fe78:9abc/64
|
||||||
|
@ -555,7 +555,7 @@ class Utilities():
|
|||||||
self.fail(f'Timed out waiting for {link} to reach state {operstate}/{setup_state}')
|
self.fail(f'Timed out waiting for {link} to reach state {operstate}/{setup_state}')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def wait_online(self, links_with_operstate, timeout='20s', bool_any=False, setup_state='configured', setup_timeout=5):
|
def wait_online(self, links_with_operstate, timeout='20s', bool_any=False, ipv4=False, ipv6=False, setup_state='configured', setup_timeout=5):
|
||||||
"""Wait for the link(s) to reach the specified operstate and/or setup state.
|
"""Wait for the link(s) to reach the specified operstate and/or setup state.
|
||||||
|
|
||||||
This is similar to wait_operstate() but can be used for multiple links,
|
This is similar to wait_operstate() but can be used for multiple links,
|
||||||
@ -569,6 +569,9 @@ class Utilities():
|
|||||||
Set 'bool_any' to True to wait for any (instead of all) of the given links.
|
Set 'bool_any' to True to wait for any (instead of all) of the given links.
|
||||||
If this is set, no setup_state checks are done.
|
If this is set, no setup_state checks are done.
|
||||||
|
|
||||||
|
Set 'ipv4' or 'ipv6' to True to wait for IPv4 address or IPv6 address, respectively, of each of the given links.
|
||||||
|
This is applied only for the operational state 'degraded' or above.
|
||||||
|
|
||||||
Note that this function waits for the link(s) to reach *or exceed* the given operstate.
|
Note that this function waits for the link(s) to reach *or exceed* the given operstate.
|
||||||
However, the setup_state, if specified, must be matched *exactly*.
|
However, the setup_state, if specified, must be matched *exactly*.
|
||||||
|
|
||||||
@ -578,6 +581,10 @@ class Utilities():
|
|||||||
args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate]
|
args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate]
|
||||||
if bool_any:
|
if bool_any:
|
||||||
args += ['--any']
|
args += ['--any']
|
||||||
|
if ipv4:
|
||||||
|
args += ['--ipv4']
|
||||||
|
if ipv6:
|
||||||
|
args += ['--ipv6']
|
||||||
try:
|
try:
|
||||||
check_output(*args, env=env)
|
check_output(*args, env=env)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
@ -1781,6 +1788,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
'gretun97',
|
'gretun97',
|
||||||
'ip6gretun97',
|
'ip6gretun97',
|
||||||
'test1',
|
'test1',
|
||||||
|
'veth-peer',
|
||||||
'veth99',
|
'veth99',
|
||||||
'vrf99',
|
'vrf99',
|
||||||
]
|
]
|
||||||
@ -1842,6 +1850,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
'25-vrf.netdev',
|
'25-vrf.netdev',
|
||||||
'25-vrf.network',
|
'25-vrf.network',
|
||||||
'26-link-local-addressing-ipv6.network',
|
'26-link-local-addressing-ipv6.network',
|
||||||
|
'dhcp-client-ipv4-ipv6ra-prefix-client-with-delay.network',
|
||||||
|
'dhcp-server-with-ipv6-prefix.network',
|
||||||
|
'ipv6ra-prefix-client-with-static-ipv4-address.network',
|
||||||
|
'ipv6-prefix-with-delay.network',
|
||||||
'routing-policy-rule-dummy98.network',
|
'routing-policy-rule-dummy98.network',
|
||||||
'routing-policy-rule-test1.network',
|
'routing-policy-rule-test1.network',
|
||||||
'routing-policy-rule-reconfigure1.network',
|
'routing-policy-rule-reconfigure1.network',
|
||||||
@ -3099,6 +3111,22 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
|
|
||||||
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
def test_wait_online_ipv4(self):
|
||||||
|
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-with-ipv6-prefix.network', 'dhcp-client-ipv4-ipv6ra-prefix-client-with-delay.network')
|
||||||
|
start_networkd()
|
||||||
|
|
||||||
|
self.wait_online(['veth99:routable'], ipv4=True)
|
||||||
|
|
||||||
|
self.wait_address('veth99', r'192.168.5.[0-9]+', ipv='-4', timeout_sec=1)
|
||||||
|
|
||||||
|
def test_wait_online_ipv6(self):
|
||||||
|
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix-with-delay.network', 'ipv6ra-prefix-client-with-static-ipv4-address.network')
|
||||||
|
start_networkd()
|
||||||
|
|
||||||
|
self.wait_online(['veth99:routable'], ipv6=True)
|
||||||
|
|
||||||
|
self.wait_address('veth99', r'2002:da8:1:0:1034:56ff:fe78:9abc', ipv='-6', timeout_sec=1)
|
||||||
|
|
||||||
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
||||||
links = [
|
links = [
|
||||||
'dummy98',
|
'dummy98',
|
||||||
@ -3135,10 +3163,13 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
|||||||
|
|
||||||
with open(path) as f:
|
with open(path) as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
|
self.assertRegex(data, r'IPV4_ADDRESS_STATE=routable')
|
||||||
|
self.assertRegex(data, r'IPV6_ADDRESS_STATE=routable')
|
||||||
self.assertRegex(data, r'ADMIN_STATE=configured')
|
self.assertRegex(data, r'ADMIN_STATE=configured')
|
||||||
self.assertRegex(data, r'OPER_STATE=routable')
|
self.assertRegex(data, r'OPER_STATE=routable')
|
||||||
self.assertRegex(data, r'REQUIRED_FOR_ONLINE=yes')
|
self.assertRegex(data, r'REQUIRED_FOR_ONLINE=yes')
|
||||||
self.assertRegex(data, r'REQUIRED_OPER_STATE_FOR_ONLINE=routable')
|
self.assertRegex(data, r'REQUIRED_OPER_STATE_FOR_ONLINE=routable')
|
||||||
|
self.assertRegex(data, r'REQUIRED_FAMILY_FOR_ONLINE=both')
|
||||||
self.assertRegex(data, r'ACTIVATION_POLICY=up')
|
self.assertRegex(data, r'ACTIVATION_POLICY=up')
|
||||||
self.assertRegex(data, r'NETWORK_FILE=/run/systemd/network/state-file-tests.network')
|
self.assertRegex(data, r'NETWORK_FILE=/run/systemd/network/state-file-tests.network')
|
||||||
self.assertRegex(data, r'DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com \[1111:2222::3333\]:1234#ccc.com')
|
self.assertRegex(data, r'DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com \[1111:2222::3333\]:1234#ccc.com')
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#set -ex
|
set -eux
|
||||||
#set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
NPROC=$(nproc)
|
NPROC=$(nproc)
|
||||||
MAX_QUEUE_SIZE=${NPROC:-2}
|
MAX_QUEUE_SIZE=${NPROC:-2}
|
||||||
IFS=$'\n' TEST_LIST=($(ls /usr/lib/systemd/tests/test-*))
|
mapfile -t TEST_LIST < <(find /usr/lib/systemd/tests/ -maxdepth 1 -type f -name "test-*")
|
||||||
|
|
||||||
# reset state
|
# reset state
|
||||||
rm /failed-tests /skipped-tests /skipped
|
rm -fv /failed-tests /skipped-tests /skipped
|
||||||
|
|
||||||
# Check & report test results
|
# Check & report test results
|
||||||
# Arguments:
|
# Arguments:
|
||||||
@ -54,10 +54,9 @@ for task in "${TEST_LIST[@]}"; do
|
|||||||
# until one of the tasks finishes, so we can replace it.
|
# until one of the tasks finishes, so we can replace it.
|
||||||
while [[ ${#running[@]} -ge $MAX_QUEUE_SIZE ]]; do
|
while [[ ${#running[@]} -ge $MAX_QUEUE_SIZE ]]; do
|
||||||
for key in "${!running[@]}"; do
|
for key in "${!running[@]}"; do
|
||||||
if ! kill -0 ${running[$key]} &>/dev/null; then
|
if ! kill -0 "${running[$key]}" &>/dev/null; then
|
||||||
# Task has finished, report its result and drop it from the queue
|
# Task has finished, report its result and drop it from the queue
|
||||||
wait ${running[$key]}
|
wait "${running[$key]}" && ec=0 || ec=$?
|
||||||
ec=$?
|
|
||||||
report_result "$key" $ec
|
report_result "$key" $ec
|
||||||
unset running["$key"]
|
unset running["$key"]
|
||||||
# Break from inner for loop and outer while loop to skip
|
# Break from inner for loop and outer while loop to skip
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
# Test merging of a --job-mode=ignore-dependencies job into a previously
|
# Test merging of a --job-mode=ignore-dependencies job into a previously
|
||||||
# installed job.
|
# installed job.
|
||||||
@ -17,7 +18,7 @@ grep 'hello\.service.*waiting' /root/list-jobs.txt
|
|||||||
START_SEC=$(date -u '+%s')
|
START_SEC=$(date -u '+%s')
|
||||||
systemctl start --job-mode=ignore-dependencies hello
|
systemctl start --job-mode=ignore-dependencies hello
|
||||||
END_SEC=$(date -u '+%s')
|
END_SEC=$(date -u '+%s')
|
||||||
ELAPSED=$(($END_SEC-$START_SEC))
|
ELAPSED=$((END_SEC-START_SEC))
|
||||||
|
|
||||||
test "$ELAPSED" -lt 3
|
test "$ELAPSED" -lt 3
|
||||||
|
|
||||||
@ -75,14 +76,14 @@ EOF
|
|||||||
START_SEC=$(date -u '+%s')
|
START_SEC=$(date -u '+%s')
|
||||||
systemctl start --wait wait2.service
|
systemctl start --wait wait2.service
|
||||||
END_SEC=$(date -u '+%s')
|
END_SEC=$(date -u '+%s')
|
||||||
ELAPSED=$(($END_SEC-$START_SEC))
|
ELAPSED=$((END_SEC-START_SEC))
|
||||||
[[ "$ELAPSED" -ge 2 ]] && [[ "$ELAPSED" -le 4 ]] || exit 1
|
[[ "$ELAPSED" -ge 2 ]] && [[ "$ELAPSED" -le 4 ]] || exit 1
|
||||||
|
|
||||||
# wait5fail fails, so systemctl should fail
|
# wait5fail fails, so systemctl should fail
|
||||||
START_SEC=$(date -u '+%s')
|
START_SEC=$(date -u '+%s')
|
||||||
systemctl start --wait wait2.service wait5fail.service && { echo 'unexpected success'; exit 1; }
|
systemctl start --wait wait2.service wait5fail.service && { echo 'unexpected success'; exit 1; }
|
||||||
END_SEC=$(date -u '+%s')
|
END_SEC=$(date -u '+%s')
|
||||||
ELAPSED=$(($END_SEC-$START_SEC))
|
ELAPSED=$((END_SEC-START_SEC))
|
||||||
[[ "$ELAPSED" -ge 5 ]] && [[ "$ELAPSED" -le 7 ]] || exit 1
|
[[ "$ELAPSED" -ge 5 ]] && [[ "$ELAPSED" -le 7 ]] || exit 1
|
||||||
|
|
||||||
# Test time-limited scopes
|
# Test time-limited scopes
|
||||||
@ -91,7 +92,7 @@ set +e
|
|||||||
systemd-run --scope --property=RuntimeMaxSec=3s sleep 10
|
systemd-run --scope --property=RuntimeMaxSec=3s sleep 10
|
||||||
RESULT=$?
|
RESULT=$?
|
||||||
END_SEC=$(date -u '+%s')
|
END_SEC=$(date -u '+%s')
|
||||||
ELAPSED=$(($END_SEC-$START_SEC))
|
ELAPSED=$((END_SEC-START_SEC))
|
||||||
[[ "$ELAPSED" -ge 3 ]] && [[ "$ELAPSED" -le 5 ]] || exit 1
|
[[ "$ELAPSED" -ge 3 ]] && [[ "$ELAPSED" -le 5 ]] || exit 1
|
||||||
[[ "$RESULT" -ne 0 ]] || exit 1
|
[[ "$RESULT" -ne 0 ]] || exit 1
|
||||||
|
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# Test stdout stream
|
# Test stdout stream
|
||||||
|
|
||||||
# Skip empty lines
|
# Skip empty lines
|
||||||
ID=$(journalctl --new-id128 | sed -n 2p)
|
ID=$(journalctl --new-id128 | sed -n 2p)
|
||||||
>/expected
|
: >/expected
|
||||||
printf $'\n\n\n' | systemd-cat -t "$ID" --level-prefix false
|
printf $'\n\n\n' | systemd-cat -t "$ID" --level-prefix false
|
||||||
journalctl --sync
|
journalctl --sync
|
||||||
journalctl -b -o cat -t "$ID" >/output
|
journalctl -b -o cat -t "$ID" >/output
|
||||||
cmp /expected /output
|
cmp /expected /output
|
||||||
|
|
||||||
ID=$(journalctl --new-id128 | sed -n 2p)
|
ID=$(journalctl --new-id128 | sed -n 2p)
|
||||||
>/expected
|
: >/expected
|
||||||
printf $'<5>\n<6>\n<7>\n' | systemd-cat -t "$ID" --level-prefix true
|
printf $'<5>\n<6>\n<7>\n' | systemd-cat -t "$ID" --level-prefix true
|
||||||
journalctl --sync
|
journalctl --sync
|
||||||
journalctl -b -o cat -t "$ID" >/output
|
journalctl -b -o cat -t "$ID" >/output
|
||||||
@ -55,7 +54,7 @@ ID=$(journalctl --new-id128 | sed -n 2p)
|
|||||||
printf $'foo' | systemd-cat -t "$ID" --level-prefix false
|
printf $'foo' | systemd-cat -t "$ID" --level-prefix false
|
||||||
journalctl --sync
|
journalctl --sync
|
||||||
journalctl -b -o export --output-fields=MESSAGE,FOO --output-fields=PRIORITY,MESSAGE -t "$ID" >/output
|
journalctl -b -o export --output-fields=MESSAGE,FOO --output-fields=PRIORITY,MESSAGE -t "$ID" >/output
|
||||||
[[ `grep -c . /output` -eq 6 ]]
|
[[ $(grep -c . /output) -eq 6 ]]
|
||||||
grep -q '^__CURSOR=' /output
|
grep -q '^__CURSOR=' /output
|
||||||
grep -q '^MESSAGE=foo$' /output
|
grep -q '^MESSAGE=foo$' /output
|
||||||
grep -q '^PRIORITY=6$' /output
|
grep -q '^PRIORITY=6$' /output
|
||||||
@ -83,7 +82,7 @@ journalctl --sync
|
|||||||
# We can drop this grep when https://github.com/systemd/systemd/issues/13937
|
# We can drop this grep when https://github.com/systemd/systemd/issues/13937
|
||||||
# has a fix.
|
# has a fix.
|
||||||
journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output
|
journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output
|
||||||
[[ `grep -c . /output` -eq 2 ]]
|
[[ $(grep -c . /output) -eq 2 ]]
|
||||||
grep -q "^_PID=$PID" /output
|
grep -q "^_PID=$PID" /output
|
||||||
grep -vq "^_PID=$PID" /output
|
grep -vq "^_PID=$PID" /output
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
P=/run/systemd/system.conf.d
|
P=/run/systemd/system.conf.d
|
||||||
@ -19,7 +18,9 @@ systemctl daemon-reload
|
|||||||
[[ "$(systemctl show -P LimitNOFILESoft testsuite-05.service)" = "10000" ]]
|
[[ "$(systemctl show -P LimitNOFILESoft testsuite-05.service)" = "10000" ]]
|
||||||
[[ "$(systemctl show -P LimitNOFILE testsuite-05.service)" = "16384" ]]
|
[[ "$(systemctl show -P LimitNOFILE testsuite-05.service)" = "16384" ]]
|
||||||
|
|
||||||
|
# shellcheck disable=SC2016
|
||||||
systemd-run --wait -t bash -c '[[ "$(ulimit -n -S)" = "10000" ]]'
|
systemd-run --wait -t bash -c '[[ "$(ulimit -n -S)" = "10000" ]]'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
systemd-run --wait -t bash -c '[[ "$(ulimit -n -H)" = "16384" ]]'
|
systemd-run --wait -t bash -c '[[ "$(ulimit -n -H)" = "16384" ]]'
|
||||||
|
|
||||||
touch /testok
|
touch /testok
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
echo 1 >/sys/fs/selinux/enforce || {
|
echo 1 >/sys/fs/selinux/enforce || {
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
set -o pipefail
|
||||||
|
|
||||||
>/failed
|
: >/failed
|
||||||
|
|
||||||
cat <<'EOL' >/lib/systemd/system/my.service
|
cat >/lib/systemd/system/my.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=/bin/echo Timer runs me
|
ExecStart=/bin/echo Timer runs me
|
||||||
EOL
|
EOF
|
||||||
|
|
||||||
cat <<'EOL' >/lib/systemd/system/my.timer
|
cat >/lib/systemd/system/my.timer <<EOF
|
||||||
[Timer]
|
[Timer]
|
||||||
OnBootSec=10s
|
OnBootSec=10s
|
||||||
OnUnitInactiveSec=1h
|
OnUnitInactiveSec=1h
|
||||||
EOL
|
EOF
|
||||||
|
|
||||||
systemctl unmask my.timer
|
systemctl unmask my.timer
|
||||||
|
|
||||||
systemctl start my.timer
|
systemctl start my.timer
|
||||||
|
|
||||||
mkdir -p /etc/systemd/system/my.timer.d/
|
mkdir -p /etc/systemd/system/my.timer.d/
|
||||||
cat <<'EOL' >/etc/systemd/system/my.timer.d/override.conf
|
cat >/etc/systemd/system/my.timer.d/override.conf <<EOF
|
||||||
[Timer]
|
[Timer]
|
||||||
OnBootSec=10s
|
OnBootSec=10s
|
||||||
OnUnitInactiveSec=1h
|
OnUnitInactiveSec=1h
|
||||||
EOL
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
systemctl start fail-on-restart.service
|
systemctl --no-block start fail-on-restart.service
|
||||||
active_state=$(systemctl show --value --property ActiveState fail-on-restart.service)
|
active_state=$(systemctl show --value --property ActiveState fail-on-restart.service)
|
||||||
while [[ "$active_state" == "activating" || "$active_state" == "active" ]]; do
|
while [[ "$active_state" == "activating" || "$active_state" == "active" ]]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
U=/run/systemd/system/test12.socket
|
U=/run/systemd/system/test12.socket
|
||||||
cat <<'EOF' >$U
|
cat >$U <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Test 12 socket
|
Description=Test 12 socket
|
||||||
[Socket]
|
[Socket]
|
||||||
@ -14,7 +13,7 @@ SocketGroup=adm
|
|||||||
SocketMode=0660
|
SocketMode=0660
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<'EOF' >/run/systemd/system/test12@.service
|
cat >/run/systemd/system/test12@.service <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Test service
|
Description=Test service
|
||||||
[Service]
|
[Service]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -x
|
# shellcheck disable=SC2016
|
||||||
set -e
|
set -eux
|
||||||
set -u
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
export SYSTEMD_LOG_LEVEL=debug
|
export SYSTEMD_LOG_LEVEL=debug
|
||||||
@ -31,10 +30,10 @@ if unshare -U sh -c :; then
|
|||||||
is_user_ns_supported=yes
|
is_user_ns_supported=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SUSE_OPTS=""
|
SUSE_OPTS=()
|
||||||
ID_LIKE=$(awk -F= '$1=="ID_LIKE" { print $2 ;}' /etc/os-release)
|
ID_LIKE=$(awk -F= '$1=="ID_LIKE" { print $2 ;}' /etc/os-release)
|
||||||
if [[ "$ID_LIKE" = *"suse"* ]]; then
|
if [[ "$ID_LIKE" = *"suse"* ]]; then
|
||||||
SUSE_OPTS="--bind /lib64 --bind /usr/lib64 "
|
SUSE_OPTS+=(--bind /lib64 --bind /usr/lib64)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function check_bind_tmp_path {
|
function check_bind_tmp_path {
|
||||||
@ -42,8 +41,8 @@ function check_bind_tmp_path {
|
|||||||
local _root="/var/lib/machines/testsuite-13.bind-tmp-path"
|
local _root="/var/lib/machines/testsuite-13.bind-tmp-path"
|
||||||
rm -rf "$_root"
|
rm -rf "$_root"
|
||||||
/usr/lib/systemd/tests/testdata/create-busybox-container "$_root"
|
/usr/lib/systemd/tests/testdata/create-busybox-container "$_root"
|
||||||
>/tmp/bind
|
: >/tmp/bind
|
||||||
systemd-nspawn $SUSE_OPTS--register=no -D "$_root" --bind=/tmp/bind /bin/sh -c 'test -e /tmp/bind'
|
systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" --bind=/tmp/bind /bin/sh -c 'test -e /tmp/bind'
|
||||||
}
|
}
|
||||||
|
|
||||||
function check_norbind {
|
function check_norbind {
|
||||||
@ -55,15 +54,15 @@ function check_norbind {
|
|||||||
mount -t tmpfs tmpfs /tmp/binddir/subdir
|
mount -t tmpfs tmpfs /tmp/binddir/subdir
|
||||||
echo -n "inner" >/tmp/binddir/subdir/file
|
echo -n "inner" >/tmp/binddir/subdir/file
|
||||||
/usr/lib/systemd/tests/testdata/create-busybox-container "$_root"
|
/usr/lib/systemd/tests/testdata/create-busybox-container "$_root"
|
||||||
systemd-nspawn $SUSE_OPTS--register=no -D "$_root" --bind=/tmp/binddir:/mnt:norbind /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi'
|
systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" --bind=/tmp/binddir:/mnt:norbind /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi'
|
||||||
}
|
}
|
||||||
|
|
||||||
function check_notification_socket {
|
function check_notification_socket {
|
||||||
# https://github.com/systemd/systemd/issues/4944
|
# https://github.com/systemd/systemd/issues/4944
|
||||||
local _cmd='echo a | $(busybox which nc) -U -u -w 1 /run/host/notify'
|
local _cmd='echo a | $(busybox which nc) -U -u -w 1 /run/host/notify'
|
||||||
# /testsuite-13.nc-container is prepared by test.sh
|
# /testsuite-13.nc-container is prepared by test.sh
|
||||||
systemd-nspawn $SUSE_OPTS--register=no -D /testsuite-13.nc-container /bin/sh -x -c "$_cmd"
|
systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D /testsuite-13.nc-container /bin/sh -x -c "$_cmd"
|
||||||
systemd-nspawn $SUSE_OPTS--register=no -D /testsuite-13.nc-container -U /bin/sh -x -c "$_cmd"
|
systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D /testsuite-13.nc-container -U /bin/sh -x -c "$_cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
function check_os_release {
|
function check_os_release {
|
||||||
@ -77,15 +76,15 @@ if echo test >>/run/host/os-release; then exit 1; fi
|
|||||||
'
|
'
|
||||||
|
|
||||||
local _os_release_source="/etc/os-release"
|
local _os_release_source="/etc/os-release"
|
||||||
if [ ! -r "${_os_release_source}" ]; then
|
if [[ ! -r "${_os_release_source}" ]]; then
|
||||||
_os_release_source="/usr/lib/os-release"
|
_os_release_source="/usr/lib/os-release"
|
||||||
elif [ -L "${_os_release_source}" ] && rm /etc/os-release; then
|
elif [[ -L "${_os_release_source}" ]] && rm /etc/os-release; then
|
||||||
# Ensure that /etc always wins if available
|
# Ensure that /etc always wins if available
|
||||||
cp /usr/lib/os-release /etc
|
cp /usr/lib/os-release /etc
|
||||||
echo MARKER=1 >>/etc/os-release
|
echo MARKER=1 >>/etc/os-release
|
||||||
fi
|
fi
|
||||||
|
|
||||||
systemd-nspawn $SUSE_OPTS--register=no -D /testsuite-13.nc-container --bind="${_os_release_source}":/tmp/os-release /bin/sh -x -e -c "$_cmd"
|
systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D /testsuite-13.nc-container --bind="${_os_release_source}":/tmp/os-release /bin/sh -x -e -c "$_cmd"
|
||||||
|
|
||||||
if grep -q MARKER /etc/os-release; then
|
if grep -q MARKER /etc/os-release; then
|
||||||
rm /etc/os-release
|
rm /etc/os-release
|
||||||
@ -96,10 +95,10 @@ if echo test >>/run/host/os-release; then exit 1; fi
|
|||||||
function check_machinectl_bind {
|
function check_machinectl_bind {
|
||||||
local _cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; sleep 0.5; done; exit 1;'
|
local _cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; sleep 0.5; done; exit 1;'
|
||||||
|
|
||||||
cat <<EOF >/run/systemd/system/nspawn_machinectl_bind.service
|
cat >/run/systemd/system/nspawn_machinectl_bind.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
Type=notify
|
Type=notify
|
||||||
ExecStart=systemd-nspawn $SUSE_OPTS -D /testsuite-13.nc-container --notify-ready=no /bin/sh -x -e -c "$_cmd"
|
ExecStart=systemd-nspawn ${SUSE_OPTS[@]} -D /testsuite-13.nc-container --notify-ready=no /bin/sh -x -e -c "$_cmd"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl start nspawn_machinectl_bind.service
|
systemctl start nspawn_machinectl_bind.service
|
||||||
@ -113,7 +112,7 @@ EOF
|
|||||||
sleep 0.1
|
sleep 0.1
|
||||||
done
|
done
|
||||||
|
|
||||||
return $(systemctl show -P ExecMainStatus nspawn_machinectl_bind.service)
|
return "$(systemctl show -P ExecMainStatus nspawn_machinectl_bind.service)"
|
||||||
}
|
}
|
||||||
|
|
||||||
function run {
|
function run {
|
||||||
@ -129,65 +128,54 @@ function run {
|
|||||||
local _root="/var/lib/machines/testsuite-13.unified-$1-cgns-$2-api-vfs-writable-$3"
|
local _root="/var/lib/machines/testsuite-13.unified-$1-cgns-$2-api-vfs-writable-$3"
|
||||||
rm -rf "$_root"
|
rm -rf "$_root"
|
||||||
/usr/lib/systemd/tests/testdata/create-busybox-container "$_root"
|
/usr/lib/systemd/tests/testdata/create-busybox-container "$_root"
|
||||||
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" -b
|
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" -b
|
||||||
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" --private-network -b
|
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" --private-network -b
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" -U -b; then
|
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" -U -b; then
|
||||||
[[ "$is_user_ns_supported" = "yes" && "$3" = "network" ]] && return 1
|
[[ "$is_user_ns_supported" = "yes" && "$3" = "network" ]] && return 1
|
||||||
else
|
else
|
||||||
[[ "$is_user_ns_supported" = "no" && "$3" = "network" ]] && return 1
|
[[ "$is_user_ns_supported" = "no" && "$3" = "network" ]] && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" --private-network -U -b; then
|
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" --private-network -U -b; then
|
||||||
[[ "$is_user_ns_supported" = "yes" && "$3" = "yes" ]] && return 1
|
[[ "$is_user_ns_supported" = "yes" && "$3" = "yes" ]] && return 1
|
||||||
else
|
else
|
||||||
[[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1
|
[[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local _netns_opt="--network-namespace-path=/proc/self/ns/net"
|
local _netns_opt="--network-namespace-path=/proc/self/ns/net"
|
||||||
|
local _net_opts=(
|
||||||
|
"--network-bridge=lo"
|
||||||
|
"--network-interface=lo"
|
||||||
|
"--network-ipvlan=lo"
|
||||||
|
"--network-macvlan=lo"
|
||||||
|
"--network-veth"
|
||||||
|
"--network-veth-extra=lo"
|
||||||
|
"--network-zone=zone"
|
||||||
|
)
|
||||||
|
|
||||||
# --network-namespace-path and network-related options cannot be used together
|
# --network-namespace-path and network-related options cannot be used together
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-interface=lo -b; then
|
for netopt in "${_net_opts[@]}"; do
|
||||||
return 1
|
echo "$_netns_opt in combination with $netopt should fail"
|
||||||
fi
|
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" -b "$_netns_opt" "$netopt"; then
|
||||||
|
echo >&2 "unexpected pass"
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-macvlan=lo -b; then
|
return 1
|
||||||
return 1
|
fi
|
||||||
fi
|
done
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-ipvlan=lo -b; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-veth -b; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-veth-extra=lo -b; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-bridge=lo -b; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --network-zone=zone -b; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# allow combination of --network-namespace-path and --private-network
|
# allow combination of --network-namespace-path and --private-network
|
||||||
if ! SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" --private-network -b; then
|
if ! SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" -b "$_netns_opt" --private-network; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# test --network-namespace-path works with a network namespace created by "ip netns"
|
# test --network-namespace-path works with a network namespace created by "ip netns"
|
||||||
ip netns add nspawn_test
|
ip netns add nspawn_test
|
||||||
_netns_opt="--network-namespace-path=/run/netns/nspawn_test"
|
_netns_opt="--network-namespace-path=/run/netns/nspawn_test"
|
||||||
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn $SUSE_OPTS--register=no -D "$_root" "$_netns_opt" /bin/ip a | grep -v -E '^1: lo.*UP'
|
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn "${SUSE_OPTS[@]}" --register=no -D "$_root" "$_netns_opt" /bin/ip a | grep -v -E '^1: lo.*UP'
|
||||||
local r=$?
|
local r=$?
|
||||||
ip netns del nspawn_test
|
ip netns del nspawn_test
|
||||||
|
|
||||||
if [ $r -ne 0 ]; then
|
if [[ $r -ne 0 ]]; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
function setup_root {
|
function setup_root {
|
||||||
local _root="$1"
|
local _root="$1"
|
||||||
@ -21,18 +21,18 @@ r="$(pwd)/overwrite-broken-machine-id"
|
|||||||
setup_root "$r"
|
setup_root "$r"
|
||||||
systemd-machine-id-setup --print --root "$r"
|
systemd-machine-id-setup --print --root "$r"
|
||||||
echo abc >>"$r/etc/machine-id"
|
echo abc >>"$r/etc/machine-id"
|
||||||
id=$(systemd-machine-id-setup --print --root "$r")
|
id="$(systemd-machine-id-setup --print --root "$r")"
|
||||||
echo $id >expected
|
echo "$id" >expected
|
||||||
check expected "$r/etc/machine-id"
|
check expected "$r/etc/machine-id"
|
||||||
|
|
||||||
r="$(pwd)/transient-machine-id"
|
r="$PWD/transient-machine-id"
|
||||||
setup_root "$r"
|
setup_root "$r"
|
||||||
systemd-machine-id-setup --print --root "$r"
|
systemd-machine-id-setup --print --root "$r"
|
||||||
echo abc >>"$r/etc/machine-id"
|
echo abc >>"$r/etc/machine-id"
|
||||||
mount -o remount,ro "$r"
|
mount -o remount,ro "$r"
|
||||||
mount -t tmpfs tmpfs "$r/run"
|
mount -t tmpfs tmpfs "$r/run"
|
||||||
transient_id=$(systemd-machine-id-setup --print --root "$r")
|
transient_id="$(systemd-machine-id-setup --print --root "$r")"
|
||||||
mount -o remount,rw "$r"
|
mount -o remount,rw "$r"
|
||||||
commited_id=$(systemd-machine-id-setup --print --commit --root "$r")
|
commited_id="$(systemd-machine-id-setup --print --commit --root "$r")"
|
||||||
[[ "$transient_id" = "$commited_id" ]]
|
[[ "$transient_id" = "$commited_id" ]]
|
||||||
check "$r/etc/machine-id" "$r/run/machine-id"
|
check "$r/etc/machine-id" "$r/run/machine-id"
|
||||||
|
@ -1,53 +1,55 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
_clear_service () {
|
_clear_service () {
|
||||||
systemctl stop $1.service 2>/dev/null || :
|
local SERVICE_NAME="${1:?_clear_service: missing argument}"
|
||||||
rm -f /{etc,run,usr/lib}/systemd/system/$1.service
|
systemctl stop "$SERVICE_NAME.service" 2>/dev/null || :
|
||||||
rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d
|
rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service
|
||||||
rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires}
|
rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d
|
||||||
if [[ $1 == *@ ]]; then
|
rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires}
|
||||||
systemctl stop $1*.service 2>/dev/null || :
|
if [[ $SERVICE_NAME == *@ ]]; then
|
||||||
rm -f /{etc,run,usr/lib}/systemd/system/$1*.service
|
systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || :
|
||||||
rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d
|
rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service
|
||||||
rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires}
|
rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d
|
||||||
|
rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_services () {
|
clear_services () {
|
||||||
for u in $*; do
|
for u in "$@"; do
|
||||||
_clear_service $u
|
_clear_service "$u"
|
||||||
done
|
done
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
}
|
}
|
||||||
|
|
||||||
create_service () {
|
create_service () {
|
||||||
clear_services $1
|
local SERVICE_NAME="${1:?create_service: missing argument}"
|
||||||
|
clear_services "$SERVICE_NAME"
|
||||||
|
|
||||||
cat >/etc/systemd/system/$1.service<<EOF
|
cat >/etc/systemd/system/"$SERVICE_NAME".service <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=$1 unit
|
Description=$SERVICE_NAME unit
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/bin/sleep 100000
|
ExecStart=/bin/sleep 100000
|
||||||
EOF
|
EOF
|
||||||
mkdir -p /{etc,run,usr/lib}/systemd/system/$1.service.d
|
mkdir -p /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d
|
||||||
mkdir -p /etc/systemd/system/$1.service.{wants,requires}
|
mkdir -p /etc/systemd/system/"$SERVICE_NAME".service.{wants,requires}
|
||||||
mkdir -p /run/systemd/system/$1.service.{wants,requires}
|
mkdir -p /run/systemd/system/"$SERVICE_NAME".service.{wants,requires}
|
||||||
mkdir -p /usr/lib/systemd/system/$1.service.{wants,requires}
|
mkdir -p /usr/lib/systemd/system/"$SERVICE_NAME".service.{wants,requires}
|
||||||
}
|
}
|
||||||
|
|
||||||
create_services () {
|
create_services () {
|
||||||
for u in $*; do
|
for u in "$@"; do
|
||||||
create_service $u
|
create_service "$u"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
check_ok () {
|
check_ok () {
|
||||||
[ $# -eq 3 ] || return
|
[ $# -eq 3 ] || return
|
||||||
|
|
||||||
x="$(systemctl show --value -p $2 $1)"
|
x="$(systemctl show --value -p "$2" "$1")"
|
||||||
case "$x" in
|
case "$x" in
|
||||||
*$3*) return 0 ;;
|
*$3*) return 0 ;;
|
||||||
*) return 1 ;;
|
*) return 1 ;;
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -v -x
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
rm -f /test.log
|
rm -f /test.log
|
||||||
|
|
||||||
TL=/test.log.XXXXXXXX
|
TESTLOG=/test.log.XXXXXXXX
|
||||||
|
|
||||||
function wait_for()
|
function wait_for()
|
||||||
{
|
{
|
||||||
service=${1}
|
local service="${1:-wait_for: missing service argument}"
|
||||||
result=${2:-success}
|
local result="${2:-success}"
|
||||||
time=${3:-45}
|
local time="${3:-45}"
|
||||||
|
|
||||||
while [[ ! -f /${service}.terminated && ! -f /${service}.success && $time -gt 0 ]]
|
while [[ ! -f /${service}.terminated && ! -f /${service}.success && $time -gt 0 ]]; do
|
||||||
do
|
|
||||||
sleep 1
|
sleep 1
|
||||||
time=$(( $time - 1 ))
|
time=$((time - 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ! -f /${service}.${result} ]]
|
if [[ ! -f /${service}.${result} ]]; then
|
||||||
then
|
journalctl -u "${service/_/-}.service" >>"$TESTLOG"
|
||||||
journalctl -u ${service/_/-}.service >> "${TL}"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +43,11 @@ wait_for fail_start startfail
|
|||||||
wait_for fail_stop stopfail
|
wait_for fail_stop stopfail
|
||||||
wait_for fail_runtime runtimefail
|
wait_for fail_runtime runtimefail
|
||||||
|
|
||||||
if [[ -f "${TL}" ]]
|
if [[ -f "$TESTLOG" ]]; then
|
||||||
then
|
|
||||||
# no mv
|
# no mv
|
||||||
cp "${TL}" /test.log
|
cp "$TESTLOG" /test.log
|
||||||
exit 1
|
exit 1
|
||||||
else
|
|
||||||
touch /testok
|
|
||||||
exit 0
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
touch /testok
|
||||||
|
exit 0
|
||||||
|
@ -27,7 +27,7 @@ run_test() {
|
|||||||
|
|
||||||
echo add >/sys/class/net/lo/uevent
|
echo add >/sys/class/net/lo/uevent
|
||||||
|
|
||||||
for n in {1..20}; do
|
for _ in {1..20}; do
|
||||||
sleep 5
|
sleep 5
|
||||||
if coredumpctl --since "$since" --no-legend --no-pager | grep /bin/udevadm ; then
|
if coredumpctl --since "$since" --no-legend --no-pager | grep /bin/udevadm ; then
|
||||||
return 0
|
return 0
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
set -o pipefail
|
||||||
|
|
||||||
>/failed
|
: >/failed
|
||||||
|
|
||||||
for t in ${0%.sh}.*.sh; do
|
for t in "${0%.sh}".*.sh; do
|
||||||
echo "Running $t"; ./$t
|
echo "Running $t"; ./"$t"
|
||||||
done
|
done
|
||||||
|
|
||||||
touch /testok
|
touch /testok
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-run --wait -p FailureAction=poweroff true
|
systemd-run --wait -p FailureAction=poweroff true
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
if grep -q cgroup2 /proc/filesystems ; then
|
if grep -q cgroup2 /proc/filesystems ; then
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
systemd-analyze log-target console
|
systemd-analyze log-target console
|
||||||
|
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
# Start a test process inside of our own cgroup
|
# Start a test process inside of our own cgroup
|
||||||
sleep infinity &
|
sleep infinity &
|
||||||
@ -14,45 +14,45 @@ disown
|
|||||||
|
|
||||||
# Start a test process outside of our own cgroup
|
# Start a test process outside of our own cgroup
|
||||||
systemd-run -p DynamicUser=1 --unit=test20-sleep.service /bin/sleep infinity
|
systemd-run -p DynamicUser=1 --unit=test20-sleep.service /bin/sleep infinity
|
||||||
EXTERNALPID=`systemctl show -P MainPID test20-sleep.service`
|
EXTERNALPID="$(systemctl show -P MainPID test20-sleep.service)"
|
||||||
|
|
||||||
# Update our own main PID to the external test PID, this should work
|
# Update our own main PID to the external test PID, this should work
|
||||||
systemd-notify MAINPID=$EXTERNALPID
|
systemd-notify MAINPID="$EXTERNALPID"
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $EXTERNALPID
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq "$EXTERNALPID"
|
||||||
|
|
||||||
# Update our own main PID to the internal test PID, this should work, too
|
# Update our own main PID to the internal test PID, this should work, too
|
||||||
systemd-notify MAINPID=$INTERNALPID
|
systemd-notify MAINPID=$INTERNALPID
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $INTERNALPID
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq "$INTERNALPID"
|
||||||
|
|
||||||
# Update it back to our own PID, this should also work
|
# Update it back to our own PID, this should also work
|
||||||
systemd-notify MAINPID=$$
|
systemd-notify MAINPID=$$
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
# Try to set it to PID 1, which it should ignore, because that's the manager
|
# Try to set it to PID 1, which it should ignore, because that's the manager
|
||||||
systemd-notify MAINPID=1
|
systemd-notify MAINPID=1
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
# Try to set it to PID 0, which is invalid and should be ignored
|
# Try to set it to PID 0, which is invalid and should be ignored
|
||||||
systemd-notify MAINPID=0
|
systemd-notify MAINPID=0
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
# Try to set it to a valid but non-existing PID, which should be ignored. (Note
|
# Try to set it to a valid but non-existing PID, which should be ignored. (Note
|
||||||
# that we set the PID to a value well above any known /proc/sys/kernel/pid_max,
|
# that we set the PID to a value well above any known /proc/sys/kernel/pid_max,
|
||||||
# which means we can be pretty sure it doesn't exist by coincidence)
|
# which means we can be pretty sure it doesn't exist by coincidence)
|
||||||
systemd-notify MAINPID=1073741824
|
systemd-notify MAINPID=1073741824
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
# Change it again to the external PID, without privileges this time. This should be ignored, because the PID is from outside of our cgroup and we lack privileges.
|
# Change it again to the external PID, without privileges this time. This should be ignored, because the PID is from outside of our cgroup and we lack privileges.
|
||||||
systemd-notify --uid=1000 MAINPID=$EXTERNALPID
|
systemd-notify --uid=1000 MAINPID="$EXTERNALPID"
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
# Change it again to the internal PID, without privileges this time. This should work, as the process is on our cgroup, and that's enough even if we lack privileges.
|
# Change it again to the internal PID, without privileges this time. This should work, as the process is on our cgroup, and that's enough even if we lack privileges.
|
||||||
systemd-notify --uid=1000 MAINPID=$INTERNALPID
|
systemd-notify --uid=1000 MAINPID="$INTERNALPID"
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $INTERNALPID
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq "$INTERNALPID"
|
||||||
|
|
||||||
# Update it back to our own PID, this should also work
|
# Update it back to our own PID, this should also work
|
||||||
systemd-notify --uid=1000 MAINPID=$$
|
systemd-notify --uid=1000 MAINPID=$$
|
||||||
test `systemctl show -P MainPID testsuite-20.service` -eq $$
|
test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
|
||||||
|
|
||||||
cat >/tmp/test20-mainpid.sh <<EOF
|
cat >/tmp/test20-mainpid.sh <<EOF
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
@ -76,7 +76,7 @@ EOF
|
|||||||
chmod +x /tmp/test20-mainpid.sh
|
chmod +x /tmp/test20-mainpid.sh
|
||||||
|
|
||||||
systemd-run --unit=test20-mainpidsh.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh -p PIDFile=/run/mainpidsh/pid /tmp/test20-mainpid.sh
|
systemd-run --unit=test20-mainpidsh.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh -p PIDFile=/run/mainpidsh/pid /tmp/test20-mainpid.sh
|
||||||
test `systemctl show -P MainPID test20-mainpidsh.service` -eq `cat /run/mainpidsh/pid`
|
test "$(systemctl show -P MainPID test20-mainpidsh.service)" -eq "$(cat /run/mainpidsh/pid)"
|
||||||
|
|
||||||
cat >/tmp/test20-mainpid2.sh <<EOF
|
cat >/tmp/test20-mainpid2.sh <<EOF
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
@ -101,7 +101,7 @@ EOF
|
|||||||
chmod +x /tmp/test20-mainpid2.sh
|
chmod +x /tmp/test20-mainpid2.sh
|
||||||
|
|
||||||
systemd-run --unit=test20-mainpidsh2.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh2 -p PIDFile=/run/mainpidsh2/pid /tmp/test20-mainpid2.sh
|
systemd-run --unit=test20-mainpidsh2.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh2 -p PIDFile=/run/mainpidsh2/pid /tmp/test20-mainpid2.sh
|
||||||
test `systemctl show -P MainPID test20-mainpidsh2.service` -eq `cat /run/mainpidsh2/pid`
|
test "$(systemctl show -P MainPID test20-mainpidsh2.service)" -eq "$(cat /run/mainpidsh2/pid)"
|
||||||
|
|
||||||
cat >/dev/shm/test20-mainpid3.sh <<EOF
|
cat >/dev/shm/test20-mainpid3.sh <<EOF
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
@ -140,7 +140,7 @@ systemd-run --unit=test20-mainpidsh3.service \
|
|||||||
&& { echo 'unexpected success'; exit 1; }
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
# Test that this failed due to timeout, and not some other error
|
# Test that this failed due to timeout, and not some other error
|
||||||
test $(systemctl show -P Result test20-mainpidsh3.service) = timeout
|
test "$(systemctl show -P Result test20-mainpidsh3.service)" = timeout
|
||||||
|
|
||||||
systemd-analyze log-level info
|
systemd-analyze log-level info
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# With "e" don't attempt to set permissions when file doesn't exist, see
|
# With "e" don't attempt to set permissions when file doesn't exist, see
|
||||||
# https://github.com/systemd/systemd/pull/6682.
|
# https://github.com/systemd/systemd/pull/6682.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
rm -fr /tmp/test
|
rm -fr /tmp/test
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Basic tests for types creating directories
|
# Basic tests for types creating directories
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
rm -fr /tmp/{C,d,D,e}
|
rm -fr /tmp/{C,d,D,e}
|
||||||
mkdir /tmp/{C,d,D,e}
|
mkdir /tmp/{C,d,D,e}
|
||||||
@ -21,10 +21,10 @@ d /tmp/d/2 0755 daemon daemon - -
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test -d /tmp/d/1
|
test -d /tmp/d/1
|
||||||
test $(stat -c %U:%G:%a /tmp/d/1) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/d/1)" = "daemon:daemon:755"
|
||||||
|
|
||||||
test -d /tmp/d/2
|
test -d /tmp/d/2
|
||||||
test $(stat -c %U:%G:%a /tmp/d/2) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/d/2)" = "daemon:daemon:755"
|
||||||
|
|
||||||
#
|
#
|
||||||
# 'D'
|
# 'D'
|
||||||
@ -39,10 +39,10 @@ D /tmp/D/2 0755 daemon daemon - -
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test -d /tmp/D/1
|
test -d /tmp/D/1
|
||||||
test $(stat -c %U:%G:%a /tmp/D/1) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/D/1)" = "daemon:daemon:755"
|
||||||
|
|
||||||
test -d /tmp/D/2
|
test -d /tmp/D/2
|
||||||
test $(stat -c %U:%G:%a /tmp/D/2) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/D/2)" = "daemon:daemon:755"
|
||||||
|
|
||||||
systemd-tmpfiles --remove - <<EOF
|
systemd-tmpfiles --remove - <<EOF
|
||||||
D /tmp/D/2 0755 daemon daemon - -
|
D /tmp/D/2 0755 daemon daemon - -
|
||||||
@ -66,12 +66,12 @@ EOF
|
|||||||
test ! -d /tmp/e/1
|
test ! -d /tmp/e/1
|
||||||
|
|
||||||
test -d /tmp/e/2
|
test -d /tmp/e/2
|
||||||
test $(stat -c %U:%G:%a /tmp/e/2) = "root:root:777"
|
test "$(stat -c %U:%G:%a /tmp/e/2)" = "root:root:777"
|
||||||
|
|
||||||
test -d /tmp/e/2/d1
|
test -d /tmp/e/2/d1
|
||||||
test $(stat -c %U:%G:%a /tmp/e/2/d1) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/e/2/d1)" = "daemon:daemon:755"
|
||||||
test -d /tmp/e/2/d2
|
test -d /tmp/e/2/d2
|
||||||
test $(stat -c %U:%G:%a /tmp/e/2/d2) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/e/2/d2)" = "daemon:daemon:755"
|
||||||
|
|
||||||
# 'e' operates on directories only
|
# 'e' operates on directories only
|
||||||
mkdir -p /tmp/e/3/{d1,d2}
|
mkdir -p /tmp/e/3/{d1,d2}
|
||||||
@ -87,12 +87,12 @@ EOF
|
|||||||
# the directories should have been processed although systemd-tmpfiles failed
|
# the directories should have been processed although systemd-tmpfiles failed
|
||||||
# previously due to the presence of a file.
|
# previously due to the presence of a file.
|
||||||
test -d /tmp/e/3/d1
|
test -d /tmp/e/3/d1
|
||||||
test $(stat -c %U:%G:%a /tmp/e/3/d1) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/e/3/d1)" = "daemon:daemon:755"
|
||||||
test -d /tmp/e/3/d2
|
test -d /tmp/e/3/d2
|
||||||
test $(stat -c %U:%G:%a /tmp/e/3/d2) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/e/3/d2)" = "daemon:daemon:755"
|
||||||
|
|
||||||
test -f /tmp/e/3/f1
|
test -f /tmp/e/3/f1
|
||||||
test $(stat -c %U:%G:%a /tmp/e/3/f1) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/e/3/f1)" = "root:root:644"
|
||||||
|
|
||||||
#
|
#
|
||||||
# 'C'
|
# 'C'
|
||||||
@ -111,12 +111,12 @@ C /tmp/C/2 0755 daemon daemon - /tmp/C/2-origin
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test -d /tmp/C/1
|
test -d /tmp/C/1
|
||||||
test $(stat -c %U:%G:%a /tmp/C/1/f1) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/C/1/f1)" = "daemon:daemon:755"
|
||||||
test -d /tmp/C/2
|
test -d /tmp/C/2
|
||||||
test $(stat -c %U:%G:%a /tmp/C/2/f1) = "daemon:daemon:755"
|
test "$(stat -c %U:%G:%a /tmp/C/2/f1)" = "daemon:daemon:755"
|
||||||
|
|
||||||
systemd-tmpfiles --create - <<EOF
|
systemd-tmpfiles --create - <<EOF
|
||||||
C /tmp/C/3 0755 daemon daemon - /tmp/C/3-origin
|
C /tmp/C/3 0755 daemon daemon - /tmp/C/3-origin
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test $(stat -c %U:%G:%a /tmp/C/3/f1) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/C/3/f1)" = "root:root:644"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Basic tests for types creating/writing files
|
# Basic tests for types creating/writing files
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
rm -fr /tmp/{f,F,w}
|
rm -fr /tmp/{f,F,w}
|
||||||
mkdir /tmp/{f,F,w}
|
mkdir /tmp/{f,F,w}
|
||||||
@ -20,9 +20,9 @@ EOF
|
|||||||
|
|
||||||
### '1' should exist and be empty
|
### '1' should exist and be empty
|
||||||
test -f /tmp/f/1; test ! -s /tmp/f/1
|
test -f /tmp/f/1; test ! -s /tmp/f/1
|
||||||
test $(stat -c %U:%G:%a /tmp/f/1) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/f/1)" = "root:root:644"
|
||||||
|
|
||||||
test $(stat -c %U:%G:%a /tmp/f/2) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/f/2)" = "root:root:644"
|
||||||
test "$(< /tmp/f/2)" = "This string should be written"
|
test "$(< /tmp/f/2)" = "This string should be written"
|
||||||
|
|
||||||
### The perms are supposed to be updated even if the file already exists.
|
### The perms are supposed to be updated even if the file already exists.
|
||||||
@ -32,7 +32,7 @@ EOF
|
|||||||
|
|
||||||
# file should be empty
|
# file should be empty
|
||||||
test ! -s /tmp/f/1
|
test ! -s /tmp/f/1
|
||||||
test $(stat -c %U:%G:%a /tmp/f/1) = "daemon:daemon:666"
|
test "$(stat -c %U:%G:%a /tmp/f/1)" = "daemon:daemon:666"
|
||||||
|
|
||||||
### But we shouldn't try to set perms on an existing file which is not a
|
### But we shouldn't try to set perms on an existing file which is not a
|
||||||
### regular one.
|
### regular one.
|
||||||
@ -44,7 +44,7 @@ f /tmp/f/fifo 0666 daemon daemon - This string should not be written
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test -p /tmp/f/fifo
|
test -p /tmp/f/fifo
|
||||||
test $(stat -c %U:%G:%a /tmp/f/fifo) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644"
|
||||||
|
|
||||||
### 'f' should not follow symlinks.
|
### 'f' should not follow symlinks.
|
||||||
ln -s missing /tmp/f/dangling
|
ln -s missing /tmp/f/dangling
|
||||||
@ -55,7 +55,7 @@ f /tmp/f/dangling 0644 daemon daemon - -
|
|||||||
f /tmp/f/symlink 0644 daemon daemon - -
|
f /tmp/f/symlink 0644 daemon daemon - -
|
||||||
EOF
|
EOF
|
||||||
test ! -e /tmp/f/missing
|
test ! -e /tmp/f/missing
|
||||||
test $(stat -c %U:%G:%a /tmp/file-owned-by-root) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644"
|
||||||
|
|
||||||
### Handle read-only filesystem gracefully: we shouldn't fail if the target
|
### Handle read-only filesystem gracefully: we shouldn't fail if the target
|
||||||
### already exists and have the correct perms.
|
### already exists and have the correct perms.
|
||||||
@ -75,7 +75,7 @@ test -f /tmp/f/ro-fs/foo; test ! -s /tmp/f/ro-fs/foo
|
|||||||
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
||||||
f /tmp/f/ro-fs/foo 0666 - - - -
|
f /tmp/f/ro-fs/foo 0666 - - - -
|
||||||
EOF
|
EOF
|
||||||
test $(stat -c %U:%G:%a /tmp/f/fifo) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644"
|
||||||
|
|
||||||
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
||||||
f /tmp/f/ro-fs/bar 0644 - - - -
|
f /tmp/f/ro-fs/bar 0644 - - - -
|
||||||
@ -109,9 +109,9 @@ test -f /tmp/F/created; test ! -s /tmp/F/created
|
|||||||
test -f /tmp/F/created-with-content
|
test -f /tmp/F/created-with-content
|
||||||
test "$(< /tmp/F/created-with-content)" = "new content"
|
test "$(< /tmp/F/created-with-content)" = "new content"
|
||||||
test -f /tmp/F/truncated; test ! -s /tmp/F/truncated
|
test -f /tmp/F/truncated; test ! -s /tmp/F/truncated
|
||||||
test $(stat -c %U:%G:%a /tmp/F/truncated) = "daemon:daemon:666"
|
test "$(stat -c %U:%G:%a /tmp/F/truncated)" = "daemon:daemon:666"
|
||||||
test -s /tmp/F/truncated-with-content
|
test -s /tmp/F/truncated-with-content
|
||||||
test $(stat -c %U:%G:%a /tmp/F/truncated-with-content) = "daemon:daemon:666"
|
test "$(stat -c %U:%G:%a /tmp/F/truncated-with-content)" = "daemon:daemon:666"
|
||||||
|
|
||||||
### We shouldn't try to truncate anything but regular files since the behavior is
|
### We shouldn't try to truncate anything but regular files since the behavior is
|
||||||
### unspecified in the other cases.
|
### unspecified in the other cases.
|
||||||
@ -132,7 +132,7 @@ f /tmp/F/dangling 0644 daemon daemon - -
|
|||||||
f /tmp/F/symlink 0644 daemon daemon - -
|
f /tmp/F/symlink 0644 daemon daemon - -
|
||||||
EOF
|
EOF
|
||||||
test ! -e /tmp/F/missing
|
test ! -e /tmp/F/missing
|
||||||
test $(stat -c %U:%G:%a /tmp/file-owned-by-root) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644"
|
||||||
|
|
||||||
### Handle read-only filesystem gracefully: we shouldn't fail if the target
|
### Handle read-only filesystem gracefully: we shouldn't fail if the target
|
||||||
### already exists and is empty.
|
### already exists and is empty.
|
||||||
@ -161,11 +161,11 @@ test -f /tmp/F/ro-fs/foo
|
|||||||
grep -q 'truncating is not allowed' /tmp/F/ro-fs/foo
|
grep -q 'truncating is not allowed' /tmp/F/ro-fs/foo
|
||||||
|
|
||||||
# Trying to change the perms should fail.
|
# Trying to change the perms should fail.
|
||||||
>/tmp/F/rw-fs/foo
|
: >/tmp/F/rw-fs/foo
|
||||||
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
||||||
F /tmp/F/ro-fs/foo 0666 - - - -
|
F /tmp/F/ro-fs/foo 0666 - - - -
|
||||||
EOF
|
EOF
|
||||||
test $(stat -c %U:%G:%a /tmp/F/ro-fs/foo) = "root:root:644"
|
test "$(stat -c %U:%G:%a /tmp/F/ro-fs/foo)" = "root:root:644"
|
||||||
|
|
||||||
### Try to create a new file.
|
### Try to create a new file.
|
||||||
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
systemd-tmpfiles --create - <<EOF && { echo 'unexpected success'; exit 1; }
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Basic tests for types creating fifos
|
# Basic tests for types creating fifos
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
rm -fr /tmp/p
|
rm -fr /tmp/p
|
||||||
mkdir /tmp/p
|
mkdir /tmp/p
|
||||||
@ -15,7 +15,7 @@ p /tmp/p/fifo1 0666 - - - -
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test -p /tmp/p/fifo1
|
test -p /tmp/p/fifo1
|
||||||
test $(stat -c %U:%G:%a /tmp/p/fifo1) = "root:root:666"
|
test "$(stat -c %U:%G:%a /tmp/p/fifo1)" = "root:root:666"
|
||||||
|
|
||||||
# Refuse to overwrite an existing file. Error is not propagated.
|
# Refuse to overwrite an existing file. Error is not propagated.
|
||||||
systemd-tmpfiles --create - <<EOF
|
systemd-tmpfiles --create - <<EOF
|
||||||
@ -30,7 +30,7 @@ p+ /tmp/p/f1 0666 - - - -
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test -p /tmp/p/f1
|
test -p /tmp/p/f1
|
||||||
test $(stat -c %U:%G:%a /tmp/p/f1) = "root:root:666"
|
test "$(stat -c %U:%G:%a /tmp/p/f1)" = "root:root:666"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Must be fixed
|
# Must be fixed
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
rm -fr /tmp/{z,Z}
|
rm -fr /tmp/{z,Z}
|
||||||
mkdir /tmp/{z,Z}
|
mkdir /tmp/{z,Z}
|
||||||
@ -17,15 +17,15 @@ z /tmp/z/f1 0755 daemon daemon - -
|
|||||||
z /tmp/z/d1 0755 daemon daemon - -
|
z /tmp/z/d1 0755 daemon daemon - -
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test $(stat -c %U:%G /tmp/z/f1) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/z/f1)" = "daemon:daemon"
|
||||||
test $(stat -c %U:%G /tmp/z/d1) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/z/d1)" = "daemon:daemon"
|
||||||
test $(stat -c %U:%G /tmp/z/d1/f11) = "root:root"
|
test "$(stat -c %U:%G /tmp/z/d1/f11)" = "root:root"
|
||||||
|
|
||||||
systemd-tmpfiles --create - <<EOF
|
systemd-tmpfiles --create - <<EOF
|
||||||
z /tmp/z/d2/* 0755 daemon daemon - -
|
z /tmp/z/d2/* 0755 daemon daemon - -
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test $(stat -c %U:%G /tmp/z/d2/f21) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/z/d2/f21)" = "daemon:daemon"
|
||||||
|
|
||||||
#
|
#
|
||||||
# 'Z'
|
# 'Z'
|
||||||
@ -38,8 +38,8 @@ Z /tmp/Z/f1 0755 daemon daemon - -
|
|||||||
Z /tmp/Z/d1 0755 daemon daemon - -
|
Z /tmp/Z/d1 0755 daemon daemon - -
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test $(stat -c %U:%G /tmp/Z/f1) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/Z/f1)" = "daemon:daemon"
|
||||||
test $(stat -c %U:%G /tmp/Z/d1) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/Z/d1)" = "daemon:daemon"
|
||||||
test $(stat -c %U:%G /tmp/Z/d1/d11) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/Z/d1/d11)" = "daemon:daemon"
|
||||||
test $(stat -c %U:%G /tmp/Z/d1/f11) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/Z/d1/f11)" = "daemon:daemon"
|
||||||
test $(stat -c %U:%G /tmp/Z/d1/d11/f111) = "daemon:daemon"
|
test "$(stat -c %U:%G /tmp/Z/d1/d11/f111)" = "daemon:daemon"
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Inspired by https://github.com/systemd/systemd/issues/9508
|
# Inspired by https://github.com/systemd/systemd/issues/9508
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
test_snippet() {
|
test_snippet() {
|
||||||
systemd-tmpfiles "$@" - <<EOF
|
systemd-tmpfiles "$@" - <<EOF
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Verifies the issues described by https://github.com/systemd/systemd/issues/10191
|
# Verifies the issues described by https://github.com/systemd/systemd/issues/10191
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
rm -rf /tmp/test-prefix
|
rm -rf /tmp/test-prefix
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Verify tmpfiles can run in a root directory under a path prefix that contains
|
# Verify tmpfiles can run in a root directory under a path prefix that contains
|
||||||
# directories owned by unprivileged users, for example when a root file system
|
# directories owned by unprivileged users, for example when a root file system
|
||||||
@ -7,7 +7,8 @@
|
|||||||
# https://github.com/systemd/systemd/pull/11820
|
# https://github.com/systemd/systemd/pull/11820
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
rm -fr /tmp/root /tmp/user
|
rm -fr /tmp/root /tmp/user
|
||||||
mkdir -p /tmp/root /tmp/user/root
|
mkdir -p /tmp/root /tmp/user/root
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
set -o pipefail
|
||||||
|
|
||||||
# Make sure that the "stat" output is not locale dependent.
|
# Make sure that the "stat" output is not locale dependent.
|
||||||
export LANG=C LC_ALL=C
|
export LANG=C LC_ALL=C
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -eux
|
||||||
set -x
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-tmpfiles --create - <<EOF
|
systemd-tmpfiles --create - <<EOF
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -x
|
set -eux
|
||||||
set -e
|
set -o pipefail
|
||||||
|
|
||||||
>/failed
|
: >/failed
|
||||||
|
|
||||||
for t in ${0%.sh}.*.sh; do
|
for t in "${0%.sh}".*.sh; do
|
||||||
echo "Running $t"; ./$t
|
echo "Running $t"; ./"$t"
|
||||||
done
|
done
|
||||||
|
|
||||||
touch /testok
|
touch /testok
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
@ -21,8 +21,8 @@ systemd-run --unit=six -p Type=exec /tmp/brokenbinary && { echo 'unexpected succ
|
|||||||
|
|
||||||
systemd-run --unit=seven -p KillSignal=SIGTERM -p RestartKillSignal=SIGINT -p Type=exec /bin/sleep infinity
|
systemd-run --unit=seven -p KillSignal=SIGTERM -p RestartKillSignal=SIGINT -p Type=exec /bin/sleep infinity
|
||||||
# Both TERM and SIGINT happen to have the same number on all architectures
|
# Both TERM and SIGINT happen to have the same number on all architectures
|
||||||
test $(systemctl show --value -p KillSignal seven.service) -eq 15
|
test "$(systemctl show --value -p KillSignal seven.service)" -eq 15
|
||||||
test $(systemctl show --value -p RestartKillSignal seven.service) -eq 2
|
test "$(systemctl show --value -p RestartKillSignal seven.service)" -eq 2
|
||||||
|
|
||||||
systemctl restart seven.service
|
systemctl restart seven.service
|
||||||
systemctl stop seven.service
|
systemctl stop seven.service
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
export SYSTEMD_PAGER=cat
|
export SYSTEMD_PAGER=cat
|
||||||
@ -120,6 +120,7 @@ test ! -f /var/lib/machines/scratch4
|
|||||||
machinectl image-status scratch4 && { echo 'unexpected success'; exit 1; }
|
machinectl image-status scratch4 && { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
# Test import-tar hyphen/stdin pipe behavior
|
# Test import-tar hyphen/stdin pipe behavior
|
||||||
|
# shellcheck disable=SC2002
|
||||||
cat /var/tmp/scratch.tar.gz | machinectl import-tar - scratch5
|
cat /var/tmp/scratch.tar.gz | machinectl import-tar - scratch5
|
||||||
test -d /var/lib/machines/scratch5
|
test -d /var/lib/machines/scratch5
|
||||||
machinectl image-status scratch5
|
machinectl image-status scratch5
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# Make sure PATH is set
|
# Make sure PATH is set
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
export SYSTEMD_LOG_LEVEL=debug
|
export SYSTEMD_LOG_LEVEL=debug
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
if journalctl -b -t systemd --grep '\.device: Changed plugged -> dead'; then
|
if journalctl -b -t systemd --grep '\.device: Changed plugged -> dead'; then
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# Let's run this test only if the "memory.oom.group" cgroupfs attribute
|
# Let's run this test only if the "memory.oom.group" cgroupfs attribute
|
||||||
@ -9,7 +9,6 @@ set -o pipefail
|
|||||||
# kernels where the concept was still new.
|
# kernels where the concept was still new.
|
||||||
|
|
||||||
if test -f /sys/fs/cgroup/system.slice/testsuite-32.service/memory.oom.group; then
|
if test -f /sys/fs/cgroup/system.slice/testsuite-32.service/memory.oom.group; then
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
systemd-analyze log-target console
|
systemd-analyze log-target console
|
||||||
|
|
||||||
@ -23,12 +22,12 @@ if test -f /sys/fs/cgroup/system.slice/testsuite-32.service/memory.oom.group; th
|
|||||||
echo f >/proc/sysrq-trigger
|
echo f >/proc/sysrq-trigger
|
||||||
|
|
||||||
while : ; do
|
while : ; do
|
||||||
STATE=`systemctl show -P ActiveState oomtest.service`
|
STATE="$(systemctl show -P ActiveState oomtest.service)"
|
||||||
[ "$STATE" = "failed" ] && break
|
[ "$STATE" = "failed" ] && break
|
||||||
sleep .5
|
sleep .5
|
||||||
done
|
done
|
||||||
|
|
||||||
RESULT=`systemctl show -P Result oomtest.service`
|
RESULT="$(systemctl show -P Result oomtest.service)"
|
||||||
test "$RESULT" = "oom-kill"
|
test "$RESULT" = "oom-kill"
|
||||||
|
|
||||||
systemd-analyze log-level info
|
systemd-analyze log-level info
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
cat >/etc/systemd/system/testservice.service <<EOF
|
cat >/etc/systemd/system/testservice.service <<EOF
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
at_exit() {
|
at_exit() {
|
||||||
if [ $? -ne 0 ]; then
|
# shellcheck disable=SC2181
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
# We're exiting with a non-zero EC, let's dump test artifacts
|
# We're exiting with a non-zero EC, let's dump test artifacts
|
||||||
# for easier debugging
|
# for easier debugging
|
||||||
[ -f "$straceLog" ] && cat "$straceLog"
|
[[ -v straceLog && -f "$straceLog" ]] && cat "$straceLog"
|
||||||
[ -f "$journalLog" ] && cat "$journalLog"
|
[[ -v journalLog && -f "$journalLog" ]] && cat "$journalLog"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,25 +27,28 @@ testUnitFile="/run/systemd/system/$testUnit"
|
|||||||
testUnitNUMAConf="$testUnitFile.d/numa.conf"
|
testUnitNUMAConf="$testUnitFile.d/numa.conf"
|
||||||
|
|
||||||
# Sleep constants (we should probably figure out something better but nothing comes to mind)
|
# Sleep constants (we should probably figure out something better but nothing comes to mind)
|
||||||
journalSleep=5
|
|
||||||
sleepAfterStart=1
|
sleepAfterStart=1
|
||||||
|
|
||||||
# Journal cursor for easier navigation
|
# Journal cursor for easier navigation
|
||||||
journalCursorFile="jounalCursorFile"
|
journalCursorFile="jounalCursorFile"
|
||||||
|
|
||||||
startStrace() {
|
startStrace() {
|
||||||
coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1
|
coproc strace -qq -p 1 -o "$straceLog" -e set_mempolicy -s 1024 ${1:+"$1"}
|
||||||
# Wait for strace to properly "initialize"
|
# Wait for strace to properly "initialize"
|
||||||
sleep $sleepAfterStart
|
sleep $sleepAfterStart
|
||||||
}
|
}
|
||||||
|
|
||||||
stopStrace() {
|
stopStrace() {
|
||||||
kill -s TERM $COPROC_PID
|
[[ -v COPROC_PID ]] || return
|
||||||
|
|
||||||
|
local PID=$COPROC_PID
|
||||||
|
kill -s TERM "$PID"
|
||||||
# Make sure the strace process is indeed dead
|
# Make sure the strace process is indeed dead
|
||||||
while kill -0 $COPROC_PID 2>/dev/null; do sleep 0.1; done
|
while kill -0 "$PID" 2>/dev/null; do sleep 0.1; done
|
||||||
}
|
}
|
||||||
|
|
||||||
startJournalctl() {
|
startJournalctl() {
|
||||||
|
: >"$journalCursorFile"
|
||||||
# Save journal's cursor for later navigation
|
# Save journal's cursor for later navigation
|
||||||
journalctl --no-pager --cursor-file="$journalCursorFile" -n0 -ocat
|
journalctl --no-pager --cursor-file="$journalCursorFile" -n0 -ocat
|
||||||
}
|
}
|
||||||
@ -55,7 +59,7 @@ stopJournalctl() {
|
|||||||
# the --sync wait until the synchronization is complete
|
# the --sync wait until the synchronization is complete
|
||||||
echo "Force journald to write all queued messages"
|
echo "Force journald to write all queued messages"
|
||||||
journalctl --sync
|
journalctl --sync
|
||||||
journalctl -u $unit --cursor-file="$journalCursorFile" >"$journalLog"
|
journalctl -u "$unit" --cursor-file="$journalCursorFile" >"$journalLog"
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNUMA() {
|
checkNUMA() {
|
||||||
@ -64,21 +68,24 @@ checkNUMA() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writePID1NUMAPolicy() {
|
writePID1NUMAPolicy() {
|
||||||
echo [Manager] >$confDir/numa.conf
|
cat >"$confDir/numa.conf" <<EOF
|
||||||
echo NUMAPolicy=$1 >>$confDir/numa.conf
|
[Manager]
|
||||||
echo NUMAMask=$2 >>$confDir/numa.conf
|
NUMAPolicy=${1:?missing argument: NUMAPolicy}
|
||||||
|
NUMAMask=${2:-""}
|
||||||
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
writeTestUnit() {
|
writeTestUnit() {
|
||||||
mkdir -p $testUnitFile.d/
|
mkdir -p "$testUnitFile.d/"
|
||||||
echo [Service] >$testUnitFile
|
printf "[Service]\nExecStart=/bin/sleep 3600\n" >"$testUnitFile"
|
||||||
echo ExecStart=/bin/sleep 3600 >>$testUnitFile
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeTestUnitNUMAPolicy() {
|
writeTestUnitNUMAPolicy() {
|
||||||
echo [Service] >$testUnitNUMAConf
|
cat >"$testUnitNUMAConf" <<EOF
|
||||||
echo NUMAPolicy=$1 >>$testUnitNUMAConf
|
[Service]
|
||||||
echo NUMAMask=$2 >>$testUnitNUMAConf
|
NUMAPolicy=${1:?missing argument: NUMAPolicy}
|
||||||
|
NUMAMask=${2:-""}
|
||||||
|
EOF
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,32 +104,38 @@ pid1ReloadWithJournal() {
|
|||||||
|
|
||||||
pid1StartUnitWithStrace() {
|
pid1StartUnitWithStrace() {
|
||||||
startStrace '-f'
|
startStrace '-f'
|
||||||
systemctl start $1
|
systemctl start "${1:?missing unit name}"
|
||||||
sleep $sleepAfterStart
|
sleep $sleepAfterStart
|
||||||
stopStrace
|
stopStrace
|
||||||
}
|
}
|
||||||
|
|
||||||
pid1StartUnitWithJournal() {
|
pid1StartUnitWithJournal() {
|
||||||
startJournalctl
|
startJournalctl
|
||||||
systemctl start $1
|
systemctl start "${1:?missing unit name}"
|
||||||
sleep $sleepAfterStart
|
sleep $sleepAfterStart
|
||||||
stopJournalctl
|
stopJournalctl
|
||||||
}
|
}
|
||||||
|
|
||||||
pid1StopUnit() {
|
pid1StopUnit() {
|
||||||
systemctl stop $1
|
systemctl stop "${1:?missing unit name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
systemctlCheckNUMAProperties() {
|
systemctlCheckNUMAProperties() {
|
||||||
local LOGFILE="$(mktemp)"
|
local UNIT_NAME="${1:?missing unit name}"
|
||||||
systemctl show -p NUMAPolicy $1 >"$LOGFILE"
|
local NUMA_POLICY="${2:?missing NUMAPolicy}"
|
||||||
grep "NUMAPolicy=$2" "$LOGFILE"
|
local NUMA_MASK="${3:-""}"
|
||||||
|
local LOGFILE
|
||||||
|
|
||||||
>"$LOGFILE"
|
LOGFILE="$(mktemp)"
|
||||||
|
|
||||||
if [ -n "$3" ]; then
|
systemctl show -p NUMAPolicy "$UNIT_NAME" >"$LOGFILE"
|
||||||
systemctl show -p NUMAMask $1 >"$LOGFILE"
|
grep "NUMAPolicy=$NUMA_POLICY" "$LOGFILE"
|
||||||
grep "NUMAMask=$3" "$LOGFILE"
|
|
||||||
|
: >"$LOGFILE"
|
||||||
|
|
||||||
|
if [ -n "$NUMA_MASK" ]; then
|
||||||
|
systemctl show -p NUMAMask "$UNIT_NAME" >"$LOGFILE"
|
||||||
|
grep "NUMAMask=$NUMA_MASK" "$LOGFILE"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +158,10 @@ if ! checkNUMA; then
|
|||||||
echo "systemd-run NUMAPolicy=default && NUMAMask=0 check without NUMA support"
|
echo "systemd-run NUMAPolicy=default && NUMAMask=0 check without NUMA support"
|
||||||
runUnit='numa-systemd-run-test.service'
|
runUnit='numa-systemd-run-test.service'
|
||||||
startJournalctl
|
startJournalctl
|
||||||
systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit "$runUnit" sleep 1000
|
||||||
sleep $sleepAfterStart
|
sleep $sleepAfterStart
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
stopJournalctl $runUnit
|
stopJournalctl "$runUnit"
|
||||||
grep "NUMA support not available, ignoring" "$journalLog"
|
grep "NUMA support not available, ignoring" "$journalLog"
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -156,43 +169,43 @@ else
|
|||||||
writePID1NUMAPolicy "default"
|
writePID1NUMAPolicy "default"
|
||||||
pid1ReloadWithStrace
|
pid1ReloadWithStrace
|
||||||
# Kernel requires that nodemask argument is set to NULL when setting default policy
|
# Kernel requires that nodemask argument is set to NULL when setting default policy
|
||||||
grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
|
grep "set_mempolicy(MPOL_DEFAULT, NULL" "$straceLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Default policy w/ mask"
|
echo "PID1 NUMAPolicy support - Default policy w/ mask"
|
||||||
writePID1NUMAPolicy "default" "0"
|
writePID1NUMAPolicy "default" "0"
|
||||||
pid1ReloadWithStrace
|
pid1ReloadWithStrace
|
||||||
grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
|
grep "set_mempolicy(MPOL_DEFAULT, NULL" "$straceLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Bind policy w/o mask"
|
echo "PID1 NUMAPolicy support - Bind policy w/o mask"
|
||||||
writePID1NUMAPolicy "bind"
|
writePID1NUMAPolicy "bind"
|
||||||
pid1ReloadWithJournal
|
pid1ReloadWithJournal
|
||||||
grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
|
grep "Failed to set NUMA memory policy: Invalid argument" "$journalLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Bind policy w/ mask"
|
echo "PID1 NUMAPolicy support - Bind policy w/ mask"
|
||||||
writePID1NUMAPolicy "bind" "0"
|
writePID1NUMAPolicy "bind" "0"
|
||||||
pid1ReloadWithStrace
|
pid1ReloadWithStrace
|
||||||
grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
|
grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" "$straceLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Interleave policy w/o mask"
|
echo "PID1 NUMAPolicy support - Interleave policy w/o mask"
|
||||||
writePID1NUMAPolicy "interleave"
|
writePID1NUMAPolicy "interleave"
|
||||||
pid1ReloadWithJournal
|
pid1ReloadWithJournal
|
||||||
grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
|
grep "Failed to set NUMA memory policy: Invalid argument" "$journalLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Interleave policy w/ mask"
|
echo "PID1 NUMAPolicy support - Interleave policy w/ mask"
|
||||||
writePID1NUMAPolicy "interleave" "0"
|
writePID1NUMAPolicy "interleave" "0"
|
||||||
pid1ReloadWithStrace
|
pid1ReloadWithStrace
|
||||||
grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
|
grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" "$straceLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Preferred policy w/o mask"
|
echo "PID1 NUMAPolicy support - Preferred policy w/o mask"
|
||||||
writePID1NUMAPolicy "preferred"
|
writePID1NUMAPolicy "preferred"
|
||||||
pid1ReloadWithJournal
|
pid1ReloadWithJournal
|
||||||
# Preferred policy with empty node mask is actually allowed and should reset allocation policy to default
|
# Preferred policy with empty node mask is actually allowed and should reset allocation policy to default
|
||||||
! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
|
grep "Failed to set NUMA memory policy: Invalid argument" "$journalLog" && { echo >&2 "unexpected pass"; exit 1; }
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Preferred policy w/ mask"
|
echo "PID1 NUMAPolicy support - Preferred policy w/ mask"
|
||||||
writePID1NUMAPolicy "preferred" "0"
|
writePID1NUMAPolicy "preferred" "0"
|
||||||
pid1ReloadWithStrace
|
pid1ReloadWithStrace
|
||||||
grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
|
grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" "$straceLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Local policy w/o mask"
|
echo "PID1 NUMAPolicy support - Local policy w/o mask"
|
||||||
writePID1NUMAPolicy "local"
|
writePID1NUMAPolicy "local"
|
||||||
@ -202,136 +215,133 @@ else
|
|||||||
# return a numerical constant instead (with a comment):
|
# return a numerical constant instead (with a comment):
|
||||||
# set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0
|
# set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0
|
||||||
# Let's cover this scenario as well
|
# Let's cover this scenario as well
|
||||||
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
|
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" "$straceLog"
|
||||||
|
|
||||||
echo "PID1 NUMAPolicy support - Local policy w/ mask"
|
echo "PID1 NUMAPolicy support - Local policy w/ mask"
|
||||||
writePID1NUMAPolicy "local" "0"
|
writePID1NUMAPolicy "local" "0"
|
||||||
pid1ReloadWithStrace
|
pid1ReloadWithStrace
|
||||||
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
|
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Default policy w/o mask"
|
echo "Unit file NUMAPolicy support - Default policy w/o mask"
|
||||||
writeTestUnitNUMAPolicy "default"
|
writeTestUnitNUMAPolicy "default"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "default"
|
systemctlCheckNUMAProperties "$testUnit" "default"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
|
grep "set_mempolicy(MPOL_DEFAULT, NULL" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Default policy w/ mask"
|
echo "Unit file NUMAPolicy support - Default policy w/ mask"
|
||||||
writeTestUnitNUMAPolicy "default" "0"
|
writeTestUnitNUMAPolicy "default" "0"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "default" "0"
|
systemctlCheckNUMAProperties "$testUnit" "default" "0"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit $testUnit
|
||||||
# Mask must be ignored
|
# Mask must be ignored
|
||||||
grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
|
grep "set_mempolicy(MPOL_DEFAULT, NULL" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Bind policy w/o mask"
|
echo "Unit file NUMAPolicy support - Bind policy w/o mask"
|
||||||
writeTestUnitNUMAPolicy "bind"
|
writeTestUnitNUMAPolicy "bind"
|
||||||
pid1StartUnitWithJournal $testUnit
|
pid1StartUnitWithJournal "$testUnit"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
|
grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" "$journalLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Bind policy w/ mask"
|
echo "Unit file NUMAPolicy support - Bind policy w/ mask"
|
||||||
writeTestUnitNUMAPolicy "bind" "0"
|
writeTestUnitNUMAPolicy "bind" "0"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "bind" "0"
|
systemctlCheckNUMAProperties "$testUnit" "bind" "0"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
|
grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Interleave policy w/o mask"
|
echo "Unit file NUMAPolicy support - Interleave policy w/o mask"
|
||||||
writeTestUnitNUMAPolicy "interleave"
|
writeTestUnitNUMAPolicy "interleave"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
|
grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" "$journalLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Interleave policy w/ mask"
|
echo "Unit file NUMAPolicy support - Interleave policy w/ mask"
|
||||||
writeTestUnitNUMAPolicy "interleave" "0"
|
writeTestUnitNUMAPolicy "interleave" "0"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "interleave" "0"
|
systemctlCheckNUMAProperties "$testUnit" "interleave" "0"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
|
grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Preferred policy w/o mask"
|
echo "Unit file NUMAPolicy support - Preferred policy w/o mask"
|
||||||
writeTestUnitNUMAPolicy "preferred"
|
writeTestUnitNUMAPolicy "preferred"
|
||||||
pid1StartUnitWithJournal $testUnit
|
pid1StartUnitWithJournal "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "preferred"
|
systemctlCheckNUMAProperties "$testUnit" "preferred"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
|
grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" "$journalLog" && { echo >&2 "unexpected pass"; exit 1; }
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Preferred policy w/ mask"
|
echo "Unit file NUMAPolicy support - Preferred policy w/ mask"
|
||||||
writeTestUnitNUMAPolicy "preferred" "0"
|
writeTestUnitNUMAPolicy "preferred" "0"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "preferred" "0"
|
systemctlCheckNUMAProperties "$testUnit" "preferred" "0"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
|
grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Local policy w/o mask"
|
echo "Unit file NUMAPolicy support - Local policy w/o mask"
|
||||||
writeTestUnitNUMAPolicy "local"
|
writeTestUnitNUMAPolicy "local"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "local"
|
systemctlCheckNUMAProperties "$testUnit" "local"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
|
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file NUMAPolicy support - Local policy w/ mask"
|
echo "Unit file NUMAPolicy support - Local policy w/ mask"
|
||||||
writeTestUnitNUMAPolicy "local" "0"
|
writeTestUnitNUMAPolicy "local" "0"
|
||||||
pid1StartUnitWithStrace $testUnit
|
pid1StartUnitWithStrace "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "local" "0"
|
systemctlCheckNUMAProperties "$testUnit" "local" "0"
|
||||||
pid1StopUnit $testUnit
|
pid1StopUnit "$testUnit"
|
||||||
# Mask must be ignored
|
# Mask must be ignored
|
||||||
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
|
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" "$straceLog"
|
||||||
|
|
||||||
echo "Unit file CPUAffinity=NUMA support"
|
echo "Unit file CPUAffinity=NUMA support"
|
||||||
writeTestUnitNUMAPolicy "bind" "0"
|
writeTestUnitNUMAPolicy "bind" "0"
|
||||||
echo "CPUAffinity=numa" >>$testUnitNUMAConf
|
echo "CPUAffinity=numa" >>"$testUnitNUMAConf"
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start $testUnit
|
systemctl start "$testUnit"
|
||||||
systemctlCheckNUMAProperties $testUnit "bind" "0"
|
systemctlCheckNUMAProperties "$testUnit" "bind" "0"
|
||||||
pid=$(systemctl show --value -p MainPID $testUnit)
|
cpulist="$(cat /sys/devices/system/node/node0/cpulist)"
|
||||||
cpulist=$(cat /sys/devices/system/node/node0/cpulist)
|
affinity_systemd="$(systemctl show --value -p CPUAffinity "$testUnit")"
|
||||||
affinity_systemd=$(systemctl show --value -p CPUAffinity $testUnit)
|
[ "$cpulist" = "$affinity_systemd" ]
|
||||||
[ $cpulist = $affinity_systemd ]
|
pid1StopUnit "$testUnit"
|
||||||
pid1StopUnit $testUnit
|
|
||||||
|
|
||||||
echo "systemd-run NUMAPolicy support"
|
echo "systemd-run NUMAPolicy support"
|
||||||
runUnit='numa-systemd-run-test.service'
|
runUnit='numa-systemd-run-test.service'
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=default --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "default"
|
systemctlCheckNUMAProperties "$runUnit" "default"
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "default" ""
|
systemctlCheckNUMAProperties "$runUnit" "default" ""
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "bind" "0"
|
systemctlCheckNUMAProperties "$runUnit" "bind" "0"
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "interleave" "0"
|
systemctlCheckNUMAProperties "$runUnit" "interleave" "0"
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "preferred" "0"
|
systemctlCheckNUMAProperties "$runUnit" "preferred" "0"
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=local --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "local"
|
systemctlCheckNUMAProperties "$runUnit" "local"
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000
|
systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit "$runUnit" sleep 1000
|
||||||
systemctlCheckNUMAProperties $runUnit "local" ""
|
systemctlCheckNUMAProperties "$runUnit" "local" ""
|
||||||
pid1StopUnit $runUnit
|
pid1StopUnit "$runUnit"
|
||||||
|
|
||||||
systemd-run -p NUMAPolicy=local -p NUMAMask=0 -p CPUAffinity=numa --unit $runUnit sleep 1000
|
|
||||||
systemctlCheckNUMAProperties $runUnit "local" ""
|
|
||||||
systemctl cat $runUnit | grep -q 'CPUAffinity=numa'
|
|
||||||
pid1StopUnit $runUnit
|
|
||||||
|
|
||||||
|
systemd-run -p NUMAPolicy=local -p NUMAMask=0 -p CPUAffinity=numa --unit "$runUnit" sleep 1000
|
||||||
|
systemctlCheckNUMAProperties "$runUnit" "local" ""
|
||||||
|
systemctl cat "$runUnit" | grep -q 'CPUAffinity=numa'
|
||||||
|
pid1StopUnit "$runUnit"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
rm -rf $testDir
|
rm -rf "$confDir"
|
||||||
rm -rf $confDir
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
||||||
systemd-analyze log-level info
|
systemd-analyze log-level info
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-mount -p RuntimeDirectory=hoge -p RuntimeDirectoryPreserve=yes -t tmpfs tmpfs /tmp/aaa
|
systemd-mount -p RuntimeDirectory=hoge -p RuntimeDirectoryPreserve=yes -t tmpfs tmpfs /tmp/aaa
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
@ -14,11 +14,11 @@ start_test_service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbus_freeze() {
|
dbus_freeze() {
|
||||||
local suffix=
|
local name object_path suffix
|
||||||
suffix="${1##*.}"
|
|
||||||
|
|
||||||
local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)"
|
suffix="${1##*.}"
|
||||||
local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}"
|
name="${1%.$suffix}"
|
||||||
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
||||||
|
|
||||||
busctl call \
|
busctl call \
|
||||||
org.freedesktop.systemd1 \
|
org.freedesktop.systemd1 \
|
||||||
@ -28,11 +28,11 @@ dbus_freeze() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbus_thaw() {
|
dbus_thaw() {
|
||||||
local suffix=
|
local name object_path suffix
|
||||||
suffix="${1##*.}"
|
|
||||||
|
|
||||||
local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)"
|
suffix="${1##*.}"
|
||||||
local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}"
|
name="${1%.$suffix}"
|
||||||
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
||||||
|
|
||||||
busctl call \
|
busctl call \
|
||||||
org.freedesktop.systemd1 \
|
org.freedesktop.systemd1 \
|
||||||
@ -62,11 +62,11 @@ dbus_thaw_unit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbus_can_freeze() {
|
dbus_can_freeze() {
|
||||||
local suffix=
|
local name object_path suffix
|
||||||
suffix="${1##*.}"
|
|
||||||
|
|
||||||
local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)"
|
suffix="${1##*.}"
|
||||||
local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}"
|
name="${1%.$suffix}"
|
||||||
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
||||||
|
|
||||||
busctl get-property \
|
busctl get-property \
|
||||||
org.freedesktop.systemd1 \
|
org.freedesktop.systemd1 \
|
||||||
@ -76,11 +76,11 @@ dbus_can_freeze() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_freezer_state() {
|
check_freezer_state() {
|
||||||
local suffix=
|
local name object_path suffix
|
||||||
suffix="${1##*.}"
|
|
||||||
|
|
||||||
local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)"
|
suffix="${1##*.}"
|
||||||
local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}"
|
name="${1%.$suffix}"
|
||||||
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
||||||
|
|
||||||
state=$(busctl get-property \
|
state=$(busctl get-property \
|
||||||
org.freedesktop.systemd1 \
|
org.freedesktop.systemd1 \
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
@ -18,12 +18,12 @@ ExecReload=/bin/false
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start $SERVICE_NAME
|
systemctl start "$SERVICE_NAME"
|
||||||
systemctl status $SERVICE_NAME
|
systemctl status "$SERVICE_NAME"
|
||||||
# The reload SHOULD fail but SHOULD NOT affect the service state
|
# The reload SHOULD fail but SHOULD NOT affect the service state
|
||||||
systemctl reload $SERVICE_NAME && { echo 'unexpected success'; exit 1; }
|
systemctl reload "$SERVICE_NAME" && { echo 'unexpected success'; exit 1; }
|
||||||
systemctl status $SERVICE_NAME
|
systemctl status "$SERVICE_NAME"
|
||||||
systemctl stop $SERVICE_NAME
|
systemctl stop "$SERVICE_NAME"
|
||||||
|
|
||||||
|
|
||||||
echo "[#2] Failing ExecReload= should not kill the service (multiple ExecReload=)"
|
echo "[#2] Failing ExecReload= should not kill the service (multiple ExecReload=)"
|
||||||
@ -36,12 +36,12 @@ ExecReload=/bin/true
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start $SERVICE_NAME
|
systemctl start "$SERVICE_NAME"
|
||||||
systemctl status $SERVICE_NAME
|
systemctl status "$SERVICE_NAME"
|
||||||
# The reload SHOULD fail but SHOULD NOT affect the service state
|
# The reload SHOULD fail but SHOULD NOT affect the service state
|
||||||
systemctl reload $SERVICE_NAME && { echo 'unexpected success'; exit 1; }
|
systemctl reload "$SERVICE_NAME" && { echo 'unexpected success'; exit 1; }
|
||||||
systemctl status $SERVICE_NAME
|
systemctl status "$SERVICE_NAME"
|
||||||
systemctl stop $SERVICE_NAME
|
systemctl stop "$SERVICE_NAME"
|
||||||
|
|
||||||
echo "[#3] Failing ExecReload=- should not affect reload's exit code"
|
echo "[#3] Failing ExecReload=- should not affect reload's exit code"
|
||||||
cat >"$SERVICE_PATH" <<EOF
|
cat >"$SERVICE_PATH" <<EOF
|
||||||
@ -51,11 +51,11 @@ ExecReload=-/bin/false
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start $SERVICE_NAME
|
systemctl start "$SERVICE_NAME"
|
||||||
systemctl status $SERVICE_NAME
|
systemctl status "$SERVICE_NAME"
|
||||||
systemctl reload $SERVICE_NAME
|
systemctl reload "$SERVICE_NAME"
|
||||||
systemctl status $SERVICE_NAME
|
systemctl status "$SERVICE_NAME"
|
||||||
systemctl stop $SERVICE_NAME
|
systemctl stop "$SERVICE_NAME"
|
||||||
|
|
||||||
systemd-analyze log-level info
|
systemd-analyze log-level info
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# wait this many secs for each test service to succeed in what is being tested
|
# wait this many secs for each test service to succeed in what is being tested
|
||||||
@ -12,7 +12,7 @@ systemd-analyze log-target console
|
|||||||
systemd-run --unit=one -p Type=oneshot -p Restart=on-failure /bin/bash -c "exit 1" \
|
systemd-run --unit=one -p Type=oneshot -p Restart=on-failure /bin/bash -c "exit 1" \
|
||||||
&& { echo 'unexpected success'; exit 1; }
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
for ((secs=0; secs<$MAX_SECS; secs++)); do
|
for ((secs = 0; secs < MAX_SECS; secs++)); do
|
||||||
[[ "$(systemctl show one.service -P NRestarts)" -le 0 ]] || break
|
[[ "$(systemctl show one.service -P NRestarts)" -le 0 ]] || break
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
@ -35,7 +35,7 @@ systemd-run --unit=two \
|
|||||||
&& { echo 'unexpected success'; exit 1; }
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
# wait for at least 3 restarts
|
# wait for at least 3 restarts
|
||||||
for ((secs=0; secs<$MAX_SECS; secs++)); do
|
for ((secs = 0; secs < MAX_SECS; secs++)); do
|
||||||
[[ $(cat $TMP_FILE) != "aaa" ]] || break
|
[[ $(cat $TMP_FILE) != "aaa" ]] || break
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
@ -7,6 +7,7 @@ systemd-analyze log-level debug
|
|||||||
runas() {
|
runas() {
|
||||||
declare userid=$1
|
declare userid=$1
|
||||||
shift
|
shift
|
||||||
|
# shellcheck disable=SC2016
|
||||||
su "$userid" -s /bin/sh -c 'XDG_RUNTIME_DIR=/run/user/$UID exec "$@"' -- sh "$@"
|
su "$userid" -s /bin/sh -c 'XDG_RUNTIME_DIR=/run/user/$UID exec "$@"' -- sh "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ runas testuser systemd-run --wait --user --unit=test-protect-home-tmpfs \
|
|||||||
-P test ! -e /home/testuser
|
-P test ! -e /home/testuser
|
||||||
|
|
||||||
# Confirm that home, /root, and /run/user are inaccessible under "yes"
|
# Confirm that home, /root, and /run/user are inaccessible under "yes"
|
||||||
|
# shellcheck disable=SC2016
|
||||||
runas testuser systemd-run --wait --user --unit=test-protect-home-yes \
|
runas testuser systemd-run --wait --user --unit=test-protect-home-yes \
|
||||||
-p PrivateUsers=yes -p ProtectHome=yes \
|
-p PrivateUsers=yes -p ProtectHome=yes \
|
||||||
-P bash -c '
|
-P bash -c '
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# Check if homectl is installed, and if it isn't bail out early instead of failing
|
# Check if homectl is installed, and if it isn't bail out early instead of failing
|
||||||
@ -14,8 +14,9 @@ inspect() {
|
|||||||
# avoid unexpected fails. To see the full outputs of both homectl &
|
# avoid unexpected fails. To see the full outputs of both homectl &
|
||||||
# userdbctl (for debugging purposes) drop the fields just before the
|
# userdbctl (for debugging purposes) drop the fields just before the
|
||||||
# comparison.
|
# comparison.
|
||||||
homectl inspect $1 | tee /tmp/a
|
local USERNAME="${1:?missing argument}"
|
||||||
userdbctl user $1 | tee /tmp/b
|
homectl inspect "$USERNAME" | tee /tmp/a
|
||||||
|
userdbctl user "$USERNAME" | tee /tmp/b
|
||||||
|
|
||||||
diff -I '/^\s*Disk (Size|Free|Floor|Ceiling):/' /tmp/{a,b}
|
diff -I '/^\s*Disk (Size|Free|Floor|Ceiling):/' /tmp/{a,b}
|
||||||
rm /tmp/{a,b}
|
rm /tmp/{a,b}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||||
set -ex
|
set -eux
|
||||||
|
|
||||||
cat >/run/systemd/system/testservice-48.target <<EOF
|
cat >/run/systemd/system/testservice-48.target <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
|
|
||||||
echo "MARKER_FIXED" >/run/testservice-49-fixed
|
echo "MARKER_FIXED" >/run/testservice-49-fixed
|
||||||
mkdir -p /run/inaccessible
|
mkdir -p /run/inaccessible
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
export SYSTEMD_LOG_LEVEL=debug
|
export SYSTEMD_LOG_LEVEL=debug
|
||||||
@ -26,48 +26,48 @@ trap cleanup EXIT
|
|||||||
|
|
||||||
cp /usr/share/minimal* "${image_dir}/"
|
cp /usr/share/minimal* "${image_dir}/"
|
||||||
image="${image_dir}/minimal_0"
|
image="${image_dir}/minimal_0"
|
||||||
roothash="$(cat ${image}.roothash)"
|
roothash="$(cat "${image}.roothash")"
|
||||||
|
|
||||||
os_release=$(test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os-release)
|
os_release="$(test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os-release)"
|
||||||
|
|
||||||
systemd-dissect --json=short ${image}.raw | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
|
systemd-dissect --json=short "${image}.raw" | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
|
||||||
systemd-dissect ${image}.raw | grep -q -F "MARKER=1"
|
systemd-dissect "${image}.raw" | grep -q -F "MARKER=1"
|
||||||
systemd-dissect ${image}.raw | grep -q -F -f <(sed 's/"//g' $os_release)
|
systemd-dissect "${image}.raw" | grep -q -F -f <(sed 's/"//g' "$os_release")
|
||||||
|
|
||||||
mv ${image}.verity ${image}.fooverity
|
mv "${image}.verity" "${image}.fooverity"
|
||||||
mv ${image}.roothash ${image}.foohash
|
mv "${image}.roothash" "${image}.foohash"
|
||||||
systemd-dissect --json=short ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
|
systemd-dissect --json=short "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
|
||||||
systemd-dissect ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F "MARKER=1"
|
systemd-dissect "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F "MARKER=1"
|
||||||
systemd-dissect ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F -f <(sed 's/"//g' $os_release)
|
systemd-dissect "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F -f <(sed 's/"//g' "$os_release")
|
||||||
mv ${image}.fooverity ${image}.verity
|
mv "${image}.fooverity" "${image}.verity"
|
||||||
mv ${image}.foohash ${image}.roothash
|
mv "${image}.foohash" "${image}.roothash"
|
||||||
|
|
||||||
mkdir -p ${image_dir}/mount ${image_dir}/mount2
|
mkdir -p "${image_dir}/mount" "${image_dir}/mount2"
|
||||||
systemd-dissect --mount ${image}.raw ${image_dir}/mount
|
systemd-dissect --mount "${image}.raw" "${image_dir}/mount"
|
||||||
cat ${image_dir}/mount/usr/lib/os-release | grep -q -F -f $os_release
|
grep -q -F -f "$os_release" "${image_dir}/mount/usr/lib/os-release"
|
||||||
cat ${image_dir}/mount/etc/os-release | grep -q -F -f $os_release
|
grep -q -F -f "$os_release" "${image_dir}/mount/etc/os-release"
|
||||||
cat ${image_dir}/mount/usr/lib/os-release | grep -q -F "MARKER=1"
|
grep -q -F "MARKER=1" "${image_dir}/mount/usr/lib/os-release"
|
||||||
# Verity volume should be shared (opened only once)
|
# Verity volume should be shared (opened only once)
|
||||||
systemd-dissect --mount ${image}.raw ${image_dir}/mount2
|
systemd-dissect --mount "${image}.raw" "${image_dir}/mount2"
|
||||||
verity_count=$(ls -1 /dev/mapper/ | grep -c verity)
|
verity_count=$(find /dev/mapper/ -name "*verity*" | wc -l)
|
||||||
# In theory we should check that count is exactly one. In practice, libdevmapper
|
# In theory we should check that count is exactly one. In practice, libdevmapper
|
||||||
# randomly and unpredictably fails with an unhelpful EINVAL when a device is open
|
# randomly and unpredictably fails with an unhelpful EINVAL when a device is open
|
||||||
# (and even mounted and in use), so best-effort is the most we can do for now
|
# (and even mounted and in use), so best-effort is the most we can do for now
|
||||||
if [ ${verity_count} -lt 1 ]; then
|
if [ "${verity_count}" -lt 1 ]; then
|
||||||
echo "Verity device ${image}.raw not found in /dev/mapper/"
|
echo "Verity device ${image}.raw not found in /dev/mapper/"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
umount ${image_dir}/mount
|
umount "${image_dir}/mount"
|
||||||
umount ${image_dir}/mount2
|
umount "${image_dir}/mount2"
|
||||||
|
|
||||||
systemd-run -t -p RootImage=${image}.raw cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p RootImage="${image}.raw" cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
mv ${image}.verity ${image}.fooverity
|
mv "${image}.verity" "${image}.fooverity"
|
||||||
mv ${image}.roothash ${image}.foohash
|
mv "${image}.roothash" "${image}.foohash"
|
||||||
systemd-run -t -p RootImage=${image}.raw -p RootHash=${image}.foohash -p RootVerity=${image}.fooverity cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p RootImage="${image}.raw" -p RootHash="${image}.foohash" -p RootVerity="${image}.fooverity" cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
# Let's use the long option name just here as a test
|
# Let's use the long option name just here as a test
|
||||||
systemd-run -t --property RootImage=${image}.raw --property RootHash=${roothash} --property RootVerity=${image}.fooverity cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t --property RootImage="${image}.raw" --property RootHash="${roothash}" --property RootVerity="${image}.fooverity" cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
mv ${image}.fooverity ${image}.verity
|
mv "${image}.fooverity" "${image}.verity"
|
||||||
mv ${image}.foohash ${image}.roothash
|
mv "${image}.foohash" "${image}.roothash"
|
||||||
|
|
||||||
# Make a GPT disk on the fly, with the squashfs as partition 1 and the verity hash tree as partition 2
|
# Make a GPT disk on the fly, with the squashfs as partition 1 and the verity hash tree as partition 2
|
||||||
machine="$(uname -m)"
|
machine="$(uname -m)"
|
||||||
@ -100,51 +100,54 @@ else
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# du rounds up to block size, which is more helpful for partitioning
|
# du rounds up to block size, which is more helpful for partitioning
|
||||||
root_size="$(du -k ${image}.raw | cut -f1)"
|
root_size="$(du -k "${image}.raw" | cut -f1)"
|
||||||
verity_size="$(du -k ${image}.verity | cut -f1)"
|
verity_size="$(du -k "${image}.verity" | cut -f1)"
|
||||||
# 4MB seems to be the minimum size blkid will accept, below that probing fails
|
# 4MB seems to be the minimum size blkid will accept, below that probing fails
|
||||||
dd if=/dev/zero of=${image}.gpt bs=512 count=$((8192+${root_size}*2+${verity_size}*2))
|
dd if=/dev/zero of="${image}.gpt" bs=512 count=$((8192+root_size*2+verity_size*2))
|
||||||
# sfdisk seems unhappy if the size overflows into the next unit, eg: 1580KiB will be interpreted as 1MiB
|
# sfdisk seems unhappy if the size overflows into the next unit, eg: 1580KiB will be interpreted as 1MiB
|
||||||
# so do some basic rounding up if the minimal image is more than 1 MB
|
# so do some basic rounding up if the minimal image is more than 1 MB
|
||||||
if [ ${root_size} -ge 1024 ]; then
|
if [ "${root_size}" -ge 1024 ]; then
|
||||||
root_size="$((${root_size}/1024 + 1))MiB"
|
root_size="$((root_size/1024 + 1))MiB"
|
||||||
else
|
else
|
||||||
root_size="${root_size}KiB"
|
root_size="${root_size}KiB"
|
||||||
fi
|
fi
|
||||||
verity_size="$((${verity_size} * 2))KiB"
|
verity_size="$((verity_size * 2))KiB"
|
||||||
uuid="$(head -c 32 ${image}.roothash | cut -c -8)-$(head -c 32 ${image}.roothash | cut -c 9-12)-$(head -c 32 ${image}.roothash | cut -c 13-16)-$(head -c 32 ${image}.roothash | cut -c 17-20)-$(head -c 32 ${image}.roothash | cut -c 21-)"
|
# Construct a UUID from hash
|
||||||
echo -e "label: gpt\nsize=${root_size}, type=${root_guid}, uuid=${uuid}" | sfdisk ${image}.gpt
|
# input: 11111111222233334444555566667777
|
||||||
uuid="$(tail -c 32 ${image}.roothash | cut -c -8)-$(tail -c 32 ${image}.roothash | cut -c 9-12)-$(tail -c 32 ${image}.roothash | cut -c 13-16)-$(tail -c 32 ${image}.roothash | cut -c 17-20)-$(tail -c 32 ${image}.roothash | cut -c 21-)"
|
# output: 11111111-2222-3333-4444-555566667777
|
||||||
echo -e "size=${verity_size}, type=${verity_guid}, uuid=${uuid}" | sfdisk ${image}.gpt --append
|
uuid="$(head -c 32 "${image}.roothash" | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/')"
|
||||||
sfdisk --part-label ${image}.gpt 1 "Root Partition"
|
echo -e "label: gpt\nsize=${root_size}, type=${root_guid}, uuid=${uuid}" | sfdisk "${image}.gpt"
|
||||||
sfdisk --part-label ${image}.gpt 2 "Verity Partition"
|
uuid="$(tail -c 32 "${image}.roothash" | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/')"
|
||||||
loop="$(losetup --show -P -f ${image}.gpt)"
|
echo -e "size=${verity_size}, type=${verity_guid}, uuid=${uuid}" | sfdisk "${image}.gpt" --append
|
||||||
dd if=${image}.raw of=${loop}p1
|
sfdisk --part-label "${image}.gpt" 1 "Root Partition"
|
||||||
dd if=${image}.verity of=${loop}p2
|
sfdisk --part-label "${image}.gpt" 2 "Verity Partition"
|
||||||
losetup -d ${loop}
|
loop="$(losetup --show -P -f "${image}.gpt")"
|
||||||
|
dd if="${image}.raw" of="${loop}p1"
|
||||||
|
dd if="${image}.verity" of="${loop}p2"
|
||||||
|
losetup -d "${loop}"
|
||||||
|
|
||||||
# Derive partition UUIDs from root hash, in UUID syntax
|
# Derive partition UUIDs from root hash, in UUID syntax
|
||||||
ROOT_UUID=$(systemd-id128 -u show $(head -c 32 ${image}.roothash) -u | tail -n 1 | cut -b 6-)
|
ROOT_UUID="$(systemd-id128 -u show "$(head -c 32 "${image}.roothash")" -u | tail -n 1 | cut -b 6-)"
|
||||||
VERITY_UUID=$(systemd-id128 -u show $(tail -c 32 ${image}.roothash) -u | tail -n 1 | cut -b 6-)
|
VERITY_UUID="$(systemd-id128 -u show "$(tail -c 32 "${image}.roothash")" -u | tail -n 1 | cut -b 6-)"
|
||||||
|
|
||||||
systemd-dissect --json=short --root-hash ${roothash} ${image}.gpt | grep -q '{"rw":"ro","designator":"root","partition_uuid":"'$ROOT_UUID'","partition_label":"Root Partition","fstype":"squashfs","architecture":"'$architecture'","verity":"yes","node":'
|
systemd-dissect --json=short --root-hash "${roothash}" "${image}.gpt" | grep -q '{"rw":"ro","designator":"root","partition_uuid":"'"$ROOT_UUID"'","partition_label":"Root Partition","fstype":"squashfs","architecture":"'"$architecture"'","verity":"yes","node":'
|
||||||
systemd-dissect --json=short --root-hash ${roothash} ${image}.gpt | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"'$VERITY_UUID'","partition_label":"Verity Partition","fstype":"DM_verity_hash","architecture":"'$architecture'","verity":null,"node":'
|
systemd-dissect --json=short --root-hash "${roothash}" "${image}.gpt" | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"'"$VERITY_UUID"'","partition_label":"Verity Partition","fstype":"DM_verity_hash","architecture":"'"$architecture"'","verity":null,"node":'
|
||||||
systemd-dissect --root-hash ${roothash} ${image}.gpt | grep -q -F "MARKER=1"
|
systemd-dissect --root-hash "${roothash}" "${image}.gpt" | grep -q -F "MARKER=1"
|
||||||
systemd-dissect --root-hash ${roothash} ${image}.gpt | grep -q -F -f <(sed 's/"//g' $os_release)
|
systemd-dissect --root-hash "${roothash}" "${image}.gpt" | grep -q -F -f <(sed 's/"//g' "$os_release")
|
||||||
|
|
||||||
systemd-dissect --root-hash ${roothash} --mount ${image}.gpt ${image_dir}/mount
|
systemd-dissect --root-hash "${roothash}" --mount "${image}.gpt" "${image_dir}/mount"
|
||||||
cat ${image_dir}/mount/usr/lib/os-release | grep -q -F -f $os_release
|
grep -q -F -f "$os_release" "${image_dir}/mount/usr/lib/os-release"
|
||||||
cat ${image_dir}/mount/etc/os-release | grep -q -F -f $os_release
|
grep -q -F -f "$os_release" "${image_dir}/mount/etc/os-release"
|
||||||
cat ${image_dir}/mount/usr/lib/os-release | grep -q -F "MARKER=1"
|
grep -q -F "MARKER=1" "${image_dir}/mount/usr/lib/os-release"
|
||||||
umount ${image_dir}/mount
|
umount "${image_dir}/mount"
|
||||||
|
|
||||||
# add explicit -p MountAPIVFS=yes once to test the parser
|
# add explicit -p MountAPIVFS=yes once to test the parser
|
||||||
systemd-run -t -p RootImage=${image}.gpt -p RootHash=${roothash} -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
|
|
||||||
systemd-run -t -p RootImage=${image}.raw -p RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p RootImage="${image}.raw" -p RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t -p RootImage=${image}.gpt -p RootImageOptions="root:ro,noatime root:ro,dev" mount | grep -F "squashfs" | grep -q -F "noatime"
|
systemd-run -t -p RootImage="${image}.gpt" -p RootImageOptions="root:ro,noatime root:ro,dev" mount | grep -F "squashfs" | grep -q -F "noatime"
|
||||||
|
|
||||||
mkdir -p mkdir -p ${image_dir}/result
|
mkdir -p "${image_dir}/result"
|
||||||
cat >/run/systemd/system/testservice-50a.service <<EOF
|
cat >/run/systemd/system/testservice-50a.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
@ -156,8 +159,8 @@ RootImageOptions=root:ro,noatime home:ro,dev relatime,dev
|
|||||||
RootImageOptions=nosuid,dev
|
RootImageOptions=nosuid,dev
|
||||||
EOF
|
EOF
|
||||||
systemctl start testservice-50a.service
|
systemctl start testservice-50a.service
|
||||||
grep -F "squashfs" ${image_dir}/result/a | grep -q -F "noatime"
|
grep -F "squashfs" "${image_dir}/result/a" | grep -q -F "noatime"
|
||||||
grep -F "squashfs" ${image_dir}/result/a | grep -q -F -v "nosuid"
|
grep -F "squashfs" "${image_dir}/result/a" | grep -q -F -v "nosuid"
|
||||||
|
|
||||||
cat >/run/systemd/system/testservice-50b.service <<EOF
|
cat >/run/systemd/system/testservice-50b.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
@ -172,7 +175,7 @@ RootImageOptions=home:ro,dev nosuid,dev,%%foo
|
|||||||
MountAPIVFS=yes
|
MountAPIVFS=yes
|
||||||
EOF
|
EOF
|
||||||
systemctl start testservice-50b.service
|
systemctl start testservice-50b.service
|
||||||
grep -F "squashfs" ${image_dir}/result/b | grep -q -F "noatime"
|
grep -F "squashfs" "${image_dir}/result/b" | grep -q -F "noatime"
|
||||||
|
|
||||||
# Check that specifier escape is applied %%foo → %foo
|
# Check that specifier escape is applied %%foo → %foo
|
||||||
busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo"
|
busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo"
|
||||||
@ -184,9 +187,9 @@ systemd-run -t -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2:nos
|
|||||||
systemd-run -t -p MountImages="${image}.gpt:/run/img1:root:nosuid ${image}.raw:/run/img2:home:suid" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p MountImages="${image}.gpt:/run/img1:root:nosuid ${image}.raw:/run/img2:home:suid" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t -p MountImages="${image}.raw:/run/img2\:3" cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p MountImages="${image}.raw:/run/img2\:3" cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t -p MountImages="${image}.raw:/run/img2\:3:nosuid" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p MountImages="${image}.raw:/run/img2\:3:nosuid" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t -p TemporaryFileSystem=/run -p RootImage=${image}.raw -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p TemporaryFileSystem=/run -p RootImage="${image}.raw" -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t -p TemporaryFileSystem=/run -p RootImage=${image}.raw -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p TemporaryFileSystem=/run -p RootImage="${image}.raw" -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t -p TemporaryFileSystem=/run -p RootImage=${image}.gpt -p RootHash=${roothash} -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p TemporaryFileSystem=/run -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
cat >/run/systemd/system/testservice-50c.service <<EOF
|
cat >/run/systemd/system/testservice-50c.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
MountAPIVFS=yes
|
MountAPIVFS=yes
|
||||||
@ -201,9 +204,9 @@ BindPaths=${image_dir}/result:/run/result
|
|||||||
Type=oneshot
|
Type=oneshot
|
||||||
EOF
|
EOF
|
||||||
systemctl start testservice-50c.service
|
systemctl start testservice-50c.service
|
||||||
grep -q -F "MARKER=1" ${image_dir}/result/c
|
grep -q -F "MARKER=1" "${image_dir}/result/c"
|
||||||
grep -F "squashfs" ${image_dir}/result/c | grep -q -F "noatime"
|
grep -F "squashfs" "${image_dir}/result/c" | grep -q -F "noatime"
|
||||||
grep -F "squashfs" ${image_dir}/result/c | grep -q -F -v "nosuid"
|
grep -F "squashfs" "${image_dir}/result/c" | grep -q -F -v "nosuid"
|
||||||
|
|
||||||
# Adding a new mounts at runtime works if the unit is in the active state,
|
# Adding a new mounts at runtime works if the unit is in the active state,
|
||||||
# so use Type=notify to make sure there's no race condition in the test
|
# so use Type=notify to make sure there's no race condition in the test
|
||||||
@ -218,7 +221,7 @@ ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img
|
|||||||
EOF
|
EOF
|
||||||
systemctl start testservice-50d.service
|
systemctl start testservice-50d.service
|
||||||
|
|
||||||
systemctl mount-image --mkdir testservice-50d.service ${image}.raw /tmp/img root:nosuid
|
systemctl mount-image --mkdir testservice-50d.service "${image}.raw" /tmp/img root:nosuid
|
||||||
|
|
||||||
while systemctl show -P SubState testservice-50d.service | grep -q running
|
while systemctl show -P SubState testservice-50d.service | grep -q running
|
||||||
do
|
do
|
||||||
@ -228,12 +231,12 @@ done
|
|||||||
systemctl is-active testservice-50d.service
|
systemctl is-active testservice-50d.service
|
||||||
|
|
||||||
# ExtensionImages will set up an overlay
|
# ExtensionImages will set up an overlay
|
||||||
systemd-run -t --property ExtensionImages=/usr/share/app0.raw --property RootImage=${image}.raw cat /opt/script0.sh | grep -q -F "extension-release.app0"
|
systemd-run -t --property ExtensionImages=/usr/share/app0.raw --property RootImage="${image}.raw" cat /opt/script0.sh | grep -q -F "extension-release.app0"
|
||||||
systemd-run -t --property ExtensionImages=/usr/share/app0.raw --property RootImage=${image}.raw cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
|
systemd-run -t --property ExtensionImages=/usr/share/app0.raw --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage=${image}.raw cat /opt/script0.sh | grep -q -F "extension-release.app0"
|
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /opt/script0.sh | grep -q -F "extension-release.app0"
|
||||||
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage=${image}.raw cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
|
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage=${image}.raw cat /opt/script1.sh | grep -q -F "extension-release.app1"
|
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /opt/script1.sh | grep -q -F "extension-release.app1"
|
||||||
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage=${image}.raw cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1"
|
systemd-run -t --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1"
|
||||||
cat >/run/systemd/system/testservice-50e.service <<EOF
|
cat >/run/systemd/system/testservice-50e.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
MountAPIVFS=yes
|
MountAPIVFS=yes
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemctl start testsuite-51-repro-1
|
systemctl start testsuite-51-repro-1
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
>/failed
|
: >/failed
|
||||||
|
|
||||||
# Reset host date to current time, 3 days in the past.
|
# Reset host date to current time, 3 days in the past.
|
||||||
date -s "-3 days"
|
date -s "-3 days"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
# shellcheck disable=SC2016
|
||||||
|
set -eux
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
|
||||||
|
@ -1,32 +1,39 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -eu -o pipefail
|
# Don't use set -x here, since it generates a lot of output and slows
|
||||||
|
# the script down, causing unexpected test fails.
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
PAGE_SIZE=$(getconf PAGE_SIZE)
|
PAGE_SIZE=$(getconf PAGE_SIZE)
|
||||||
BLOAT_ITERATION_TARGET=$(( 100 << 20 )) # 100 MB
|
BLOAT_ITERATION_TARGET=$((100 << 20)) # 100 MB
|
||||||
BLOAT_HOLDER=()
|
BLOAT_HOLDER=()
|
||||||
PID="$$"
|
PID="$$"
|
||||||
|
|
||||||
function bloat {
|
function bloat {
|
||||||
local set_size=$(cat "/proc/$PID/statm" | cut -d " " -f2)
|
local set_size mem_usage target_mem_size
|
||||||
local mem_usage=$(( "$set_size" * "$PAGE_SIZE" ))
|
|
||||||
local target_mem_size=$(( "$mem_usage" + "$1" ))
|
# Following `| cat` weirdness is intentional to generate some reclaim
|
||||||
|
# activity in case there's no swap available.
|
||||||
|
set_size=$(cut -d " " -f2 "/proc/$PID/statm" | cat)
|
||||||
|
mem_usage=$((set_size * PAGE_SIZE))
|
||||||
|
target_mem_size=$((mem_usage + $1))
|
||||||
|
|
||||||
BLOAT_HOLDER=()
|
BLOAT_HOLDER=()
|
||||||
while [[ "$mem_usage" -lt "$target_mem_size" ]]; do
|
while [[ "$mem_usage" -lt "$target_mem_size" ]]; do
|
||||||
echo "target $target_mem_size"
|
echo "target $target_mem_size"
|
||||||
echo "mem usage $mem_usage"
|
echo "mem usage $mem_usage"
|
||||||
BLOAT_HOLDER+=( $(printf "%0.sg" {1..1000000}) )
|
BLOAT_HOLDER+=("$(printf "=%0.s" {1..1000000})")
|
||||||
set_size=$(cat "/proc/$PID/statm" | cut -d " " -f2)
|
set_size=$(cut -d " " -f2 "/proc/$PID/statm" | cat)
|
||||||
mem_usage=$(( "$set_size" * "$PAGE_SIZE" ))
|
mem_usage=$((set_size * PAGE_SIZE))
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function run {
|
function run {
|
||||||
local arr=()
|
local arr=()
|
||||||
|
|
||||||
while [[ true ]]; do
|
while :; do
|
||||||
bloat "$BLOAT_ITERATION_TARGET"
|
bloat "$BLOAT_ITERATION_TARGET"
|
||||||
arr+=( "$BLOAT_HOLDER" )
|
arr+=("${BLOAT_HOLDER[@]}")
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
@ -7,14 +7,17 @@ systemd-analyze log-target console
|
|||||||
|
|
||||||
# Loose checks to ensure the environment has the necessary features for systemd-oomd
|
# Loose checks to ensure the environment has the necessary features for systemd-oomd
|
||||||
[[ -e /proc/pressure ]] || echo "no PSI" >>/skipped
|
[[ -e /proc/pressure ]] || echo "no PSI" >>/skipped
|
||||||
cgroup_type=$(stat -fc %T /sys/fs/cgroup/)
|
cgroup_type="$(stat -fc %T /sys/fs/cgroup/)"
|
||||||
if [[ "$cgroup_type" != *"cgroup2"* ]] && [[ "$cgroup_type" != *"0x63677270"* ]]; then
|
if [[ "$cgroup_type" != *"cgroup2"* ]] && [[ "$cgroup_type" != *"0x63677270"* ]]; then
|
||||||
echo "no cgroup2" >>/skipped
|
echo "no cgroup2" >>/skipped
|
||||||
fi
|
fi
|
||||||
if [ ! -f /usr/lib/systemd/systemd-oomd ] && [ ! -f /lib/systemd/systemd-oomd ]; then
|
if [ ! -f /usr/lib/systemd/systemd-oomd ] && [ ! -f /lib/systemd/systemd-oomd ]; then
|
||||||
echo "no oomd" >>/skipped
|
echo "no oomd" >>/skipped
|
||||||
fi
|
fi
|
||||||
[[ -e /skipped ]] && exit 0 || true
|
|
||||||
|
if [[ -e /skipped ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf /etc/systemd/system/testsuite-55-testbloat.service.d
|
rm -rf /etc/systemd/system/testsuite-55-testbloat.service.d
|
||||||
|
|
||||||
@ -30,7 +33,7 @@ oomctl | grep "Default Memory Pressure Duration: 5s"
|
|||||||
|
|
||||||
# systemd-oomd watches for elevated pressure for 5 seconds before acting.
|
# systemd-oomd watches for elevated pressure for 5 seconds before acting.
|
||||||
# It can take time to build up pressure so either wait 2 minutes or for the service to fail.
|
# It can take time to build up pressure so either wait 2 minutes or for the service to fail.
|
||||||
timeout=$(date -ud "2 minutes" +%s)
|
timeout="$(date -ud "2 minutes" +%s)"
|
||||||
while [[ $(date -u +%s) -le $timeout ]]; do
|
while [[ $(date -u +%s) -le $timeout ]]; do
|
||||||
if ! systemctl status testsuite-55-testbloat.service; then
|
if ! systemctl status testsuite-55-testbloat.service; then
|
||||||
break
|
break
|
||||||
@ -55,8 +58,8 @@ if setfattr -n user.xattr_test -v 1 /sys/fs/cgroup/; then
|
|||||||
systemctl start testsuite-55-testmunch.service
|
systemctl start testsuite-55-testmunch.service
|
||||||
systemctl start testsuite-55-testbloat.service
|
systemctl start testsuite-55-testbloat.service
|
||||||
|
|
||||||
timeout=$(date -ud "2 minutes" +%s)
|
timeout="$(date -ud "2 minutes" +%s)"
|
||||||
while [[ $(date -u +%s) -le $timeout ]]; do
|
while [[ "$(date -u +%s)" -le "$timeout" ]]; do
|
||||||
if ! systemctl status testsuite-55-testmunch.service; then
|
if ! systemctl status testsuite-55-testmunch.service; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -eux
|
||||||
|
|
||||||
systemd-analyze log-level debug
|
systemd-analyze log-level debug
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user