← Commit list

f5c0543fd

Denys Vlasenko
Denys Vlasenko
2026-09-24
SUCCESS Duration: 371s

Subject

swaplabel: new applet

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

include/libbb.h+4 -0
@@ -2485,6 +2485,10 @@ extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
*/
#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
+/* Stored without terminating NUL */
+extern const char bb_SWAPSPACE2[sizeof("SWAPSPACE2")-1];
+
+
extern const int const_int_0;
//extern const int const_int_1;
libbb/get_volsize.c+22 -13
@@ -14,35 +14,44 @@ uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
int extend)
{
uoff_t result;
+#define ULL(x) ((unsigned long long)(x))
if (override) {
result = XATOOFF(override);
if (result >= (uoff_t)(MAXINT(off_t)) / override_units)
- bb_simple_error_msg_and_die("image size is too big");
+ bb_error_msg_and_die("image size %lld is too big", ULL(result));
result *= override_units;
- /* seek past end fails on block devices but works on files */
+ if (result == 0)
+ goto insane;
+ // Do we need to extend the file?
+ // Seek past end fails on block devices but works on files!
if (lseek(fd, result - 1, SEEK_SET) != (off_t)-1) {
- if (extend)
- xwrite(fd, "", 1); /* file grows if needed */
+ char dummy;
+ if (extend && safe_read(fd, &dummy, 1) != 1) {
+ // the file is shorter
+ xwrite(fd, "", 1); // grow it
+ }
}
//else {
// bb_error_msg("warning, block device is smaller");
//}
} else {
- /* more portable than BLKGETSIZE[64] */
+ // more portable than BLKGETSIZE[64]
result = xlseek(fd, 0, SEEK_END);
}
xlseek(fd, 0, SEEK_SET);
- /* Prevent things like this:
- * $ dd if=/dev/zero of=foo count=1 bs=1024
- * $ mkswap foo
- * Setting up swapspace version 1, size = 18446744073709548544 bytes
- *
- * Picked 16k arbitrarily: */
- if (result < 16*1024)
- bb_simple_error_msg_and_die("image is too small");
+ // Prevent things like this:
+ // $ dd if=/dev/zero of=foo count=1 bs=1024
+ // $ mkswap foo
+ // Setting up swapspace version 1, size = 18446744073709548544 bytes
+ //
+ // Picked 16k arbitrarily:
+ if (result < 16*1024) {
+ insane:
+ bb_error_msg_and_die("image is too small: %lld bytes", ULL(result));
+ }
return result;
}
libbb/messages.c+5 -0
@@ -33,6 +33,11 @@ const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
* but I want to save a few bytes here. Check libbb.h before changing! */
const char bb_PATH_root_path[] ALIGN1 = BB_PATH_ROOT_PATH;
+#if ENABLE_MKSWAP || ENABLE_SWAPLABEL
+/* Stored without terminating NUL */
+const char bb_SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2";
+#endif
+
//const int const_int_1 = 1;
/* explicitly = 0, otherwise gcc may make it a common variable
util-linux/mkswap.c+1 -4
@@ -107,9 +107,6 @@ struct BUG_sizes {
char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1];
};
-/* Stored without terminating NUL */
-static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2";
-
int mkswap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int mkswap_main(int argc UNUSED_PARAM, char **argv)
{
@@ -160,7 +157,7 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv)
* signature on disk (not in cache) during swapon. */
xwrite(fd, hdr, NWORDS * 4);
xlseek(fd, pagesize - 10, SEEK_SET);
- xwrite(fd, SWAPSPACE2, 10);
+ xwrite(fd, bb_SWAPSPACE2, 10);
fsync(fd);
if (ENABLE_FEATURE_CLEAN_UP)
util-linux/swaplabel.c+83 -0
@@ -0,0 +1,83 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright 2026 Denys Vlasenko <[email protected]>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+//config:config SWAPLABEL
+//config: bool "swaplabel (1 kb)"
+//config: default y
+//config: help
+//config: swaplabel shows or sets swap's label.
+
+//applet:IF_SWAPLABEL(APPLET(swaplabel, BB_DIR_SBIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_SWAPLABEL) += swaplabel.o
+
+//usage:#define swaplabel_trivial_usage
+//usage: "[-L LBL] BLOCKDEV"
+//usage:#define swaplabel_full_usage "\n\n"
+//usage: "Show or set swap label on BLOCKDEV\n"
+//usage: "\n -L LBL Label"
+
+#include "libbb.h"
+#include "common_bufsiz.h"
+
+/* from Linux 2.6.23 */
+/*
+ * Magic header for a swap area. ... Note that the first
+ * kilobyte is reserved for boot loader or disk label stuff.
+ */
+struct swap_header_v1 {
+/* char bootbits[1024]; Space for disklabel etc. */
+ uint32_t version; /* second kbyte, word 0 */
+ uint32_t last_page; /* 1 */
+ uint32_t nr_badpages; /* 2 */
+ uint8_t sws_uuid[16]; /* 3,4,5,6 */
+ char sws_volume[16]; /* 7,8,9,10 */
+ uint32_t padding[117]; /* 11..127 */
+ uint32_t badpages[1]; /* 128 */
+ /* total 129 32-bit words in 2nd kilobyte */
+} FIX_ALIASING;
+
+int swaplabel_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int swaplabel_main(int argc UNUSED_PARAM, char **argv)
+{
+ char buf32[32];
+ const char *label = NULL;
+ int fd;
+
+ // TODO: -U UUID
+ getopt32(argv, "^" "L:" "\0" "=1"/*exactly one arg*/, &label);
+ argv += optind;
+
+ fd = xopen(argv[0], label ? O_RDWR : O_RDONLY);
+
+ xlseek(fd, bb_getpagesize() - 10, SEEK_SET);
+ xread(fd, buf32, 10);
+ if (memcmp(buf32, bb_SWAPSPACE2, 10) != 0)
+ bb_error_msg_and_die("%s: not a valid swap partition", argv[0]);
+ // TODO: also check hdr.version == 1?
+
+ xlseek(fd, 1024 + offsetof(struct swap_header_v1, sws_uuid) + 16 * (!!label), SEEK_SET);
+ if (label) {
+ int sz = strnlen(label, 15) + 1; // includes NUL unless full 16 bytes
+ xwrite(fd, label, sz);
+ // BTW, writing to active swap partition fails with ETXTBUSY!
+ } else {
+ char uuid_string37[37];
+
+ xread(fd, buf32, 32);
+ if (buf32[16])
+ printf("LABEL: %.16s\n", buf32 + 16);
+
+ // f.e. dfd9c173-be52-4d27-99a5-c34c6c2ff55f
+ format_uuid_DCE_37_chars(uuid_string37, (uint8_t*)buf32);
+ printf("UUID: %s\n", uuid_string37);
+ }
+
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close(fd);
+
+ return 0;
+}
util-linux/volume_id/linux_swap.c+1 -1
@@ -58,7 +58,7 @@ int FAST_FUNC volume_id_probe_linux_swap(struct volume_id *id /*,uint64_t off*/)
goto found;
}
- if (memcmp(buf, "SWAPSPACE2", 10) == 0
+ if (memcmp(buf, bb_SWAPSPACE2, 10) == 0
|| memcmp(buf, "S1SUSPEND", 9) == 0
|| memcmp(buf, "S2SUSPEND", 9) == 0
|| memcmp(buf, "ULSUSPEND", 9) == 0