From: Thomas Weißschuh Date: Thu, 15 Dec 2022 13:32:31 +0000 (+0000) Subject: mkswap: create files with specific endianness X-Git-Tag: v2.39-rc1~364^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a80192f027eed952c8ecee68ecc9676971f31db;p=thirdparty%2Futil-linux.git mkswap: create files with specific endianness --- diff --git a/disk-utils/mkswap.8.adoc b/disk-utils/mkswap.8.adoc index 0a25a2dbed..904467d772 100644 --- a/disk-utils/mkswap.8.adoc +++ b/disk-utils/mkswap.8.adoc @@ -70,6 +70,9 @@ generate a new randomly-generated UUID *time*;; 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*. + *-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).) diff --git a/disk-utils/mkswap.c b/disk-utils/mkswap.c index d14f24901c..6f6d3048a3 100644 --- a/disk-utils/mkswap.c +++ b/disk-utils/mkswap.c @@ -42,6 +42,7 @@ #include "closestream.h" #include "ismounted.h" #include "optutils.h" +#include "bitops.h" #ifdef HAVE_LIBUUID # include @@ -55,6 +56,12 @@ #define SELINUX_SWAPFILE_TYPE "swapfile_t" +enum ENDIANNESS { + ENDIANNESS_NATIVE, + ENDIANNESS_LITTLE, + ENDIANNESS_BIG, +}; + struct mkswap_control { struct swap_header_v1_2 *hdr; /* swap header */ void *signature_page;/* buffer with swap header */ @@ -75,12 +82,24 @@ struct mkswap_control { size_t nbad_extents; + enum ENDIANNESS endianness; + unsigned int check:1, /* --check */ verbose:1, /* --verbose */ quiet:1, /* --quiet */ force:1; /* --force */ }; +static uint32_t cpu32_to_endianness(uint32_t v, enum ENDIANNESS e) +{ + switch (e) { + case ENDIANNESS_NATIVE: return v; + case ENDIANNESS_LITTLE: return cpu_to_le32(v); + case ENDIANNESS_BIG: return cpu_to_be32(v); + } + abort(); +} + static void init_signature_page(struct mkswap_control *ctl) { const int kernel_pagesize = getpagesize(); @@ -172,6 +191,9 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -L, --label LABEL specify label\n"), out); fputs(_(" -v, --swapversion NUM specify swap-space version number\n"), out); fputs(_(" -U, --uuid UUID specify the uuid to use\n"), out); + fprintf(out, + _(" -e, --endianness= specify the endianness to use " + "(%s, %s or %s)\n"), "native", "little", "big"); fputs(_(" --verbose verbose output\n"), out); fprintf(out, @@ -458,7 +480,7 @@ static void write_header_to_device(struct mkswap_control *ctl) int main(int argc, char **argv) { - struct mkswap_control ctl = { .fd = -1 }; + struct mkswap_control ctl = { .fd = -1, .endianness = ENDIANNESS_NATIVE }; int c, permMask; uint64_t sz; int version = SWAP_VERSION; @@ -479,6 +501,7 @@ int main(int argc, char **argv) { "label", required_argument, NULL, 'L' }, { "swapversion", required_argument, NULL, 'v' }, { "uuid", required_argument, NULL, 'U' }, + { "endianness", required_argument, NULL, 'e' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, { "lock", optional_argument, NULL, OPT_LOCK }, @@ -497,7 +520,7 @@ int main(int argc, char **argv) textdomain(PACKAGE); close_stdout_atexit(); - while((c = getopt_long(argc, argv, "cfp:qL:v:U:Vh", longopts, NULL)) != -1) { + while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:Vh", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); @@ -531,6 +554,18 @@ int main(int argc, char **argv) program_invocation_short_name); #endif break; + case 'e': + if (strcmp(optarg, "native") == 0) { + ctl.endianness = ENDIANNESS_NATIVE; + } else if (strcmp(optarg, "little") == 0) { + ctl.endianness = ENDIANNESS_LITTLE; + } else if (strcmp(optarg, "big") == 0) { + ctl.endianness = ENDIANNESS_BIG; + } else { + errx(EXIT_FAILURE, + _("invalid endianness %s is not supported"), optarg); + } + break; case 'V': print_version(EXIT_SUCCESS); break; @@ -637,9 +672,9 @@ int main(int argc, char **argv) wipe_device(&ctl); assert(ctl.hdr); - ctl.hdr->version = version; - ctl.hdr->last_page = ctl.npages - 1; - ctl.hdr->nr_badpages = ctl.nbadpages; + ctl.hdr->version = cpu32_to_endianness(version, ctl.endianness); + ctl.hdr->last_page = cpu32_to_endianness(ctl.npages - 1, ctl.endianness); + ctl.hdr->nr_badpages = cpu32_to_endianness(ctl.nbadpages, ctl.endianness); if ((ctl.npages - MIN_GOODPAGES) < ctl.nbadpages) errx(EXIT_FAILURE, _("Unable to set up swap-space: unreadable")); diff --git a/tests/ts/mkswap/mkswap b/tests/ts/mkswap/mkswap index 2cb999a277..fa4856b719 100755 --- a/tests/ts/mkswap/mkswap +++ b/tests/ts/mkswap/mkswap @@ -28,26 +28,38 @@ ts_check_test_command "$TS_HELPER_SYSINFO" ts_check_prog "xz" ts_check_prog "cmp" -BYTE_ORDER="$("$TS_HELPER_SYSINFO" byte-order)" UUID=4c08e1cd-3c82-46bf-a55b-0c3270d6dfeb for PAGESIZE in 4096 8192; do - name="${BYTE_ORDER}-${PAGESIZE}" - outimg="$TS_OUTDIR/${name}.img" - origimg="$TS_OUTDIR/${name}.img.orig" + for ENDIANNESS in native little big; do + case "$ENDIANNESS" in + native) BYTE_ORDER="$("$TS_HELPER_SYSINFO" byte-order)";; + little) BYTE_ORDER=LE;; + big) BYTE_ORDER=BE;; + esac - ts_init_subtest $name + if [ "$ENDIANNESS" == "native" ]; then + name="NATIVE-${PAGESIZE}" + else + name="${BYTE_ORDER}-${PAGESIZE}" + fi + outimg="$TS_OUTDIR/${BYTE_ORDER}-${PAGESIZE}.img" + origimg="$TS_OUTDIR/${BYTE_ORDER}-${PAGESIZE}.img.orig" - rm -f "$outimg" - truncate -s $(( PAGESIZE * 10 )) "$outimg" > $TS_ERRLOG 2>&1 + ts_init_subtest $name - "$TS_CMD_MKSWAP" -q -L label -U "$UUID" -p "$PAGESIZE" "$outimg" \ - > "$TS_OUTPUT" 2> "$TS_ERRLOG" || ts_log "mkswap failed" - xz -dc "$TS_SELF/${name}.img.xz" > "$origimg" + rm -f "$outimg" + truncate -s $(( PAGESIZE * 10 )) "$outimg" > $TS_ERRLOG 2>&1 - cmp "$origimg" "$outimg" > "$TS_ERRLOG" 2>&1 + "$TS_CMD_MKSWAP" -q -L label -U "$UUID" -e "$ENDIANNESS" -p "$PAGESIZE" "$outimg" \ + > "$TS_OUTPUT" 2>/dev/null \ + || ts_log "mkswap failed" + xz -dc "$TS_SELF/${BYTE_ORDER}-${PAGESIZE}.img.xz" > "$origimg" - ts_finalize_subtest + cmp "$origimg" "$outimg" > "$TS_ERRLOG" 2>&1 + + ts_finalize_subtest + done done ts_finalize