};
typedef struct Context {
+ char **definitions;
+
LIST_HEAD(Partition, partitions);
size_t n_partitions;
bool node_is_our_file;
int backing_fd;
+ EmptyMode empty;
+ bool dry_run;
+
bool from_scratch;
X509 *certificate;
DEFINE_TRIVIAL_CLEANUP_FUNC(Partition*, partition_free);
static Context* context_new(
+ char **definitions,
+ EmptyMode empty,
+ bool dry_run,
sd_id128_t seed,
X509 *certificate,
EVP_PKEY *private_key) {
- Context *context;
-
/* Note: This function takes ownership of the certificate and private_key arguments. */
- context = new(Context, 1);
+ _cleanup_strv_free_ char **d = NULL;
+ if (!strv_isempty(definitions)) {
+ d = strv_copy(definitions);
+ if (!d)
+ return NULL;
+ }
+
+ Context *context = new(Context, 1);
if (!context)
return NULL;
*context = (Context) {
+ .definitions = TAKE_PTR(d),
.start = UINT64_MAX,
.end = UINT64_MAX,
.total = UINT64_MAX,
.seed = seed,
.certificate = certificate,
.private_key = private_key,
+ .empty = empty,
+ .dry_run = dry_run,
};
return context;
if (!context)
return NULL;
+ strv_free(context->definitions);
+
while (context->partitions)
partition_unlink_and_free(context, context->partitions);
assert(context->n_partitions == 0);
return flags;
}
-static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) {
+static int partition_read_definition(
+ Context *c,
+ Partition *p,
+ const char *path,
+ const char *const *conf_file_dirs) {
ConfigTableItem table[] = {
{ "Partition", "Type", config_parse_type, 0, &p->type },
const char* dropin_dirname;
int r;
+ assert(c);
+ assert(p);
+ assert(path);
+
r = path_extract_filename(path, &filename);
if (r < 0)
return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);
STRV_MAKE_CONST(path),
conf_file_dirs,
dropin_dirname,
- arg_definitions ? NULL : arg_root,
+ c->definitions ? NULL : arg_root,
"Partition\0",
config_item_table_lookup, table,
CONFIG_PARSE_WARN,
assert(context);
- dirs = (const char* const*) (arg_definitions ?: CONF_PATHS_STRV("repart.d"));
+ dirs = (const char* const*) (context->definitions ?: CONF_PATHS_STRV("repart.d"));
- r = conf_files_list_strv(&files, ".conf", arg_definitions ? NULL : arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs);
+ r = conf_files_list_strv(
+ &files,
+ ".conf",
+ context->definitions ? NULL : arg_root,
+ CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
+ dirs);
if (r < 0)
return log_error_errno(r, "Failed to enumerate *.conf files: %m");
if (!p->definition_path)
return log_oom();
- r = partition_read_definition(p, *f, dirs);
+ r = partition_read_definition(context, p, *f, dirs);
if (r < 0)
return r;
if (r == 0)
r = context_open_and_lock_backing_fd(
context->node,
- arg_dry_run ? LOCK_SH : LOCK_EX,
+ context->dry_run ? LOCK_SH : LOCK_EX,
&context->backing_fd);
if (r < 0)
return r;
if (fstat(context->backing_fd, &st) < 0)
return log_error_errno(errno, "Failed to stat %s: %m", context->node);
- if (IN_SET(arg_empty, EMPTY_REQUIRE, EMPTY_FORCE, EMPTY_CREATE) && S_ISREG(st.st_mode))
+ if (IN_SET(context->empty, EMPTY_REQUIRE, EMPTY_FORCE, EMPTY_CREATE) && S_ISREG(st.st_mode))
/* Don't probe sector size from partition table if we are supposed to start from an empty disk */
ssz = 512;
else {
r = fdisk_assign_device(
c,
context->backing_fd >= 0 ? FORMAT_PROC_FD_PATH(context->backing_fd) : context->node,
- arg_dry_run);
+ context->dry_run);
if (r == -EINVAL && arg_size_auto) {
struct stat st;
if (context->backing_fd < 0) {
/* If we have no fd referencing the device yet, make a copy of the fd now, so that we have one */
r = context_open_and_lock_backing_fd(FORMAT_PROC_FD_PATH(fdisk_get_devfd(c)),
- arg_dry_run ? LOCK_SH : LOCK_EX,
+ context->dry_run ? LOCK_SH : LOCK_EX,
&context->backing_fd);
if (r < 0)
return r;
log_debug("Sector size of device is %lu bytes. Using default filesystem sector size of %" PRIu64 " and grain size of %" PRIu64 ".", secsz, fs_secsz, grainsz);
- switch (arg_empty) {
+ switch (context->empty) {
case EMPTY_REFUSE:
/* Refuse empty disks, insist on an existing GPT partition table */
assert(context);
- if (arg_empty == EMPTY_CREATE) /* If we just created the image, no need to wipe */
+ if (context->empty == EMPTY_CREATE) /* If we just created the image, no need to wipe */
return 0;
/* Wipe and discard the contents of all partitions we are about to create. We skip the discarding if
r = read_attr_fd(fdisk_get_devfd(context->fdisk_context), &attrs);
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r))
- log_warning_errno(r, "Failed to read file attributes of %s, ignoring: %m", arg_node);
+ log_warning_errno(r, "Failed to read file attributes of %s, ignoring: %m", context->node);
if (FLAGS_SET(attrs, FS_NOCOW_FL)) {
r = chattr_fd(fd, FS_NOCOW_FL, FS_NOCOW_FL);
r = read_attr_fd(fd, &attrs);
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r))
- log_warning_errno(r, "Failed to read file attributes of %s, ignoring: %m", arg_node);
+ log_warning_errno(r, "Failed to read file attributes of %s, ignoring: %m", context->node);
}
fdt = xopenat_full(
return 0;
}
- if (arg_dry_run) {
+ if (context->dry_run) {
log_notice("Refusing to repartition, please re-run with --dry-run=no.");
return 0;
}
log_info("Applying changes to %s.", context->node);
- if (context->from_scratch && arg_empty != EMPTY_CREATE) {
+ if (context->from_scratch && context->empty != EMPTY_CREATE) {
/* Erase everything if we operate from scratch, except if the image was just created anyway, and thus is definitely empty. */
r = context_wipe_range(context, 0, context->total);
if (r < 0)
if (context->from_scratch) /* Nothing to reset if we start from scratch */
return 0;
- if (arg_dry_run) {
+ if (context->dry_run) {
log_notice("Refusing to factory reset, please re-run with --dry-run=no.");
return 0;
}
r = read_attr_fd(context->backing_fd, &attrs);
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r))
- log_warning_errno(r, "Failed to read file attributes of %s, ignoring: %m", arg_node);
+ log_warning_errno(r, "Failed to read file attributes of %s, ignoring: %m", context->node);
LIST_FOREACH(partitions, p, context->partitions) {
_cleanup_(rm_rf_physical_and_freep) char *root = NULL;
assert(context);
if (arg_node) {
- if (arg_empty == EMPTY_CREATE) {
+ if (context->empty == EMPTY_CREATE) {
_cleanup_close_ int fd = -EBADF;
_cleanup_free_ char *s = NULL;
return 0;
}
- assert(IN_SET(arg_empty, EMPTY_REFUSE, EMPTY_ALLOW));
+ assert(IN_SET(context->empty, EMPTY_REFUSE, EMPTY_ALLOW));
/* If the root mount has been replaced by some form of volatile file system (overlayfs), the
* original root block device node is symlinked in /run/systemd/volatile-root. Let's read that
return log_oom();
}
- context = context_new(arg_seed, certificate, private_key);
+ context = context_new(
+ arg_definitions,
+ arg_empty,
+ arg_dry_run,
+ arg_seed,
+ certificate,
+ private_key);
if (!context)
return log_oom();
if (arg_make_ddi) {
_cleanup_free_ char *d = NULL, *dp = NULL;
- assert(!arg_definitions);
+ assert(!context->definitions);
d = strjoin(arg_make_ddi, ".repart.d/");
if (!d)
if (r < 0)
return log_error_errno(r, "DDI type '%s' is not defined: %m", arg_make_ddi);
- if (strv_consume(&arg_definitions, TAKE_PTR(dp)) < 0)
+ if (strv_consume(&context->definitions, TAKE_PTR(dp)) < 0)
return log_oom();
} else
- strv_uniq(arg_definitions);
+ strv_uniq(context->definitions);
r = context_read_definitions(context);
if (r < 0)