1
0
mirror of https://github.com/systemd/systemd synced 2025-09-24 06:14:44 +02:00

Compare commits

..

No commits in common. "cb1277fa3b1d7a5b6e1b7cce31b91cd2efdad97a" and "214ffe64fc4ef0e9999abf95f8cbe97ded39e464" have entirely different histories.

22 changed files with 126 additions and 440 deletions

3
TODO
View File

@ -178,6 +178,9 @@ Features:
* systemd-repart: allow config of partition uuid * systemd-repart: allow config of partition uuid
* systemd-repart: add --make= switch for fallocating a new file of the
specified size first.
* userdb: allow username prefix searches in varlink API, allow realname and * userdb: allow username prefix searches in varlink API, allow realname and
realname substr searches in varlink API realname substr searches in varlink API

View File

@ -58,7 +58,7 @@
<itemizedlist> <itemizedlist>
<listitem><para>The root partition may be grown to cover the whole available disk space</para></listitem> <listitem><para>The root partition may be grown to cover the whole available disk space</para></listitem>
<listitem><para>A <filename>/home/</filename>, swap or <filename>/srv/</filename> partition can be added in</para></listitem> <listitem><para>A <filename>/home/</filename>, swap or <filename>/srv</filename> partition can be added in</para></listitem>
<listitem><para>A second (or third, …) root partition may be added in, to cover A/B style setups <listitem><para>A second (or third, …) root partition may be added in, to cover A/B style setups
where a second version of the root file system is alternatingly used for implementing update where a second version of the root file system is alternatingly used for implementing update
schemes. The deployed image would carry only a single partition ("A") but on first boot a second schemes. The deployed image would carry only a single partition ("A") but on first boot a second
@ -145,12 +145,6 @@
also be set explicitly, formatted as UUID via the <option>--seed=</option> option. By hashing these UUIDs also be set explicitly, formatted as UUID via the <option>--seed=</option> option. By hashing these UUIDs
from a common seed images prepared with this tool become reproducible and the result of the algorithm from a common seed images prepared with this tool become reproducible and the result of the algorithm
above deterministic.</para> above deterministic.</para>
<para>The positional argument should specify the block device to operate on. Instead of a block device
node path a regular file may be specified too, in which case the command operates on it like it would if
a loopback block device node was specified with the file attached. If <option>--empty=create</option> is
specified the specified path is created as regular file, which is useful for generating disk images from
scratch.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -171,9 +165,9 @@
<varlistentry> <varlistentry>
<term><option>--empty=</option></term> <term><option>--empty=</option></term>
<listitem><para>Takes one of <literal>refuse</literal>, <literal>allow</literal>, <listitem><para>Takes one of <literal>refuse</literal>, <literal>allow</literal>,
<literal>require</literal>, <literal>force</literal> or <literal>create</literal>. Controls how to <literal>require</literal> or <literal>force</literal>. Controls how to operate on block devices that
operate on block devices that are entirely empty, i.e. carry no partition table/disk label yet. If are entirely empty, i.e. carry no partition table/disk label yet. If this switch is not specified the
this switch is not specified the implied default is <literal>refuse</literal>.</para> implied default is <literal>refuse</literal>.</para>
<para>If <literal>refuse</literal> <command>systemd-repart</command> requires that the block device <para>If <literal>refuse</literal> <command>systemd-repart</command> requires that the block device
it shall operate on already carries a partition table and refuses operation if none is found. If it shall operate on already carries a partition table and refuses operation if none is found. If
@ -182,9 +176,7 @@
exists so far, and refuse operation if one already exists. If <literal>force</literal> it will create exists so far, and refuse operation if one already exists. If <literal>force</literal> it will create
a fresh partition table unconditionally, erasing the disk fully in effect. If a fresh partition table unconditionally, erasing the disk fully in effect. If
<literal>force</literal> no existing partitions will be taken into account or survive the <literal>force</literal> no existing partitions will be taken into account or survive the
operation. Hence: use with care, this is a great way to lose all your data. If operation. Hence: use with care, this is a great way to lose all your data.</para></listitem>
<literal>create</literal> a new loopback file is create under the path passed via the device node
parameter, of the size indicated with <option>--size=</option>, see below.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -194,20 +186,7 @@
the implied default. Controls whether to issue the <constant>BLKDISCARD</constant> I/O control the implied default. Controls whether to issue the <constant>BLKDISCARD</constant> I/O control
command on the space taken up by any added partitions or on the space in between them. Usually, it's command on the space taken up by any added partitions or on the space in between them. Usually, it's
a good idea to issue this request since it tells the underlying hardware that the covered blocks a good idea to issue this request since it tells the underlying hardware that the covered blocks
shall be considered empty, improving performance. If operating on a regular file instead of a block shall be considered empty, improving performance.</para></listitem>
device node, a sparse file is generated.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--size=</option></term>
<listitem><para>Takes a size in bytes, using the usual K, M, G, T suffixes. If used the specified
device node path must refer to a regular file, which is then grown to the specified size if smaller,
before any change is made to the partition table. This is not supported if the specified node is a
block device. This switch has no effect if the file is already as large as the specified size or
larger. The specified size is implicitly rounded up to multiples of 4096. When used with
<option>--empty=create</option> this specifies the initial size of the loopback file to
create.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -86,10 +86,6 @@
<listitem><para>Automount units acquire automatic <varname>Before=</varname> and <listitem><para>Automount units acquire automatic <varname>Before=</varname> and
<varname>Conflicts=</varname> on <filename>umount.target</filename> in order to be stopped during <varname>Conflicts=</varname> on <filename>umount.target</filename> in order to be stopped during
shutdown.</para></listitem> shutdown.</para></listitem>
<listitem><para>Automount units automatically gain an <varname>After=</varname> dependency
on <filename>local-fs-pre.target</filename>, and a <varname>Before=</varname> dependency on
<filename>local-fs.target</filename>.</para></listitem>
</itemizedlist> </itemizedlist>
</refsect2> </refsect2>
</refsect1> </refsect1>

