]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: Allow devices as sources for --copy-from
authorNick Labich <nick@labich.org>
Tue, 22 Apr 2025 00:03:46 +0000 (20:03 -0400)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Apr 2025 00:33:51 +0000 (09:33 +0900)
Implements #37208

man/systemd-repart.xml
src/repart/repart.c

index 40376bc77387804eeba0c5c1a9488930d0b0d6a5..0c41ef38ab093e0e7d1c397f0a6112a44fc85906 100644 (file)
       </varlistentry>
 
       <varlistentry>
-        <term><option>--copy-from=<replaceable>IMAGE</replaceable></option></term>
+        <term><option>--copy-from=<replaceable>PATH</replaceable></option></term>
 
         <listitem><para>Instructs <command>systemd-repart</command> to synthesize partition definitions from
-        the partition table in the given image. This option can be specified multiple times to synthesize
-        definitions from each of the given images. The generated definitions will copy the partitions into
-        the destination partition table. The copied partitions will have the same size, metadata and contents
-        but might have a different partition number and might be located at a different offset in the
-        destination partition table. These definitions can be combined with partition definitions read from
-        regular partition definition files. The synthesized definitions take precedence over the definitions
-        read from partition definition files.</para>
+        the partition table in the given image or device. This option can be specified multiple times to
+        synthesize definitions from each of the given images or devices. The generated definitions will copy
+        the partitions into the destination partition table. The copied partitions will have the same size,
+        metadata and contents but might have a different partition number and might be located at a different
+        offset in the destination partition table. These definitions can be combined with partition
+        definitions read from regular partition definition files. The synthesized definitions take precedence
+        over the definitions read from partition definition files.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
       </varlistentry>
index c0fd1cc7bcff7d4b5febfe2aa15f79f5e66005e9..80fbafdb4b3c24ffcd556bc1b3f12b3b963d4102 100644 (file)
@@ -2676,6 +2676,26 @@ static int determine_current_padding(
         return 0;
 }
 
+static int verify_regular_or_block(int fd) {
+        struct stat st;
+
+        assert(fd >= 0);
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        if (S_ISDIR(st.st_mode))
+                return -EISDIR;
+
+        if (S_ISLNK(st.st_mode))
+                return -ELOOP;
+
+        if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
+                return -EBADFD;
+
+        return 0;
+}
+
 static int context_copy_from_one(Context *context, const char *src) {
         _cleanup_close_ int fd = -EBADF;
         _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
@@ -2691,9 +2711,9 @@ static int context_copy_from_one(Context *context, const char *src) {
         if (r < 0)
                 return r;
 
-        r = fd_verify_regular(fd);
+        r = verify_regular_or_block(fd);
         if (r < 0)
-                return log_error_errno(r, "%s is not a file: %m", src);
+                return log_error_errno(r, "%s is not a file nor a block device: %m", src);
 
         r = fdisk_new_context_at(fd, /* path = */ NULL, /* read_only = */ true, /* sector_size = */ UINT32_MAX, &c);
         if (r < 0)