mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
repart: Allow configuring sector size
Let's allow users to configure the (logical) sector size of their image. This is required when building images for a 4k sector size disk on a 512b sector size host or vice-versa.
This commit is contained in:
@@ -387,6 +387,15 @@
|
||||
<command>systemd-repart</command> was executed.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--sector-size=</option><arg>BYTES</arg></term>
|
||||
|
||||
<listitem><para>This option allows configuring the sector size of the image produced by
|
||||
<command>systemd-repart</command>. It takes a value that is a power of <literal>2</literal> between
|
||||
<literal>512</literal> and <literal>4096</literal>. This option is useful when building images for
|
||||
disks that use a different sector size as the disk on which the image is produced.</para></listitem>.
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||
|
||||
@@ -256,6 +256,26 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_sector_size(const char *t, uint64_t *ret) {
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
assert(ret);
|
||||
|
||||
uint64_t ss;
|
||||
|
||||
r = safe_atou64(t, &ss);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse sector size parameter %s", t);
|
||||
if (ss < 512 || ss > 4096) /* Allow up to 4K due to dm-crypt support and 4K alignment by the homed LUKS backend */
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Sector size not between 512 and 4096: %s", t);
|
||||
if (!ISPOWEROF2(ss))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Sector size not power of 2: %s", t);
|
||||
|
||||
*ret = ss;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_range(const char *t, unsigned *lower, unsigned *upper) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
unsigned l, u;
|
||||
|
||||
@@ -18,6 +18,7 @@ int parse_ifindex(const char *s);
|
||||
int parse_mtu(int family, const char *s, uint32_t *ret);
|
||||
|
||||
int parse_size(const char *t, uint64_t base, uint64_t *size);
|
||||
int parse_sector_size(const char *t, uint64_t *ret);
|
||||
int parse_range(const char *t, unsigned *lower, unsigned *upper);
|
||||
int parse_errno(const char *t);
|
||||
|
||||
|
||||
@@ -1798,26 +1798,6 @@ static int parse_disk_size(const char *t, uint64_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_sector_size(const char *t, uint64_t *ret) {
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
assert(ret);
|
||||
|
||||
uint64_t ss;
|
||||
|
||||
r = safe_atou64(t, &ss);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse sector size parameter %s", t);
|
||||
if (ss < 512 || ss > 4096) /* Allow up to 4K due to dm-crypt support and 4K alignment by the homed LUKS backend */
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Sector size not between 512 and 4096: %s", t);
|
||||
if (!ISPOWEROF2(ss))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Sector size not power of 2: %s", t);
|
||||
|
||||
*ret = ss;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int resize_home(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_(user_record_unrefp) UserRecord *secret = NULL;
|
||||
|
||||
@@ -2356,7 +2356,7 @@ int home_create_luks(
|
||||
r = mkfs_options_for_fstype(fstype, &extra_mkfs_options);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine mkfs command line options for '%s': %m", fstype);
|
||||
r = make_filesystem(setup->dm_node, fstype, user_record_user_name_and_realm(h), NULL, fs_uuid, user_record_luks_discard(h), extra_mkfs_options);
|
||||
r = make_filesystem(setup->dm_node, fstype, user_record_user_name_and_realm(h), NULL, fs_uuid, user_record_luks_discard(h), 0, extra_mkfs_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract file name from '%s': %m", device);
|
||||
|
||||
return make_filesystem(device, fstype, label, NULL, uuid, true, NULL);
|
||||
return make_filesystem(device, fstype, label, NULL, uuid, true, 0, NULL);
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION(run);
|
||||
|
||||
@@ -147,6 +147,7 @@ static size_t arg_n_filter_partitions = 0;
|
||||
static FilterPartitionsType arg_filter_partitions_type = FILTER_PARTITIONS_NONE;
|
||||
static sd_id128_t *arg_defer_partitions = NULL;
|
||||
static size_t arg_n_defer_partitions = 0;
|
||||
static uint64_t arg_sector_size = 0;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||
@@ -1973,16 +1974,22 @@ static int context_load_partition_table(Context *context) {
|
||||
assert(context->end == UINT64_MAX);
|
||||
assert(context->total == UINT64_MAX);
|
||||
|
||||
c = fdisk_new_context();
|
||||
if (!c)
|
||||
return log_oom();
|
||||
|
||||
if (arg_sector_size > 0) {
|
||||
r = fdisk_save_user_sector_size(c, /* phy= */ 0, arg_sector_size);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set sector size: %m");
|
||||
}
|
||||
|
||||
/* 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 (context->backing_fd < 0) {
|
||||
c = fdisk_new_context();
|
||||
if (!c)
|
||||
return log_oom();
|
||||
|
||||
r = fdisk_assign_device(c, context->node, arg_dry_run);
|
||||
} else
|
||||
r = fdisk_new_context_fd(context->backing_fd, arg_dry_run, &c);
|
||||
r = fdisk_assign_device(
|
||||
c,
|
||||
context->backing_fd >= 0 ? FORMAT_PROC_FD_PATH(context->backing_fd) : context->node,
|
||||
arg_dry_run);
|
||||
|
||||
if (r == -EINVAL && arg_size_auto) {
|
||||
struct stat st;
|
||||
@@ -1999,7 +2006,7 @@ static int context_load_partition_table(Context *context) {
|
||||
|
||||
if (S_ISREG(st.st_mode) && st.st_size == 0) {
|
||||
/* User the fallback values if we have no better idea */
|
||||
context->sector_size = 512;
|
||||
context->sector_size = arg_sector_size ?: 512;
|
||||
context->grain_size = 4096;
|
||||
return /* from_scratch = */ true;
|
||||
}
|
||||
@@ -4031,7 +4038,7 @@ static int context_mkfs(Context *context) {
|
||||
}
|
||||
|
||||
r = make_filesystem(partition_target_path(t), p->format, strempty(p->new_label), root,
|
||||
p->fs_uuid, arg_discard, NULL);
|
||||
p->fs_uuid, arg_discard, context->sector_size, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -5361,7 +5368,8 @@ static int context_minimize(Context *context) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = make_filesystem(d ? d->node : temp, p->format, strempty(p->new_label), root, fs_uuid, arg_discard, NULL);
|
||||
r = make_filesystem(d ? d->node : temp, p->format, strempty(p->new_label), root, fs_uuid,
|
||||
arg_discard, context->sector_size, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -5414,7 +5422,8 @@ static int context_minimize(Context *context) {
|
||||
if (r < 0 && r != -ENOENT && !ERRNO_IS_PRIVILEGE(r))
|
||||
return log_error_errno(r, "Failed to make loopback device of %s: %m", temp);
|
||||
|
||||
r = make_filesystem(d ? d->node : temp, p->format, strempty(p->new_label), root, p->fs_uuid, arg_discard, NULL);
|
||||
r = make_filesystem(d ? d->node : temp, p->format, strempty(p->new_label), root, p->fs_uuid,
|
||||
arg_discard, context->sector_size, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -5511,6 +5520,7 @@ static int help(void) {
|
||||
" --defer-partitions=PARTITION1,PARTITION2,PARTITION3,…\n"
|
||||
" Take partitions of the specified types into account\n"
|
||||
" but don't populate them yet\n"
|
||||
" --sector-size=SIZE Set the logical sector size for the image\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
@@ -5549,6 +5559,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_INCLUDE_PARTITIONS,
|
||||
ARG_EXCLUDE_PARTITIONS,
|
||||
ARG_DEFER_PARTITIONS,
|
||||
ARG_SECTOR_SIZE,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -5579,6 +5590,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "include-partitions", required_argument, NULL, ARG_INCLUDE_PARTITIONS },
|
||||
{ "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS },
|
||||
{ "defer-partitions", required_argument, NULL, ARG_DEFER_PARTITIONS },
|
||||
{ "sector-size", required_argument, NULL, ARG_SECTOR_SIZE },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -5866,6 +5878,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case ARG_SECTOR_SIZE:
|
||||
r = parse_sector_size(optarg, &arg_sector_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -301,6 +301,7 @@ int make_filesystem(
|
||||
const char *root,
|
||||
sd_id128_t uuid,
|
||||
bool discard,
|
||||
uint64_t sector_size,
|
||||
char * const *extra_mkfs_args) {
|
||||
|
||||
_cleanup_free_ char *mkfs = NULL, *mangled_label = NULL;
|
||||
@@ -397,6 +398,7 @@ int make_filesystem(
|
||||
"-I", "256",
|
||||
"-m", "0",
|
||||
"-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
|
||||
"-b", "4096",
|
||||
node);
|
||||
if (!argv)
|
||||
return log_oom();
|
||||
@@ -413,6 +415,7 @@ int make_filesystem(
|
||||
"-O", "has_journal",
|
||||
"-m", "0",
|
||||
"-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
|
||||
"-b", "4096",
|
||||
node);
|
||||
|
||||
if (root && strv_extend_strv(&argv, STRV_MAKE("-d", root), false) < 0)
|
||||
@@ -469,7 +472,15 @@ int make_filesystem(
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
} else if (streq(fstype, "vfat"))
|
||||
if (sector_size > 0) {
|
||||
if (strv_extend(&argv, "-s") < 0)
|
||||
return log_oom();
|
||||
|
||||
if (strv_extendf(&argv, "size=%"PRIu64, sector_size) < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
} else if (streq(fstype, "vfat")) {
|
||||
|
||||
argv = strv_new(mkfs,
|
||||
"-i", vol_id,
|
||||
@@ -477,7 +488,15 @@ int make_filesystem(
|
||||
"-F", "32", /* yes, we force FAT32 here */
|
||||
node);
|
||||
|
||||
else if (streq(fstype, "swap"))
|
||||
if (sector_size > 0) {
|
||||
if (strv_extend(&argv, "-S") < 0)
|
||||
return log_oom();
|
||||
|
||||
if (strv_extendf(&argv, "%"PRIu64, sector_size) < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
} else if (streq(fstype, "swap"))
|
||||
/* TODO: add --quiet here if
|
||||
* https://github.com/util-linux/util-linux/issues/1499 resolved. */
|
||||
|
||||
|
||||
@@ -11,4 +11,12 @@ int mkfs_exists(const char *fstype);
|
||||
|
||||
int mkfs_supports_root_option(const char *fstype);
|
||||
|
||||
int make_filesystem(const char *node, const char *fstype, const char *label, const char *root, sd_id128_t uuid, bool discard, char * const *extra_mkfs_args);
|
||||
int make_filesystem(
|
||||
const char *node,
|
||||
const char *fstype,
|
||||
const char *label,
|
||||
const char *root,
|
||||
sd_id128_t uuid,
|
||||
bool discard,
|
||||
uint64_t sector_size,
|
||||
char * const *extra_mkfs_args);
|
||||
|
||||
@@ -245,16 +245,16 @@ static int run(int argc, char *argv[]) {
|
||||
assert_se(r >= 0);
|
||||
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_ESP].node, "vfat", "EFI", NULL, id, true, NULL) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_ESP].node, "vfat", "EFI", NULL, id, true, 0, NULL) >= 0);
|
||||
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_XBOOTLDR].node, "vfat", "xbootldr", NULL, id, true, NULL) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_XBOOTLDR].node, "vfat", "xbootldr", NULL, id, true, 0, NULL) >= 0);
|
||||
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_ROOT].node, "ext4", "root", NULL, id, true, NULL) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_ROOT].node, "ext4", "root", NULL, id, true, 0, NULL) >= 0);
|
||||
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", NULL, id, true, NULL) >= 0);
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", NULL, id, true, 0, NULL) >= 0);
|
||||
|
||||
dissected = dissected_image_unref(dissected);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user