]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/partition/repart.c
Merge pull request #24263 from pothos/sysext-for-static-binaries
[thirdparty/systemd.git] / src / partition / repart.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #if HAVE_VALGRIND_MEMCHECK_H
4 #include <valgrind/memcheck.h>
5 #endif
6
7 #include <fcntl.h>
8 #include <getopt.h>
9 #include <linux/fs.h>
10 #include <linux/loop.h>
11 #include <sys/file.h>
12 #include <sys/ioctl.h>
13 #include <sys/stat.h>
14
15 #include "sd-device.h"
16 #include "sd-id128.h"
17
18 #include "alloc-util.h"
19 #include "blkid-util.h"
20 #include "blockdev-util.h"
21 #include "btrfs-util.h"
22 #include "chase-symlinks.h"
23 #include "conf-files.h"
24 #include "conf-parser.h"
25 #include "cryptsetup-util.h"
26 #include "def.h"
27 #include "devnum-util.h"
28 #include "dirent-util.h"
29 #include "efivars.h"
30 #include "errno-util.h"
31 #include "fd-util.h"
32 #include "fdisk-util.h"
33 #include "fileio.h"
34 #include "format-table.h"
35 #include "format-util.h"
36 #include "fs-util.h"
37 #include "glyph-util.h"
38 #include "gpt.h"
39 #include "hexdecoct.h"
40 #include "hmac.h"
41 #include "id128-util.h"
42 #include "json.h"
43 #include "list.h"
44 #include "loop-util.h"
45 #include "main-func.h"
46 #include "mkdir.h"
47 #include "mkfs-util.h"
48 #include "mount-util.h"
49 #include "mountpoint-util.h"
50 #include "parse-argument.h"
51 #include "parse-helpers.h"
52 #include "pretty-print.h"
53 #include "proc-cmdline.h"
54 #include "process-util.h"
55 #include "random-util.h"
56 #include "resize-fs.h"
57 #include "sort-util.h"
58 #include "specifier.h"
59 #include "stdio-util.h"
60 #include "string-table.h"
61 #include "string-util.h"
62 #include "strv.h"
63 #include "sync-util.h"
64 #include "terminal-util.h"
65 #include "tpm2-util.h"
66 #include "user-util.h"
67 #include "utf8.h"
68
69 /* If not configured otherwise use a minimal partition size of 10M */
70 #define DEFAULT_MIN_SIZE (10*1024*1024)
71
72 /* Hard lower limit for new partition sizes */
73 #define HARD_MIN_SIZE 4096
74
75 /* libfdisk takes off slightly more than 1M of the disk size when creating a GPT disk label */
76 #define GPT_METADATA_SIZE (1044*1024)
77
78 /* LUKS2 takes off 16M of the partition size with its metadata by default */
79 #define LUKS2_METADATA_SIZE (16*1024*1024)
80
81 /* Note: When growing and placing new partitions we always align to 4K sector size. It's how newer hard disks
82 * are designed, and if everything is aligned to that performance is best. And for older hard disks with 512B
83 * sector size devices were generally assumed to have an even number of sectors, hence at the worst we'll
84 * waste 3K per partition, which is probably fine. */
85
86 static enum {
87 EMPTY_REFUSE, /* refuse empty disks, never create a partition table */
88 EMPTY_ALLOW, /* allow empty disks, create partition table if necessary */
89 EMPTY_REQUIRE, /* require an empty disk, create a partition table */
90 EMPTY_FORCE, /* make disk empty, erase everything, create a partition table always */
91 EMPTY_CREATE, /* create disk as loopback file, create a partition table always */
92 } arg_empty = EMPTY_REFUSE;
93
94 static bool arg_dry_run = true;
95 static const char *arg_node = NULL;
96 static char *arg_root = NULL;
97 static char *arg_image = NULL;
98 static char *arg_definitions = NULL;
99 static bool arg_discard = true;
100 static bool arg_can_factory_reset = false;
101 static int arg_factory_reset = -1;
102 static sd_id128_t arg_seed = SD_ID128_NULL;
103 static bool arg_randomize = false;
104 static int arg_pretty = -1;
105 static uint64_t arg_size = UINT64_MAX;
106 static bool arg_size_auto = false;
107 static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
108 static PagerFlags arg_pager_flags = 0;
109 static bool arg_legend = true;
110 static void *arg_key = NULL;
111 static size_t arg_key_size = 0;
112 static char *arg_tpm2_device = NULL;
113 static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
114
115 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
116 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
117 STATIC_DESTRUCTOR_REGISTER(arg_definitions, freep);
118 STATIC_DESTRUCTOR_REGISTER(arg_key, erase_and_freep);
119 STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
120
121 typedef struct Partition Partition;
122 typedef struct FreeArea FreeArea;
123 typedef struct Context Context;
124
125 typedef enum EncryptMode {
126 ENCRYPT_OFF,
127 ENCRYPT_KEY_FILE,
128 ENCRYPT_TPM2,
129 ENCRYPT_KEY_FILE_TPM2,
130 _ENCRYPT_MODE_MAX,
131 _ENCRYPT_MODE_INVALID = -EINVAL,
132 } EncryptMode;
133
134 struct Partition {
135 char *definition_path;
136 char **drop_in_files;
137
138 sd_id128_t type_uuid;
139 sd_id128_t current_uuid, new_uuid;
140 char *current_label, *new_label;
141
142 bool dropped;
143 bool factory_reset;
144 int32_t priority;
145
146 uint32_t weight, padding_weight;
147
148 uint64_t current_size, new_size;
149 uint64_t size_min, size_max;
150
151 uint64_t current_padding, new_padding;
152 uint64_t padding_min, padding_max;
153
154 uint64_t partno;
155 uint64_t offset;
156
157 struct fdisk_partition *current_partition;
158 struct fdisk_partition *new_partition;
159 FreeArea *padding_area;
160 FreeArea *allocated_to_area;
161
162 char *copy_blocks_path;
163 bool copy_blocks_auto;
164 int copy_blocks_fd;
165 uint64_t copy_blocks_size;
166
167 char *format;
168 char **copy_files;
169 char **make_directories;
170 EncryptMode encrypt;
171
172 uint64_t gpt_flags;
173 int no_auto;
174 int read_only;
175 int growfs;
176
177 LIST_FIELDS(Partition, partitions);
178 };
179
180 #define PARTITION_IS_FOREIGN(p) (!(p)->definition_path)
181 #define PARTITION_EXISTS(p) (!!(p)->current_partition)
182
183 struct FreeArea {
184 Partition *after;
185 uint64_t size;
186 uint64_t allocated;
187 };
188
189 struct Context {
190 LIST_HEAD(Partition, partitions);
191 size_t n_partitions;
192
193 FreeArea **free_areas;
194 size_t n_free_areas;
195
196 uint64_t start, end, total;
197
198 struct fdisk_context *fdisk_context;
199 uint64_t sector_size;
200 uint64_t grain_size;
201
202 sd_id128_t seed;
203 };
204
205 static const char *encrypt_mode_table[_ENCRYPT_MODE_MAX] = {
206 [ENCRYPT_OFF] = "off",
207 [ENCRYPT_KEY_FILE] = "key-file",
208 [ENCRYPT_TPM2] = "tpm2",
209 [ENCRYPT_KEY_FILE_TPM2] = "key-file+tpm2",
210 };
211
212 #if HAVE_LIBCRYPTSETUP
213 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(encrypt_mode, EncryptMode, ENCRYPT_KEY_FILE);
214 #else
215 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(encrypt_mode, EncryptMode, ENCRYPT_KEY_FILE);
216 #endif
217
218
219 static uint64_t round_down_size(uint64_t v, uint64_t p) {
220 return (v / p) * p;
221 }
222
223 static uint64_t round_up_size(uint64_t v, uint64_t p) {
224
225 v = DIV_ROUND_UP(v, p);
226
227 if (v > UINT64_MAX / p)
228 return UINT64_MAX; /* overflow */
229
230 return v * p;
231 }
232
233 static Partition *partition_new(void) {
234 Partition *p;
235
236 p = new(Partition, 1);
237 if (!p)
238 return NULL;
239
240 *p = (Partition) {
241 .weight = 1000,
242 .padding_weight = 0,
243 .current_size = UINT64_MAX,
244 .new_size = UINT64_MAX,
245 .size_min = UINT64_MAX,
246 .size_max = UINT64_MAX,
247 .current_padding = UINT64_MAX,
248 .new_padding = UINT64_MAX,
249 .padding_min = UINT64_MAX,
250 .padding_max = UINT64_MAX,
251 .partno = UINT64_MAX,
252 .offset = UINT64_MAX,
253 .copy_blocks_fd = -1,
254 .copy_blocks_size = UINT64_MAX,
255 .no_auto = -1,
256 .read_only = -1,
257 .growfs = -1,
258 };
259
260 return p;
261 }
262
263 static Partition* partition_free(Partition *p) {
264 if (!p)
265 return NULL;
266
267 free(p->current_label);
268 free(p->new_label);
269 free(p->definition_path);
270 strv_free(p->drop_in_files);
271
272 if (p->current_partition)
273 fdisk_unref_partition(p->current_partition);
274 if (p->new_partition)
275 fdisk_unref_partition(p->new_partition);
276
277 free(p->copy_blocks_path);
278 safe_close(p->copy_blocks_fd);
279
280 free(p->format);
281 strv_free(p->copy_files);
282 strv_free(p->make_directories);
283
284 return mfree(p);
285 }
286
287 static Partition* partition_unlink_and_free(Context *context, Partition *p) {
288 if (!p)
289 return NULL;
290
291 LIST_REMOVE(partitions, context->partitions, p);
292
293 assert(context->n_partitions > 0);
294 context->n_partitions--;
295
296 return partition_free(p);
297 }
298
299 DEFINE_TRIVIAL_CLEANUP_FUNC(Partition*, partition_free);
300
301 static Context *context_new(sd_id128_t seed) {
302 Context *context;
303
304 context = new(Context, 1);
305 if (!context)
306 return NULL;
307
308 *context = (Context) {
309 .start = UINT64_MAX,
310 .end = UINT64_MAX,
311 .total = UINT64_MAX,
312 .seed = seed,
313 };
314
315 return context;
316 }
317
318 static void context_free_free_areas(Context *context) {
319 assert(context);
320
321 for (size_t i = 0; i < context->n_free_areas; i++)
322 free(context->free_areas[i]);
323
324 context->free_areas = mfree(context->free_areas);
325 context->n_free_areas = 0;
326 }
327
328 static Context *context_free(Context *context) {
329 if (!context)
330 return NULL;
331
332 while (context->partitions)
333 partition_unlink_and_free(context, context->partitions);
334 assert(context->n_partitions == 0);
335
336 context_free_free_areas(context);
337
338 if (context->fdisk_context)
339 fdisk_unref_context(context->fdisk_context);
340
341 return mfree(context);
342 }
343
344 DEFINE_TRIVIAL_CLEANUP_FUNC(Context*, context_free);
345
346 static int context_add_free_area(
347 Context *context,
348 uint64_t size,
349 Partition *after) {
350
351 FreeArea *a;
352
353 assert(context);
354 assert(!after || !after->padding_area);
355
356 if (!GREEDY_REALLOC(context->free_areas, context->n_free_areas + 1))
357 return -ENOMEM;
358
359 a = new(FreeArea, 1);
360 if (!a)
361 return -ENOMEM;
362
363 *a = (FreeArea) {
364 .size = size,
365 .after = after,
366 };
367
368 context->free_areas[context->n_free_areas++] = a;
369
370 if (after)
371 after->padding_area = a;
372
373 return 0;
374 }
375
376 static bool context_drop_one_priority(Context *context) {
377 int32_t priority = 0;
378 bool exists = false;
379
380 LIST_FOREACH(partitions, p, context->partitions) {
381 if (p->dropped)
382 continue;
383 if (p->priority < priority)
384 continue;
385 if (p->priority == priority) {
386 exists = exists || PARTITION_EXISTS(p);
387 continue;
388 }
389
390 priority = p->priority;
391 exists = PARTITION_EXISTS(p);
392 }
393
394 /* Refuse to drop partitions with 0 or negative priorities or partitions of priorities that have at
395 * least one existing priority */
396 if (priority <= 0 || exists)
397 return false;
398
399 LIST_FOREACH(partitions, p, context->partitions) {
400 if (p->priority < priority)
401 continue;
402
403 if (p->dropped)
404 continue;
405
406 p->dropped = true;
407 log_info("Can't fit partition %s of priority %" PRIi32 ", dropping.", p->definition_path, p->priority);
408 }
409
410 return true;
411 }
412
413 static uint64_t partition_min_size(Context *context, const Partition *p) {
414 uint64_t sz;
415
416 assert(context);
417 assert(p);
418
419 /* Calculate the disk space we really need at minimum for this partition. If the partition already
420 * exists the current size is what we really need. If it doesn't exist yet refuse to allocate less
421 * than 4K.
422 *
423 * DEFAULT_MIN_SIZE is the default SizeMin= we configure if nothing else is specified. */
424
425 if (PARTITION_IS_FOREIGN(p)) {
426 /* Don't allow changing size of partitions not managed by us */
427 assert(p->current_size != UINT64_MAX);
428 return p->current_size;
429 }
430
431 sz = p->current_size != UINT64_MAX ? p->current_size : HARD_MIN_SIZE;
432
433 if (!PARTITION_EXISTS(p)) {
434 uint64_t d = 0;
435
436 if (p->encrypt != ENCRYPT_OFF)
437 d += round_up_size(LUKS2_METADATA_SIZE, context->grain_size);
438
439 if (p->copy_blocks_size != UINT64_MAX)
440 d += round_up_size(p->copy_blocks_size, context->grain_size);
441 else if (p->format || p->encrypt != ENCRYPT_OFF) {
442 uint64_t f;
443
444 /* If we shall synthesize a file system, take minimal fs size into account (assumed to be 4K if not known) */
445 f = p->format ? round_up_size(minimal_size_by_fs_name(p->format), context->grain_size) : UINT64_MAX;
446 d += f == UINT64_MAX ? context->grain_size : f;
447 }
448
449 if (d > sz)
450 sz = d;
451 }
452
453 return MAX(round_up_size(p->size_min != UINT64_MAX ? p->size_min : DEFAULT_MIN_SIZE, context->grain_size), sz);
454 }
455
456 static uint64_t partition_max_size(const Context *context, const Partition *p) {
457 uint64_t sm;
458
459 /* Calculate how large the partition may become at max. This is generally the configured maximum
460 * size, except when it already exists and is larger than that. In that case it's the existing size,
461 * since we never want to shrink partitions. */
462
463 assert(context);
464 assert(p);
465
466 if (PARTITION_IS_FOREIGN(p)) {
467 /* Don't allow changing size of partitions not managed by us */
468 assert(p->current_size != UINT64_MAX);
469 return p->current_size;
470 }
471
472 sm = round_down_size(p->size_max, context->grain_size);
473
474 if (p->current_size != UINT64_MAX)
475 return MAX(p->current_size, sm);
476
477 return sm;
478 }
479
480 static uint64_t partition_min_size_with_padding(Context *context, const Partition *p) {
481 uint64_t sz;
482
483 /* Calculate the disk space we need for this partition plus any free space coming after it. This
484 * takes user configured padding into account as well as any additional whitespace needed to align
485 * the next partition to 4K again. */
486
487 assert(context);
488 assert(p);
489
490 sz = partition_min_size(context, p);
491
492 if (p->padding_min != UINT64_MAX)
493 sz += p->padding_min;
494
495 if (PARTITION_EXISTS(p)) {
496 /* If the partition wasn't aligned, add extra space so that any we might add will be aligned */
497 assert(p->offset != UINT64_MAX);
498 return round_up_size(p->offset + sz, context->grain_size) - p->offset;
499 }
500
501 /* If this is a new partition we'll place it aligned, hence we just need to round up the required size here */
502 return round_up_size(sz, context->grain_size);
503 }
504
505 static uint64_t free_area_available(const FreeArea *a) {
506 assert(a);
507
508 /* Determines how much of this free area is not allocated yet */
509
510 assert(a->size >= a->allocated);
511 return a->size - a->allocated;
512 }
513
514 static uint64_t free_area_available_for_new_partitions(Context *context, const FreeArea *a) {
515 uint64_t avail;
516
517 assert(context);
518 assert(a);
519
520 /* Similar to free_area_available(), but takes into account that the required size and padding of the
521 * preceding partition is honoured. */
522
523 avail = free_area_available(a);
524 if (a->after) {
525 uint64_t need, space_end, new_end;
526
527 need = partition_min_size_with_padding(context, a->after);
528
529 assert(a->after->offset != UINT64_MAX);
530 assert(a->after->current_size != UINT64_MAX);
531
532 /* Calculate where the free area ends, based on the offset of the partition preceding it */
533 space_end = round_up_size(a->after->offset + a->after->current_size, context->grain_size) + avail;
534
535 /* Calculate where the partition would end when we give it as much as it needs */
536 new_end = round_up_size(a->after->offset + need, context->grain_size);
537
538 /* Calculate saturated difference of the two: that's how much we have free for other partitions */
539 return LESS_BY(space_end, new_end);
540 }
541
542 return avail;
543 }
544
545 static int free_area_compare(FreeArea *const *a, FreeArea *const*b, Context *context) {
546 assert(context);
547
548 return CMP(free_area_available_for_new_partitions(context, *a),
549 free_area_available_for_new_partitions(context, *b));
550 }
551
552 static uint64_t charge_size(Context *context, uint64_t total, uint64_t amount) {
553 assert(context);
554 /* Subtract the specified amount from total, rounding up to multiple of 4K if there's room */
555 assert(amount <= total);
556 return LESS_BY(total, round_up_size(amount, context->grain_size));
557 }
558
559 static uint64_t charge_weight(uint64_t total, uint64_t amount) {
560 assert(amount <= total);
561 return total - amount;
562 }
563
564 static bool context_allocate_partitions(Context *context, uint64_t *ret_largest_free_area) {
565 assert(context);
566
567 /* Sort free areas by size, putting smallest first */
568 typesafe_qsort_r(context->free_areas, context->n_free_areas, free_area_compare, context);
569
570 /* In any case return size of the largest free area (i.e. not the size of all free areas
571 * combined!) */
572 if (ret_largest_free_area)
573 *ret_largest_free_area =
574 context->n_free_areas == 0 ? 0 :
575 free_area_available_for_new_partitions(context, context->free_areas[context->n_free_areas-1]);
576
577 /* A simple first-fit algorithm. We return true if we can fit the partitions in, otherwise false. */
578 LIST_FOREACH(partitions, p, context->partitions) {
579 bool fits = false;
580 uint64_t required;
581 FreeArea *a = NULL;
582
583 /* Skip partitions we already dropped or that already exist */
584 if (p->dropped || PARTITION_EXISTS(p))
585 continue;
586
587 /* How much do we need to fit? */
588 required = partition_min_size_with_padding(context, p);
589 assert(required % context->grain_size == 0);
590
591 for (size_t i = 0; i < context->n_free_areas; i++) {
592 a = context->free_areas[i];
593
594 if (free_area_available_for_new_partitions(context, a) >= required) {
595 fits = true;
596 break;
597 }
598 }
599
600 if (!fits)
601 return false; /* 😢 Oh no! We can't fit this partition into any free area! */
602
603 /* Assign the partition to this free area */
604 p->allocated_to_area = a;
605
606 /* Budget the minimal partition size */
607 a->allocated += required;
608 }
609
610 return true;
611 }
612
613 static int context_sum_weights(Context *context, FreeArea *a, uint64_t *ret) {
614 uint64_t weight_sum = 0;
615
616 assert(context);
617 assert(a);
618 assert(ret);
619
620 /* Determine the sum of the weights of all partitions placed in or before the specified free area */
621
622 LIST_FOREACH(partitions, p, context->partitions) {
623 if (p->padding_area != a && p->allocated_to_area != a)
624 continue;
625
626 if (p->weight > UINT64_MAX - weight_sum)
627 goto overflow_sum;
628 weight_sum += p->weight;
629
630 if (p->padding_weight > UINT64_MAX - weight_sum)
631 goto overflow_sum;
632 weight_sum += p->padding_weight;
633 }
634
635 *ret = weight_sum;
636 return 0;
637
638 overflow_sum:
639 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Combined weight of partition exceeds unsigned 64bit range, refusing.");
640 }
641
642 static int scale_by_weight(uint64_t value, uint64_t weight, uint64_t weight_sum, uint64_t *ret) {
643 assert(weight_sum >= weight);
644 assert(ret);
645
646 if (weight == 0) {
647 *ret = 0;
648 return 0;
649 }
650
651 if (value > UINT64_MAX / weight)
652 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Scaling by weight of partition exceeds unsigned 64bit range, refusing.");
653
654 *ret = value * weight / weight_sum;
655 return 0;
656 }
657
658 typedef enum GrowPartitionPhase {
659 /* The first phase: we charge partitions which need more (according to constraints) than their weight-based share. */
660 PHASE_OVERCHARGE,
661
662 /* The second phase: we charge partitions which need less (according to constraints) than their weight-based share. */
663 PHASE_UNDERCHARGE,
664
665 /* The third phase: we distribute what remains among the remaining partitions, according to the weights */
666 PHASE_DISTRIBUTE,
667
668 _GROW_PARTITION_PHASE_MAX,
669 } GrowPartitionPhase;
670
671 static int context_grow_partitions_phase(
672 Context *context,
673 FreeArea *a,
674 GrowPartitionPhase phase,
675 uint64_t *span,
676 uint64_t *weight_sum) {
677
678 int r;
679
680 assert(context);
681 assert(a);
682
683 /* Now let's look at the intended weights and adjust them taking the minimum space assignments into
684 * account. i.e. if a partition has a small weight but a high minimum space value set it should not
685 * get any additional room from the left-overs. Similar, if two partitions have the same weight they
686 * should get the same space if possible, even if one has a smaller minimum size than the other. */
687 LIST_FOREACH(partitions, p, context->partitions) {
688
689 /* Look only at partitions associated with this free area, i.e. immediately
690 * preceding it, or allocated into it */
691 if (p->allocated_to_area != a && p->padding_area != a)
692 continue;
693
694 if (p->new_size == UINT64_MAX) {
695 bool charge = false, try_again = false;
696 uint64_t share, rsz, xsz;
697
698 /* Calculate how much this space this partition needs if everyone would get
699 * the weight based share */
700 r = scale_by_weight(*span, p->weight, *weight_sum, &share);
701 if (r < 0)
702 return r;
703
704 rsz = partition_min_size(context, p);
705 xsz = partition_max_size(context, p);
706
707 if (phase == PHASE_OVERCHARGE && rsz > share) {
708 /* This partition needs more than its calculated share. Let's assign
709 * it that, and take this partition out of all calculations and start
710 * again. */
711
712 p->new_size = rsz;
713 charge = try_again = true;
714
715 } else if (phase == PHASE_UNDERCHARGE && xsz != UINT64_MAX && xsz < share) {
716 /* This partition accepts less than its calculated
717 * share. Let's assign it that, and take this partition out
718 * of all calculations and start again. */
719
720 p->new_size = xsz;
721 charge = try_again = true;
722
723 } else if (phase == PHASE_DISTRIBUTE) {
724 /* This partition can accept its calculated share. Let's
725 * assign it. There's no need to restart things here since
726 * assigning this shouldn't impact the shares of the other
727 * partitions. */
728
729 if (PARTITION_IS_FOREIGN(p))
730 /* Never change of foreign partitions (i.e. those we don't manage) */
731 p->new_size = p->current_size;
732 else
733 p->new_size = MAX(round_down_size(share, context->grain_size), rsz);
734
735 charge = true;
736 }
737
738 if (charge) {
739 *span = charge_size(context, *span, p->new_size);
740 *weight_sum = charge_weight(*weight_sum, p->weight);
741 }
742
743 if (try_again)
744 return 0; /* try again */
745 }
746
747 if (p->new_padding == UINT64_MAX) {
748 bool charge = false, try_again = false;
749 uint64_t share;
750
751 r = scale_by_weight(*span, p->padding_weight, *weight_sum, &share);
752 if (r < 0)
753 return r;
754
755 if (phase == PHASE_OVERCHARGE && p->padding_min != UINT64_MAX && p->padding_min > share) {
756 p->new_padding = p->padding_min;
757 charge = try_again = true;
758 } else if (phase == PHASE_UNDERCHARGE && p->padding_max != UINT64_MAX && p->padding_max < share) {
759 p->new_padding = p->padding_max;
760 charge = try_again = true;
761 } else if (phase == PHASE_DISTRIBUTE) {
762
763 p->new_padding = round_down_size(share, context->grain_size);
764 if (p->padding_min != UINT64_MAX && p->new_padding < p->padding_min)
765 p->new_padding = p->padding_min;
766
767 charge = true;
768 }
769
770 if (charge) {
771 *span = charge_size(context, *span, p->new_padding);
772 *weight_sum = charge_weight(*weight_sum, p->padding_weight);
773 }
774
775 if (try_again)
776 return 0; /* try again */
777 }
778 }
779
780 return 1; /* done */
781 }
782
783 static int context_grow_partitions_on_free_area(Context *context, FreeArea *a) {
784 uint64_t weight_sum = 0, span;
785 int r;
786
787 assert(context);
788 assert(a);
789
790 r = context_sum_weights(context, a, &weight_sum);
791 if (r < 0)
792 return r;
793
794 /* Let's calculate the total area covered by this free area and the partition before it */
795 span = a->size;
796 if (a->after) {
797 assert(a->after->offset != UINT64_MAX);
798 assert(a->after->current_size != UINT64_MAX);
799
800 span += round_up_size(a->after->offset + a->after->current_size, context->grain_size) - a->after->offset;
801 }
802
803 for (GrowPartitionPhase phase = 0; phase < _GROW_PARTITION_PHASE_MAX;) {
804 r = context_grow_partitions_phase(context, a, phase, &span, &weight_sum);
805 if (r < 0)
806 return r;
807 if (r == 0) /* not done yet, re-run this phase */
808 continue;
809
810 phase++; /* got to next phase */
811 }
812
813 /* We still have space left over? Donate to preceding partition if we have one */
814 if (span > 0 && a->after && !PARTITION_IS_FOREIGN(a->after)) {
815 uint64_t m, xsz;
816
817 assert(a->after->new_size != UINT64_MAX);
818
819 /* Calculate new size and align (but ensure this doesn't shrink the size) */
820 m = MAX(a->after->new_size, round_down_size(a->after->new_size + span, context->grain_size));
821
822 xsz = partition_max_size(context, a->after);
823 if (xsz != UINT64_MAX && m > xsz)
824 m = xsz;
825
826 span = charge_size(context, span, m - a->after->new_size);
827 a->after->new_size = m;
828 }
829
830 /* What? Even still some space left (maybe because there was no preceding partition, or it had a
831 * size limit), then let's donate it to whoever wants it. */
832 if (span > 0)
833 LIST_FOREACH(partitions, p, context->partitions) {
834 uint64_t m, xsz;
835
836 if (p->allocated_to_area != a)
837 continue;
838
839 if (PARTITION_IS_FOREIGN(p))
840 continue;
841
842 assert(p->new_size != UINT64_MAX);
843 m = MAX(p->new_size, round_down_size(p->new_size + span, context->grain_size));
844
845 xsz = partition_max_size(context, p);
846 if (xsz != UINT64_MAX && m > xsz)
847 m = xsz;
848
849 span = charge_size(context, span, m - p->new_size);
850 p->new_size = m;
851
852 if (span == 0)
853 break;
854 }
855
856 /* Yuck, still no one? Then make it padding */
857 if (span > 0 && a->after) {
858 assert(a->after->new_padding != UINT64_MAX);
859 a->after->new_padding += span;
860 }
861
862 return 0;
863 }
864
865 static int context_grow_partitions(Context *context) {
866 int r;
867
868 assert(context);
869
870 for (size_t i = 0; i < context->n_free_areas; i++) {
871 r = context_grow_partitions_on_free_area(context, context->free_areas[i]);
872 if (r < 0)
873 return r;
874 }
875
876 /* All existing partitions that have no free space after them can't change size */
877 LIST_FOREACH(partitions, p, context->partitions) {
878 if (p->dropped)
879 continue;
880
881 if (!PARTITION_EXISTS(p) || p->padding_area) {
882 /* The algorithm above must have initialized this already */
883 assert(p->new_size != UINT64_MAX);
884 continue;
885 }
886
887 assert(p->new_size == UINT64_MAX);
888 p->new_size = p->current_size;
889
890 assert(p->new_padding == UINT64_MAX);
891 p->new_padding = p->current_padding;
892 }
893
894 return 0;
895 }
896
897 static void context_place_partitions(Context *context) {
898 uint64_t partno = 0;
899
900 assert(context);
901
902 /* Determine next partition number to assign */
903 LIST_FOREACH(partitions, p, context->partitions) {
904 if (!PARTITION_EXISTS(p))
905 continue;
906
907 assert(p->partno != UINT64_MAX);
908 if (p->partno >= partno)
909 partno = p->partno + 1;
910 }
911
912 for (size_t i = 0; i < context->n_free_areas; i++) {
913 FreeArea *a = context->free_areas[i];
914 _unused_ uint64_t left;
915 uint64_t start;
916
917 if (a->after) {
918 assert(a->after->offset != UINT64_MAX);
919 assert(a->after->new_size != UINT64_MAX);
920 assert(a->after->new_padding != UINT64_MAX);
921
922 start = a->after->offset + a->after->new_size + a->after->new_padding;
923 } else
924 start = context->start;
925
926 start = round_up_size(start, context->grain_size);
927 left = a->size;
928
929 LIST_FOREACH(partitions, p, context->partitions) {
930 if (p->allocated_to_area != a)
931 continue;
932
933 p->offset = start;
934 p->partno = partno++;
935
936 assert(left >= p->new_size);
937 start += p->new_size;
938 left -= p->new_size;
939
940 assert(left >= p->new_padding);
941 start += p->new_padding;
942 left -= p->new_padding;
943 }
944 }
945 }
946
947 static int config_parse_type(
948 const char *unit,
949 const char *filename,
950 unsigned line,
951 const char *section,
952 unsigned section_line,
953 const char *lvalue,
954 int ltype,
955 const char *rvalue,
956 void *data,
957 void *userdata) {
958
959 sd_id128_t *type_uuid = data;
960 int r;
961
962 assert(rvalue);
963 assert(type_uuid);
964
965 r = gpt_partition_type_uuid_from_string(rvalue, type_uuid);
966 if (r < 0)
967 return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition type: %s", rvalue);
968
969 return 0;
970 }
971
972 static int config_parse_label(
973 const char *unit,
974 const char *filename,
975 unsigned line,
976 const char *section,
977 unsigned section_line,
978 const char *lvalue,
979 int ltype,
980 const char *rvalue,
981 void *data,
982 void *userdata) {
983
984 _cleanup_free_ char *resolved = NULL;
985 char **label = data;
986 int r;
987
988 assert(rvalue);
989 assert(label);
990
991 /* Nota bene: the empty label is a totally valid one. Let's hence not follow our usual rule of
992 * assigning the empty string to reset to default here, but really accept it as label to set. */
993
994 r = specifier_printf(rvalue, GPT_LABEL_MAX, system_and_tmp_specifier_table, arg_root, NULL, &resolved);
995 if (r < 0) {
996 log_syntax(unit, LOG_WARNING, filename, line, r,
997 "Failed to expand specifiers in Label=, ignoring: %s", rvalue);
998 return 0;
999 }
1000
1001 if (!utf8_is_valid(resolved)) {
1002 log_syntax(unit, LOG_WARNING, filename, line, 0,
1003 "Partition label not valid UTF-8, ignoring: %s", rvalue);
1004 return 0;
1005 }
1006
1007 r = gpt_partition_label_valid(resolved);
1008 if (r < 0) {
1009 log_syntax(unit, LOG_WARNING, filename, line, r,
1010 "Failed to check if string is valid as GPT partition label, ignoring: \"%s\" (from \"%s\")",
1011 resolved, rvalue);
1012 return 0;
1013 }
1014 if (!r) {
1015 log_syntax(unit, LOG_WARNING, filename, line, 0,
1016 "Partition label too long for GPT table, ignoring: \"%s\" (from \"%s\")",
1017 resolved, rvalue);
1018 return 0;
1019 }
1020
1021 free_and_replace(*label, resolved);
1022 return 0;
1023 }
1024
1025 static int config_parse_weight(
1026 const char *unit,
1027 const char *filename,
1028 unsigned line,
1029 const char *section,
1030 unsigned section_line,
1031 const char *lvalue,
1032 int ltype,
1033 const char *rvalue,
1034 void *data,
1035 void *userdata) {
1036
1037 uint32_t *priority = data, v;
1038 int r;
1039
1040 assert(rvalue);
1041 assert(priority);
1042
1043 r = safe_atou32(rvalue, &v);
1044 if (r < 0) {
1045 log_syntax(unit, LOG_WARNING, filename, line, r,
1046 "Failed to parse weight value, ignoring: %s", rvalue);
1047 return 0;
1048 }
1049
1050 if (v > 1000U*1000U) {
1051 log_syntax(unit, LOG_WARNING, filename, line, 0,
1052 "Weight needs to be in range 0…10000000, ignoring: %" PRIu32, v);
1053 return 0;
1054 }
1055
1056 *priority = v;
1057 return 0;
1058 }
1059
1060 static int config_parse_size4096(
1061 const char *unit,
1062 const char *filename,
1063 unsigned line,
1064 const char *section,
1065 unsigned section_line,
1066 const char *lvalue,
1067 int ltype,
1068 const char *rvalue,
1069 void *data,
1070 void *userdata) {
1071
1072 uint64_t *sz = data, parsed;
1073 int r;
1074
1075 assert(rvalue);
1076 assert(data);
1077
1078 r = parse_size(rvalue, 1024, &parsed);
1079 if (r < 0)
1080 return log_syntax(unit, LOG_ERR, filename, line, r,
1081 "Failed to parse size value: %s", rvalue);
1082
1083 if (ltype > 0)
1084 *sz = round_up_size(parsed, 4096);
1085 else if (ltype < 0)
1086 *sz = round_down_size(parsed, 4096);
1087 else
1088 *sz = parsed;
1089
1090 if (*sz != parsed)
1091 log_syntax(unit, LOG_NOTICE, filename, line, r, "Rounded %s= size %" PRIu64 " %s %" PRIu64 ", a multiple of 4096.",
1092 lvalue, parsed, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), *sz);
1093
1094 return 0;
1095 }
1096
1097 static int config_parse_fstype(
1098 const char *unit,
1099 const char *filename,
1100 unsigned line,
1101 const char *section,
1102 unsigned section_line,
1103 const char *lvalue,
1104 int ltype,
1105 const char *rvalue,
1106 void *data,
1107 void *userdata) {
1108
1109 char **fstype = data;
1110
1111 assert(rvalue);
1112 assert(data);
1113
1114 if (!filename_is_valid(rvalue))
1115 return log_syntax(unit, LOG_ERR, filename, line, 0,
1116 "File system type is not valid, refusing: %s", rvalue);
1117
1118 return free_and_strdup_warn(fstype, rvalue);
1119 }
1120
1121 static int config_parse_copy_files(
1122 const char *unit,
1123 const char *filename,
1124 unsigned line,
1125 const char *section,
1126 unsigned section_line,
1127 const char *lvalue,
1128 int ltype,
1129 const char *rvalue,
1130 void *data,
1131 void *userdata) {
1132
1133 _cleanup_free_ char *source = NULL, *buffer = NULL, *resolved_source = NULL, *resolved_target = NULL;
1134 const char *p = rvalue, *target;
1135 Partition *partition = data;
1136 int r;
1137
1138 assert(rvalue);
1139 assert(partition);
1140
1141 r = extract_first_word(&p, &source, ":", EXTRACT_CUNESCAPE|EXTRACT_DONT_COALESCE_SEPARATORS);
1142 if (r < 0)
1143 return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract source path: %s", rvalue);
1144 if (r == 0) {
1145 log_syntax(unit, LOG_WARNING, filename, line, 0, "No argument specified: %s", rvalue);
1146 return 0;
1147 }
1148
1149 r = extract_first_word(&p, &buffer, ":", EXTRACT_CUNESCAPE|EXTRACT_DONT_COALESCE_SEPARATORS);
1150 if (r < 0)
1151 return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract target path: %s", rvalue);
1152 if (r == 0)
1153 target = source; /* No target, then it's the same as the source */
1154 else
1155 target = buffer;
1156
1157 if (!isempty(p))
1158 return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);
1159
1160 r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_source);
1161 if (r < 0) {
1162 log_syntax(unit, LOG_WARNING, filename, line, r,
1163 "Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
1164 return 0;
1165 }
1166
1167 r = path_simplify_and_warn(resolved_source, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
1168 if (r < 0)
1169 return 0;
1170
1171 r = specifier_printf(target, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_target);
1172 if (r < 0) {
1173 log_syntax(unit, LOG_WARNING, filename, line, r,
1174 "Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
1175 return 0;
1176 }
1177
1178 r = path_simplify_and_warn(resolved_target, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
1179 if (r < 0)
1180 return 0;
1181
1182 r = strv_consume_pair(&partition->copy_files, TAKE_PTR(resolved_source), TAKE_PTR(resolved_target));
1183 if (r < 0)
1184 return log_oom();
1185
1186 return 0;
1187 }
1188
1189 static int config_parse_copy_blocks(
1190 const char *unit,
1191 const char *filename,
1192 unsigned line,
1193 const char *section,
1194 unsigned section_line,
1195 const char *lvalue,
1196 int ltype,
1197 const char *rvalue,
1198 void *data,
1199 void *userdata) {
1200
1201 _cleanup_free_ char *d = NULL;
1202 Partition *partition = data;
1203 int r;
1204
1205 assert(rvalue);
1206 assert(partition);
1207
1208 if (isempty(rvalue)) {
1209 partition->copy_blocks_path = mfree(partition->copy_blocks_path);
1210 partition->copy_blocks_auto = false;
1211 return 0;
1212 }
1213
1214 if (streq(rvalue, "auto")) {
1215 partition->copy_blocks_path = mfree(partition->copy_blocks_path);
1216 partition->copy_blocks_auto = true;
1217 return 0;
1218 }
1219
1220 r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &d);
1221 if (r < 0) {
1222 log_syntax(unit, LOG_WARNING, filename, line, r,
1223 "Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
1224 return 0;
1225 }
1226
1227 r = path_simplify_and_warn(d, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
1228 if (r < 0)
1229 return 0;
1230
1231 free_and_replace(partition->copy_blocks_path, d);
1232 partition->copy_blocks_auto = false;
1233 return 0;
1234 }
1235
1236 static int config_parse_make_dirs(
1237 const char *unit,
1238 const char *filename,
1239 unsigned line,
1240 const char *section,
1241 unsigned section_line,
1242 const char *lvalue,
1243 int ltype,
1244 const char *rvalue,
1245 void *data,
1246 void *userdata) {
1247
1248 Partition *partition = data;
1249 const char *p = rvalue;
1250 int r;
1251
1252 assert(rvalue);
1253 assert(partition);
1254
1255 for (;;) {
1256 _cleanup_free_ char *word = NULL, *d = NULL;
1257
1258 r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
1259 if (r == -ENOMEM)
1260 return log_oom();
1261 if (r < 0) {
1262 log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
1263 return 0;
1264 }
1265 if (r == 0)
1266 return 0;
1267
1268 r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &d);
1269 if (r < 0) {
1270 log_syntax(unit, LOG_WARNING, filename, line, r,
1271 "Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);
1272 continue;
1273 }
1274
1275 r = path_simplify_and_warn(d, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
1276 if (r < 0)
1277 continue;
1278
1279 r = strv_consume(&partition->make_directories, TAKE_PTR(d));
1280 if (r < 0)
1281 return log_oom();
1282 }
1283 }
1284
1285 static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_encrypt, encrypt_mode, EncryptMode, ENCRYPT_OFF, "Invalid encryption mode");
1286
1287 static int config_parse_gpt_flags(
1288 const char *unit,
1289 const char *filename,
1290 unsigned line,
1291 const char *section,
1292 unsigned section_line,
1293 const char *lvalue,
1294 int ltype,
1295 const char *rvalue,
1296 void *data,
1297 void *userdata) {
1298
1299 uint64_t *gpt_flags = data;
1300 int r;
1301
1302 assert(rvalue);
1303 assert(gpt_flags);
1304
1305 r = safe_atou64(rvalue, gpt_flags);
1306 if (r < 0) {
1307 log_syntax(unit, LOG_WARNING, filename, line, r,
1308 "Failed to parse Flags= value, ignoring: %s", rvalue);
1309 return 0;
1310 }
1311
1312 return 0;
1313 }
1314
1315 static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) {
1316
1317 ConfigTableItem table[] = {
1318 { "Partition", "Type", config_parse_type, 0, &p->type_uuid },
1319 { "Partition", "Label", config_parse_label, 0, &p->new_label },
1320 { "Partition", "UUID", config_parse_id128, 0, &p->new_uuid },
1321 { "Partition", "Priority", config_parse_int32, 0, &p->priority },
1322 { "Partition", "Weight", config_parse_weight, 0, &p->weight },
1323 { "Partition", "PaddingWeight", config_parse_weight, 0, &p->padding_weight },
1324 { "Partition", "SizeMinBytes", config_parse_size4096, 1, &p->size_min },
1325 { "Partition", "SizeMaxBytes", config_parse_size4096, -1, &p->size_max },
1326 { "Partition", "PaddingMinBytes", config_parse_size4096, 1, &p->padding_min },
1327 { "Partition", "PaddingMaxBytes", config_parse_size4096, -1, &p->padding_max },
1328 { "Partition", "FactoryReset", config_parse_bool, 0, &p->factory_reset },
1329 { "Partition", "CopyBlocks", config_parse_copy_blocks, 0, p },
1330 { "Partition", "Format", config_parse_fstype, 0, &p->format },
1331 { "Partition", "CopyFiles", config_parse_copy_files, 0, p },
1332 { "Partition", "MakeDirectories", config_parse_make_dirs, 0, p },
1333 { "Partition", "Encrypt", config_parse_encrypt, 0, &p->encrypt },
1334 { "Partition", "Flags", config_parse_gpt_flags, 0, &p->gpt_flags },
1335 { "Partition", "ReadOnly", config_parse_tristate, 0, &p->read_only },
1336 { "Partition", "NoAuto", config_parse_tristate, 0, &p->no_auto },
1337 { "Partition", "GrowFileSystem", config_parse_tristate, 0, &p->growfs },
1338 {}
1339 };
1340 int r;
1341 _cleanup_free_ char *filename = NULL;
1342 const char* dropin_dirname;
1343
1344 r = path_extract_filename(path, &filename);
1345 if (r < 0)
1346 return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);;
1347
1348 dropin_dirname = strjoina(filename, ".d");
1349
1350 r = config_parse_many(
1351 STRV_MAKE_CONST(path),
1352 conf_file_dirs,
1353 dropin_dirname,
1354 "Partition\0",
1355 config_item_table_lookup, table,
1356 CONFIG_PARSE_WARN,
1357 p,
1358 NULL,
1359 &p->drop_in_files);
1360 if (r < 0)
1361 return r;
1362
1363 if (p->size_min != UINT64_MAX && p->size_max != UINT64_MAX && p->size_min > p->size_max)
1364 return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
1365 "SizeMinBytes= larger than SizeMaxBytes=, refusing.");
1366
1367 if (p->padding_min != UINT64_MAX && p->padding_max != UINT64_MAX && p->padding_min > p->padding_max)
1368 return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
1369 "PaddingMinBytes= larger than PaddingMaxBytes=, refusing.");
1370
1371 if (sd_id128_is_null(p->type_uuid))
1372 return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
1373 "Type= not defined, refusing.");
1374
1375 if ((p->copy_blocks_path || p->copy_blocks_auto) &&
1376 (p->format || !strv_isempty(p->copy_files) || !strv_isempty(p->make_directories)))
1377 return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
1378 "Format=/CopyFiles=/MakeDirectories= and CopyBlocks= cannot be combined, refusing.");
1379
1380 if ((!strv_isempty(p->copy_files) || !strv_isempty(p->make_directories)) && streq_ptr(p->format, "swap"))
1381 return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
1382 "Format=swap and CopyFiles= cannot be combined, refusing.");
1383
1384 if (!p->format && (!strv_isempty(p->copy_files) || !strv_isempty(p->make_directories) || (p->encrypt != ENCRYPT_OFF && !(p->copy_blocks_path || p->copy_blocks_auto)))) {
1385 /* Pick "ext4" as file system if we are configured to copy files or encrypt the device */
1386 p->format = strdup("ext4");
1387 if (!p->format)
1388 return log_oom();
1389 }
1390
1391 /* Verity partitions are read only, let's imply the RO flag hence, unless explicitly configured otherwise. */
1392 if ((gpt_partition_type_is_root_verity(p->type_uuid) ||
1393 gpt_partition_type_is_usr_verity(p->type_uuid)) &&
1394 p->read_only < 0)
1395 p->read_only = true;
1396
1397 /* Default to "growfs" on, unless read-only */
1398 if (gpt_partition_type_knows_growfs(p->type_uuid) &&
1399 p->read_only <= 0)
1400 p->growfs = true;
1401
1402 return 0;
1403 }
1404
1405 static int context_read_definitions(
1406 Context *context,
1407 const char *directory,
1408 const char *root) {
1409
1410 _cleanup_strv_free_ char **files = NULL;
1411 Partition *last = NULL;
1412 int r;
1413 const char *const *dirs;
1414
1415 assert(context);
1416
1417 dirs = directory ?
1418 STRV_MAKE_CONST(directory) :
1419 (const char* const*)CONF_PATHS_STRV("repart.d");
1420
1421 r = conf_files_list_strv(&files, ".conf", directory ? NULL : root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs);
1422 if (r < 0)
1423 return log_error_errno(r, "Failed to enumerate *.conf files: %m");
1424
1425 STRV_FOREACH(f, files) {
1426 _cleanup_(partition_freep) Partition *p = NULL;
1427
1428 p = partition_new();
1429 if (!p)
1430 return log_oom();
1431
1432 p->definition_path = strdup(*f);
1433 if (!p->definition_path)
1434 return log_oom();
1435
1436 r = partition_read_definition(p, *f, dirs);
1437 if (r < 0)
1438 return r;
1439
1440 LIST_INSERT_AFTER(partitions, context->partitions, last, p);
1441 last = TAKE_PTR(p);
1442 context->n_partitions++;
1443 }
1444
1445 return 0;
1446 }
1447
1448 static int determine_current_padding(
1449 struct fdisk_context *c,
1450 struct fdisk_table *t,
1451 struct fdisk_partition *p,
1452 uint64_t secsz,
1453 uint64_t grainsz,
1454 uint64_t *ret) {
1455
1456 size_t n_partitions;
1457 uint64_t offset, next = UINT64_MAX;
1458
1459 assert(c);
1460 assert(t);
1461 assert(p);
1462
1463 if (!fdisk_partition_has_end(p))
1464 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Partition has no end!");
1465
1466 offset = fdisk_partition_get_end(p);
1467 assert(offset < UINT64_MAX / secsz);
1468 offset *= secsz;
1469
1470 n_partitions = fdisk_table_get_nents(t);
1471 for (size_t i = 0; i < n_partitions; i++) {
1472 struct fdisk_partition *q;
1473 uint64_t start;
1474
1475 q = fdisk_table_get_partition(t, i);
1476 if (!q)
1477 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to read partition metadata: %m");
1478
1479 if (fdisk_partition_is_used(q) <= 0)
1480 continue;
1481
1482 if (!fdisk_partition_has_start(q))
1483 continue;
1484
1485 start = fdisk_partition_get_start(q);
1486 assert(start < UINT64_MAX / secsz);
1487 start *= secsz;
1488
1489 if (start >= offset && (next == UINT64_MAX || next > start))
1490 next = start;
1491 }
1492
1493 if (next == UINT64_MAX) {
1494 /* No later partition? In that case check the end of the usable area */
1495 next = fdisk_get_last_lba(c);
1496 assert(next < UINT64_MAX);
1497 next++; /* The last LBA is one sector before the end */
1498
1499 assert(next < UINT64_MAX / secsz);
1500 next *= secsz;
1501
1502 if (offset > next)
1503 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Partition end beyond disk end.");
1504 }
1505
1506 assert(next >= offset);
1507 offset = round_up_size(offset, grainsz);
1508 next = round_down_size(next, grainsz);
1509
1510 *ret = LESS_BY(next, offset); /* Saturated subtraction, rounding might have fucked things up */
1511 return 0;
1512 }
1513
1514 static int fdisk_ask_cb(struct fdisk_context *c, struct fdisk_ask *ask, void *data) {
1515 _cleanup_free_ char *ids = NULL;
1516 int r;
1517
1518 if (fdisk_ask_get_type(ask) != FDISK_ASKTYPE_STRING)
1519 return -EINVAL;
1520
1521 ids = new(char, SD_ID128_UUID_STRING_MAX);
1522 if (!ids)
1523 return -ENOMEM;
1524
1525 r = fdisk_ask_string_set_result(ask, sd_id128_to_uuid_string(*(sd_id128_t*) data, ids));
1526 if (r < 0)
1527 return r;
1528
1529 TAKE_PTR(ids);
1530 return 0;
1531 }
1532
1533 static int fdisk_set_disklabel_id_by_uuid(struct fdisk_context *c, sd_id128_t id) {
1534 int r;
1535
1536 r = fdisk_set_ask(c, fdisk_ask_cb, &id);
1537 if (r < 0)
1538 return r;
1539
1540 r = fdisk_set_disklabel_id(c);
1541 if (r < 0)
1542 return r;
1543
1544 return fdisk_set_ask(c, NULL, NULL);
1545 }
1546
1547 static int derive_uuid(sd_id128_t base, const char *token, sd_id128_t *ret) {
1548 union {
1549 uint8_t md[SHA256_DIGEST_SIZE];
1550 sd_id128_t id;
1551 } result;
1552
1553 assert(token);
1554 assert(ret);
1555
1556 /* Derive a new UUID from the specified UUID in a stable and reasonably safe way. Specifically, we
1557 * calculate the HMAC-SHA256 of the specified token string, keyed by the supplied base (typically the
1558 * machine ID). We use the machine ID as key (and not as cleartext!) of the HMAC operation since it's
1559 * the machine ID we don't want to leak. */
1560
1561 hmac_sha256(base.bytes, sizeof(base.bytes), token, strlen(token), result.md);
1562
1563 /* Take the first half, mark it as v4 UUID */
1564 assert_cc(sizeof(result.md) == sizeof(result.id) * 2);
1565 *ret = id128_make_v4_uuid(result.id);
1566 return 0;
1567 }
1568
1569 static int context_load_partition_table(
1570 Context *context,
1571 const char *node,
1572 int *backing_fd) {
1573
1574 _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
1575 _cleanup_(fdisk_unref_tablep) struct fdisk_table *t = NULL;
1576 uint64_t left_boundary = UINT64_MAX, first_lba, last_lba, nsectors;
1577 _cleanup_free_ char *disk_uuid_string = NULL;
1578 bool from_scratch = false;
1579 sd_id128_t disk_uuid;
1580 size_t n_partitions;
1581 unsigned long secsz;
1582 uint64_t grainsz;
1583 int r;
1584
1585 assert(context);
1586 assert(node);
1587 assert(backing_fd);
1588 assert(!context->fdisk_context);
1589 assert(!context->free_areas);
1590 assert(context->start == UINT64_MAX);
1591 assert(context->end == UINT64_MAX);
1592 assert(context->total == UINT64_MAX);
1593
1594 c = fdisk_new_context();
1595 if (!c)
1596 return log_oom();
1597
1598 /* libfdisk doesn't have an API to operate on arbitrary fds, hence reopen the fd going via the
1599 * /proc/self/fd/ magic path if we have an existing fd. Open the original file otherwise. */
1600 if (*backing_fd < 0)
1601 r = fdisk_assign_device(c, node, arg_dry_run);
1602 else
1603 r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(*backing_fd), arg_dry_run);
1604 if (r == -EINVAL && arg_size_auto) {
1605 struct stat st;
1606
1607 /* libfdisk returns EINVAL if opening a file of size zero. Let's check for that, and accept
1608 * it if automatic sizing is requested. */
1609
1610 if (*backing_fd < 0)
1611 r = stat(node, &st);
1612 else
1613 r = fstat(*backing_fd, &st);
1614 if (r < 0)
1615 return log_error_errno(errno, "Failed to stat block device '%s': %m", node);
1616
1617 if (S_ISREG(st.st_mode) && st.st_size == 0) {
1618 /* User the fallback values if we have no better idea */
1619 context->sector_size = 512;
1620 context->grain_size = 4096;
1621 return /* from_scratch = */ true;
1622 }
1623
1624 r = -EINVAL;
1625 }
1626 if (r < 0)
1627 return log_error_errno(r, "Failed to open device '%s': %m", node);
1628
1629 if (*backing_fd < 0) {
1630 /* If we have no fd referencing the device yet, make a copy of the fd now, so that we have one */
1631 *backing_fd = fd_reopen(fdisk_get_devfd(c), O_RDONLY|O_CLOEXEC);
1632 if (*backing_fd < 0)
1633 return log_error_errno(*backing_fd, "Failed to duplicate fdisk fd: %m");
1634
1635 /* Tell udev not to interfere while we are processing the device */
1636 if (flock(*backing_fd, arg_dry_run ? LOCK_SH : LOCK_EX) < 0)
1637 return log_error_errno(errno, "Failed to lock block device: %m");
1638 }
1639
1640 /* The offsets/sizes libfdisk returns to us will be in multiple of the sector size of the
1641 * device. This is typically 512, and sometimes 4096. Let's query libfdisk once for it, and then use
1642 * it for all our needs. Note that the values we use ourselves always are in bytes though, thus mean
1643 * the same thing universally. Also note that regardless what kind of sector size is in use we'll
1644 * place partitions at multiples of 4K. */
1645 secsz = fdisk_get_sector_size(c);
1646
1647 /* Insist on a power of two, and that it's a multiple of 512, i.e. the traditional sector size. */
1648 if (secsz < 512 || !ISPOWEROF2(secsz))
1649 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Sector size %lu is not a power of two larger than 512? Refusing.", secsz);
1650
1651 /* Use at least 4K, and ensure it's a multiple of the sector size, regardless if that is smaller or
1652 * larger */
1653 grainsz = secsz < 4096 ? 4096 : secsz;
1654
1655 log_debug("Sector size of device is %lu bytes. Using grain size of %" PRIu64 ".", secsz, grainsz);
1656
1657 switch (arg_empty) {
1658
1659 case EMPTY_REFUSE:
1660 /* Refuse empty disks, insist on an existing GPT partition table */
1661 if (!fdisk_is_labeltype(c, FDISK_DISKLABEL_GPT))
1662 return log_notice_errno(SYNTHETIC_ERRNO(EHWPOISON), "Disk %s has no GPT disk label, not repartitioning.", node);
1663
1664 break;
1665
1666 case EMPTY_REQUIRE:
1667 /* Require an empty disk, refuse any existing partition table */
1668 r = fdisk_has_label(c);
1669 if (r < 0)
1670 return log_error_errno(r, "Failed to determine whether disk %s has a disk label: %m", node);
1671 if (r > 0)
1672 return log_notice_errno(SYNTHETIC_ERRNO(EHWPOISON), "Disk %s already has a disk label, refusing.", node);
1673
1674 from_scratch = true;
1675 break;
1676
1677 case EMPTY_ALLOW:
1678 /* Allow both an empty disk and an existing partition table, but only GPT */
1679 r = fdisk_has_label(c);
1680 if (r < 0)
1681 return log_error_errno(r, "Failed to determine whether disk %s has a disk label: %m", node);
1682 if (r > 0) {
1683 if (!fdisk_is_labeltype(c, FDISK_DISKLABEL_GPT))
1684 return log_notice_errno(SYNTHETIC_ERRNO(EHWPOISON), "Disk %s has non-GPT disk label, not repartitioning.", node);
1685 } else
1686 from_scratch = true;
1687
1688 break;
1689
1690 case EMPTY_FORCE:
1691 case EMPTY_CREATE:
1692 /* Always reinitiaize the disk, don't consider what there was on the disk before */
1693 from_scratch = true;
1694 break;
1695 }
1696
1697 if (from_scratch) {
1698 r = fdisk_create_disklabel(c, "gpt");
1699 if (r < 0)
1700 return log_error_errno(r, "Failed to create GPT disk label: %m");
1701
1702 r = derive_uuid(context->seed, "disk-uuid", &disk_uuid);
1703 if (r < 0)
1704 return log_error_errno(r, "Failed to acquire disk GPT uuid: %m");
1705
1706 r = fdisk_set_disklabel_id_by_uuid(c, disk_uuid);
1707 if (r < 0)
1708 return log_error_errno(r, "Failed to set GPT disk label: %m");
1709
1710 goto add_initial_free_area;
1711 }
1712
1713 r = fdisk_get_disklabel_id(c, &disk_uuid_string);
1714 if (r < 0)
1715 return log_error_errno(r, "Failed to get current GPT disk label UUID: %m");
1716
1717 r = sd_id128_from_string(disk_uuid_string, &disk_uuid);
1718 if (r < 0)
1719 return log_error_errno(r, "Failed to parse current GPT disk label UUID: %m");
1720
1721 if (sd_id128_is_null(disk_uuid)) {
1722 r = derive_uuid(context->seed, "disk-uuid", &disk_uuid);
1723 if (r < 0)
1724 return log_error_errno(r, "Failed to acquire disk GPT uuid: %m");
1725
1726 r = fdisk_set_disklabel_id(c);
1727 if (r < 0)
1728 return log_error_errno(r, "Failed to set GPT disk label: %m");
1729 }
1730
1731 r = fdisk_get_partitions(c, &t);
1732 if (r < 0)
1733 return log_error_errno(r, "Failed to acquire partition table: %m");
1734
1735 n_partitions = fdisk_table_get_nents(t);
1736 for (size_t i = 0; i < n_partitions; i++) {
1737 _cleanup_free_ char *label_copy = NULL;
1738 Partition *last = NULL;
1739 struct fdisk_partition *p;
1740 struct fdisk_parttype *pt;
1741 const char *pts, *ids, *label;
1742 uint64_t sz, start;
1743 bool found = false;
1744 sd_id128_t ptid, id;
1745 size_t partno;
1746
1747 p = fdisk_table_get_partition(t, i);
1748 if (!p)
1749 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to read partition metadata: %m");
1750
1751 if (fdisk_partition_is_used(p) <= 0)
1752 continue;
1753
1754 if (fdisk_partition_has_start(p) <= 0 ||
1755 fdisk_partition_has_size(p) <= 0 ||
1756 fdisk_partition_has_partno(p) <= 0)
1757 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Found a partition without a position, size or number.");
1758
1759 pt = fdisk_partition_get_type(p);
1760 if (!pt)
1761 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to acquire type of partition: %m");
1762
1763 pts = fdisk_parttype_get_string(pt);
1764 if (!pts)
1765 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to acquire type of partition as string: %m");
1766
1767 r = sd_id128_from_string(pts, &ptid);
1768 if (r < 0)
1769 return log_error_errno(r, "Failed to parse partition type UUID %s: %m", pts);
1770
1771 ids = fdisk_partition_get_uuid(p);
1772 if (!ids)
1773 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Found a partition without a UUID.");
1774
1775 r = sd_id128_from_string(ids, &id);
1776 if (r < 0)
1777 return log_error_errno(r, "Failed to parse partition UUID %s: %m", ids);
1778
1779 label = fdisk_partition_get_name(p);
1780 if (!isempty(label)) {
1781 label_copy = strdup(label);
1782 if (!label_copy)
1783 return log_oom();
1784 }
1785
1786 sz = fdisk_partition_get_size(p);
1787 assert(sz <= UINT64_MAX/secsz);
1788 sz *= secsz;
1789
1790 start = fdisk_partition_get_start(p);
1791 assert(start <= UINT64_MAX/secsz);
1792 start *= secsz;
1793
1794 partno = fdisk_partition_get_partno(p);
1795
1796 if (left_boundary == UINT64_MAX || left_boundary > start)
1797 left_boundary = start;
1798
1799 /* Assign this existing partition to the first partition of the right type that doesn't have
1800 * an existing one assigned yet. */
1801 LIST_FOREACH(partitions, pp, context->partitions) {
1802 last = pp;
1803
1804 if (!sd_id128_equal(pp->type_uuid, ptid))
1805 continue;
1806
1807 if (!pp->current_partition) {
1808 pp->current_uuid = id;
1809 pp->current_size = sz;
1810 pp->offset = start;
1811 pp->partno = partno;
1812 pp->current_label = TAKE_PTR(label_copy);
1813
1814 pp->current_partition = p;
1815 fdisk_ref_partition(p);
1816
1817 r = determine_current_padding(c, t, p, secsz, grainsz, &pp->current_padding);
1818 if (r < 0)
1819 return r;
1820
1821 if (pp->current_padding > 0) {
1822 r = context_add_free_area(context, pp->current_padding, pp);
1823 if (r < 0)
1824 return r;
1825 }
1826
1827 found = true;
1828 break;
1829 }
1830 }
1831
1832 /* If we have no matching definition, create a new one. */
1833 if (!found) {
1834 _cleanup_(partition_freep) Partition *np = NULL;
1835
1836 np = partition_new();
1837 if (!np)
1838 return log_oom();
1839
1840 np->current_uuid = id;
1841 np->type_uuid = ptid;
1842 np->current_size = sz;
1843 np->offset = start;
1844 np->partno = partno;
1845 np->current_label = TAKE_PTR(label_copy);
1846
1847 np->current_partition = p;
1848 fdisk_ref_partition(p);
1849
1850 r = determine_current_padding(c, t, p, secsz, grainsz, &np->current_padding);
1851 if (r < 0)
1852 return r;
1853
1854 if (np->current_padding > 0) {
1855 r = context_add_free_area(context, np->current_padding, np);
1856 if (r < 0)
1857 return r;
1858 }
1859
1860 LIST_INSERT_AFTER(partitions, context->partitions, last, TAKE_PTR(np));
1861 context->n_partitions++;
1862 }
1863 }
1864
1865 add_initial_free_area:
1866 nsectors = fdisk_get_nsectors(c);
1867 assert(nsectors <= UINT64_MAX/secsz);
1868 nsectors *= secsz;
1869
1870 first_lba = fdisk_get_first_lba(c);
1871 assert(first_lba <= UINT64_MAX/secsz);
1872 first_lba *= secsz;
1873
1874 last_lba = fdisk_get_last_lba(c);
1875 assert(last_lba < UINT64_MAX);
1876 last_lba++;
1877 assert(last_lba <= UINT64_MAX/secsz);
1878 last_lba *= secsz;
1879
1880 assert(last_lba >= first_lba);
1881
1882 if (left_boundary == UINT64_MAX) {
1883 /* No partitions at all? Then the whole disk is up for grabs. */
1884
1885 first_lba = round_up_size(first_lba, grainsz);
1886 last_lba = round_down_size(last_lba, grainsz);
1887
1888 if (last_lba > first_lba) {
1889 r = context_add_free_area(context, last_lba - first_lba, NULL);
1890 if (r < 0)
1891 return r;
1892 }
1893 } else {
1894 /* Add space left of first partition */
1895 assert(left_boundary >= first_lba);
1896
1897 first_lba = round_up_size(first_lba, grainsz);
1898 left_boundary = round_down_size(left_boundary, grainsz);
1899 last_lba = round_down_size(last_lba, grainsz);
1900
1901 if (left_boundary > first_lba) {
1902 r = context_add_free_area(context, left_boundary - first_lba, NULL);
1903 if (r < 0)
1904 return r;
1905 }
1906 }
1907
1908 context->start = first_lba;
1909 context->end = last_lba;
1910 context->total = nsectors;
1911 context->sector_size = secsz;
1912 context->grain_size = grainsz;
1913 context->fdisk_context = TAKE_PTR(c);
1914
1915 return from_scratch;
1916 }
1917
1918 static void context_unload_partition_table(Context *context) {
1919 assert(context);
1920
1921 LIST_FOREACH(partitions, p, context->partitions) {
1922
1923 /* Entirely remove partitions that have no configuration */
1924 if (PARTITION_IS_FOREIGN(p)) {
1925 partition_unlink_and_free(context, p);
1926 continue;
1927 }
1928
1929 /* Otherwise drop all data we read off the block device and everything we might have
1930 * calculated based on it */
1931
1932 p->dropped = false;
1933 p->current_size = UINT64_MAX;
1934 p->new_size = UINT64_MAX;
1935 p->current_padding = UINT64_MAX;
1936 p->new_padding = UINT64_MAX;
1937 p->partno = UINT64_MAX;
1938 p->offset = UINT64_MAX;
1939
1940 if (p->current_partition) {
1941 fdisk_unref_partition(p->current_partition);
1942 p->current_partition = NULL;
1943 }
1944
1945 if (p->new_partition) {
1946 fdisk_unref_partition(p->new_partition);
1947 p->new_partition = NULL;
1948 }
1949
1950 p->padding_area = NULL;
1951 p->allocated_to_area = NULL;
1952
1953 p->current_uuid = SD_ID128_NULL;
1954 p->current_label = mfree(p->current_label);
1955 }
1956
1957 context->start = UINT64_MAX;
1958 context->end = UINT64_MAX;
1959 context->total = UINT64_MAX;
1960
1961 if (context->fdisk_context) {
1962 fdisk_unref_context(context->fdisk_context);
1963 context->fdisk_context = NULL;
1964 }
1965
1966 context_free_free_areas(context);
1967 }
1968
1969 static int format_size_change(uint64_t from, uint64_t to, char **ret) {
1970 char *t;
1971
1972 if (from != UINT64_MAX) {
1973 if (from == to || to == UINT64_MAX)
1974 t = strdup(FORMAT_BYTES(from));
1975 else
1976 t = strjoin(FORMAT_BYTES(from), " ", special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), " ", FORMAT_BYTES(to));
1977 } else if (to != UINT64_MAX)
1978 t = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), " ", FORMAT_BYTES(to));
1979 else {
1980 *ret = NULL;
1981 return 0;
1982 }
1983
1984 if (!t)
1985 return log_oom();
1986
1987 *ret = t;
1988 return 1;
1989 }
1990
1991 static const char *partition_label(const Partition *p) {
1992 assert(p);
1993
1994 if (p->new_label)
1995 return p->new_label;
1996
1997 if (p->current_label)
1998 return p->current_label;
1999
2000 return gpt_partition_type_uuid_to_string(p->type_uuid);
2001 }
2002
2003 static int context_dump_partitions(Context *context, const char *node) {
2004 _cleanup_(table_unrefp) Table *t = NULL;
2005 uint64_t sum_padding = 0, sum_size = 0;
2006 int r;
2007 const size_t dropin_files_col = 13;
2008 bool no_dropin_files = true;
2009
2010 if ((arg_json_format_flags & JSON_FORMAT_OFF) && context->n_partitions == 0) {
2011 log_info("Empty partition table.");
2012 return 0;
2013 }
2014
2015 t = table_new("type", "label", "uuid", "file", "node", "offset", "old size", "raw size", "size", "old padding", "raw padding", "padding", "activity", "drop-in files");
2016 if (!t)
2017 return log_oom();
2018
2019 if (!DEBUG_LOGGING) {
2020 if (arg_json_format_flags & JSON_FORMAT_OFF)
2021 (void) table_set_display(t, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) 3, (size_t) 4,
2022 (size_t) 8, (size_t) 11, dropin_files_col);
2023 else
2024 (void) table_set_display(t, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) 3, (size_t) 4,
2025 (size_t) 5, (size_t) 6, (size_t) 7, (size_t) 9, (size_t) 10, (size_t) 12,
2026 dropin_files_col);
2027 }
2028
2029 (void) table_set_align_percent(t, table_get_cell(t, 0, 5), 100);
2030 (void) table_set_align_percent(t, table_get_cell(t, 0, 6), 100);
2031 (void) table_set_align_percent(t, table_get_cell(t, 0, 7), 100);
2032 (void) table_set_align_percent(t, table_get_cell(t, 0, 8), 100);
2033 (void) table_set_align_percent(t, table_get_cell(t, 0, 9), 100);
2034 (void) table_set_align_percent(t, table_get_cell(t, 0, 10), 100);
2035 (void) table_set_align_percent(t, table_get_cell(t, 0, 11), 100);
2036
2037 LIST_FOREACH(partitions, p, context->partitions) {
2038 _cleanup_free_ char *size_change = NULL, *padding_change = NULL, *partname = NULL;
2039 char uuid_buffer[SD_ID128_UUID_STRING_MAX];
2040 const char *label, *activity = NULL;
2041
2042 if (p->dropped)
2043 continue;
2044
2045 if (p->current_size == UINT64_MAX)
2046 activity = "create";
2047 else if (p->current_size != p->new_size)
2048 activity = "resize";
2049
2050 label = partition_label(p);
2051 partname = p->partno != UINT64_MAX ? fdisk_partname(node, p->partno+1) : NULL;
2052
2053 r = format_size_change(p->current_size, p->new_size, &size_change);
2054 if (r < 0)
2055 return r;
2056
2057 r = format_size_change(p->current_padding, p->new_padding, &padding_change);
2058 if (r < 0)
2059 return r;
2060
2061 if (p->new_size != UINT64_MAX)
2062 sum_size += p->new_size;
2063 if (p->new_padding != UINT64_MAX)
2064 sum_padding += p->new_padding;
2065
2066 r = table_add_many(
2067 t,
2068 TABLE_STRING, gpt_partition_type_uuid_to_string_harder(p->type_uuid, uuid_buffer),
2069 TABLE_STRING, empty_to_null(label) ?: "-", TABLE_SET_COLOR, empty_to_null(label) ? NULL : ansi_grey(),
2070 TABLE_UUID, sd_id128_is_null(p->new_uuid) ? p->current_uuid : p->new_uuid,
2071 TABLE_STRING, p->definition_path ? basename(p->definition_path) : "-", TABLE_SET_COLOR, p->definition_path ? NULL : ansi_grey(),
2072 TABLE_STRING, partname ?: "-", TABLE_SET_COLOR, partname ? NULL : ansi_highlight(),
2073 TABLE_UINT64, p->offset,
2074 TABLE_UINT64, p->current_size == UINT64_MAX ? 0 : p->current_size,
2075 TABLE_UINT64, p->new_size,
2076 TABLE_STRING, size_change, TABLE_SET_COLOR, !p->partitions_next && sum_size > 0 ? ansi_underline() : NULL,
2077 TABLE_UINT64, p->current_padding == UINT64_MAX ? 0 : p->current_padding,
2078 TABLE_UINT64, p->new_padding,
2079 TABLE_STRING, padding_change, TABLE_SET_COLOR, !p->partitions_next && sum_padding > 0 ? ansi_underline() : NULL,
2080 TABLE_STRING, activity ?: "unchanged",
2081 TABLE_STRV, p->drop_in_files);
2082 if (r < 0)
2083 return table_log_add_error(r);
2084
2085 no_dropin_files = no_dropin_files && strv_isempty(p->drop_in_files);
2086 }
2087
2088 if ((arg_json_format_flags & JSON_FORMAT_OFF) && (sum_padding > 0 || sum_size > 0)) {
2089 const char *a, *b;
2090
2091 a = strjoina(special_glyph(SPECIAL_GLYPH_SIGMA), " = ", FORMAT_BYTES(sum_size));
2092 b = strjoina(special_glyph(SPECIAL_GLYPH_SIGMA), " = ", FORMAT_BYTES(sum_padding));
2093
2094 r = table_add_many(
2095 t,
2096 TABLE_EMPTY,
2097 TABLE_EMPTY,
2098 TABLE_EMPTY,
2099 TABLE_EMPTY,
2100 TABLE_EMPTY,
2101 TABLE_EMPTY,
2102 TABLE_EMPTY,
2103 TABLE_EMPTY,
2104 TABLE_STRING, a,
2105 TABLE_EMPTY,
2106 TABLE_EMPTY,
2107 TABLE_STRING, b,
2108 TABLE_EMPTY,
2109 TABLE_EMPTY);
2110 if (r < 0)
2111 return table_log_add_error(r);
2112 }
2113
2114 if (no_dropin_files) {
2115 r = table_hide_column_from_display(t, dropin_files_col);
2116 if (r < 0)
2117 return log_error_errno(r, "Failed to set columns to display: %m");
2118 }
2119
2120 return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, arg_legend);
2121 }
2122
2123 static void context_bar_char_process_partition(
2124 Context *context,
2125 Partition *bar[],
2126 size_t n,
2127 Partition *p,
2128 size_t *ret_start) {
2129
2130 uint64_t from, to, total;
2131 size_t x, y;
2132
2133 assert(context);
2134 assert(bar);
2135 assert(n > 0);
2136 assert(p);
2137
2138 if (p->dropped)
2139 return;
2140
2141 assert(p->offset != UINT64_MAX);
2142 assert(p->new_size != UINT64_MAX);
2143
2144 from = p->offset;
2145 to = from + p->new_size;
2146
2147 assert(context->total > 0);
2148 total = context->total;
2149
2150 assert(from <= total);
2151 x = from * n / total;
2152
2153 assert(to <= total);
2154 y = to * n / total;
2155
2156 assert(x <= y);
2157 assert(y <= n);
2158
2159 for (size_t i = x; i < y; i++)
2160 bar[i] = p;
2161
2162 *ret_start = x;
2163 }
2164
2165 static int partition_hint(const Partition *p, const char *node, char **ret) {
2166 _cleanup_free_ char *buf = NULL;
2167 const char *label;
2168 sd_id128_t id;
2169
2170 /* Tries really hard to find a suitable description for this partition */
2171
2172 if (p->definition_path) {
2173 buf = strdup(basename(p->definition_path));
2174 goto done;
2175 }
2176
2177 label = partition_label(p);
2178 if (!isempty(label)) {
2179 buf = strdup(label);
2180 goto done;
2181 }
2182
2183 if (p->partno != UINT64_MAX) {
2184 buf = fdisk_partname(node, p->partno+1);
2185 goto done;
2186 }
2187
2188 if (!sd_id128_is_null(p->new_uuid))
2189 id = p->new_uuid;
2190 else if (!sd_id128_is_null(p->current_uuid))
2191 id = p->current_uuid;
2192 else
2193 id = p->type_uuid;
2194
2195 buf = strdup(SD_ID128_TO_UUID_STRING(id));
2196
2197 done:
2198 if (!buf)
2199 return -ENOMEM;
2200
2201 *ret = TAKE_PTR(buf);
2202 return 0;
2203 }
2204
2205 static int context_dump_partition_bar(Context *context, const char *node) {
2206 _cleanup_free_ Partition **bar = NULL;
2207 _cleanup_free_ size_t *start_array = NULL;
2208 Partition *last = NULL;
2209 bool z = false;
2210 size_t c, j = 0;
2211
2212 assert_se((c = columns()) >= 2);
2213 c -= 2; /* We do not use the leftmost and rightmost character cell */
2214
2215 bar = new0(Partition*, c);
2216 if (!bar)
2217 return log_oom();
2218
2219 start_array = new(size_t, context->n_partitions);
2220 if (!start_array)
2221 return log_oom();
2222
2223 LIST_FOREACH(partitions, p, context->partitions)
2224 context_bar_char_process_partition(context, bar, c, p, start_array + j++);
2225
2226 putc(' ', stdout);
2227
2228 for (size_t i = 0; i < c; i++) {
2229 if (bar[i]) {
2230 if (last != bar[i])
2231 z = !z;
2232
2233 fputs(z ? ansi_green() : ansi_yellow(), stdout);
2234 fputs(special_glyph(SPECIAL_GLYPH_DARK_SHADE), stdout);
2235 } else {
2236 fputs(ansi_normal(), stdout);
2237 fputs(special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), stdout);
2238 }
2239
2240 last = bar[i];
2241 }
2242
2243 fputs(ansi_normal(), stdout);
2244 putc('\n', stdout);
2245
2246 for (size_t i = 0; i < context->n_partitions; i++) {
2247 _cleanup_free_ char **line = NULL;
2248
2249 line = new0(char*, c);
2250 if (!line)
2251 return log_oom();
2252
2253 j = 0;
2254 LIST_FOREACH(partitions, p, context->partitions) {
2255 _cleanup_free_ char *d = NULL;
2256 j++;
2257
2258 if (i < context->n_partitions - j) {
2259
2260 if (line[start_array[j-1]]) {
2261 const char *e;
2262
2263 /* Upgrade final corner to the right with a branch to the right */
2264 e = startswith(line[start_array[j-1]], special_glyph(SPECIAL_GLYPH_TREE_RIGHT));
2265 if (e) {
2266 d = strjoin(special_glyph(SPECIAL_GLYPH_TREE_BRANCH), e);
2267 if (!d)
2268 return log_oom();
2269 }
2270 }
2271
2272 if (!d) {
2273 d = strdup(special_glyph(SPECIAL_GLYPH_TREE_VERTICAL));
2274 if (!d)
2275 return log_oom();
2276 }
2277
2278 } else if (i == context->n_partitions - j) {
2279 _cleanup_free_ char *hint = NULL;
2280
2281 (void) partition_hint(p, node, &hint);
2282
2283 if (streq_ptr(line[start_array[j-1]], special_glyph(SPECIAL_GLYPH_TREE_VERTICAL)))
2284 d = strjoin(special_glyph(SPECIAL_GLYPH_TREE_BRANCH), " ", strna(hint));
2285 else
2286 d = strjoin(special_glyph(SPECIAL_GLYPH_TREE_RIGHT), " ", strna(hint));
2287
2288 if (!d)
2289 return log_oom();
2290 }
2291
2292 if (d)
2293 free_and_replace(line[start_array[j-1]], d);
2294 }
2295
2296 putc(' ', stdout);
2297
2298 j = 0;
2299 while (j < c) {
2300 if (line[j]) {
2301 fputs(line[j], stdout);
2302 j += utf8_console_width(line[j]);
2303 } else {
2304 putc(' ', stdout);
2305 j++;
2306 }
2307 }
2308
2309 putc('\n', stdout);
2310
2311 for (j = 0; j < c; j++)
2312 free(line[j]);
2313 }
2314
2315 return 0;
2316 }
2317
2318 static bool context_changed(const Context *context) {
2319 assert(context);
2320
2321 LIST_FOREACH(partitions, p, context->partitions) {
2322 if (p->dropped)
2323 continue;
2324
2325 if (p->allocated_to_area)
2326 return true;
2327
2328 if (p->new_size != p->current_size)
2329 return true;
2330 }
2331
2332 return false;
2333 }
2334
2335 static int context_wipe_range(Context *context, uint64_t offset, uint64_t size) {
2336 _cleanup_(blkid_free_probep) blkid_probe probe = NULL;
2337 int r;
2338
2339 assert(context);
2340 assert(offset != UINT64_MAX);
2341 assert(size != UINT64_MAX);
2342
2343 probe = blkid_new_probe();
2344 if (!probe)
2345 return log_oom();
2346
2347 errno = 0;
2348 r = blkid_probe_set_device(probe, fdisk_get_devfd(context->fdisk_context), offset, size);
2349 if (r < 0)
2350 return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to allocate device probe for wiping.");
2351
2352 errno = 0;
2353 if (blkid_probe_enable_superblocks(probe, true) < 0 ||
2354 blkid_probe_set_superblocks_flags(probe, BLKID_SUBLKS_MAGIC|BLKID_SUBLKS_BADCSUM) < 0 ||
2355 blkid_probe_enable_partitions(probe, true) < 0 ||
2356 blkid_probe_set_partitions_flags(probe, BLKID_PARTS_MAGIC) < 0)
2357 return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to enable superblock and partition probing.");
2358
2359 for (;;) {
2360 errno = 0;
2361 r = blkid_do_probe(probe);
2362 if (r < 0)
2363 return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe for file systems.");
2364 if (r > 0)
2365 break;
2366
2367 errno = 0;
2368 if (blkid_do_wipe(probe, false) < 0)
2369 return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to wipe file system signature.");
2370 }
2371
2372 return 0;
2373 }
2374
2375 static int context_wipe_partition(Context *context, Partition *p) {
2376 int r;
2377
2378 assert(context);
2379 assert(p);
2380 assert(!PARTITION_EXISTS(p)); /* Safety check: never wipe existing partitions */
2381
2382 assert(p->offset != UINT64_MAX);
2383 assert(p->new_size != UINT64_MAX);
2384
2385 r = context_wipe_range(context, p->offset, p->new_size);
2386 if (r < 0)
2387 return r;
2388
2389 log_info("Successfully wiped file system signatures from future partition %" PRIu64 ".", p->partno);
2390 return 0;
2391 }
2392
2393 static int context_discard_range(
2394 Context *context,
2395 uint64_t offset,
2396 uint64_t size) {
2397
2398 struct stat st;
2399 int fd;
2400
2401 assert(context);
2402 assert(offset != UINT64_MAX);
2403 assert(size != UINT64_MAX);
2404
2405 if (size <= 0)
2406 return 0;
2407
2408 assert_se((fd = fdisk_get_devfd(context->fdisk_context)) >= 0);
2409
2410 if (fstat(fd, &st) < 0)
2411 return -errno;
2412
2413 if (S_ISREG(st.st_mode)) {
2414 if (fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, size) < 0) {
2415 if (ERRNO_IS_NOT_SUPPORTED(errno))
2416 return -EOPNOTSUPP;
2417
2418 return -errno;
2419 }
2420
2421 return 1;
2422 }
2423
2424 if (S_ISBLK(st.st_mode)) {
2425 uint64_t range[2], end;
2426
2427 range[0] = round_up_size(offset, context->sector_size);
2428
2429 if (offset > UINT64_MAX - size)
2430 return -ERANGE;
2431
2432 end = offset + size;
2433 if (end <= range[0])
2434 return 0;
2435
2436 range[1] = round_down_size(end - range[0], context->sector_size);
2437 if (range[1] <= 0)
2438 return 0;
2439
2440 if (ioctl(fd, BLKDISCARD, range) < 0) {
2441 if (ERRNO_IS_NOT_SUPPORTED(errno))
2442 return -EOPNOTSUPP;
2443
2444 return -errno;
2445 }
2446
2447 return 1;
2448 }
2449
2450 return -EOPNOTSUPP;
2451 }
2452
2453 static int context_discard_partition(Context *context, Partition *p) {
2454 int r;
2455
2456 assert(context);
2457 assert(p);
2458
2459 assert(p->offset != UINT64_MAX);
2460 assert(p->new_size != UINT64_MAX);
2461 assert(!PARTITION_EXISTS(p)); /* Safety check: never discard existing partitions */
2462
2463 if (!arg_discard)
2464 return 0;
2465
2466 r = context_discard_range(context, p->offset, p->new_size);
2467 if (r == -EOPNOTSUPP) {
2468 log_info("Storage does not support discard, not discarding data in future partition %" PRIu64 ".", p->partno);
2469 return 0;
2470 }
2471 if (r == -EBUSY) {
2472 /* Let's handle this gracefully: https://bugzilla.kernel.org/show_bug.cgi?id=211167 */
2473 log_info("Block device is busy, not discarding partition %" PRIu64 " because it probably is mounted.", p->partno);
2474 return 0;
2475 }
2476 if (r == 0) {
2477 log_info("Partition %" PRIu64 " too short for discard, skipping.", p->partno);
2478 return 0;
2479 }
2480 if (r < 0)
2481 return log_error_errno(r, "Failed to discard data for future partition %" PRIu64 ".", p->partno);
2482
2483 log_info("Successfully discarded data from future partition %" PRIu64 ".", p->partno);
2484 return 1;
2485 }
2486
2487 static int context_discard_gap_after(Context *context, Partition *p) {
2488 uint64_t gap, next = UINT64_MAX;
2489 int r;
2490
2491 assert(context);
2492 assert(!p || (p->offset != UINT64_MAX && p->new_size != UINT64_MAX));
2493
2494 if (p)
2495 gap = p->offset + p->new_size;
2496 else
2497 gap = context->start;
2498
2499 LIST_FOREACH(partitions, q, context->partitions) {
2500 if (q->dropped)
2501 continue;
2502
2503 assert(q->offset != UINT64_MAX);
2504 assert(q->new_size != UINT64_MAX);
2505
2506 if (q->offset < gap)
2507 continue;
2508
2509 if (next == UINT64_MAX || q->offset < next)
2510 next = q->offset;
2511 }
2512
2513 if (next == UINT64_MAX) {
2514 next = context->end;
2515 if (gap > next)
2516 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Partition end beyond disk end.");
2517 }
2518
2519 assert(next >= gap);
2520 r = context_discard_range(context, gap, next - gap);
2521 if (r == -EOPNOTSUPP) {
2522 if (p)
2523 log_info("Storage does not support discard, not discarding gap after partition %" PRIu64 ".", p->partno);
2524 else
2525 log_info("Storage does not support discard, not discarding gap at beginning of disk.");
2526 return 0;
2527 }
2528 if (r == 0) /* Too short */
2529 return 0;
2530 if (r < 0) {
2531 if (p)
2532 return log_error_errno(r, "Failed to discard gap after partition %" PRIu64 ".", p->partno);
2533 else
2534 return log_error_errno(r, "Failed to discard gap at beginning of disk.");
2535 }
2536
2537 if (p)
2538 log_info("Successfully discarded gap after partition %" PRIu64 ".", p->partno);
2539 else
2540 log_info("Successfully discarded gap at beginning of disk.");
2541
2542 return 0;
2543 }
2544
2545 static int context_wipe_and_discard(Context *context, bool from_scratch) {
2546 int r;
2547
2548 assert(context);
2549
2550 /* Wipe and discard the contents of all partitions we are about to create. We skip the discarding if
2551 * we were supposed to start from scratch anyway, as in that case we just discard the whole block
2552 * device in one go early on. */
2553
2554 LIST_FOREACH(partitions, p, context->partitions) {
2555
2556 if (!p->allocated_to_area)
2557 continue;
2558
2559 r = context_wipe_partition(context, p);
2560 if (r < 0)
2561 return r;
2562
2563 if (!from_scratch) {
2564 r = context_discard_partition(context, p);
2565 if (r < 0)
2566 return r;
2567
2568 r = context_discard_gap_after(context, p);
2569 if (r < 0)
2570 return r;
2571 }
2572 }
2573
2574 if (!from_scratch) {
2575 r = context_discard_gap_after(context, NULL);
2576 if (r < 0)
2577 return r;
2578 }
2579
2580 return 0;
2581 }
2582
2583 static int partition_encrypt(
2584 Context *context,
2585 Partition *p,
2586 const char *node,
2587 struct crypt_device **ret_cd,
2588 char **ret_volume,
2589 int *ret_fd) {
2590 #if HAVE_LIBCRYPTSETUP
2591 _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
2592 _cleanup_(erase_and_freep) void *volume_key = NULL;
2593 _cleanup_free_ char *dm_name = NULL, *vol = NULL;
2594 size_t volume_key_size = 256 / 8;
2595 sd_id128_t uuid;
2596 int r;
2597
2598 assert(context);
2599 assert(p);
2600 assert(p->encrypt != ENCRYPT_OFF);
2601
2602 log_debug("Encryption mode for partition %" PRIu64 ": %s", p->partno, encrypt_mode_to_string(p->encrypt));
2603
2604 r = dlopen_cryptsetup();
2605 if (r < 0)
2606 return log_error_errno(r, "libcryptsetup not found, cannot encrypt: %m");
2607
2608 if (asprintf(&dm_name, "luks-repart-%08" PRIx64, random_u64()) < 0)
2609 return log_oom();
2610
2611 if (ret_volume) {
2612 vol = path_join("/dev/mapper/", dm_name);
2613 if (!vol)
2614 return log_oom();
2615 }
2616
2617 r = derive_uuid(p->new_uuid, "luks-uuid", &uuid);
2618 if (r < 0)
2619 return r;
2620
2621 log_info("Encrypting future partition %" PRIu64 "...", p->partno);
2622
2623 volume_key = malloc(volume_key_size);
2624 if (!volume_key)
2625 return log_oom();
2626
2627 r = crypto_random_bytes(volume_key, volume_key_size);
2628 if (r < 0)
2629 return log_error_errno(r, "Failed to generate volume key: %m");
2630
2631 r = sym_crypt_init(&cd, node);
2632 if (r < 0)
2633 return log_error_errno(r, "Failed to allocate libcryptsetup context: %m");
2634
2635 cryptsetup_enable_logging(cd);
2636
2637 r = sym_crypt_format(cd,
2638 CRYPT_LUKS2,
2639 "aes",
2640 "xts-plain64",
2641 SD_ID128_TO_UUID_STRING(uuid),
2642 volume_key,
2643 volume_key_size,
2644 &(struct crypt_params_luks2) {
2645 .label = strempty(p->new_label),
2646 .sector_size = context->sector_size,
2647 });
2648 if (r < 0)
2649 return log_error_errno(r, "Failed to LUKS2 format future partition: %m");
2650
2651 if (IN_SET(p->encrypt, ENCRYPT_KEY_FILE, ENCRYPT_KEY_FILE_TPM2)) {
2652 r = sym_crypt_keyslot_add_by_volume_key(
2653 cd,
2654 CRYPT_ANY_SLOT,
2655 volume_key,
2656 volume_key_size,
2657 strempty(arg_key),
2658 arg_key_size);
2659 if (r < 0)
2660 return log_error_errno(r, "Failed to add LUKS2 key: %m");
2661 }
2662
2663 if (IN_SET(p->encrypt, ENCRYPT_TPM2, ENCRYPT_KEY_FILE_TPM2)) {
2664 #if HAVE_TPM2
2665 _cleanup_(erase_and_freep) char *base64_encoded = NULL;
2666 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
2667 _cleanup_(erase_and_freep) void *secret = NULL;
2668 _cleanup_free_ void *blob = NULL, *hash = NULL;
2669 size_t secret_size, blob_size, hash_size;
2670 uint16_t pcr_bank, primary_alg;
2671 int keyslot;
2672
2673 r = tpm2_seal(arg_tpm2_device, arg_tpm2_pcr_mask, NULL, &secret, &secret_size, &blob, &blob_size, &hash, &hash_size, &pcr_bank, &primary_alg);
2674 if (r < 0)
2675 return log_error_errno(r, "Failed to seal to TPM2: %m");
2676
2677 r = base64mem(secret, secret_size, &base64_encoded);
2678 if (r < 0)
2679 return log_error_errno(r, "Failed to base64 encode secret key: %m");
2680
2681 r = cryptsetup_set_minimal_pbkdf(cd);
2682 if (r < 0)
2683 return log_error_errno(r, "Failed to set minimal PBKDF: %m");
2684
2685 keyslot = sym_crypt_keyslot_add_by_volume_key(
2686 cd,
2687 CRYPT_ANY_SLOT,
2688 volume_key,
2689 volume_key_size,
2690 base64_encoded,
2691 strlen(base64_encoded));
2692 if (keyslot < 0)
2693 return log_error_errno(keyslot, "Failed to add new TPM2 key to %s: %m", node);
2694
2695 r = tpm2_make_luks2_json(keyslot, arg_tpm2_pcr_mask, pcr_bank, primary_alg, blob, blob_size, hash, hash_size, 0, &v);
2696 if (r < 0)
2697 return log_error_errno(r, "Failed to prepare TPM2 JSON token object: %m");
2698
2699 r = cryptsetup_add_token_json(cd, v);
2700 if (r < 0)
2701 return log_error_errno(r, "Failed to add TPM2 JSON token to LUKS2 header: %m");
2702 #else
2703 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2704 "Support for TPM2 enrollment not enabled.");
2705 #endif
2706 }
2707
2708 r = sym_crypt_activate_by_volume_key(
2709 cd,
2710 dm_name,
2711 volume_key,
2712 volume_key_size,
2713 arg_discard ? CRYPT_ACTIVATE_ALLOW_DISCARDS : 0);
2714 if (r < 0)
2715 return log_error_errno(r, "Failed to activate LUKS superblock: %m");
2716
2717 log_info("Successfully encrypted future partition %" PRIu64 ".", p->partno);
2718
2719 if (ret_fd) {
2720 _cleanup_close_ int dev_fd = -1;
2721
2722 dev_fd = open(vol, O_RDWR|O_CLOEXEC|O_NOCTTY);
2723 if (dev_fd < 0)
2724 return log_error_errno(errno, "Failed to open LUKS volume '%s': %m", vol);
2725
2726 *ret_fd = TAKE_FD(dev_fd);
2727 }
2728
2729 if (ret_cd)
2730 *ret_cd = TAKE_PTR(cd);
2731 if (ret_volume)
2732 *ret_volume = TAKE_PTR(vol);
2733
2734 return 0;
2735 #else
2736 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libcryptsetup is not supported, cannot encrypt: %m");
2737 #endif
2738 }
2739
2740 static int deactivate_luks(struct crypt_device *cd, const char *node) {
2741 #if HAVE_LIBCRYPTSETUP
2742 int r;
2743
2744 if (!cd)
2745 return 0;
2746
2747 assert(node);
2748
2749 /* udev or so might access out block device in the background while we are done. Let's hence force
2750 * detach the volume. We sync'ed before, hence this should be safe. */
2751
2752 r = sym_crypt_deactivate_by_name(cd, basename(node), CRYPT_DEACTIVATE_FORCE);
2753 if (r < 0)
2754 return log_error_errno(r, "Failed to deactivate LUKS device: %m");
2755
2756 return 1;
2757 #else
2758 return 0;
2759 #endif
2760 }
2761
2762 static int context_copy_blocks(Context *context) {
2763 int whole_fd = -1, r;
2764
2765 assert(context);
2766
2767 /* Copy in file systems on the block level */
2768
2769 LIST_FOREACH(partitions, p, context->partitions) {
2770 _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
2771 _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
2772 _cleanup_free_ char *encrypted = NULL;
2773 _cleanup_close_ int encrypted_dev_fd = -1;
2774 int target_fd;
2775
2776 if (p->copy_blocks_fd < 0)
2777 continue;
2778
2779 if (p->dropped)
2780 continue;
2781
2782 if (PARTITION_EXISTS(p)) /* Never copy over existing partitions */
2783 continue;
2784
2785 assert(p->new_size != UINT64_MAX);
2786 assert(p->copy_blocks_size != UINT64_MAX);
2787 assert(p->new_size >= p->copy_blocks_size);
2788
2789 if (whole_fd < 0)
2790 assert_se((whole_fd = fdisk_get_devfd(context->fdisk_context)) >= 0);
2791
2792 if (p->encrypt != ENCRYPT_OFF) {
2793 r = loop_device_make(whole_fd, O_RDWR, p->offset, p->new_size, 0, &d);
2794 if (r < 0)
2795 return log_error_errno(r, "Failed to make loopback device of future partition %" PRIu64 ": %m", p->partno);
2796
2797 r = loop_device_flock(d, LOCK_EX);
2798 if (r < 0)
2799 return log_error_errno(r, "Failed to lock loopback device: %m");
2800
2801 r = partition_encrypt(context, p, d->node, &cd, &encrypted, &encrypted_dev_fd);
2802 if (r < 0)
2803 return log_error_errno(r, "Failed to encrypt device: %m");
2804
2805 if (flock(encrypted_dev_fd, LOCK_EX) < 0)
2806 return log_error_errno(errno, "Failed to lock LUKS device: %m");
2807
2808 target_fd = encrypted_dev_fd;
2809 } else {
2810 if (lseek(whole_fd, p->offset, SEEK_SET) == (off_t) -1)
2811 return log_error_errno(errno, "Failed to seek to partition offset: %m");
2812
2813 target_fd = whole_fd;
2814 }
2815
2816 log_info("Copying in '%s' (%s) on block level into future partition %" PRIu64 ".",
2817 p->copy_blocks_path, FORMAT_BYTES(p->copy_blocks_size), p->partno);
2818
2819 r = copy_bytes_full(p->copy_blocks_fd, target_fd, p->copy_blocks_size, 0, NULL, NULL, NULL, NULL);
2820 if (r < 0)
2821 return log_error_errno(r, "Failed to copy in data from '%s': %m", p->copy_blocks_path);
2822
2823 if (fsync(target_fd) < 0)
2824 return log_error_errno(errno, "Failed to synchronize copied data blocks: %m");
2825
2826 if (p->encrypt != ENCRYPT_OFF) {
2827 encrypted_dev_fd = safe_close(encrypted_dev_fd);
2828
2829 r = deactivate_luks(cd, encrypted);
2830 if (r < 0)
2831 return r;
2832
2833 sym_crypt_free(cd);
2834 cd = NULL;
2835
2836 r = loop_device_sync(d);
2837 if (r < 0)
2838 return log_error_errno(r, "Failed to sync loopback device: %m");
2839 }
2840
2841 log_info("Copying in of '%s' on block level completed.", p->copy_blocks_path);
2842 }
2843
2844 return 0;
2845 }
2846
2847 static int do_copy_files(Partition *p, const char *fs) {
2848 int r;
2849
2850 assert(p);
2851 assert(fs);
2852
2853 STRV_FOREACH_PAIR(source, target, p->copy_files) {
2854 _cleanup_close_ int sfd = -1, pfd = -1, tfd = -1;
2855
2856 sfd = chase_symlinks_and_open(*source, arg_root, CHASE_PREFIX_ROOT|CHASE_WARN, O_CLOEXEC|O_NOCTTY, NULL);
2857 if (sfd < 0)
2858 return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_root), *source);
2859
2860 r = fd_verify_regular(sfd);
2861 if (r < 0) {
2862 if (r != -EISDIR)
2863 return log_error_errno(r, "Failed to check type of source file '%s': %m", *source);
2864
2865 /* We are looking at a directory */
2866 tfd = chase_symlinks_and_open(*target, fs, CHASE_PREFIX_ROOT|CHASE_WARN, O_RDONLY|O_DIRECTORY|O_CLOEXEC, NULL);
2867 if (tfd < 0) {
2868 _cleanup_free_ char *dn = NULL, *fn = NULL;
2869
2870 if (tfd != -ENOENT)
2871 return log_error_errno(tfd, "Failed to open target directory '%s': %m", *target);
2872
2873 r = path_extract_filename(*target, &fn);
2874 if (r < 0)
2875 return log_error_errno(r, "Failed to extract filename from '%s': %m", *target);
2876
2877 r = path_extract_directory(*target, &dn);
2878 if (r < 0)
2879 return log_error_errno(r, "Failed to extract directory from '%s': %m", *target);
2880
2881 r = mkdir_p_root(fs, dn, UID_INVALID, GID_INVALID, 0755);
2882 if (r < 0)
2883 return log_error_errno(r, "Failed to create parent directory '%s': %m", dn);
2884
2885 pfd = chase_symlinks_and_open(dn, fs, CHASE_PREFIX_ROOT|CHASE_WARN, O_RDONLY|O_DIRECTORY|O_CLOEXEC, NULL);
2886 if (pfd < 0)
2887 return log_error_errno(pfd, "Failed to open parent directory of target: %m");
2888
2889 r = copy_tree_at(
2890 sfd, ".",
2891 pfd, fn,
2892 UID_INVALID, GID_INVALID,
2893 COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS);
2894 } else
2895 r = copy_tree_at(
2896 sfd, ".",
2897 tfd, ".",
2898 UID_INVALID, GID_INVALID,
2899 COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS);
2900 if (r < 0)
2901 return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_root), *target);
2902 } else {
2903 _cleanup_free_ char *dn = NULL, *fn = NULL;
2904
2905 /* We are looking at a regular file */
2906
2907 r = path_extract_filename(*target, &fn);
2908 if (r == -EADDRNOTAVAIL || r == O_DIRECTORY)
2909 return log_error_errno(SYNTHETIC_ERRNO(EISDIR),
2910 "Target path '%s' refers to a directory, but source path '%s' refers to regular file, can't copy.", *target, *source);
2911 if (r < 0)
2912 return log_error_errno(r, "Failed to extract filename from '%s': %m", *target);
2913
2914 r = path_extract_directory(*target, &dn);
2915 if (r < 0)
2916 return log_error_errno(r, "Failed to extract directory from '%s': %m", *target);
2917
2918 r = mkdir_p_root(fs, dn, UID_INVALID, GID_INVALID, 0755);
2919 if (r < 0)
2920 return log_error_errno(r, "Failed to create parent directory: %m");
2921
2922 pfd = chase_symlinks_and_open(dn, fs, CHASE_PREFIX_ROOT|CHASE_WARN, O_RDONLY|O_DIRECTORY|O_CLOEXEC, NULL);
2923 if (pfd < 0)
2924 return log_error_errno(pfd, "Failed to open parent directory of target: %m");
2925
2926 tfd = openat(pfd, fn, O_CREAT|O_EXCL|O_WRONLY|O_CLOEXEC, 0700);
2927 if (tfd < 0)
2928 return log_error_errno(errno, "Failed to create target file '%s': %m", *target);
2929
2930 r = copy_bytes(sfd, tfd, UINT64_MAX, COPY_REFLINK|COPY_SIGINT);
2931 if (r < 0)
2932 return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_root), *target);
2933
2934 (void) copy_xattr(sfd, tfd, COPY_ALL_XATTRS);
2935 (void) copy_access(sfd, tfd);
2936 (void) copy_times(sfd, tfd, 0);
2937 }
2938 }
2939
2940 return 0;
2941 }
2942
2943 static int do_make_directories(Partition *p, const char *fs) {
2944 int r;
2945
2946 assert(p);
2947 assert(fs);
2948
2949 STRV_FOREACH(d, p->make_directories) {
2950
2951 r = mkdir_p_root(fs, *d, UID_INVALID, GID_INVALID, 0755);
2952 if (r < 0)
2953 return log_error_errno(r, "Failed to create directory '%s' in file system: %m", *d);
2954 }
2955
2956 return 0;
2957 }
2958
2959 static int partition_populate(Partition *p, const char *node) {
2960 int r;
2961
2962 assert(p);
2963 assert(node);
2964
2965 if (strv_isempty(p->copy_files) && strv_isempty(p->make_directories))
2966 return 0;
2967
2968 log_info("Populating partition %" PRIu64 " with files.", p->partno);
2969
2970 /* We copy in a child process, since we have to mount the fs for that, and we don't want that fs to
2971 * appear in the host namespace. Hence we fork a child that has its own file system namespace and
2972 * detached mount propagation. */
2973
2974 r = safe_fork("(sd-copy)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
2975 if (r < 0)
2976 return r;
2977 if (r == 0) {
2978 static const char fs[] = "/run/systemd/mount-root";
2979 /* This is a child process with its own mount namespace and propagation to host turned off */
2980
2981 r = mkdir_p(fs, 0700);
2982 if (r < 0) {
2983 log_error_errno(r, "Failed to create mount point: %m");
2984 _exit(EXIT_FAILURE);
2985 }
2986
2987 if (mount_nofollow_verbose(LOG_ERR, node, fs, p->format, MS_NOATIME|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL) < 0)
2988 _exit(EXIT_FAILURE);
2989
2990 if (do_copy_files(p, fs) < 0)
2991 _exit(EXIT_FAILURE);
2992
2993 if (do_make_directories(p, fs) < 0)
2994 _exit(EXIT_FAILURE);
2995
2996 r = syncfs_path(AT_FDCWD, fs);
2997 if (r < 0) {
2998 log_error_errno(r, "Failed to synchronize written files: %m");
2999 _exit(EXIT_FAILURE);
3000 }
3001
3002 _exit(EXIT_SUCCESS);
3003 }
3004
3005 log_info("Successfully populated partition %" PRIu64 " with files.", p->partno);
3006 return 0;
3007 }
3008
3009 static int context_mkfs(Context *context) {
3010 int fd = -1, r;
3011
3012 assert(context);
3013
3014 /* Make a file system */
3015
3016 LIST_FOREACH(partitions, p, context->partitions) {
3017 _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
3018 _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
3019 _cleanup_free_ char *encrypted = NULL;
3020 _cleanup_close_ int encrypted_dev_fd = -1;
3021 const char *fsdev;
3022 sd_id128_t fs_uuid;
3023
3024 if (p->dropped)
3025 continue;
3026
3027 if (PARTITION_EXISTS(p)) /* Never format existing partitions */
3028 continue;
3029
3030 if (!p->format)
3031 continue;
3032
3033 assert(p->offset != UINT64_MAX);
3034 assert(p->new_size != UINT64_MAX);
3035
3036 if (fd < 0)
3037 assert_se((fd = fdisk_get_devfd(context->fdisk_context)) >= 0);
3038
3039 /* Loopback block devices are not only useful to turn regular files into block devices, but
3040 * also to cut out sections of block devices into new block devices. */
3041
3042 r = loop_device_make(fd, O_RDWR, p->offset, p->new_size, 0, &d);
3043 if (r < 0)
3044 return log_error_errno(r, "Failed to make loopback device of future partition %" PRIu64 ": %m", p->partno);
3045
3046 r = loop_device_flock(d, LOCK_EX);
3047 if (r < 0)
3048 return log_error_errno(r, "Failed to lock loopback device: %m");
3049
3050 if (p->encrypt != ENCRYPT_OFF) {
3051 r = partition_encrypt(context, p, d->node, &cd, &encrypted, &encrypted_dev_fd);
3052 if (r < 0)
3053 return log_error_errno(r, "Failed to encrypt device: %m");
3054
3055 if (flock(encrypted_dev_fd, LOCK_EX) < 0)
3056 return log_error_errno(errno, "Failed to lock LUKS device: %m");
3057
3058 fsdev = encrypted;
3059 } else
3060 fsdev = d->node;
3061
3062 log_info("Formatting future partition %" PRIu64 ".", p->partno);
3063
3064 /* Calculate the UUID for the file system as HMAC-SHA256 of the string "file-system-uuid",
3065 * keyed off the partition UUID. */
3066 r = derive_uuid(p->new_uuid, "file-system-uuid", &fs_uuid);
3067 if (r < 0)
3068 return r;
3069
3070 r = make_filesystem(fsdev, p->format, strempty(p->new_label), fs_uuid, arg_discard);
3071 if (r < 0) {
3072 encrypted_dev_fd = safe_close(encrypted_dev_fd);
3073 (void) deactivate_luks(cd, encrypted);
3074 return r;
3075 }
3076
3077 log_info("Successfully formatted future partition %" PRIu64 ".", p->partno);
3078
3079 /* The file system is now created, no need to delay udev further */
3080 if (p->encrypt != ENCRYPT_OFF)
3081 if (flock(encrypted_dev_fd, LOCK_UN) < 0)
3082 return log_error_errno(errno, "Failed to unlock LUKS device: %m");
3083
3084 r = partition_populate(p, fsdev);
3085 if (r < 0) {
3086 encrypted_dev_fd = safe_close(encrypted_dev_fd);
3087 (void) deactivate_luks(cd, encrypted);
3088 return r;
3089 }
3090
3091 /* Note that we always sync explicitly here, since mkfs.fat doesn't do that on its own, and
3092 * if we don't sync before detaching a block device the in-flight sectors possibly won't hit
3093 * the disk. */
3094
3095 if (p->encrypt != ENCRYPT_OFF) {
3096 if (fsync(encrypted_dev_fd) < 0)
3097 return log_error_errno(errno, "Failed to synchronize LUKS volume: %m");
3098 encrypted_dev_fd = safe_close(encrypted_dev_fd);
3099
3100 r = deactivate_luks(cd, encrypted);
3101 if (r < 0)
3102 return r;
3103
3104 sym_crypt_free(cd);
3105 cd = NULL;
3106 }
3107
3108 r = loop_device_sync(d);
3109 if (r < 0)
3110 return log_error_errno(r, "Failed to sync loopback device: %m");
3111 }
3112
3113 return 0;
3114 }
3115
3116 static int partition_acquire_uuid(Context *context, Partition *p, sd_id128_t *ret) {
3117 struct {
3118 sd_id128_t type_uuid;
3119 uint64_t counter;
3120 } _packed_ plaintext = {};
3121 union {
3122 uint8_t md[SHA256_DIGEST_SIZE];
3123 sd_id128_t id;
3124 } result;
3125
3126 uint64_t k = 0;
3127 int r;
3128
3129 assert(context);
3130 assert(p);
3131 assert(ret);
3132
3133 /* Calculate a good UUID for the indicated partition. We want a certain degree of reproducibility,
3134 * hence we won't generate the UUIDs randomly. Instead we use a cryptographic hash (precisely:
3135 * HMAC-SHA256) to derive them from a single seed. The seed is generally the machine ID of the
3136 * installation we are processing, but if random behaviour is desired can be random, too. We use the
3137 * seed value as key for the HMAC (since the machine ID is something we generally don't want to leak)
3138 * and the partition type as plaintext. The partition type is suffixed with a counter (only for the
3139 * second and later partition of the same type) if we have more than one partition of the same
3140 * time. Or in other words:
3141 *
3142 * With:
3143 * SEED := /etc/machine-id
3144 *
3145 * If first partition instance of type TYPE_UUID:
3146 * PARTITION_UUID := HMAC-SHA256(SEED, TYPE_UUID)
3147 *
3148 * For all later partition instances of type TYPE_UUID with INSTANCE being the LE64 encoded instance number:
3149 * PARTITION_UUID := HMAC-SHA256(SEED, TYPE_UUID || INSTANCE)
3150 */
3151
3152 LIST_FOREACH(partitions, q, context->partitions) {
3153 if (p == q)
3154 break;
3155
3156 if (!sd_id128_equal(p->type_uuid, q->type_uuid))
3157 continue;
3158
3159 k++;
3160 }
3161
3162 plaintext.type_uuid = p->type_uuid;
3163 plaintext.counter = htole64(k);
3164
3165 hmac_sha256(context->seed.bytes, sizeof(context->seed.bytes),
3166 &plaintext,
3167 k == 0 ? sizeof(sd_id128_t) : sizeof(plaintext),
3168 result.md);
3169
3170 /* Take the first half, mark it as v4 UUID */
3171 assert_cc(sizeof(result.md) == sizeof(result.id) * 2);
3172 result.id = id128_make_v4_uuid(result.id);
3173
3174 /* Ensure this partition UUID is actually unique, and there's no remaining partition from an earlier run? */
3175 LIST_FOREACH(partitions, q, context->partitions) {
3176 if (p == q)
3177 continue;
3178
3179 if (sd_id128_in_set(result.id, q->current_uuid, q->new_uuid)) {
3180 log_warning("Partition UUID calculated from seed for partition %" PRIu64 " already used, reverting to randomized UUID.", p->partno);
3181
3182 r = sd_id128_randomize(&result.id);
3183 if (r < 0)
3184 return log_error_errno(r, "Failed to generate randomized UUID: %m");
3185
3186 break;
3187 }
3188 }
3189
3190 *ret = result.id;
3191 return 0;
3192 }
3193
3194 static int partition_acquire_label(Context *context, Partition *p, char **ret) {
3195 _cleanup_free_ char *label = NULL;
3196 const char *prefix;
3197 unsigned k = 1;
3198
3199 assert(context);
3200 assert(p);
3201 assert(ret);
3202
3203 prefix = gpt_partition_type_uuid_to_string(p->type_uuid);
3204 if (!prefix)
3205 prefix = "linux";
3206
3207 for (;;) {
3208 const char *ll = label ?: prefix;
3209 bool retry = false;
3210
3211 LIST_FOREACH(partitions, q, context->partitions) {
3212 if (p == q)
3213 break;
3214
3215 if (streq_ptr(ll, q->current_label) ||
3216 streq_ptr(ll, q->new_label)) {
3217 retry = true;
3218 break;
3219 }
3220 }
3221
3222 if (!retry)
3223 break;
3224
3225 label = mfree(label);
3226 if (asprintf(&label, "%s-%u", prefix, ++k) < 0)
3227 return log_oom();
3228 }
3229
3230 if (!label) {
3231 label = strdup(prefix);
3232 if (!label)
3233 return log_oom();
3234 }
3235
3236 *ret = TAKE_PTR(label);
3237 return 0;
3238 }
3239
3240 static int context_acquire_partition_uuids_and_labels(Context *context) {
3241 int r;
3242
3243 assert(context);
3244
3245 LIST_FOREACH(partitions, p, context->partitions) {
3246 /* Never touch foreign partitions */
3247 if (PARTITION_IS_FOREIGN(p)) {
3248 p->new_uuid = p->current_uuid;
3249
3250 if (p->current_label) {
3251 r = free_and_strdup_warn(&p->new_label, strempty(p->current_label));
3252 if (r < 0)
3253 return r;
3254 }
3255
3256 continue;
3257 }
3258
3259 if (!sd_id128_is_null(p->current_uuid))
3260 p->new_uuid = p->current_uuid; /* Never change initialized UUIDs */
3261 else if (sd_id128_is_null(p->new_uuid)) {
3262 /* Not explicitly set by user! */
3263 r = partition_acquire_uuid(context, p, &p->new_uuid);
3264 if (r < 0)
3265 return r;
3266 }
3267
3268 if (!isempty(p->current_label)) {
3269 /* never change initialized labels */
3270 r = free_and_strdup_warn(&p->new_label, p->current_label);
3271 if (r < 0)
3272 return r;
3273 } else if (!p->new_label) {
3274 /* Not explicitly set by user! */
3275
3276 r = partition_acquire_label(context, p, &p->new_label);
3277 if (r < 0)
3278 return r;
3279 }
3280 }
3281
3282 return 0;
3283 }
3284
3285 static int set_gpt_flags(struct fdisk_partition *q, uint64_t flags) {
3286 _cleanup_free_ char *a = NULL;
3287
3288 for (unsigned i = 0; i < sizeof(flags) * 8; i++) {
3289 uint64_t bit = UINT64_C(1) << i;
3290 char buf[DECIMAL_STR_MAX(unsigned)+1];
3291
3292 if (!FLAGS_SET(flags, bit))
3293 continue;
3294
3295 xsprintf(buf, "%u", i);
3296 if (!strextend_with_separator(&a, ",", buf))
3297 return -ENOMEM;
3298 }
3299
3300 return fdisk_partition_set_attrs(q, a);
3301 }
3302
3303 static uint64_t partition_merge_flags(Partition *p) {
3304 uint64_t f;
3305
3306 assert(p);
3307
3308 f = p->gpt_flags;
3309
3310 if (p->no_auto >= 0) {
3311 if (gpt_partition_type_knows_no_auto(p->type_uuid))
3312 SET_FLAG(f, GPT_FLAG_NO_AUTO, p->no_auto);
3313 else {
3314 char buffer[SD_ID128_UUID_STRING_MAX];
3315 log_warning("Configured NoAuto=%s for partition type '%s' that doesn't support it, ignoring.",
3316 yes_no(p->no_auto),
3317 gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer));
3318 }
3319 }
3320
3321 if (p->read_only >= 0) {
3322 if (gpt_partition_type_knows_read_only(p->type_uuid))
3323 SET_FLAG(f, GPT_FLAG_READ_ONLY, p->read_only);
3324 else {
3325 char buffer[SD_ID128_UUID_STRING_MAX];
3326 log_warning("Configured ReadOnly=%s for partition type '%s' that doesn't support it, ignoring.",
3327 yes_no(p->read_only),
3328 gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer));
3329 }
3330 }
3331
3332 if (p->growfs >= 0) {
3333 if (gpt_partition_type_knows_growfs(p->type_uuid))
3334 SET_FLAG(f, GPT_FLAG_GROWFS, p->growfs);
3335 else {
3336 char buffer[SD_ID128_UUID_STRING_MAX];
3337 log_warning("Configured GrowFileSystem=%s for partition type '%s' that doesn't support it, ignoring.",
3338 yes_no(p->growfs),
3339 gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer));
3340 }
3341 }
3342
3343 return f;
3344 }
3345
3346 static int context_mangle_partitions(Context *context) {
3347 int r;
3348
3349 assert(context);
3350
3351 LIST_FOREACH(partitions, p, context->partitions) {
3352 if (p->dropped)
3353 continue;
3354
3355 assert(p->new_size != UINT64_MAX);
3356 assert(p->offset != UINT64_MAX);
3357 assert(p->partno != UINT64_MAX);
3358
3359 if (PARTITION_EXISTS(p)) {
3360 bool changed = false;
3361
3362 assert(p->current_partition);
3363
3364 if (p->new_size != p->current_size) {
3365 assert(p->new_size >= p->current_size);
3366 assert(p->new_size % context->sector_size == 0);
3367
3368 r = fdisk_partition_size_explicit(p->current_partition, true);
3369 if (r < 0)
3370 return log_error_errno(r, "Failed to enable explicit sizing: %m");
3371
3372 r = fdisk_partition_set_size(p->current_partition, p->new_size / context->sector_size);
3373 if (r < 0)
3374 return log_error_errno(r, "Failed to grow partition: %m");
3375
3376 log_info("Growing existing partition %" PRIu64 ".", p->partno);
3377 changed = true;
3378 }
3379
3380 if (!sd_id128_equal(p->new_uuid, p->current_uuid)) {
3381 assert(!sd_id128_is_null(p->new_uuid));
3382
3383 r = fdisk_partition_set_uuid(p->current_partition, SD_ID128_TO_UUID_STRING(p->new_uuid));
3384 if (r < 0)
3385 return log_error_errno(r, "Failed to set partition UUID: %m");
3386
3387 log_info("Initializing UUID of existing partition %" PRIu64 ".", p->partno);
3388 changed = true;
3389 }
3390
3391 if (!streq_ptr(p->new_label, p->current_label)) {
3392 r = fdisk_partition_set_name(p->current_partition, strempty(p->new_label));
3393 if (r < 0)
3394 return log_error_errno(r, "Failed to set partition label: %m");
3395
3396 log_info("Setting partition label of existing partition %" PRIu64 ".", p->partno);
3397 changed = true;
3398 }
3399
3400 if (changed) {
3401 assert(!PARTITION_IS_FOREIGN(p)); /* never touch foreign partitions */
3402
3403 r = fdisk_set_partition(context->fdisk_context, p->partno, p->current_partition);
3404 if (r < 0)
3405 return log_error_errno(r, "Failed to update partition: %m");
3406 }
3407 } else {
3408 _cleanup_(fdisk_unref_partitionp) struct fdisk_partition *q = NULL;
3409 _cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL;
3410
3411 assert(!p->new_partition);
3412 assert(p->offset % context->sector_size == 0);
3413 assert(p->new_size % context->sector_size == 0);
3414 assert(!sd_id128_is_null(p->new_uuid));
3415 assert(p->new_label);
3416
3417 t = fdisk_new_parttype();
3418 if (!t)
3419 return log_oom();
3420
3421 r = fdisk_parttype_set_typestr(t, SD_ID128_TO_UUID_STRING(p->type_uuid));
3422 if (r < 0)
3423 return log_error_errno(r, "Failed to initialize partition type: %m");
3424
3425 q = fdisk_new_partition();
3426 if (!q)
3427 return log_oom();
3428
3429 r = fdisk_partition_set_type(q, t);
3430 if (r < 0)
3431 return log_error_errno(r, "Failed to set partition type: %m");
3432
3433 r = fdisk_partition_size_explicit(q, true);
3434 if (r < 0)
3435 return log_error_errno(r, "Failed to enable explicit sizing: %m");
3436
3437 r = fdisk_partition_set_start(q, p->offset / context->sector_size);
3438 if (r < 0)
3439 return log_error_errno(r, "Failed to position partition: %m");
3440
3441 r = fdisk_partition_set_size(q, p->new_size / context->sector_size);
3442 if (r < 0)
3443 return log_error_errno(r, "Failed to grow partition: %m");
3444
3445 r = fdisk_partition_set_partno(q, p->partno);
3446 if (r < 0)
3447 return log_error_errno(r, "Failed to set partition number: %m");
3448
3449 r = fdisk_partition_set_uuid(q, SD_ID128_TO_UUID_STRING(p->new_uuid));
3450 if (r < 0)
3451 return log_error_errno(r, "Failed to set partition UUID: %m");
3452
3453 r = fdisk_partition_set_name(q, strempty(p->new_label));
3454 if (r < 0)
3455 return log_error_errno(r, "Failed to set partition label: %m");
3456
3457 /* Merge the no auto + read only + growfs setting with the literal flags, and set them for the partition */
3458 r = set_gpt_flags(q, partition_merge_flags(p));
3459 if (r < 0)
3460 return log_error_errno(r, "Failed to set GPT partition flags: %m");
3461
3462 log_info("Adding new partition %" PRIu64 " to partition table.", p->partno);
3463
3464 r = fdisk_add_partition(context->fdisk_context, q, NULL);
3465 if (r < 0)
3466 return log_error_errno(r, "Failed to add partition: %m");
3467
3468 assert(!p->new_partition);
3469 p->new_partition = TAKE_PTR(q);
3470 }
3471 }
3472
3473 return 0;
3474 }
3475
3476 static int context_write_partition_table(
3477 Context *context,
3478 const char *node,
3479 bool from_scratch) {
3480
3481 _cleanup_(fdisk_unref_tablep) struct fdisk_table *original_table = NULL;
3482 int capable, r;
3483
3484 assert(context);
3485
3486 if (arg_pretty > 0 ||
3487 (arg_pretty < 0 && isatty(STDOUT_FILENO) > 0) ||
3488 !FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF)) {
3489
3490 (void) context_dump_partitions(context, node);
3491
3492 if (arg_json_format_flags & JSON_FORMAT_OFF) {
3493 putc('\n', stdout);
3494 (void) context_dump_partition_bar(context, node);
3495 putc('\n', stdout);
3496 }
3497
3498 fflush(stdout);
3499 }
3500
3501 if (!from_scratch && !context_changed(context)) {
3502 log_info("No changes.");
3503 return 0;
3504 }
3505
3506 if (arg_dry_run) {
3507 log_notice("Refusing to repartition, please re-run with --dry-run=no.");
3508 return 0;
3509 }
3510
3511 log_info("Applying changes.");
3512
3513 if (from_scratch) {
3514 r = context_wipe_range(context, 0, context->total);
3515 if (r < 0)
3516 return r;
3517
3518 log_info("Wiped block device.");
3519
3520 r = context_discard_range(context, 0, context->total);
3521 if (r == -EOPNOTSUPP)
3522 log_info("Storage does not support discard, not discarding entire block device data.");
3523 else if (r < 0)
3524 return log_error_errno(r, "Failed to discard entire block device: %m");
3525 else if (r > 0)
3526 log_info("Discarded entire block device.");
3527 }
3528
3529 r = fdisk_get_partitions(context->fdisk_context, &original_table);
3530 if (r < 0)
3531 return log_error_errno(r, "Failed to acquire partition table: %m");
3532
3533 /* Wipe fs signatures and discard sectors where the new partitions are going to be placed and in the
3534 * gaps between partitions, just to be sure. */
3535 r = context_wipe_and_discard(context, from_scratch);
3536 if (r < 0)
3537 return r;
3538
3539 r = context_copy_blocks(context);
3540 if (r < 0)
3541 return r;
3542
3543 r = context_mkfs(context);
3544 if (r < 0)
3545 return r;
3546
3547 r = context_mangle_partitions(context);
3548 if (r < 0)
3549 return r;
3550
3551 log_info("Writing new partition table.");
3552
3553 r = fdisk_write_disklabel(context->fdisk_context);
3554 if (r < 0)
3555 return log_error_errno(r, "Failed to write partition table: %m");
3556
3557 capable = blockdev_partscan_enabled(fdisk_get_devfd(context->fdisk_context));
3558 if (capable == -ENOTBLK)
3559 log_debug("Not telling kernel to reread partition table, since we are not operating on a block device.");
3560 else if (capable < 0)
3561 return log_error_errno(capable, "Failed to check if block device supports partition scanning: %m");
3562 else if (capable > 0) {
3563 log_info("Telling kernel to reread partition table.");
3564
3565 if (from_scratch)
3566 r = fdisk_reread_partition_table(context->fdisk_context);
3567 else
3568 r = fdisk_reread_changes(context->fdisk_context, original_table);
3569 if (r < 0)
3570 return log_error_errno(r, "Failed to reread partition table: %m");
3571 } else
3572 log_notice("Not telling kernel to reread partition table, because selected image does not support kernel partition block devices.");
3573
3574 log_info("All done.");
3575
3576 return 0;
3577 }
3578
3579 static int context_read_seed(Context *context, const char *root) {
3580 int r;
3581
3582 assert(context);
3583
3584 if (!sd_id128_is_null(context->seed))
3585 return 0;
3586
3587 if (!arg_randomize) {
3588 _cleanup_close_ int fd = -1;
3589
3590 fd = chase_symlinks_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC, NULL);
3591 if (fd == -ENOENT)
3592 log_info("No machine ID set, using randomized partition UUIDs.");
3593 else if (fd < 0)
3594 return log_error_errno(fd, "Failed to determine machine ID of image: %m");
3595 else {
3596 r = id128_read_fd(fd, ID128_PLAIN_OR_UNINIT, &context->seed);
3597 if (r == -ENOMEDIUM)
3598 log_info("No machine ID set, using randomized partition UUIDs.");
3599 else if (r < 0)
3600 return log_error_errno(r, "Failed to parse machine ID of image: %m");
3601
3602 return 0;
3603 }
3604 }
3605
3606 r = sd_id128_randomize(&context->seed);
3607 if (r < 0)
3608 return log_error_errno(r, "Failed to generate randomized seed: %m");
3609
3610 return 0;
3611 }
3612
3613 static int context_factory_reset(Context *context, bool from_scratch) {
3614 size_t n = 0;
3615 int r;
3616
3617 assert(context);
3618
3619 if (arg_factory_reset <= 0)
3620 return 0;
3621
3622 if (from_scratch) /* Nothing to reset if we start from scratch */
3623 return 0;
3624
3625 if (arg_dry_run) {
3626 log_notice("Refusing to factory reset, please re-run with --dry-run=no.");
3627 return 0;
3628 }
3629
3630 log_info("Applying factory reset.");
3631
3632 LIST_FOREACH(partitions, p, context->partitions) {
3633
3634 if (!p->factory_reset || !PARTITION_EXISTS(p))
3635 continue;
3636
3637 assert(p->partno != UINT64_MAX);
3638
3639 log_info("Removing partition %" PRIu64 " for factory reset.", p->partno);
3640
3641 r = fdisk_delete_partition(context->fdisk_context, p->partno);
3642 if (r < 0)
3643 return log_error_errno(r, "Failed to remove partition %" PRIu64 ": %m", p->partno);
3644
3645 n++;
3646 }
3647
3648 if (n == 0) {
3649 log_info("Factory reset requested, but no partitions to delete found.");
3650 return 0;
3651 }
3652
3653 r = fdisk_write_disklabel(context->fdisk_context);
3654 if (r < 0)
3655 return log_error_errno(r, "Failed to write disk label: %m");
3656
3657 log_info("Successfully deleted %zu partitions.", n);
3658 return 1;
3659 }
3660
3661 static int context_can_factory_reset(Context *context) {
3662 assert(context);
3663
3664 LIST_FOREACH(partitions, p, context->partitions)
3665 if (p->factory_reset && PARTITION_EXISTS(p))
3666 return true;
3667
3668 return false;
3669 }
3670
3671 static int resolve_copy_blocks_auto_candidate(
3672 dev_t partition_devno,
3673 sd_id128_t partition_type_uuid,
3674 dev_t restrict_devno,
3675 sd_id128_t *ret_uuid) {
3676
3677 _cleanup_(blkid_free_probep) blkid_probe b = NULL;
3678 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
3679 _cleanup_close_ int fd = -1;
3680 const char *pttype, *t, *p;
3681 sd_id128_t pt_parsed, u;
3682 blkid_partition pp;
3683 dev_t whole_devno;
3684 blkid_partlist pl;
3685 int r;
3686
3687 /* Checks if the specified partition has the specified GPT type UUID, and is located on the specified
3688 * 'restrict_devno' device. The type check is particularly relevant if we have Verity volume which is
3689 * backed by two separate partitions: the data and the hash partitions, and we need to find the right
3690 * one of the two. */
3691
3692 r = block_get_whole_disk(partition_devno, &whole_devno);
3693 if (r < 0)
3694 return log_error_errno(
3695 r,
3696 "Unable to determine containing block device of partition %u:%u: %m",
3697 major(partition_devno), minor(partition_devno));
3698
3699 if (restrict_devno != (dev_t) -1 &&
3700 restrict_devno != whole_devno)
3701 return log_error_errno(
3702 SYNTHETIC_ERRNO(EPERM),
3703 "Partition %u:%u is located outside of block device %u:%u, refusing.",
3704 major(partition_devno), minor(partition_devno),
3705 major(restrict_devno), minor(restrict_devno));
3706
3707 r = sd_device_new_from_devnum(&dev, 'b', whole_devno);
3708 if (r < 0)
3709 return log_error_errno(r, "Failed to create sd-device for block device %u:%u: %m",
3710 major(whole_devno), minor(whole_devno));
3711
3712 r = sd_device_get_devname(dev, &p);
3713 if (r < 0)
3714 return log_error_errno(r, "Failed to get name of block device %u:%u: %m",
3715 major(whole_devno), minor(whole_devno));
3716
3717 fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
3718 if (fd < 0)
3719 return log_error_errno(fd, "Failed to open block device %s: %m", p);
3720
3721 b = blkid_new_probe();
3722 if (!b)
3723 return log_oom();
3724
3725 errno = 0;
3726 r = blkid_probe_set_device(b, fd, 0, 0);
3727 if (r != 0)
3728 return log_error_errno(errno_or_else(ENOMEM), "Failed to open block device '%s': %m", p);
3729
3730 (void) blkid_probe_enable_partitions(b, 1);
3731 (void) blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
3732
3733 errno = 0;
3734 r = blkid_do_safeprobe(b);
3735 if (IN_SET(r, -2, 1)) { /* nothing found or ambiguous result */
3736 log_debug("Didn't find partition table on block device '%s'.", p);
3737 return false;
3738 }
3739 if (r != 0)
3740 return log_error_errno(errno_or_else(EIO), "Unable to probe for partition table of '%s': %m", p);
3741
3742 (void) blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
3743 if (!streq_ptr(pttype, "gpt")) {
3744 log_debug("Didn't find a GPT partition table on '%s'.", p);
3745 return false;
3746 }
3747
3748 errno = 0;
3749 pl = blkid_probe_get_partitions(b);
3750 if (!pl)
3751 return log_error_errno(errno_or_else(EIO), "Unable read partition table of '%s': %m", p);
3752 errno = 0;
3753
3754 pp = blkid_partlist_devno_to_partition(pl, partition_devno);
3755 if (!pp) {
3756 log_debug("Partition %u:%u has no matching partition table entry on '%s'.",
3757 major(partition_devno), minor(partition_devno), p);
3758 return false;
3759 }
3760
3761 t = blkid_partition_get_type_string(pp);
3762 if (isempty(t)) {
3763 log_debug("Partition %u:%u has no type on '%s'.",
3764 major(partition_devno), minor(partition_devno), p);
3765 return false;
3766 }
3767
3768 r = sd_id128_from_string(t, &pt_parsed);
3769 if (r < 0) {
3770 log_debug_errno(r, "Failed to parse partition type \"%s\": %m", t);
3771 return false;
3772 }
3773
3774 if (!sd_id128_equal(pt_parsed, partition_type_uuid)) {
3775 log_debug("Partition %u:%u has non-matching partition type " SD_ID128_FORMAT_STR " (needed: " SD_ID128_FORMAT_STR "), ignoring.",
3776 major(partition_devno), minor(partition_devno),
3777 SD_ID128_FORMAT_VAL(pt_parsed), SD_ID128_FORMAT_VAL(partition_type_uuid));
3778 return false;
3779 }
3780
3781 t = blkid_partition_get_uuid(pp);
3782 if (isempty(t)) {
3783 log_debug("Partition %u:%u has no UUID.",
3784 major(partition_devno), minor(partition_devno));
3785 return false;
3786 }
3787
3788 r = sd_id128_from_string(t, &u);
3789 if (r < 0) {
3790 log_debug_errno(r, "Failed to parse partition UUID \"%s\": %m", t);
3791 return false;
3792 }
3793
3794 log_debug("Automatically found partition %u:%u of right type " SD_ID128_FORMAT_STR ".",
3795 major(partition_devno), minor(partition_devno),
3796 SD_ID128_FORMAT_VAL(pt_parsed));
3797
3798 if (ret_uuid)
3799 *ret_uuid = u;
3800
3801 return true;
3802 }
3803
3804 static int find_backing_devno(
3805 const char *path,
3806 const char *root,
3807 dev_t *ret) {
3808
3809 _cleanup_free_ char *resolved = NULL;
3810 int r;
3811
3812 assert(path);
3813
3814 r = chase_symlinks(path, root, CHASE_PREFIX_ROOT, &resolved, NULL);
3815 if (r < 0)
3816 return r;
3817
3818 r = path_is_mount_point(resolved, NULL, 0);
3819 if (r < 0)
3820 return r;
3821 if (r == 0) /* Not a mount point, then it's not a partition of its own, let's not automatically use it. */
3822 return -ENOENT;
3823
3824 r = get_block_device(resolved, ret);
3825 if (r < 0)
3826 return r;
3827 if (r == 0) /* Not backed by physical file system, we can't use this */
3828 return -ENOENT;
3829
3830 return 0;
3831 }
3832
3833 static int resolve_copy_blocks_auto(
3834 sd_id128_t type_uuid,
3835 const char *root,
3836 dev_t restrict_devno,
3837 dev_t *ret_devno,
3838 sd_id128_t *ret_uuid) {
3839
3840 const char *try1 = NULL, *try2 = NULL;
3841 char p[SYS_BLOCK_PATH_MAX("/slaves")];
3842 _cleanup_(closedirp) DIR *d = NULL;
3843 sd_id128_t found_uuid = SD_ID128_NULL;
3844 dev_t devno, found = 0;
3845 int r;
3846
3847 /* Enforce some security restrictions: CopyBlocks=auto should not be an avenue to get outside of the
3848 * --root=/--image= confinement. Specifically, refuse CopyBlocks= in combination with --root= at all,
3849 * and restrict block device references in the --image= case to loopback block device we set up.
3850 *
3851 * restrict_devno contain the dev_t of the loop back device we operate on in case of --image=, and
3852 * thus declares which device (and its partition subdevices) we shall limit access to. If
3853 * restrict_devno is zero no device probing access shall be allowed at all (used for --root=) and if
3854 * it is (dev_t) -1 then free access shall be allowed (if neither switch is used). */
3855
3856 if (restrict_devno == 0)
3857 return log_error_errno(SYNTHETIC_ERRNO(EPERM),
3858 "Automatic discovery of backing block devices not permitted in --root= mode, refusing.");
3859
3860 /* Handles CopyBlocks=auto, and finds the right source partition to copy from. We look for matching
3861 * partitions in the host, using the appropriate directory as key and ensuring that the partition
3862 * type matches. */
3863
3864 if (gpt_partition_type_is_root(type_uuid))
3865 try1 = "/";
3866 else if (gpt_partition_type_is_usr(type_uuid))
3867 try1 = "/usr/";
3868 else if (gpt_partition_type_is_root_verity(type_uuid))
3869 try1 = "/";
3870 else if (gpt_partition_type_is_usr_verity(type_uuid))
3871 try1 = "/usr/";
3872 else if (sd_id128_equal(type_uuid, GPT_ESP)) {
3873 try1 = "/efi/";
3874 try2 = "/boot/";
3875 } else if (sd_id128_equal(type_uuid, GPT_XBOOTLDR))
3876 try1 = "/boot/";
3877 else
3878 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3879 "Partition type " SD_ID128_FORMAT_STR " not supported from automatic source block device discovery.",
3880 SD_ID128_FORMAT_VAL(type_uuid));
3881
3882 r = find_backing_devno(try1, root, &devno);
3883 if (r == -ENOENT && try2)
3884 r = find_backing_devno(try2, root, &devno);
3885 if (r < 0)
3886 return log_error_errno(r, "Failed to resolve automatic CopyBlocks= path for partition type " SD_ID128_FORMAT_STR ", sorry: %m",
3887 SD_ID128_FORMAT_VAL(type_uuid));
3888
3889 xsprintf_sys_block_path(p, "/slaves", devno);
3890 d = opendir(p);
3891 if (d) {
3892 struct dirent *de;
3893
3894 for (;;) {
3895 _cleanup_free_ char *q = NULL, *t = NULL;
3896 sd_id128_t u;
3897 dev_t sl;
3898
3899 errno = 0;
3900 de = readdir_no_dot(d);
3901 if (!de) {
3902 if (errno != 0)
3903 return log_error_errno(errno, "Failed to read directory '%s': %m", p);
3904
3905 break;
3906 }
3907
3908 if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
3909 continue;
3910
3911 q = path_join(p, de->d_name, "/dev");
3912 if (!q)
3913 return log_oom();
3914
3915 r = read_one_line_file(q, &t);
3916 if (r < 0)
3917 return log_error_errno(r, "Failed to read %s: %m", q);
3918
3919 r = parse_devnum(t, &sl);
3920 if (r < 0) {
3921 log_debug_errno(r, "Failed to parse %s, ignoring: %m", q);
3922 continue;
3923 }
3924 if (major(sl) == 0) {
3925 log_debug_errno(r, "Device backing %s is special, ignoring: %m", q);
3926 continue;
3927 }
3928
3929 r = resolve_copy_blocks_auto_candidate(sl, type_uuid, restrict_devno, &u);
3930 if (r < 0)
3931 return r;
3932 if (r > 0) {
3933 /* We found a matching one! */
3934 if (found != 0)
3935 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
3936 "Multiple matching partitions found, refusing.");
3937
3938 found = sl;
3939 found_uuid = u;
3940 }
3941 }
3942 } else if (errno != ENOENT)
3943 return log_error_errno(errno, "Failed open %s: %m", p);
3944 else {
3945 r = resolve_copy_blocks_auto_candidate(devno, type_uuid, restrict_devno, &found_uuid);
3946 if (r < 0)
3947 return r;
3948 if (r > 0)
3949 found = devno;
3950 }
3951
3952 if (found == 0)
3953 return log_error_errno(SYNTHETIC_ERRNO(ENXIO),
3954 "Unable to automatically discover suitable partition to copy blocks from.");
3955
3956 if (ret_devno)
3957 *ret_devno = found;
3958
3959 if (ret_uuid)
3960 *ret_uuid = found_uuid;
3961
3962 return 0;
3963 }
3964
3965 static int context_open_copy_block_paths(
3966 Context *context,
3967 const char *root,
3968 dev_t restrict_devno) {
3969
3970 int r;
3971
3972 assert(context);
3973
3974 LIST_FOREACH(partitions, p, context->partitions) {
3975 _cleanup_close_ int source_fd = -1;
3976 _cleanup_free_ char *opened = NULL;
3977 sd_id128_t uuid = SD_ID128_NULL;
3978 uint64_t size;
3979 struct stat st;
3980
3981 assert(p->copy_blocks_fd < 0);
3982 assert(p->copy_blocks_size == UINT64_MAX);
3983
3984 if (PARTITION_EXISTS(p)) /* Never copy over partitions that already exist! */
3985 continue;
3986
3987 if (p->copy_blocks_path) {
3988
3989 source_fd = chase_symlinks_and_open(p->copy_blocks_path, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_NONBLOCK, &opened);
3990 if (source_fd < 0)
3991 return log_error_errno(source_fd, "Failed to open '%s': %m", p->copy_blocks_path);
3992
3993 if (fstat(source_fd, &st) < 0)
3994 return log_error_errno(errno, "Failed to stat block copy file '%s': %m", opened);
3995
3996 if (!S_ISREG(st.st_mode) && restrict_devno != (dev_t) -1)
3997 return log_error_errno(SYNTHETIC_ERRNO(EPERM),
3998 "Copying from block device node is not permitted in --image=/--root= mode, refusing.");
3999
4000 } else if (p->copy_blocks_auto) {
4001 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
4002 const char *devname;
4003 dev_t devno;
4004
4005 r = resolve_copy_blocks_auto(p->type_uuid, root, restrict_devno, &devno, &uuid);
4006 if (r < 0)
4007 return r;
4008
4009 r = sd_device_new_from_devnum(&dev, 'b', devno);
4010 if (r < 0)
4011 return log_error_errno(r, "Failed to create sd-device object for device %u:%u: %m", major(devno), minor(devno));
4012
4013 r = sd_device_get_devname(dev, &devname);
4014 if (r < 0)
4015 return log_error_errno(r, "Failed to get device name of %u:%u: %m", major(devno), minor(devno));
4016
4017 opened = strdup(devname);
4018 if (!opened)
4019 return log_oom();
4020
4021 source_fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
4022 if (source_fd < 0)
4023 return log_error_errno(source_fd, "Failed to open automatically determined source block copy device '%s': %m", opened);
4024
4025 if (fstat(source_fd, &st) < 0)
4026 return log_error_errno(errno, "Failed to stat block copy file '%s': %m", opened);
4027 } else
4028 continue;
4029
4030 if (S_ISDIR(st.st_mode)) {
4031 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
4032 const char *bdev;
4033
4034 /* If the file is a directory, automatically find the backing block device */
4035
4036 if (major(st.st_dev) != 0)
4037 r = sd_device_new_from_devnum(&dev, 'b', st.st_dev);
4038 else {
4039 dev_t devt;
4040
4041 /* Special support for btrfs */
4042
4043 r = btrfs_get_block_device_fd(source_fd, &devt);
4044 if (r == -EUCLEAN)
4045 return btrfs_log_dev_root(LOG_ERR, r, opened);
4046 if (r < 0)
4047 return log_error_errno(r, "Unable to determine backing block device of '%s': %m", opened);
4048
4049 r = sd_device_new_from_devnum(&dev, 'b', devt);
4050 }
4051 if (r < 0)
4052 return log_error_errno(r, "Failed to create sd-device object for block device backing '%s': %m", opened);
4053
4054 r = sd_device_get_devpath(dev, &bdev);
4055 if (r < 0)
4056 return log_error_errno(r, "Failed to get device name for block device backing '%s': %m", opened);
4057
4058 safe_close(source_fd);
4059
4060 source_fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
4061 if (source_fd < 0)
4062 return log_error_errno(source_fd, "Failed to open block device '%s': %m", bdev);
4063
4064 if (fstat(source_fd, &st) < 0)
4065 return log_error_errno(errno, "Failed to stat block device '%s': %m", bdev);
4066 }
4067
4068 if (S_ISREG(st.st_mode))
4069 size = st.st_size;
4070 else if (S_ISBLK(st.st_mode)) {
4071 if (ioctl(source_fd, BLKGETSIZE64, &size) != 0)
4072 return log_error_errno(errno, "Failed to determine size of block device to copy from: %m");
4073 } else
4074 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path to copy blocks from '%s' is not a regular file, block device or directory, refusing: %m", opened);
4075
4076 if (size <= 0)
4077 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File to copy bytes from '%s' has zero size, refusing.", opened);
4078 if (size % 512 != 0)
4079 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File to copy bytes from '%s' has size that is not multiple of 512, refusing.", opened);
4080
4081 p->copy_blocks_fd = TAKE_FD(source_fd);
4082 p->copy_blocks_size = size;
4083
4084 free_and_replace(p->copy_blocks_path, opened);
4085
4086 /* When copying from an existing partition copy that partitions UUID if none is configured explicitly */
4087 if (sd_id128_is_null(p->new_uuid) && !sd_id128_is_null(uuid))
4088 p->new_uuid = uuid;
4089 }
4090
4091 return 0;
4092 }
4093
4094 static int help(void) {
4095 _cleanup_free_ char *link = NULL;
4096 int r;
4097
4098 r = terminal_urlify_man("systemd-repart", "1", &link);
4099 if (r < 0)
4100 return log_oom();
4101
4102 printf("%s [OPTIONS...] [DEVICE]\n"
4103 "\n%sGrow and add partitions to partition table.%s\n\n"
4104 " -h --help Show this help\n"
4105 " --version Show package version\n"
4106 " --no-pager Do not pipe output into a pager\n"
4107 " --no-legend Do not show the headers and footers\n"
4108 " --dry-run=BOOL Whether to run dry-run operation\n"
4109 " --empty=MODE One of refuse, allow, require, force, create; controls\n"
4110 " how to handle empty disks lacking partition tables\n"
4111 " --discard=BOOL Whether to discard backing blocks for new partitions\n"
4112 " --pretty=BOOL Whether to show pretty summary before doing changes\n"
4113 " --factory-reset=BOOL Whether to remove data partitions before recreating\n"
4114 " them\n"
4115 " --can-factory-reset Test whether factory reset is defined\n"
4116 " --root=PATH Operate relative to root path\n"
4117 " --image=PATH Operate relative to image file\n"
4118 " --definitions=DIR Find partition definitions in specified directory\n"
4119 " --key-file=PATH Key to use when encrypting partitions\n"
4120 " --tpm2-device=PATH Path to TPM2 device node to use\n"
4121 " --tpm2-pcrs=PCR1+PCR2+PCR3+…\n"
4122 " TPM2 PCR indexes to use for TPM2 enrollment\n"
4123 " --seed=UUID 128bit seed UUID to derive all UUIDs from\n"
4124 " --size=BYTES Grow loopback file to specified size\n"
4125 " --json=pretty|short|off\n"
4126 " Generate JSON output\n"
4127 "\nSee the %s for details.\n",
4128 program_invocation_short_name,
4129 ansi_highlight(),
4130 ansi_normal(),
4131 link);
4132
4133 return 0;
4134 }
4135
4136 static int parse_argv(int argc, char *argv[]) {
4137
4138 enum {
4139 ARG_VERSION = 0x100,
4140 ARG_NO_PAGER,
4141 ARG_NO_LEGEND,
4142 ARG_DRY_RUN,
4143 ARG_EMPTY,
4144 ARG_DISCARD,
4145 ARG_FACTORY_RESET,
4146 ARG_CAN_FACTORY_RESET,
4147 ARG_ROOT,
4148 ARG_IMAGE,
4149 ARG_SEED,
4150 ARG_PRETTY,
4151 ARG_DEFINITIONS,
4152 ARG_SIZE,
4153 ARG_JSON,
4154 ARG_KEY_FILE,
4155 ARG_TPM2_DEVICE,
4156 ARG_TPM2_PCRS,
4157 };
4158
4159 static const struct option options[] = {
4160 { "help", no_argument, NULL, 'h' },
4161 { "version", no_argument, NULL, ARG_VERSION },
4162 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4163 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4164 { "dry-run", required_argument, NULL, ARG_DRY_RUN },
4165 { "empty", required_argument, NULL, ARG_EMPTY },
4166 { "discard", required_argument, NULL, ARG_DISCARD },
4167 { "factory-reset", required_argument, NULL, ARG_FACTORY_RESET },
4168 { "can-factory-reset", no_argument, NULL, ARG_CAN_FACTORY_RESET },
4169 { "root", required_argument, NULL, ARG_ROOT },
4170 { "image", required_argument, NULL, ARG_IMAGE },
4171 { "seed", required_argument, NULL, ARG_SEED },
4172 { "pretty", required_argument, NULL, ARG_PRETTY },
4173 { "definitions", required_argument, NULL, ARG_DEFINITIONS },
4174 { "size", required_argument, NULL, ARG_SIZE },
4175 { "json", required_argument, NULL, ARG_JSON },
4176 { "key-file", required_argument, NULL, ARG_KEY_FILE },
4177 { "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
4178 { "tpm2-pcrs", required_argument, NULL, ARG_TPM2_PCRS },
4179 {}
4180 };
4181
4182 int c, r, dry_run = -1;
4183
4184 assert(argc >= 0);
4185 assert(argv);
4186
4187 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
4188
4189 switch (c) {
4190
4191 case 'h':
4192 return help();
4193
4194 case ARG_VERSION:
4195 return version();
4196
4197 case ARG_NO_PAGER:
4198 arg_pager_flags |= PAGER_DISABLE;
4199 break;
4200
4201 case ARG_NO_LEGEND:
4202 arg_legend = false;
4203 break;
4204
4205 case ARG_DRY_RUN:
4206 r = parse_boolean_argument("--dry-run=", optarg, &arg_dry_run);
4207 if (r < 0)
4208 return r;
4209 break;
4210
4211 case ARG_EMPTY:
4212 if (isempty(optarg) || streq(optarg, "refuse"))
4213 arg_empty = EMPTY_REFUSE;
4214 else if (streq(optarg, "allow"))
4215 arg_empty = EMPTY_ALLOW;
4216 else if (streq(optarg, "require"))
4217 arg_empty = EMPTY_REQUIRE;
4218 else if (streq(optarg, "force"))
4219 arg_empty = EMPTY_FORCE;
4220 else if (streq(optarg, "create")) {
4221 arg_empty = EMPTY_CREATE;
4222
4223 if (dry_run < 0)
4224 dry_run = false; /* Imply --dry-run=no if we create the loopback file
4225 * anew. After all we cannot really break anyone's
4226 * partition tables that way. */
4227 } else
4228 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
4229 "Failed to parse --empty= parameter: %s", optarg);
4230 break;
4231
4232 case ARG_DISCARD:
4233 r = parse_boolean_argument("--discard=", optarg, &arg_discard);
4234 if (r < 0)
4235 return r;
4236 break;
4237
4238 case ARG_FACTORY_RESET:
4239 r = parse_boolean_argument("--factory-reset=", optarg, NULL);
4240 if (r < 0)
4241 return r;
4242 arg_factory_reset = r;
4243 break;
4244
4245 case ARG_CAN_FACTORY_RESET:
4246 arg_can_factory_reset = true;
4247 break;
4248
4249 case ARG_ROOT:
4250 r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_root);
4251 if (r < 0)
4252 return r;
4253 break;
4254
4255 case ARG_IMAGE:
4256 r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image);
4257 if (r < 0)
4258 return r;
4259 break;
4260
4261 case ARG_SEED:
4262 if (isempty(optarg)) {
4263 arg_seed = SD_ID128_NULL;
4264 arg_randomize = false;
4265 } else if (streq(optarg, "random"))
4266 arg_randomize = true;
4267 else {
4268 r = sd_id128_from_string(optarg, &arg_seed);
4269 if (r < 0)
4270 return log_error_errno(r, "Failed to parse seed: %s", optarg);
4271
4272 arg_randomize = false;
4273 }
4274
4275 break;
4276
4277 case ARG_PRETTY:
4278 r = parse_boolean_argument("--pretty=", optarg, NULL);
4279 if (r < 0)
4280 return r;
4281 arg_pretty = r;
4282 break;
4283
4284 case ARG_DEFINITIONS:
4285 r = parse_path_argument(optarg, false, &arg_definitions);
4286 if (r < 0)
4287 return r;
4288 break;
4289
4290 case ARG_SIZE: {
4291 uint64_t parsed, rounded;
4292
4293 if (streq(optarg, "auto")) {
4294 arg_size = UINT64_MAX;
4295 arg_size_auto = true;
4296 break;
4297 }
4298
4299 r = parse_size(optarg, 1024, &parsed);
4300 if (r < 0)
4301 return log_error_errno(r, "Failed to parse --size= parameter: %s", optarg);
4302
4303 rounded = round_up_size(parsed, 4096);
4304 if (rounded == 0)
4305 return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Specified image size too small, refusing.");
4306 if (rounded == UINT64_MAX)
4307 return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Specified image size too large, refusing.");
4308
4309 if (rounded != parsed)
4310 log_warning("Specified size is not a multiple of 4096, rounding up automatically. (%" PRIu64 " %s %" PRIu64 ")",
4311 parsed, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), rounded);
4312
4313 arg_size = rounded;
4314 arg_size_auto = false;
4315 break;
4316 }
4317
4318 case ARG_JSON:
4319 r = parse_json_argument(optarg, &arg_json_format_flags);
4320 if (r <= 0)
4321 return r;
4322
4323 break;
4324
4325 case ARG_KEY_FILE: {
4326 _cleanup_(erase_and_freep) char *k = NULL;
4327 size_t n = 0;
4328
4329 r = read_full_file_full(
4330 AT_FDCWD, optarg, UINT64_MAX, SIZE_MAX,
4331 READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
4332 NULL,
4333 &k, &n);
4334 if (r < 0)
4335 return log_error_errno(r, "Failed to read key file '%s': %m", optarg);
4336
4337 erase_and_free(arg_key);
4338 arg_key = TAKE_PTR(k);
4339 arg_key_size = n;
4340 break;
4341 }
4342
4343 case ARG_TPM2_DEVICE: {
4344 _cleanup_free_ char *device = NULL;
4345
4346 if (streq(optarg, "list"))
4347 return tpm2_list_devices();
4348
4349 if (!streq(optarg, "auto")) {
4350 device = strdup(optarg);
4351 if (!device)
4352 return log_oom();
4353 }
4354
4355 free(arg_tpm2_device);
4356 arg_tpm2_device = TAKE_PTR(device);
4357 break;
4358 }
4359
4360 case ARG_TPM2_PCRS: {
4361 uint32_t mask;
4362
4363 if (isempty(optarg)) {
4364 arg_tpm2_pcr_mask = 0;
4365 break;
4366 }
4367
4368 r = tpm2_parse_pcrs(optarg, &mask);
4369 if (r < 0)
4370 return r;
4371
4372 if (arg_tpm2_pcr_mask == UINT32_MAX)
4373 arg_tpm2_pcr_mask = mask;
4374 else
4375 arg_tpm2_pcr_mask |= mask;
4376
4377 break;
4378 }
4379
4380 case '?':
4381 return -EINVAL;
4382
4383 default:
4384 assert_not_reached();
4385 }
4386
4387 if (argc - optind > 1)
4388 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
4389 "Expected at most one argument, the path to the block device.");
4390
4391 if (arg_factory_reset > 0 && IN_SET(arg_empty, EMPTY_FORCE, EMPTY_REQUIRE, EMPTY_CREATE))
4392 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
4393 "Combination of --factory-reset=yes and --empty=force/--empty=require/--empty=create is invalid.");
4394
4395 if (arg_can_factory_reset)
4396 arg_dry_run = true; /* When --can-factory-reset is specified we don't make changes, hence
4397 * non-dry-run mode makes no sense. Thus, imply dry run mode so that we
4398 * open things strictly read-only. */
4399 else if (dry_run >= 0)
4400 arg_dry_run = dry_run;
4401
4402 if (arg_empty == EMPTY_CREATE && (arg_size == UINT64_MAX && !arg_size_auto))
4403 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
4404 "If --empty=create is specified, --size= must be specified, too.");
4405
4406 if (arg_image && arg_root)
4407 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
4408 else if (!arg_image && !arg_root && in_initrd()) {
4409
4410 /* By default operate on /sysusr/ or /sysroot/ when invoked in the initrd. We prefer the
4411 * former, if it is mounted, so that we have deterministic behaviour on systems where /usr/
4412 * is vendor-supplied but the root fs formatted on first boot. */
4413 r = path_is_mount_point("/sysusr/usr", NULL, 0);
4414 if (r <= 0) {
4415 if (r < 0 && r != -ENOENT)
4416 log_debug_errno(r, "Unable to determine whether /sysusr/usr is a mount point, assuming it is not: %m");
4417
4418 arg_root = strdup("/sysroot");
4419 } else
4420 arg_root = strdup("/sysusr");
4421 if (!arg_root)
4422 return log_oom();
4423 }
4424
4425 arg_node = argc > optind ? argv[optind] : NULL;
4426
4427 if (IN_SET(arg_empty, EMPTY_FORCE, EMPTY_REQUIRE, EMPTY_CREATE) && !arg_node && !arg_image)
4428 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
4429 "A path to a device node or loopback file must be specified when --empty=force, --empty=require or --empty=create are used.");
4430
4431 if (arg_tpm2_pcr_mask == UINT32_MAX)
4432 arg_tpm2_pcr_mask = TPM2_PCR_MASK_DEFAULT;
4433
4434 return 1;
4435 }
4436
4437 static int parse_proc_cmdline_factory_reset(void) {
4438 bool b;
4439 int r;
4440
4441 if (arg_factory_reset >= 0) /* Never override what is specified on the process command line */
4442 return 0;
4443
4444 if (!in_initrd()) /* Never honour kernel command line factory reset request outside of the initrd */
4445 return 0;
4446
4447 r = proc_cmdline_get_bool("systemd.factory_reset", &b);
4448 if (r < 0)
4449 return log_error_errno(r, "Failed to parse systemd.factory_reset kernel command line argument: %m");
4450 if (r > 0) {
4451 arg_factory_reset = b;
4452
4453 if (b)
4454 log_notice("Honouring factory reset requested via kernel command line.");
4455 }
4456
4457 return 0;
4458 }
4459
4460 static int parse_efi_variable_factory_reset(void) {
4461 _cleanup_free_ char *value = NULL;
4462 int r;
4463
4464 if (arg_factory_reset >= 0) /* Never override what is specified on the process command line */
4465 return 0;
4466
4467 if (!in_initrd()) /* Never honour EFI variable factory reset request outside of the initrd */
4468 return 0;
4469
4470 r = efi_get_variable_string(EFI_SYSTEMD_VARIABLE(FactoryReset), &value);
4471 if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r))
4472 return 0;
4473 if (r < 0)
4474 return log_error_errno(r, "Failed to read EFI variable FactoryReset: %m");
4475
4476 r = parse_boolean(value);
4477 if (r < 0)
4478 return log_error_errno(r, "Failed to parse EFI variable FactoryReset: %m");
4479
4480 arg_factory_reset = r;
4481 if (r)
4482 log_notice("Factory reset requested via EFI variable FactoryReset.");
4483
4484 return 0;
4485 }
4486
4487 static int remove_efi_variable_factory_reset(void) {
4488 int r;
4489
4490 r = efi_set_variable(EFI_SYSTEMD_VARIABLE(FactoryReset), NULL, 0);
4491 if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r))
4492 return 0;
4493 if (r < 0)
4494 return log_error_errno(r, "Failed to remove EFI variable FactoryReset: %m");
4495
4496 log_info("Successfully unset EFI variable FactoryReset.");
4497 return 0;
4498 }
4499
4500 static int acquire_root_devno(
4501 const char *p,
4502 const char *root,
4503 int mode,
4504 char **ret,
4505 int *ret_fd) {
4506
4507 _cleanup_free_ char *found_path = NULL;
4508 dev_t devno, fd_devno = MODE_INVALID;
4509 _cleanup_close_ int fd = -1;
4510 struct stat st;
4511 int r;
4512
4513 assert(p);
4514 assert(ret);
4515 assert(ret_fd);
4516
4517 fd = chase_symlinks_and_open(p, root, CHASE_PREFIX_ROOT, mode, &found_path);
4518 if (fd < 0)
4519 return fd;
4520
4521 if (fstat(fd, &st) < 0)
4522 return -errno;
4523
4524 if (S_ISREG(st.st_mode)) {
4525 *ret = TAKE_PTR(found_path);
4526 *ret_fd = TAKE_FD(fd);
4527 return 0;
4528 }
4529
4530 if (S_ISBLK(st.st_mode)) {
4531 /* Refuse referencing explicit block devices if a root dir is specified, after all we should
4532 * not be able to leave the image the root path constrains us to. */
4533 if (root)
4534 return -EPERM;
4535
4536 fd_devno = devno = st.st_rdev;
4537 } else if (S_ISDIR(st.st_mode)) {
4538
4539 devno = st.st_dev;
4540 if (major(devno) == 0) {
4541 r = btrfs_get_block_device_fd(fd, &devno);
4542 if (r == -ENOTTY) /* not btrfs */
4543 return -ENODEV;
4544 if (r < 0)
4545 return r;
4546 }
4547 } else
4548 return -ENOTBLK;
4549
4550 /* From dm-crypt to backing partition */
4551 r = block_get_originating(devno, &devno);
4552 if (r == -ENOENT)
4553 log_debug_errno(r, "Device '%s' has no dm-crypt/dm-verity device, no need to look for underlying block device.", p);
4554 else if (r < 0)
4555 log_debug_errno(r, "Failed to find underlying block device for '%s', ignoring: %m", p);
4556
4557 /* From partition to whole disk containing it */
4558 r = block_get_whole_disk(devno, &devno);
4559 if (r < 0)
4560 log_debug_errno(r, "Failed to find whole disk block device for '%s', ignoring: %m", p);
4561
4562 r = device_path_make_canonical(S_IFBLK, devno, ret);
4563 if (r < 0)
4564 return log_debug_errno(r, "Failed to determine canonical path for '%s': %m", p);
4565
4566 /* Only if we still look at the same block device we can reuse the fd. Otherwise return an
4567 * invalidated fd. */
4568 *ret_fd = fd_devno != MODE_INVALID && fd_devno == devno ? TAKE_FD(fd) : -1;
4569 return 0;
4570 }
4571
4572 static int find_root(char **ret, int *ret_fd) {
4573 _cleanup_free_ char *device = NULL;
4574 int r;
4575
4576 assert(ret);
4577 assert(ret_fd);
4578
4579 if (arg_node) {
4580 if (arg_empty == EMPTY_CREATE) {
4581 _cleanup_close_ int fd = -1;
4582 _cleanup_free_ char *s = NULL;
4583
4584 s = strdup(arg_node);
4585 if (!s)
4586 return log_oom();
4587
4588 fd = open(arg_node, O_RDONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOFOLLOW, 0666);
4589 if (fd < 0)
4590 return log_error_errno(errno, "Failed to create '%s': %m", arg_node);
4591
4592 *ret = TAKE_PTR(s);
4593 *ret_fd = TAKE_FD(fd);
4594 return 0;
4595 }
4596
4597 /* Note that we don't specify a root argument here: if the user explicitly configured a node
4598 * we'll take it relative to the host, not the image */
4599 r = acquire_root_devno(arg_node, NULL, O_RDONLY|O_CLOEXEC, ret, ret_fd);
4600 if (r == -EUCLEAN)
4601 return btrfs_log_dev_root(LOG_ERR, r, arg_node);
4602 if (r < 0)
4603 return log_error_errno(r, "Failed to open file or determine backing device of %s: %m", arg_node);
4604
4605 return 0;
4606 }
4607
4608 assert(IN_SET(arg_empty, EMPTY_REFUSE, EMPTY_ALLOW));
4609
4610 /* If the root mount has been replaced by some form of volatile file system (overlayfs), the
4611 * original root block device node is symlinked in /run/systemd/volatile-root. Let's read that
4612 * here. */
4613 r = readlink_malloc("/run/systemd/volatile-root", &device);
4614 if (r == -ENOENT) { /* volatile-root not found */
4615 /* Let's search for the root device. We look for two cases here: first in /, and then in /usr. The
4616 * latter we check for cases where / is a tmpfs and only /usr is an actual persistent block device
4617 * (think: volatile setups) */
4618
4619 FOREACH_STRING(p, "/", "/usr") {
4620
4621 r = acquire_root_devno(p, arg_root, O_RDONLY|O_DIRECTORY|O_CLOEXEC, ret, ret_fd);
4622 if (r < 0) {
4623 if (r == -EUCLEAN)
4624 return btrfs_log_dev_root(LOG_ERR, r, p);
4625 if (r != -ENODEV)
4626 return log_error_errno(r, "Failed to determine backing device of %s: %m", p);
4627 } else
4628 return 0;
4629 }
4630 } else if (r < 0)
4631 return log_error_errno(r, "Failed to read symlink /run/systemd/volatile-root: %m");
4632 else {
4633 r = acquire_root_devno(device, NULL, O_RDONLY|O_CLOEXEC, ret, ret_fd);
4634 if (r == -EUCLEAN)
4635 return btrfs_log_dev_root(LOG_ERR, r, device);
4636 if (r < 0)
4637 return log_error_errno(r, "Failed to open file or determine backing device of %s: %m", device);
4638
4639 return 0;
4640 }
4641
4642 return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device.");
4643 }
4644
4645 static int resize_pt(int fd) {
4646 _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
4647 int r;
4648
4649 /* After resizing the backing file we need to resize the partition table itself too, so that it takes
4650 * possession of the enlarged backing file. For this it suffices to open the device with libfdisk and
4651 * immediately write it again, with no changes. */
4652
4653 c = fdisk_new_context();
4654 if (!c)
4655 return log_oom();
4656
4657 r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(fd), 0);
4658 if (r < 0)
4659 return log_error_errno(r, "Failed to open device '%s': %m", FORMAT_PROC_FD_PATH(fd));
4660
4661 r = fdisk_has_label(c);
4662 if (r < 0)
4663 return log_error_errno(r, "Failed to determine whether disk '%s' has a disk label: %m", FORMAT_PROC_FD_PATH(fd));
4664 if (r == 0) {
4665 log_debug("Not resizing partition table, as there currently is none.");
4666 return 0;
4667 }
4668
4669 r = fdisk_write_disklabel(c);
4670 if (r < 0)
4671 return log_error_errno(r, "Failed to write resized partition table: %m");
4672
4673 log_info("Resized partition table.");
4674 return 1;
4675 }
4676
4677 static int resize_backing_fd(
4678 const char *node, /* The primary way we access the disk image to operate on */
4679 int *fd, /* An O_RDONLY fd referring to that inode */
4680 const char *backing_file, /* If the above refers to a loopback device, the backing regular file for that, which we can grow */
4681 LoopDevice *loop_device) {
4682
4683 _cleanup_close_ int writable_fd = -1;
4684 uint64_t current_size;
4685 struct stat st;
4686 int r;
4687
4688 assert(node);
4689 assert(fd);
4690
4691 if (arg_size == UINT64_MAX) /* Nothing to do */
4692 return 0;
4693
4694 if (*fd < 0) {
4695 /* Open the file if we haven't opened it yet. Note that we open it read-only here, just to
4696 * keep a reference to the file we can pass around. */
4697 *fd = open(node, O_RDONLY|O_CLOEXEC);
4698 if (*fd < 0)
4699 return log_error_errno(errno, "Failed to open '%s' in order to adjust size: %m", node);
4700 }
4701
4702 if (fstat(*fd, &st) < 0)
4703 return log_error_errno(errno, "Failed to stat '%s': %m", node);
4704
4705 if (S_ISBLK(st.st_mode)) {
4706 if (!backing_file)
4707 return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Cannot resize block device '%s'.", node);
4708
4709 assert(loop_device);
4710
4711 if (ioctl(*fd, BLKGETSIZE64, &current_size) < 0)
4712 return log_error_errno(errno, "Failed to determine size of block device %s: %m", node);
4713 } else {
4714 r = stat_verify_regular(&st);
4715 if (r < 0)
4716 return log_error_errno(r, "Specified path '%s' is not a regular file or loopback block device, cannot resize: %m", node);
4717
4718 assert(!backing_file);
4719 assert(!loop_device);
4720 current_size = st.st_size;
4721 }
4722
4723 if (current_size >= arg_size) {
4724 log_info("File '%s' already is of requested size or larger, not growing. (%s >= %s)",
4725 node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
4726 return 0;
4727 }
4728
4729 if (S_ISBLK(st.st_mode)) {
4730 assert(backing_file);
4731
4732 /* This is a loopback device. We can't really grow those directly, but we can grow the
4733 * backing file, hence let's do that. */
4734
4735 writable_fd = open(backing_file, O_WRONLY|O_CLOEXEC|O_NONBLOCK);
4736 if (writable_fd < 0)
4737 return log_error_errno(errno, "Failed to open backing file '%s': %m", backing_file);
4738
4739 if (fstat(writable_fd, &st) < 0)
4740 return log_error_errno(errno, "Failed to stat() backing file '%s': %m", backing_file);
4741
4742 r = stat_verify_regular(&st);
4743 if (r < 0)
4744 return log_error_errno(r, "Backing file '%s' of block device is not a regular file: %m", backing_file);
4745
4746 if ((uint64_t) st.st_size != current_size)
4747 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
4748 "Size of backing file '%s' of loopback block device '%s' don't match, refusing.",
4749 node, backing_file);
4750 } else {
4751 assert(S_ISREG(st.st_mode));
4752 assert(!backing_file);
4753
4754 /* The file descriptor is read-only. In order to grow the file we need to have a writable fd. We
4755 * reopen the file for that temporarily. We keep the writable fd only open for this operation though,
4756 * as fdisk can't accept it anyway. */
4757
4758 writable_fd = fd_reopen(*fd, O_WRONLY|O_CLOEXEC);
4759 if (writable_fd < 0)
4760 return log_error_errno(writable_fd, "Failed to reopen backing file '%s' writable: %m", node);
4761 }
4762
4763 if (!arg_discard) {
4764 if (fallocate(writable_fd, 0, 0, arg_size) < 0) {
4765 if (!ERRNO_IS_NOT_SUPPORTED(errno))
4766 return log_error_errno(errno, "Failed to grow '%s' from %s to %s by allocation: %m",
4767 node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
4768
4769 /* Fallback to truncation, if fallocate() is not supported. */
4770 log_debug("Backing file system does not support fallocate(), falling back to ftruncate().");
4771 } else {
4772 if (current_size == 0) /* Likely regular file just created by us */
4773 log_info("Allocated %s for '%s'.", FORMAT_BYTES(arg_size), node);
4774 else
4775 log_info("File '%s' grown from %s to %s by allocation.",
4776 node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
4777
4778 goto done;
4779 }
4780 }
4781
4782 if (ftruncate(writable_fd, arg_size) < 0)
4783 return log_error_errno(errno, "Failed to grow '%s' from %s to %s by truncation: %m",
4784 node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
4785
4786 if (current_size == 0) /* Likely regular file just created by us */
4787 log_info("Sized '%s' to %s.", node, FORMAT_BYTES(arg_size));
4788 else
4789 log_info("File '%s' grown from %s to %s by truncation.",
4790 node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
4791
4792 done:
4793 r = resize_pt(writable_fd);
4794 if (r < 0)
4795 return r;
4796
4797 if (loop_device) {
4798 r = loop_device_refresh_size(loop_device, UINT64_MAX, arg_size);
4799 if (r < 0)
4800 return log_error_errno(r, "Failed to update loop device size: %m");
4801 }
4802
4803 return 1;
4804 }
4805
4806 static int determine_auto_size(Context *c) {
4807 uint64_t sum;
4808
4809 assert(c);
4810
4811 sum = round_up_size(GPT_METADATA_SIZE, 4096);
4812
4813 LIST_FOREACH(partitions, p, c->partitions) {
4814 uint64_t m;
4815
4816 if (p->dropped)
4817 continue;
4818
4819 m = partition_min_size_with_padding(c, p);
4820 if (m > UINT64_MAX - sum)
4821 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Image would grow too large, refusing.");
4822
4823 sum += m;
4824 }
4825
4826 if (c->total != UINT64_MAX)
4827 /* Image already allocated? Then show its size. */
4828 log_info("Automatically determined minimal disk image size as %s, current image size is %s.",
4829 FORMAT_BYTES(sum), FORMAT_BYTES(c->total));
4830 else
4831 /* If the image is being created right now, then it has no previous size, suppress any comment about it hence. */
4832 log_info("Automatically determined minimal disk image size as %s.",
4833 FORMAT_BYTES(sum));
4834
4835 arg_size = sum;
4836 return 0;
4837 }
4838
4839 static int run(int argc, char *argv[]) {
4840 _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
4841 _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
4842 _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
4843 _cleanup_(context_freep) Context* context = NULL;
4844 _cleanup_free_ char *node = NULL;
4845 _cleanup_close_ int backing_fd = -1;
4846 bool from_scratch, node_is_our_loop = false;
4847 int r;
4848
4849 log_show_color(true);
4850 log_parse_environment();
4851 log_open();
4852
4853 r = parse_argv(argc, argv);
4854 if (r <= 0)
4855 return r;
4856
4857 r = parse_proc_cmdline_factory_reset();
4858 if (r < 0)
4859 return r;
4860
4861 r = parse_efi_variable_factory_reset();
4862 if (r < 0)
4863 return r;
4864
4865 #if HAVE_LIBCRYPTSETUP
4866 cryptsetup_enable_logging(NULL);
4867 #endif
4868
4869 if (arg_image) {
4870 assert(!arg_root);
4871
4872 /* Mount this strictly read-only: we shall modify the partition table, not the file
4873 * systems */
4874 r = mount_image_privately_interactively(
4875 arg_image,
4876 DISSECT_IMAGE_MOUNT_READ_ONLY |
4877 (arg_node ? DISSECT_IMAGE_DEVICE_READ_ONLY : 0) | /* If a different node to make changes to is specified let's open the device in read-only mode) */
4878 DISSECT_IMAGE_GPT_ONLY |
4879 DISSECT_IMAGE_RELAX_VAR_CHECK |
4880 DISSECT_IMAGE_USR_NO_ROOT |
4881 DISSECT_IMAGE_REQUIRE_ROOT,
4882 &mounted_dir,
4883 &loop_device,
4884 &decrypted_image);
4885 if (r < 0)
4886 return r;
4887
4888 arg_root = strdup(mounted_dir);
4889 if (!arg_root)
4890 return log_oom();
4891
4892 if (!arg_node) {
4893 arg_node = strdup(loop_device->node);
4894 if (!arg_node)
4895 return log_oom();
4896
4897 /* Remember that the device we are about to manipulate is actually the one we
4898 * allocated here, and thus to increase its backing file we know what to do */
4899 node_is_our_loop = true;
4900 }
4901 }
4902
4903 context = context_new(arg_seed);
4904 if (!context)
4905 return log_oom();
4906
4907 r = context_read_definitions(context, arg_definitions, arg_root);
4908 if (r < 0)
4909 return r;
4910
4911 if (context->n_partitions <= 0 && arg_empty == EMPTY_REFUSE) {
4912 log_info("Didn't find any partition definition files, nothing to do.");
4913 return 0;
4914 }
4915
4916 r = find_root(&node, &backing_fd);
4917 if (r < 0)
4918 return r;
4919
4920 if (arg_size != UINT64_MAX) {
4921 r = resize_backing_fd(
4922 node,
4923 &backing_fd,
4924 node_is_our_loop ? arg_image : NULL,
4925 node_is_our_loop ? loop_device : NULL);
4926 if (r < 0)
4927 return r;
4928 }
4929
4930 r = context_load_partition_table(context, node, &backing_fd);
4931 if (r == -EHWPOISON)
4932 return 77; /* Special return value which means "Not GPT, so not doing anything". This isn't
4933 * really an error when called at boot. */
4934 if (r < 0)
4935 return r;
4936 from_scratch = r > 0; /* Starting from scratch */
4937
4938 if (arg_can_factory_reset) {
4939 r = context_can_factory_reset(context);
4940 if (r < 0)
4941 return r;
4942 if (r == 0)
4943 return EXIT_FAILURE;
4944
4945 return 0;
4946 }
4947
4948 r = context_factory_reset(context, from_scratch);
4949 if (r < 0)
4950 return r;
4951 if (r > 0) {
4952 /* We actually did a factory reset! */
4953 r = remove_efi_variable_factory_reset();
4954 if (r < 0)
4955 return r;
4956
4957 /* Reload the reduced partition table */
4958 context_unload_partition_table(context);
4959 r = context_load_partition_table(context, node, &backing_fd);
4960 if (r < 0)
4961 return r;
4962 }
4963
4964 #if 0
4965 (void) context_dump_partitions(context, node);
4966 putchar('\n');
4967 #endif
4968
4969 r = context_read_seed(context, arg_root);
4970 if (r < 0)
4971 return r;
4972
4973 /* Open all files to copy blocks from now, since we want to take their size into consideration */
4974 r = context_open_copy_block_paths(
4975 context,
4976 arg_root,
4977 loop_device ? loop_device->devno : /* if --image= is specified, only allow partitions on the loopback device */
4978 arg_root && !arg_image ? 0 : /* if --root= is specified, don't accept any block device */
4979 (dev_t) -1); /* if neither is specified, make no restrictions */
4980 if (r < 0)
4981 return r;
4982
4983 if (arg_size_auto) {
4984 r = determine_auto_size(context);
4985 if (r < 0)
4986 return r;
4987
4988 /* Flush out everything again, and let's grow the file first, then start fresh */
4989 context_unload_partition_table(context);
4990
4991 assert(arg_size != UINT64_MAX);
4992 r = resize_backing_fd(
4993 node,
4994 &backing_fd,
4995 node_is_our_loop ? arg_image : NULL,
4996 node_is_our_loop ? loop_device : NULL);
4997 if (r < 0)
4998 return r;
4999
5000 r = context_load_partition_table(context, node, &backing_fd);
5001 if (r < 0)
5002 return r;
5003 }
5004
5005 /* First try to fit new partitions in, dropping by priority until it fits */
5006 for (;;) {
5007 uint64_t largest_free_area;
5008
5009 if (context_allocate_partitions(context, &largest_free_area))
5010 break; /* Success! */
5011
5012 if (!context_drop_one_priority(context)) {
5013 r = log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
5014 "Can't fit requested partitions into available free space (%s), refusing.",
5015 FORMAT_BYTES(largest_free_area));
5016 determine_auto_size(context);
5017 return r;
5018 }
5019 }
5020
5021 /* Now assign free space according to the weight logic */
5022 r = context_grow_partitions(context);
5023 if (r < 0)
5024 return r;
5025
5026 /* Now calculate where each new partition gets placed */
5027 context_place_partitions(context);
5028
5029 /* Make sure each partition has a unique UUID and unique label */
5030 r = context_acquire_partition_uuids_and_labels(context);
5031 if (r < 0)
5032 return r;
5033
5034 r = context_write_partition_table(context, node, from_scratch);
5035 if (r < 0)
5036 return r;
5037
5038 return 0;
5039 }
5040
5041 DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);