]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
mkswap: implement --offset
authorThomas Weißschuh <thomas@t-8ch.de>
Fri, 28 Apr 2023 18:42:01 +0000 (20:42 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Thu, 11 May 2023 10:09:56 +0000 (12:09 +0200)
Addresses #2166

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
bash-completion/mkswap
disk-utils/mkswap.8.adoc
disk-utils/mkswap.c
tests/ts/mkswap/mkswap

index 61157ef13effe005a9c7303aa884835d72639e16..33b0a70cebbc6ba854960845275d078e0da34b50 100644 (file)
@@ -21,13 +21,17 @@ _mkswap_module()
                        COMPREPLY=( $(compgen -W "$(uuidgen -r)" -- $cur) )
                        return 0
                        ;;
+               '-o'|'--offset')
+                       COMPREPLY=( $(compgen -W "bytes" -- $cur) )
+                       return 0
+                       ;;
                '-h'|'--help'|'-V'|'--version')
                        return 0
                        ;;
        esac
        case $cur in
                -*)
-                       OPTS="--check --force --pagesize --lock --label --swapversion --uuid --verbose --version --help"
+                       OPTS="--check --force --pagesize --lock --label --swapversion --uuid --offset --verbose --version --help"
                        COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
                        return 0
                        ;;
index 904467d772592197de8bb2dd02151ef4bc664cdc..ad48c99e08343c8213f7073720da71792e8a7b75 100644 (file)
@@ -73,6 +73,9 @@ generate a new time-based UUID
 *-e*, *--endianness* _ENDIANNESS_::
 Specify the _ENDIANNESS_ to use, valid arguments are *native*, *little* or *big*. The default is *native*.
 
+*-o*, *--offset* _offset_::
+Specify the _offset_ to write the swap area to.
+
 *-v*, *--swapversion 1*::
 Specify the swap-space version. (This option is currently pointless, as the old *-v 0* option has become obsolete and now only *-v 1* is supported. The kernel has not supported v0 swap-space format since 2.5.22 (June 2002). The new version v1 is supported since 2.1.117 (August 1998).)
 
index bd02301774535a0084638d86120e5291906351a5..b6deadf38acd06961593bab7a71fbc4fc7817a47 100644 (file)
@@ -76,6 +76,7 @@ struct mkswap_control {
 
        int                     user_pagesize;  /* --pagesize */
        int                     pagesize;       /* final pagesize used for the header */
+       off_t                   offset;         /* offset of the header in the target */
 
        char                    *opt_label;     /* LABEL as specified on command line */
        unsigned char           *uuid;          /* UUID parsed by libbuuid */
@@ -194,6 +195,7 @@ static void __attribute__((__noreturn__)) usage(void)
        fprintf(out,
              _(" -e, --endianness=<value>  specify the endianness to use "
                                            "(%s, %s or %s)\n"), "native", "little", "big");
+       fputs(_(" -o, --offset OFFSET       specify the offset in the device\n"), out);
        fputs(_("     --verbose             verbose output\n"), out);
 
        fprintf(out,
@@ -347,6 +349,9 @@ static unsigned long long get_size(const struct mkswap_control *ctl)
                err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
        if (blkdev_get_size(fd, &size) < 0)
                err(EXIT_FAILURE, _("cannot determine size of %s"), ctl->devname);
+       if ((unsigned long long) ctl->offset > size)
+               errx(EXIT_FAILURE, _("offset larger than file size"));
+       size -= ctl->offset;
        size /= ctl->pagesize;
 
        close(fd);
@@ -465,11 +470,15 @@ static void wipe_device(struct mkswap_control *ctl)
 
 static void write_header_to_device(struct mkswap_control *ctl)
 {
+       off_t offset;
+
        assert(ctl);
        assert(ctl->fd > -1);
        assert(ctl->signature_page);
 
-       if (lseek(ctl->fd, SIGNATURE_OFFSET, SEEK_SET) != SIGNATURE_OFFSET)
+       offset = SIGNATURE_OFFSET + ctl->offset;
+
+       if (lseek(ctl->fd, offset, SEEK_SET) != offset)
                errx(EXIT_FAILURE, _("unable to rewind swap-device"));
 
        if (write_all(ctl->fd, (char *) ctl->signature_page + SIGNATURE_OFFSET,
@@ -503,6 +512,7 @@ int main(int argc, char **argv)
                { "swapversion", required_argument, NULL, 'v' },
                { "uuid",        required_argument, NULL, 'U' },
                { "endianness",  required_argument, NULL, 'e' },
+               { "offset",      required_argument, NULL, 'o' },
                { "version",     no_argument,       NULL, 'V' },
                { "help",        no_argument,       NULL, 'h' },
                { "lock",        optional_argument, NULL, OPT_LOCK },
@@ -521,7 +531,7 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
        close_stdout_atexit();
 
-       while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:Vh", longopts, NULL)) != -1) {
+       while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:o:Vh", longopts, NULL)) != -1) {
 
                err_exclusive_options(c, longopts, excl, excl_st);
 
@@ -567,6 +577,10 @@ int main(int argc, char **argv)
                                        _("invalid endianness %s is not supported"), optarg);
                        }
                        break;
+               case 'o':
+                       ctl.offset = str2unum_or_err(optarg,
+                                       10, _("Invalid offset"), SINT_MAX(off_t));
+                       break;
                case 'V':
                        print_version(EXIT_SUCCESS);
                        break;
index bed7941899cbfbde6c53f72a6922df578ab891f5..c4fdce4f03b8216d4a0d29eb5bb122534f5fd5e8 100755 (executable)
@@ -63,4 +63,28 @@ for PAGESIZE in 4096 8192; do
        done
 done
 
+ts_init_subtest offset
+
+offset=10000
+outimg="$TS_OUTDIR/offset.img"
+
+rm -f "$outimg"
+truncate -s $(( 4096 * 10 )) "$outimg" > $TS_ERRLOG 2>&1
+
+rm -f "$outimg.offset"
+truncate -s $(( 4096 * 10 + $offset )) "$outimg.offset" > $TS_ERRLOG 2>&1
+
+"$TS_CMD_MKSWAP" -q -U "$UUID" -p 4096 "$outimg" \
+       >> "$TS_OUTPUT" 2>/dev/null \
+       || ts_log "mkswap failed"
+
+"$TS_CMD_MKSWAP" -q -U "$UUID" -p 4096 -o "$offset" "$outimg.offset" \
+       >> "$TS_OUTPUT" 2>/dev/null \
+       || ts_log "mkswap -o failed"
+
+cmp -n "$offset" "$outimg.offset" /dev/zero >> "$TS_ERRLOG" 2>&1
+cmp "$outimg" "$outimg.offset" 0 "$offset" >> "$TS_ERRLOG" 2>&1
+
+ts_finalize_subtest
+
 ts_finalize