View File

@ -205,15 +205,6 @@
controlled by other applications.</para> controlled by other applications.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>Group=</varname></term>
<listitem>
<para>Link groups are similar to port ranges found in managed switches.
When network interfaces are added to a numbered group, operations on
all the interfaces from that group can be performed at once. An unsigned
integer ranges 0 to 4294967294. Default to unset.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>RequiredForOnline=</varname></term> <term><varname>RequiredForOnline=</varname></term>
<listitem> <listitem>

View File

@ -152,10 +152,6 @@ static int automount_add_default_dependencies(Automount *a) {
if (!MANAGER_IS_SYSTEM(UNIT(a)->manager)) if (!MANAGER_IS_SYSTEM(UNIT(a)->manager))
return 0; return 0;
r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_LOCAL_FS_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
if (r < 0)
return r;
r = unit_add_dependency_by_name(UNIT(a), UNIT_AFTER, SPECIAL_LOCAL_FS_PRE_TARGET, true, UNIT_DEPENDENCY_DEFAULT); r = unit_add_dependency_by_name(UNIT(a), UNIT_AFTER, SPECIAL_LOCAL_FS_PRE_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -1063,6 +1063,7 @@ const UnitVTable device_vtable = {
"Device\0" "Device\0"
"Install\0", "Install\0",
.refuse_after = true,
.gc_jobs = true, .gc_jobs = true,
.init = device_init, .init = device_init,

View File

@ -66,14 +66,6 @@ static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
MOUNT_CLEANING); MOUNT_CLEANING);
} }
static bool mount_is_automount(const MountParameters *p) {
assert(p);
return fstab_test_option(p->options,
"comment=systemd.automount\0"
"x-systemd.automount\0");
}
static bool mount_is_network(const MountParameters *p) { static bool mount_is_network(const MountParameters *p) {
assert(p); assert(p);
@ -86,15 +78,6 @@ static bool mount_is_network(const MountParameters *p) {
return false; return false;
} }
static bool mount_is_nofail(const Mount *m) {
assert(m);
if (!m->from_fragment)
return false;
return fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0");
}
static bool mount_is_loop(const MountParameters *p) { static bool mount_is_loop(const MountParameters *p) {
assert(p); assert(p);
@ -417,72 +400,42 @@ static bool mount_is_extrinsic(Mount *m) {
MountParameters *p; MountParameters *p;
assert(m); assert(m);
/* Returns true for all units that are "magic" and should be excluded from the usual /* Returns true for all units that are "magic" and should be excluded from the usual start-up and shutdown
* start-up and shutdown dependencies. We call them "extrinsic" here, as they are generally * dependencies. We call them "extrinsic" here, as they are generally mounted outside of the systemd dependency
* mounted outside of the systemd dependency logic. We shouldn't attempt to manage them * logic. We shouldn't attempt to manage them ourselves but it's fine if the user operates on them with us. */
* ourselves but it's fine if the user operates on them with us. */
/* We only automatically manage mounts if we are in system mode */ if (!MANAGER_IS_SYSTEM(UNIT(m)->manager)) /* We only automatically manage mounts if we are in system mode */
if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
return true; return true;
if (UNIT(m)->perpetual) /* All perpetual units never change state */ if (UNIT(m)->perpetual) /* All perpetual units never change state */
return true; return true;
if (PATH_IN_SET(m->where, /* Don't bother with the OS data itself */
"/", /* (strictly speaking redundant: should already be covered by the perpetual flag check above) */
"/usr",
"/etc"))
return true;
if (PATH_STARTSWITH_SET(m->where,
"/run/initramfs", /* This should stay around from before we boot until after we shutdown */
"/proc", /* All of this is API VFS */
"/sys", /* … dito … */
"/dev")) /* … dito … */
return true;
/* If this is an initrd mount, and we are not in the initrd, then leave this around forever, too. */
p = get_mount_parameters(m); p = get_mount_parameters(m);
if (p && fstab_is_extrinsic(m->where, p->options)) if (p && fstab_test_option(p->options, "x-initrd.mount\0") && !in_initrd())
return true; return true;
return false; return false;
} }
static int mount_add_default_ordering_dependencies(
Mount *m,
MountParameters *p,
UnitDependencyMask mask) {
const char *after, *before, *e;
int r;
assert(m);
e = path_startswith(m->where, "/sysroot");
if (e && in_initrd()) {
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW,
* it's not technically part of the basic initrd filesystem itself, and so
* shouldn't inherit the default Before=local-fs.target dependency. */
after = NULL;
before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
} else if (mount_is_network(p)) {
after = SPECIAL_REMOTE_FS_PRE_TARGET;
before = SPECIAL_REMOTE_FS_TARGET;
} else {
after = SPECIAL_LOCAL_FS_PRE_TARGET;
before = SPECIAL_LOCAL_FS_TARGET;
}
if (!mount_is_nofail(m) && !mount_is_automount(p)) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
if (r < 0)
return r;
}
if (after) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask);
if (r < 0)
return r;
}
return unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS,
SPECIAL_UMOUNT_TARGET, true, mask);
}
static int mount_add_default_dependencies(Mount *m) { static int mount_add_default_dependencies(Mount *m) {
const char *after, *before;
UnitDependencyMask mask; UnitDependencyMask mask;
MountParameters *p; MountParameters *p;
bool nofail;
int r; int r;
assert(m); assert(m);
@ -490,10 +443,9 @@ static int mount_add_default_dependencies(Mount *m) {
if (!UNIT(m)->default_dependencies) if (!UNIT(m)->default_dependencies)
return 0; return 0;
/* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are /* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are guaranteed to stay
* guaranteed to stay mounted the whole time, since our system is on it. Also, don't * mounted the whole time, since our system is on it. Also, don't bother with anything mounted below virtual
* bother with anything mounted below virtual file systems, it's also going to be virtual, * file systems, it's also going to be virtual, and hence not worth the effort. */
* and hence not worth the effort. */
if (mount_is_extrinsic(m)) if (mount_is_extrinsic(m))
return 0; return 0;
@ -502,31 +454,51 @@ static int mount_add_default_dependencies(Mount *m) {
return 0; return 0;
mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT; mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT;
nofail = m->from_fragment ? fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0") : false;
r = mount_add_default_ordering_dependencies(m, p, mask);
if (r < 0)
return r;
if (mount_is_network(p)) { if (mount_is_network(p)) {
/* We order ourselves after network.target. This is primarily useful at shutdown: /* We order ourselves after network.target. This is
* services that take down the network should order themselves before * primarily useful at shutdown: services that take
* network.target, so that they are shut down only after this mount unit is * down the network should order themselves before
* stopped. */ * network.target, so that they are shut down only
* after this mount unit is stopped. */
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, true, mask); r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, true, mask);
if (r < 0) if (r < 0)
return r; return r;
/* We pull in network-online.target, and order ourselves after it. This is useful /* We pull in network-online.target, and order
* at start-up to actively pull in tools that want to be started before we start * ourselves after it. This is useful at start-up to
* mounting network file systems, and whose purpose it is to delay this until the * actively pull in tools that want to be started
* network is "up". */ * before we start mounting network file systems, and
* whose purpose it is to delay this until the network
* is "up". */
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, true, mask); r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, true, mask);
if (r < 0) if (r < 0)
return r; return r;
after = SPECIAL_REMOTE_FS_PRE_TARGET;
before = SPECIAL_REMOTE_FS_TARGET;
} else {
after = SPECIAL_LOCAL_FS_PRE_TARGET;
before = SPECIAL_LOCAL_FS_TARGET;
} }
if (!nofail) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
if (r < 0)
return r;
}
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask);
if (r < 0)
return r;
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, mask);
if (r < 0)
return r;
/* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */ /* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */
if (streq_ptr(p->fstype, "tmpfs")) { if (streq_ptr(p->fstype, "tmpfs")) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, true, mask); r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, true, mask);

