core: change RootImageOptions to use names instead of partition numbers
Follow the designations from the Discoverable Partitions Specification
This commit is contained in:
parent
bc8d56d305
commit
9ece644435
|
@ -149,11 +149,53 @@
|
||||||
<term><varname>RootImageOptions=</varname></term>
|
<term><varname>RootImageOptions=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Takes a comma-separated list of mount options that will be used on disk images specified by
|
<listitem><para>Takes a comma-separated list of mount options that will be used on disk images specified by
|
||||||
<varname>RootImage=</varname>. Optionally a partition number can be prefixed, followed by colon, in
|
<varname>RootImage=</varname>. Optionally a partition name can be prefixed, followed by colon, in
|
||||||
case the image has multiple partitions, otherwise partition number 0 is implied.
|
case the image has multiple partitions, otherwise partition name <literal>root</literal> is implied.
|
||||||
Options for multiple partitions can be specified in a single line with space separators. Assigning an empty
|
Options for multiple partitions can be specified in a single line with space separators. Assigning an empty
|
||||||
string removes previous assignments. For a list of valid mount options, please refer to
|
string removes previous assignments. Duplicated options are ignored. For a list of valid mount options, please
|
||||||
<citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
refer to <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||||
|
|
||||||
|
<para>Valid partition names follow the <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable
|
||||||
|
Partitions Specification</ulink>.</para>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<title>Accepted partition names</title>
|
||||||
|
|
||||||
|
<tgroup cols='1'>
|
||||||
|
<colspec colname='partition' />
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Partition Name</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry>root</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>root-secondary</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>home</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>srv</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>esp</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>xbootldr</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>tmp</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>var</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -802,12 +802,14 @@ static int property_get_root_image_options(
|
||||||
assert(property);
|
assert(property);
|
||||||
assert(reply);
|
assert(reply);
|
||||||
|
|
||||||
r = sd_bus_message_open_container(reply, 'a', "(us)");
|
r = sd_bus_message_open_container(reply, 'a', "(ss)");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
LIST_FOREACH(mount_options, m, c->root_image_options) {
|
LIST_FOREACH(mount_options, m, c->root_image_options) {
|
||||||
r = sd_bus_message_append(reply, "(us)", m->partition_number, m->options);
|
r = sd_bus_message_append(reply, "(ss)",
|
||||||
|
partition_designator_to_string(m->partition_designator),
|
||||||
|
m->options);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -891,7 +893,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||||
SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RootImageOptions", "a(us)", property_get_root_image_options, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RootImageOptions", "a(ss)", property_get_root_image_options, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RootHash", "ay", property_get_root_hash, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RootHash", "ay", property_get_root_hash, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RootHashPath", "s", NULL, offsetof(ExecContext, root_hash_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RootHashPath", "s", NULL, offsetof(ExecContext, root_hash_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RootHashSignature", "ay", property_get_root_hash_sig, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RootHashSignature", "ay", property_get_root_hash_sig, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
@ -1371,29 +1373,35 @@ int bus_exec_context_set_transient_property(
|
||||||
if (streq(name, "RootImageOptions")) {
|
if (streq(name, "RootImageOptions")) {
|
||||||
_cleanup_(mount_options_free_allp) MountOptions *options = NULL;
|
_cleanup_(mount_options_free_allp) MountOptions *options = NULL;
|
||||||
_cleanup_free_ char *format_str = NULL;
|
_cleanup_free_ char *format_str = NULL;
|
||||||
const char *mount_options;
|
const char *mount_options, *partition;
|
||||||
unsigned partition_number;
|
|
||||||
|
|
||||||
r = sd_bus_message_enter_container(message, 'a', "(us)");
|
r = sd_bus_message_enter_container(message, 'a', "(ss)");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
while ((r = sd_bus_message_read(message, "(us)", &partition_number, &mount_options)) > 0) {
|
while ((r = sd_bus_message_read(message, "(ss)", &partition, &mount_options)) > 0) {
|
||||||
_cleanup_free_ char *previous = TAKE_PTR(format_str);
|
_cleanup_free_ char *previous = TAKE_PTR(format_str);
|
||||||
_cleanup_free_ MountOptions *o = NULL;
|
_cleanup_free_ MountOptions *o = NULL;
|
||||||
|
int partition_designator;
|
||||||
|
|
||||||
if (chars_intersect(mount_options, WHITESPACE))
|
if (chars_intersect(mount_options, WHITESPACE))
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
"Invalid mount options string, contains whitespace character(s): %s", mount_options);
|
"Invalid mount options string, contains whitespace character(s): %s", mount_options);
|
||||||
|
|
||||||
if (asprintf(&format_str, "%s%s%u:%s", strempty(previous), previous ? " " : "", partition_number, mount_options) < 0)
|
partition_designator = partition_designator_from_string(partition);
|
||||||
|
if (partition_designator < 0)
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
|
"Invalid partition name: %s", partition);
|
||||||
|
|
||||||
|
format_str = strjoin(previous, previous ? " " : "", partition, ":", mount_options);
|
||||||
|
if (!format_str)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
o = new(MountOptions, 1);
|
o = new(MountOptions, 1);
|
||||||
if (!o)
|
if (!o)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
*o = (MountOptions) {
|
*o = (MountOptions) {
|
||||||
.partition_number = partition_number,
|
.partition_designator = partition_designator,
|
||||||
.options = strdup(mount_options),
|
.options = strdup(mount_options),
|
||||||
};
|
};
|
||||||
if (!o->options)
|
if (!o->options)
|
||||||
|
|
|
@ -4634,7 +4634,9 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||||
fprintf(f, "%sRootImageOptions:", prefix);
|
fprintf(f, "%sRootImageOptions:", prefix);
|
||||||
LIST_FOREACH(mount_options, o, c->root_image_options)
|
LIST_FOREACH(mount_options, o, c->root_image_options)
|
||||||
if (!isempty(o->options))
|
if (!isempty(o->options))
|
||||||
fprintf(f, " %u:%s", o->partition_number, o->options);
|
fprintf(f, " %s:%s",
|
||||||
|
partition_designator_to_string(o->partition_designator),
|
||||||
|
o->options);
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1454,22 +1454,23 @@ int config_parse_root_image_options(
|
||||||
}
|
}
|
||||||
|
|
||||||
STRV_FOREACH_PAIR(first, second, l) {
|
STRV_FOREACH_PAIR(first, second, l) {
|
||||||
_cleanup_free_ char *mount_options_resolved = NULL;
|
|
||||||
const char *mount_options = NULL;
|
|
||||||
MountOptions *o = NULL;
|
MountOptions *o = NULL;
|
||||||
unsigned int partition_number = 0;
|
_cleanup_free_ char *mount_options_resolved = NULL;
|
||||||
|
const char *mount_options = NULL, *partition = "root";
|
||||||
|
int partition_designator;
|
||||||
|
|
||||||
/* Format is either '0:foo' or 'foo' (0 is implied) */
|
/* Format is either 'root:foo' or 'foo' (root is implied) */
|
||||||
if (!isempty(*second)) {
|
if (!isempty(*second)) {
|
||||||
|
partition = *first;
|
||||||
mount_options = *second;
|
mount_options = *second;
|
||||||
r = safe_atou(*first, &partition_number);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition number from \"%s\", ignoring: %m", *first);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
mount_options = *first;
|
mount_options = *first;
|
||||||
|
|
||||||
|
partition_designator = partition_designator_from_string(partition);
|
||||||
|
if (partition_designator < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Invalid partition name %s, ignoring", partition);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
r = unit_full_printf(u, mount_options, &mount_options_resolved);
|
r = unit_full_printf(u, mount_options, &mount_options_resolved);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", mount_options);
|
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", mount_options);
|
||||||
|
@ -1480,10 +1481,10 @@ int config_parse_root_image_options(
|
||||||
if (!o)
|
if (!o)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
*o = (MountOptions) {
|
*o = (MountOptions) {
|
||||||
.partition_number = partition_number,
|
.partition_designator = partition_designator,
|
||||||
.options = TAKE_PTR(mount_options_resolved),
|
.options = TAKE_PTR(mount_options_resolved),
|
||||||
};
|
};
|
||||||
LIST_APPEND(mount_options, options, o);
|
LIST_APPEND(mount_options, options, TAKE_PTR(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* empty spaces/separators only */
|
/* empty spaces/separators only */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "condition.h"
|
#include "condition.h"
|
||||||
#include "coredump-util.h"
|
#include "coredump-util.h"
|
||||||
#include "cpu-set-util.h"
|
#include "cpu-set-util.h"
|
||||||
|
#include "dissect-image.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "exec-util.h"
|
#include "exec-util.h"
|
||||||
#include "exit-status.h"
|
#include "exit-status.h"
|
||||||
|
@ -1468,11 +1469,11 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
r = sd_bus_message_open_container(m, 'v', "a(us)");
|
r = sd_bus_message_open_container(m, 'v', "a(ss)");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
r = sd_bus_message_open_container(m, 'a', "(us)");
|
r = sd_bus_message_open_container(m, 'a', "(ss)");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
|
@ -1481,21 +1482,13 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
return log_error_errno(r, "Failed to parse argument: %m");
|
return log_error_errno(r, "Failed to parse argument: %m");
|
||||||
|
|
||||||
STRV_FOREACH_PAIR(first, second, l) {
|
STRV_FOREACH_PAIR(first, second, l) {
|
||||||
const char *mount_options;
|
/* Format is either 'root:foo' or 'foo' (root is implied) */
|
||||||
unsigned partition_number = 0;
|
if (!isempty(*second) && partition_designator_from_string(*first) < 0)
|
||||||
|
return bus_log_create_error(-EINVAL);
|
||||||
|
|
||||||
/* Format is either '0:foo' or 'foo' (0 is implied) */
|
r = sd_bus_message_append(m, "(ss)",
|
||||||
if (!isempty(*second)) {
|
!isempty(*second) ? *first : "root",
|
||||||
mount_options = *second;
|
!isempty(*second) ? *second : *first);
|
||||||
r = safe_atou(*first, &partition_number);
|
|
||||||
if (r < 0) {
|
|
||||||
log_error_errno(r, "Failed to parse partition number from %s: %m", *first);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
mount_options = *first;
|
|
||||||
|
|
||||||
r = sd_bus_message_append(m, "(us)", partition_number, mount_options);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,7 +420,7 @@ int dissect_image(
|
||||||
m->verity = root_hash && verity_data;
|
m->verity = root_hash && verity_data;
|
||||||
m->can_verity = !!verity_data;
|
m->can_verity = !!verity_data;
|
||||||
|
|
||||||
options = mount_options_from_part(mount_options, 0);
|
options = mount_options_from_part(mount_options, PARTITION_ROOT);
|
||||||
if (options) {
|
if (options) {
|
||||||
o = strdup(options);
|
o = strdup(options);
|
||||||
if (!o)
|
if (!o)
|
||||||
|
@ -716,7 +716,7 @@ int dissect_image(
|
||||||
if (!n)
|
if (!n)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
options = mount_options_from_part(mount_options, nr);
|
options = mount_options_from_part(mount_options, designator);
|
||||||
if (options) {
|
if (options) {
|
||||||
o = strdup(options);
|
o = strdup(options);
|
||||||
if (!o)
|
if (!o)
|
||||||
|
@ -773,7 +773,7 @@ int dissect_image(
|
||||||
if (!n)
|
if (!n)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
options = mount_options_from_part(mount_options, nr);
|
options = mount_options_from_part(mount_options, PARTITION_XBOOTLDR);
|
||||||
if (options) {
|
if (options) {
|
||||||
o = strdup(options);
|
o = strdup(options);
|
||||||
if (!o)
|
if (!o)
|
||||||
|
@ -827,7 +827,7 @@ int dissect_image(
|
||||||
if (multiple_generic)
|
if (multiple_generic)
|
||||||
return -ENOTUNIQ;
|
return -ENOTUNIQ;
|
||||||
|
|
||||||
options = mount_options_from_part(mount_options, generic_nr);
|
options = mount_options_from_part(mount_options, PARTITION_ROOT);
|
||||||
if (options) {
|
if (options) {
|
||||||
o = strdup(options);
|
o = strdup(options);
|
||||||
if (!o)
|
if (!o)
|
||||||
|
@ -2023,11 +2023,11 @@ MountOptions* mount_options_free_all(MountOptions *options) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* mount_options_from_part(const MountOptions *options, unsigned int partition_number) {
|
const char* mount_options_from_part(const MountOptions *options, int designator) {
|
||||||
MountOptions *m;
|
MountOptions *m;
|
||||||
|
|
||||||
LIST_FOREACH(mount_options, m, (MountOptions *)options)
|
LIST_FOREACH(mount_options, m, (MountOptions *)options)
|
||||||
if (partition_number == m->partition_number && !isempty(m->options))
|
if (designator == m->partition_designator && !isempty(m->options))
|
||||||
return m->options;
|
return m->options;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -87,14 +87,14 @@ struct DissectedImage {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MountOptions {
|
struct MountOptions {
|
||||||
unsigned partition_number;
|
int partition_designator;
|
||||||
char *options;
|
char *options;
|
||||||
LIST_FIELDS(MountOptions, mount_options);
|
LIST_FIELDS(MountOptions, mount_options);
|
||||||
};
|
};
|
||||||
|
|
||||||
MountOptions* mount_options_free_all(MountOptions *options);
|
MountOptions* mount_options_free_all(MountOptions *options);
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
|
||||||
const char* mount_options_from_part(const MountOptions *options, unsigned int partition_number);
|
const char* mount_options_from_part(const MountOptions *options, int designator);
|
||||||
|
|
||||||
int probe_filesystem(const char *node, char **ret_fstype);
|
int probe_filesystem(const char *node, char **ret_fstype);
|
||||||
int dissect_image(int fd, const void *root_hash, size_t root_hash_size, const char *verity_data, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
int dissect_image(int fd, const void *root_hash, size_t root_hash_size, const char *verity_data, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
||||||
|
|
|
@ -128,33 +128,38 @@ umount ${image_dir}/mount
|
||||||
|
|
||||||
systemd-run -t --property RootImage=${image}.gpt --property RootHash=${roothash} /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t --property RootImage=${image}.gpt --property RootHash=${roothash} /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
|
|
||||||
systemd-run -t --property RootImage=${image}.raw --property RootImageOptions="1:ro,noatime 2:ro,dev nosuid,dev" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t --property RootImage=${image}.raw --property RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t --property RootImage=${image}.gpt --property RootImageOptions="1:ro,noatime 1:ro,dev" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "noatime"
|
systemd-run -t --property RootImage=${image}.gpt --property RootImageOptions="root:ro,noatime root:ro,dev" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "noatime"
|
||||||
|
|
||||||
|
mkdir -p 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
|
||||||
ExecStart=mount
|
ExecStart=bash -c "mount > /run/result/a"
|
||||||
|
BindPaths=${image_dir}/result:/run/result
|
||||||
|
TemporaryFileSystem=/run
|
||||||
MountAPIVFS=yes
|
MountAPIVFS=yes
|
||||||
RootImage=${image}.raw
|
RootImage=${image}.raw
|
||||||
RootImageOptions=1:ro,noatime,nosuid 2:ro,dev noatime,dev
|
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
|
||||||
journalctl -b -u testservice-50a.service | grep -F "squashfs" | grep -q -F "noatime"
|
grep -F "squashfs" ${image_dir}/result/a | grep -q -F "noatime"
|
||||||
journalctl -b -u testservice-50a.service | grep -F "squashfs" | 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]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=mount
|
ExecStart=bash -c "mount > /run/result/b"
|
||||||
|
BindPaths=${image_dir}/result:/run/result
|
||||||
|
TemporaryFileSystem=/run
|
||||||
MountAPIVFS=yes
|
MountAPIVFS=yes
|
||||||
RootImage=${image}.gpt
|
RootImage=${image}.gpt
|
||||||
RootImageOptions=1:ro,noatime,nosuid 2:ro,dev nosuid,dev
|
RootImageOptions=root:ro,noatime,nosuid home:ro,dev nosuid,dev
|
||||||
RootImageOptions=2:ro,dev nosuid,dev,%%foo
|
RootImageOptions=home:ro,dev nosuid,dev,%%foo
|
||||||
EOF
|
EOF
|
||||||
systemctl start testservice-50b.service
|
systemctl start testservice-50b.service
|
||||||
journalctl -b -u testservice-50b.service | grep -F "squashfs" | 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"
|
||||||
|
|
Loading…
Reference in New Issue