View File

@ -3028,10 +3028,13 @@ int unit_add_dependency(
return 0; return 0;
} }
/* Note that ordering a device unit after a unit is permitted since it if (d == UNIT_AFTER && UNIT_VTABLE(u)->refuse_after) {
* allows to start its job running timeout at a specific time. */ log_unit_warning(u, "Requested dependency After=%s ignored (%s units cannot be delayed).", other->id, unit_type_to_string(u->type));
if (d == UNIT_BEFORE && other->type == UNIT_DEVICE) { return 0;
log_unit_warning(u, "Dependency Before=%s ignored (.device units cannot be delayed)", other->id); }
if (d == UNIT_BEFORE && UNIT_VTABLE(other)->refuse_after) {
log_unit_warning(u, "Requested dependency Before=%s ignored (%s units cannot be delayed).", other->id, unit_type_to_string(other->type));
return 0; return 0;
} }

View File

@ -615,6 +615,9 @@ typedef struct UnitVTable {
/* True if the unit type knows a failure state, and thus can be source of an OnFailure= dependency */ /* True if the unit type knows a failure state, and thus can be source of an OnFailure= dependency */
bool can_fail:1; bool can_fail:1;
/* True if After= dependencies should be refused */
bool refuse_after:1;
/* True if units of this type shall be startable only once and then never again */ /* True if units of this type shall be startable only once and then never again */
bool once_only:1; bool once_only:1;

View File

@ -391,6 +391,12 @@ static int add_mount(
"SourcePath=%s\n", "SourcePath=%s\n",
source); source);
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW, it's not
* technically part of the basic initrd filesystem itself, and so shouldn't inherit the default
* Before=local-fs.target dependency. */
if (in_initrd() && path_startswith(where, "/sysroot"))
fprintf(f, "DefaultDependencies=no\n");
if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) && if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) &&
fstab_test_yes_no_option(opts, "bg\0" "fg\0")) { fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
/* The default retry timeout that mount.nfs uses for 'bg' mounts /* The default retry timeout that mount.nfs uses for 'bg' mounts
@ -405,6 +411,9 @@ static int add_mount(
SET_FLAG(flags, NOFAIL, true); SET_FLAG(flags, NOFAIL, true);
} }
if (!(flags & NOFAIL) && !(flags & AUTOMOUNT))
fprintf(f, "Before=%s\n", post);
if (!(flags & AUTOMOUNT) && opts) { if (!(flags & AUTOMOUNT) && opts) {
r = write_after(f, opts); r = write_after(f, opts);
if (r < 0) if (r < 0)
@ -526,6 +535,8 @@ static int add_mount(
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
source); source);
fprintf(f, "Before=%s\n", post);
if (opts) { if (opts) {
r = write_after(f, opts); r = write_after(f, opts);
if (r < 0) if (r < 0)

View File

@ -1825,53 +1825,6 @@ int link_down(Link *link, link_netlink_message_handler_t callback) {
return 0; return 0;
} }
static int link_group_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0)
log_link_message_warning_errno(link, m, r, "Could not set group for the interface");
return 1;
}
static int link_set_group(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
assert(link);
assert(link->network);
assert(link->manager);
assert(link->manager->rtnl);
if (link->network->group <= 0)
return 0;
log_link_debug(link, "Setting group");
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
r = sd_netlink_message_append_u32(req, IFLA_GROUP, link->network->group);
if (r < 0)
return log_link_error_errno(link, r, "Could not set link group: %m");
r = netlink_call_async(link->manager->rtnl, NULL, req, link_group_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
return 0;
}
static int link_handle_bound_to_list(Link *link) { static int link_handle_bound_to_list(Link *link) {
Link *l; Link *l;
Iterator i; Iterator i;
@ -2866,10 +2819,6 @@ static int link_configure(Link *link) {
if (r < 0) if (r < 0)
return r; return r;
r = link_set_group(link);
if (r < 0)
return r;
if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) { if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) {
r = ipv4ll_configure(link); r = ipv4ll_configure(link);
if (r < 0) if (r < 0)

View File

@ -46,7 +46,6 @@ Match.KernelVersion, config_parse_net_condition,
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu) Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu)
Link.Group, config_parse_uint32, 0, offsetof(Network, group)
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp) Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)
Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast) Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast) Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)

View File

@ -247,7 +247,6 @@ struct Network {
struct ether_addr *mac; struct ether_addr *mac;
uint32_t mtu; uint32_t mtu;
uint32_t group;
int arp; int arp;
int multicast; int multicast;
int allmulticast; int allmulticast;

View File

@ -58,7 +58,6 @@ static enum {
EMPTY_ALLOW, /* allow empty disks, create partition table if necessary */ EMPTY_ALLOW, /* allow empty disks, create partition table if necessary */
EMPTY_REQUIRE, /* require an empty disk, create a partition table */ EMPTY_REQUIRE, /* require an empty disk, create a partition table */
EMPTY_FORCE, /* make disk empty, erase everything, create a partition table always */ EMPTY_FORCE, /* make disk empty, erase everything, create a partition table always */
EMPTY_CREATE, /* create disk as loopback file, create a partition table always */
} arg_empty = EMPTY_REFUSE; } arg_empty = EMPTY_REFUSE;
static bool arg_dry_run = true; static bool arg_dry_run = true;
@ -71,7 +70,6 @@ static int arg_factory_reset = -1;
static sd_id128_t arg_seed = SD_ID128_NULL; static sd_id128_t arg_seed = SD_ID128_NULL;
static bool arg_randomize = false; static bool arg_randomize = false;
static int arg_pretty = -1; static int arg_pretty = -1;
static uint64_t arg_size = UINT64_MAX;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_definitions, freep); STATIC_DESTRUCTOR_REGISTER(arg_definitions, freep);
@ -1168,11 +1166,7 @@ static int disk_acquire_uuid(Context *context, sd_id128_t *ret) {
return 0; return 0;
} }
static int context_load_partition_table( static int context_load_partition_table(Context *context, const char *node) {
Context *context,
const char *node,
int *backing_fd) {
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
_cleanup_(fdisk_unref_tablep) struct fdisk_table *t = NULL; _cleanup_(fdisk_unref_tablep) struct fdisk_table *t = NULL;
uint64_t left_boundary = UINT64_MAX, first_lba, last_lba, nsectors; uint64_t left_boundary = UINT64_MAX, first_lba, last_lba, nsectors;
@ -1184,31 +1178,14 @@ static int context_load_partition_table(
assert(context); assert(context);
assert(node); assert(node);
assert(backing_fd);
c = fdisk_new_context(); c = fdisk_new_context();
if (!c) if (!c)
return log_oom(); return log_oom();
/* libfdisk doesn't have an API to operate on arbitrary fds, hence reopen the fd going via the
* /proc/self/fd/ magic path if we have an existing fd. Open the original file otherwise. */
if (*backing_fd < 0)
r = fdisk_assign_device(c, node, arg_dry_run); r = fdisk_assign_device(c, node, arg_dry_run);
else {
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
xsprintf(procfs_path, "/proc/self/fd/%i", *backing_fd);
r = fdisk_assign_device(c, procfs_path, arg_dry_run);
}
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to open device '%s': %m", node); return log_error_errno(r, "Failed to open device: %m");
if (*backing_fd < 0) {
/* If we have no fd referencing the device yet, make a copy of the fd now, so that we have one */
*backing_fd = fcntl(fdisk_get_devfd(c), F_DUPFD_CLOEXEC, 3);
if (*backing_fd < 0)
return log_error_errno(errno, "Failed to duplicate fdisk fd: %m");
}
/* Tell udev not to interfere while we are processing the device */ /* Tell udev not to interfere while we are processing the device */
if (flock(fdisk_get_devfd(c), arg_dry_run ? LOCK_SH : LOCK_EX) < 0) if (flock(fdisk_get_devfd(c), arg_dry_run ? LOCK_SH : LOCK_EX) < 0)
@ -1248,7 +1225,6 @@ static int context_load_partition_table(
break; break;
case EMPTY_FORCE: case EMPTY_FORCE:
case EMPTY_CREATE:
/* Always reinitiaize the disk, don't consider what there was on the disk before */ /* Always reinitiaize the disk, don't consider what there was on the disk before */
from_scratch = true; from_scratch = true;
break; break;
@ -1924,7 +1900,8 @@ static int context_discard_range(Context *context, uint64_t offset, uint64_t siz
if (size <= 0) if (size <= 0)
return 0; return 0;
assert_se((fd = fdisk_get_devfd(context->fdisk_context)) >= 0); fd = fdisk_get_devfd(context->fdisk_context);
assert(fd >= 0);
if (fstat(fd, &st) < 0) if (fstat(fd, &st) < 0)
return -errno; return -errno;
@ -2279,7 +2256,7 @@ static int device_kernel_partitions_supported(int fd) {
if (fstat(fd, &st) < 0) if (fstat(fd, &st) < 0)
return log_error_errno(fd, "Failed to fstat() image file: %m"); return log_error_errno(fd, "Failed to fstat() image file: %m");
if (!S_ISBLK(st.st_mode)) if (!S_ISBLK(st.st_mode))
return -ENOTBLK; /* we do not log in this one special case about errors */ return false;
if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) { if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {
@ -2484,11 +2461,9 @@ static int context_write_partition_table(
return log_error_errno(r, "Failed to write partition table: %m"); return log_error_errno(r, "Failed to write partition table: %m");
capable = device_kernel_partitions_supported(fdisk_get_devfd(context->fdisk_context)); capable = device_kernel_partitions_supported(fdisk_get_devfd(context->fdisk_context));
if (capable == -ENOTBLK) if (capable < 0)
log_debug("Not telling kernel to reread partition table, since we are not operating on a block device.");
else if (capable < 0)
return capable; return capable;
else if (capable > 0) { if (capable > 0) {
log_info("Telling kernel to reread partition table."); log_info("Telling kernel to reread partition table.");
if (from_scratch) if (from_scratch)
@ -2613,8 +2588,8 @@ static int help(void) {
" -h --help Show this help\n" " -h --help Show this help\n"
" --version Show package version\n" " --version Show package version\n"
" --dry-run=BOOL Whether to run dry-run operation\n" " --dry-run=BOOL Whether to run dry-run operation\n"
" --empty=MODE One of refuse, allow, require, force, create; controls\n" " --empty=MODE One of refuse, allow, require, force; controls how to\n"
" how to handle empty disks lacking partition tables\n" " handle empty disks lacking partition table\n"
" --discard=BOOL Whether to discard backing blocks for new partitions\n" " --discard=BOOL Whether to discard backing blocks for new partitions\n"
" --pretty=BOOL Whether to show pretty summary before executing operation\n" " --pretty=BOOL Whether to show pretty summary before executing operation\n"
" --factory-reset=BOOL Whether to remove data partitions before recreating\n" " --factory-reset=BOOL Whether to remove data partitions before recreating\n"
@ -2623,7 +2598,6 @@ static int help(void) {
" --root=PATH Operate relative to root path\n" " --root=PATH Operate relative to root path\n"
" --definitions=DIR Find partitions in specified directory\n" " --definitions=DIR Find partitions in specified directory\n"
" --seed=UUID 128bit seed UUID to derive all UUIDs from\n" " --seed=UUID 128bit seed UUID to derive all UUIDs from\n"
" --size=BYTES Grow loopback file to specified size\n"
"\nSee the %s for details.\n" "\nSee the %s for details.\n"
, program_invocation_short_name , program_invocation_short_name
, ansi_highlight(), ansi_normal() , ansi_highlight(), ansi_normal()
@ -2646,7 +2620,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SEED, ARG_SEED,
ARG_PRETTY, ARG_PRETTY,
ARG_DEFINITIONS, ARG_DEFINITIONS,
ARG_SIZE,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -2661,11 +2634,10 @@ static int parse_argv(int argc, char *argv[]) {
{ "seed", required_argument, NULL, ARG_SEED }, { "seed", required_argument, NULL, ARG_SEED },
{ "pretty", required_argument, NULL, ARG_PRETTY }, { "pretty", required_argument, NULL, ARG_PRETTY },
{ "definitions", required_argument, NULL, ARG_DEFINITIONS }, { "definitions", required_argument, NULL, ARG_DEFINITIONS },
{ "size", required_argument, NULL, ARG_SIZE },
{} {}
}; };
int c, r, dry_run = -1; int c, r;
assert(argc >= 0); assert(argc >= 0);
assert(argv); assert(argv);
@ -2685,7 +2657,7 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --dry-run= parameter: %s", optarg); return log_error_errno(r, "Failed to parse --dry-run= parameter: %s", optarg);
dry_run = r; arg_dry_run = r;
break; break;
case ARG_EMPTY: case ARG_EMPTY:
@ -2697,14 +2669,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_empty = EMPTY_REQUIRE; arg_empty = EMPTY_REQUIRE;
else if (streq(optarg, "force")) else if (streq(optarg, "force"))
arg_empty = EMPTY_FORCE; arg_empty = EMPTY_FORCE;
else if (streq(optarg, "create")) { else
arg_empty = EMPTY_CREATE;
if (dry_run < 0)
dry_run = false; /* Imply --dry-run=no if we create the loopback file
* anew. After all we cannot really break anyone's
* partition tables that way. */
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse --empty= parameter: %s", optarg); "Failed to parse --empty= parameter: %s", optarg);
break; break;
@ -2765,27 +2730,6 @@ static int parse_argv(int argc, char *argv[]) {
return r; return r;
break; break;
case ARG_SIZE: {
uint64_t parsed, rounded;
r = parse_size(optarg, 1024, &parsed);
if (r < 0)
return log_error_errno(r, "Failed to parse --size= parameter: %s", optarg);
rounded = round_up_size(parsed, 4096);
if (rounded == 0)
return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Specified image size too small, refusing.");
if (rounded == UINT64_MAX)
return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Specified image size too large, refusing.");
if (rounded != parsed)
log_warning("Specified size is not a multiple of 4096, rounding up automatically. (%" PRIu64 " → %" PRIu64 ")",
parsed, rounded);
arg_size = rounded;
break;
}
case '?': case '?':
return -EINVAL; return -EINVAL;
@ -2797,27 +2741,14 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Expected at most one argument, the path to the block device."); "Expected at most one argument, the path to the block device.");
if (arg_factory_reset > 0 && IN_SET(arg_empty, EMPTY_FORCE, EMPTY_REQUIRE, EMPTY_CREATE)) if (arg_factory_reset > 0 && IN_SET(arg_empty, EMPTY_FORCE, EMPTY_REQUIRE))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Combination of --factory-reset=yes and --empty=force/--empty=require/--empty=create is invalid."); "Combination of --factory-reset=yes and --empty=force/--empty=require is invalid.");
if (arg_can_factory_reset) if (arg_can_factory_reset)
arg_dry_run = true; /* When --can-factory-reset is specified we don't make changes, hence arg_dry_run = true;
* non-dry-run mode makes no sense. Thus, imply dry run mode so that we
* open things strictly read-only. */
else if (dry_run >= 0)
arg_dry_run = dry_run;
if (arg_empty == EMPTY_CREATE && arg_size == UINT64_MAX)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"If --empty=create is specified, --size= must be specified, too.");
arg_node = argc > optind ? argv[optind] : NULL; arg_node = argc > optind ? argv[optind] : NULL;
if (IN_SET(arg_empty, EMPTY_FORCE, EMPTY_REQUIRE, EMPTY_CREATE) && !arg_node)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"A path to a device node or loopback file must be specified when --empty=force, --empty=require or --empty=create are used.");
return 1; return 1;
} }
@ -2884,16 +2815,12 @@ static int remove_efi_variable_factory_reset(void) {
return 0; return 0;
} }
static int acquire_root_devno(const char *p, int mode, char **ret, int *ret_fd) { static int acquire_root_devno(const char *p, int mode, char **ret) {
_cleanup_close_ int fd = -1; _cleanup_close_ int fd = -1;
struct stat st; struct stat st;
dev_t devno, fd_devno = (mode_t) -1; dev_t devno;
int r; int r;
assert(p);
assert(ret);
assert(ret_fd);
fd = open(p, mode); fd = open(p, mode);
if (fd < 0) if (fd < 0)
return -errno; return -errno;
@ -2909,23 +2836,23 @@ static int acquire_root_devno(const char *p, int mode, char **ret, int *ret_fd)
return log_oom(); return log_oom();
*ret = s; *ret = s;
*ret_fd = TAKE_FD(fd);
return 0; return 0;
} }
if (S_ISBLK(st.st_mode)) if (S_ISBLK(st.st_mode))
fd_devno = devno = st.st_rdev; devno = st.st_rdev;
else if (S_ISDIR(st.st_mode)) { else if (S_ISDIR(st.st_mode)) {
devno = st.st_dev; devno = st.st_dev;
if (major(devno) == 0) {
if (major(st.st_dev) == 0) {
r = btrfs_get_block_device_fd(fd, &devno); r = btrfs_get_block_device_fd(fd, &devno);
if (r == -ENOTTY) /* not btrfs */ if (r == -ENOTTY) /* not btrfs */
return -ENODEV; return -ENODEV;
if (r < 0) if (r < 0)
return r; return r;
} }
} else } else
return -ENOTBLK; return -ENOTBLK;
@ -2939,50 +2866,21 @@ static int acquire_root_devno(const char *p, int mode, char **ret, int *ret_fd)
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to find whole disk block device for '%s', ignoring: %m", p); log_debug_errno(r, "Failed to find whole disk block device for '%s', ignoring: %m", p);
r = device_path_make_canonical(S_IFBLK, devno, ret); return device_path_make_canonical(S_IFBLK, devno, ret);
if (r < 0)
return log_debug_errno(r, "Failed to determine canonical path for '%s': %m", p);
/* Only if we still lock at the same block device we can reuse the fd. Otherwise return an
* invalidated fd. */
*ret_fd = fd_devno != (mode_t) -1 && fd_devno == devno ? TAKE_FD(fd) : -1;
return 0;
} }
static int find_root(char **ret, int *ret_fd) { static int find_root(char **ret) {
const char *t; const char *t;
int r; int r;
assert(ret);
assert(ret_fd);
if (arg_node) { if (arg_node) {
if (arg_empty == EMPTY_CREATE) { r = acquire_root_devno(arg_node, O_RDONLY|O_CLOEXEC, ret);
_cleanup_close_ int fd = -1;
_cleanup_free_ char *s = NULL;
s = strdup(arg_node);
if (!s)
return log_oom();
fd = open(arg_node, O_RDONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOFOLLOW, 0777);
if (fd < 0)
return log_error_errno(errno, "Failed to create '%s': %m", arg_node);
*ret = TAKE_PTR(s);
*ret_fd = TAKE_FD(fd);
return 0;
}
r = acquire_root_devno(arg_node, O_RDONLY|O_CLOEXEC, ret, ret_fd);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to determine backing device of %s: %m", arg_node); return log_error_errno(r, "Failed to determine backing device of %s: %m", arg_node);
return 0; return 0;
} }
assert(IN_SET(arg_empty, EMPTY_REFUSE, EMPTY_ALLOW));
/* Let's search for the root device. We look for two cases here: first in /, and then in /usr. The /* Let's search for the root device. We look for two cases here: first in /, and then in /usr. The
* latter we check for cases where / is a tmpfs and only /usr is an actual persistent block device * latter we check for cases where / is a tmpfs and only /usr is an actual persistent block device
* (think: volatile setups) */ * (think: volatile setups) */
@ -3000,7 +2898,7 @@ static int find_root(char **ret, int *ret_fd) {
} else } else
p = t; p = t;
r = acquire_root_devno(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC, ret, ret_fd); r = acquire_root_devno(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC, ret);
if (r < 0) { if (r < 0) {
if (r != -ENODEV) if (r != -ENODEV)
return log_error_errno(r, "Failed to determine backing device of %s: %m", p); return log_error_errno(r, "Failed to determine backing device of %s: %m", p);
@ -3011,83 +2909,9 @@ static int find_root(char **ret, int *ret_fd) {
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device."); return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device.");
} }
static int resize_backing_fd(const char *node, int *fd) {
char buf1[FORMAT_BYTES_MAX], buf2[FORMAT_BYTES_MAX];
_cleanup_close_ int writable_fd = -1;
struct stat st;
int r;
assert(node);
assert(fd);
if (arg_size == UINT64_MAX) /* Nothing to do */
return 0;
if (*fd < 0) {
/* Open the file if we haven't opened it yet. Note that we open it read-only here, just to
* keep a reference to the file we can pass around. */
*fd = open(node, O_RDONLY|O_CLOEXEC);
if (*fd < 0)
return log_error_errno(errno, "Failed to open '%s' in order to adjust size: %m", node);
}
if (fstat(*fd, &st) < 0)
return log_error_errno(errno, "Failed to stat '%s': %m", node);
r = stat_verify_regular(&st);
if (r < 0)
return log_error_errno(r, "Specified path '%s' is not a regular file, cannot resize: %m", node);
assert_se(format_bytes(buf1, sizeof(buf1), st.st_size));
assert_se(format_bytes(buf2, sizeof(buf2), arg_size));
if ((uint64_t) st.st_size >= arg_size) {
log_info("File '%s' already is of requested size or larger, not growing. (%s >= %s)", node, buf1, buf2);
return 0;
}
/* The file descriptor is read-only. In order to grow the file we need to have a writable fd. We
* reopen the file for that temporarily. We keep the writable fd only open for this operation though,
* as fdisk can't accept it anyway. */
writable_fd = fd_reopen(*fd, O_WRONLY|O_CLOEXEC);
if (writable_fd < 0)
return log_error_errno(writable_fd, "Failed to reopen backing file '%s' writable: %m", node);
if (!arg_discard) {
if (fallocate(writable_fd, 0, 0, arg_size) < 0) {
if (!ERRNO_IS_NOT_SUPPORTED(errno))
return log_error_errno(errno, "Failed to grow '%s' from %s to %s by allocation: %m",
node, buf1, buf2);
/* Fallback to truncation, if fallocate() is not supported. */
log_debug("Backing file system does not support fallocate(), falling back to ftruncate().");
} else {
if (st.st_size == 0) /* Likely regular file just created by us */
log_info("Allocated %s for '%s'.", buf2, node);
else
log_info("File '%s' grown from %s to %s by allocation.", node, buf1, buf2);
return 1;
}
}
if (ftruncate(writable_fd, arg_size) < 0)
return log_error_errno(errno, "Failed to grow '%s' from %s to %s by truncation: %m",
node, buf1, buf2);
if (st.st_size == 0) /* Likely regular file just created by us */
log_info("Sized '%s' to %s.", node, buf2);
else
log_info("File '%s' grown from %s to %s by truncation.", node, buf1, buf2);
return 1;
}
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(context_freep) Context* context = NULL; _cleanup_(context_freep) Context* context = NULL;
_cleanup_free_ char *node = NULL; _cleanup_free_ char *node = NULL;
_cleanup_close_ int backing_fd = -1;
bool from_scratch; bool from_scratch;
int r; int r;
@ -3122,22 +2946,14 @@ static int run(int argc, char *argv[]) {
if (r < 0) if (r < 0)
return r; return r;
if (context->n_partitions <= 0 && arg_empty == EMPTY_REFUSE) { if (context->n_partitions <= 0 && arg_empty != EMPTY_FORCE)
log_info("Didn't find any partition definition files, nothing to do.");
return 0; return 0;
}
r = find_root(&node, &backing_fd); r = find_root(&node);
if (r < 0) if (r < 0)
return r; return r;
if (arg_size != UINT64_MAX) { r = context_load_partition_table(context, node);
r = resize_backing_fd(node, &backing_fd);
if (r < 0)
return r;
}
r = context_load_partition_table(context, node, &backing_fd);
if (r == -EHWPOISON) if (r == -EHWPOISON)
return 77; /* Special return value which means "Not GPT, so not doing anything". This isn't return 77; /* Special return value which means "Not GPT, so not doing anything". This isn't
* really an error when called at boot. */ * really an error when called at boot. */
@ -3166,7 +2982,7 @@ static int run(int argc, char *argv[]) {
/* Reload the reduced partition table */ /* Reload the reduced partition table */
context_unload_partition_table(context); context_unload_partition_table(context);
r = context_load_partition_table(context, node, &backing_fd); r = context_load_partition_table(context, node);
if (r < 0) if (r < 0)
return r; return r;
} }

View File

@ -8,9 +8,11 @@ D=$(mktemp --directory)
trap "rm -rf '$D'" EXIT INT QUIT PIPE trap "rm -rf '$D'" EXIT INT QUIT PIPE
mkdir -p $D/definitions mkdir -p $D/definitions
truncate -s 1G $D/zzz
SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8 SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8
$repart $D/zzz --empty=create --size=1G --seed=$SEED $repart $D/zzz --empty=force --dry-run=no --seed=$SEED
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' > $D/empty sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' > $D/empty
@ -88,7 +90,9 @@ $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-09
$D/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic" $D/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic"
EOF EOF
$repart $D/zzz --size=2G --dry-run=no --seed=$SEED --definitions=$D/definitions truncate -s 2G $D/zzz
$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated3 sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated3

View File

@ -659,10 +659,6 @@ static int prepend_component(const char **p, bool usec, unsigned nesting, Calend
/* If no repeat value is specified for the µs component, then let's explicitly refuse ranges /* If no repeat value is specified for the µs component, then let's explicitly refuse ranges
* below 1s because our default repeat granularity is beyond that. */ * below 1s because our default repeat granularity is beyond that. */
/* Overflow check */
if (start > INT_MAX - repeat)
return -ERANGE;
if (usec && stop >= 0 && start + repeat > stop) if (usec && stop >= 0 && start + repeat > stop)
return -EINVAL; return -EINVAL;
} }

View File

@ -35,30 +35,6 @@ int fstab_has_fstype(const char *fstype) {
return false; return false;
} }
bool fstab_is_extrinsic(const char *mount, const char *opts) {
/* Don't bother with the OS data itself */
if (PATH_IN_SET(mount,
"/",
"/usr",
"/etc"))
return true;
if (PATH_STARTSWITH_SET(mount,
"/run/initramfs", /* This should stay around from before we boot until after we shutdown */
"/proc", /* All of this is API VFS */
"/sys", /* … dito … */
"/dev")) /* … dito … */
return true;
/* If this is an initrd mount, and we are not in the initrd, then leave
* this around forever, too. */
if (opts && fstab_test_option(opts, "x-initrd.mount\0") && !in_initrd())
return true;
return false;
}
int fstab_is_mount_point(const char *mount) { int fstab_is_mount_point(const char *mount) {
_cleanup_endmntent_ FILE *f = NULL; _cleanup_endmntent_ FILE *f = NULL;
struct mntent *m; struct mntent *m;

View File

@ -6,7 +6,6 @@
#include "macro.h" #include "macro.h"
bool fstab_is_extrinsic(const char *mount, const char *opts);
int fstab_is_mount_point(const char *mount); int fstab_is_mount_point(const char *mount);
int fstab_has_fstype(const char *fstype); int fstab_has_fstype(const char *fstype);

View File

@ -260,9 +260,6 @@ int generator_write_device_deps(
_cleanup_free_ char *node = NULL, *unit = NULL; _cleanup_free_ char *node = NULL, *unit = NULL;
int r; int r;
if (fstab_is_extrinsic(where, opts))
return 0;
if (!fstab_test_option(opts, "_netdev\0")) if (!fstab_test_option(opts, "_netdev\0"))
return 0; return 0;

View File

@ -413,11 +413,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
log_warning_errno(r, "Could not set ring buffer of %s: %m", old_name); log_warning_errno(r, "Could not set ring buffer of %s: %m", old_name);
} }
if (config->rx_flow_control >= 0 || config->tx_flow_control >= 0 || config->autoneg_flow_control >= 0) {
r = ethtool_set_flow_control(&ctx->ethtool_fd, old_name, config->rx_flow_control, config->tx_flow_control, config->autoneg_flow_control); r = ethtool_set_flow_control(&ctx->ethtool_fd, old_name, config->rx_flow_control, config->tx_flow_control, config->autoneg_flow_control);
if (r < 0) if (r < 0)
log_warning_errno(r, "Could not set flow control of %s: %m", old_name); log_warning_errno(r, "Could not set flow control of %s: %m", old_name);
}
r = sd_device_get_ifindex(device, &ifindex); r = sd_device_get_ifindex(device, &ifindex);
if (r < 0) if (r < 0)

View File

@ -1 +0,0 @@
4:3:2147..2

View File

@ -37,7 +37,6 @@ Unmanaged=
MTUBytes= MTUBytes=
Multicast= Multicast=
MACAddress= MACAddress=
Group=
[BridgeFDB] [BridgeFDB]
VLANId= VLANId=
MACAddress= MACAddress=