summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Bongio <bongiojp@gmail.com>2022-07-21 15:39:30 -0700
committerZorro Lang <zlang@kernel.org>2022-07-24 22:30:58 +0800
commitd628ffcb3278d0284380cbf2decc00dfd61738a1 (patch)
treec121bb71d28f1516a0e4e8d4572f55b093a6b9cb /src
parent9e0b9837cc499b45c33a4d8b204f3b61832282b4 (diff)
ext4: add test for ext4 uuid get/set ioctls during fsstress.
Adds a utility to get/set uuid through ext4 ioctl. Executes the ioctls while running fsstress. These ioctls are used by tune2fs to safely change the uuid without racing other filesystem modifications. Reviewed-by: Zorro Lang <zlang@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Jeremy Bongio <bongiojp@gmail.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Zorro Lang <zlang@kernel.org>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile5
-rw-r--r--src/uuid_ioctl.c105
2 files changed, 108 insertions, 2 deletions
diff --git a/src/Makefile b/src/Makefile
index 7eeb08ef..665edcf9 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -31,14 +31,15 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
dio-invalidate-cache stat_test t_encrypted_d_revalidate \
attr_replace_test swapon mkswap t_attr_corruption t_open_tmpfiles \
fscrypt-crypt-util bulkstat_null_ocount splice-test chprojid_fail \
- detached_mounts_propagation ext4_resize t_readdir_3 splice2pipe
+ detached_mounts_propagation ext4_resize t_readdir_3 splice2pipe \
+ uuid_ioctl
EXTRA_EXECS = dmerror fill2attr fill2fs fill2fs_check scaleread.sh \
btrfs_crc32c_forged_name.py
SUBDIRS = log-writes perf
-LLDLIBS = $(LIBHANDLE) $(LIBACL) -lpthread -lrt
+LLDLIBS = $(LIBHANDLE) $(LIBACL) -lpthread -lrt -luuid
ifeq ($(HAVE_XLOG_ASSIGN_LSN), true)
LINUX_TARGETS += loggen
diff --git a/src/uuid_ioctl.c b/src/uuid_ioctl.c
new file mode 100644
index 00000000..89a9b5d8
--- /dev/null
+++ b/src/uuid_ioctl.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Google, Inc. All Rights Reserved.
+ *
+ * Test program which uses the raw ext4 set_fsuuid ioctl directly.
+ * SYNOPSIS:
+ * $0 COMMAND MOUNT_POINT [UUID]
+ *
+ * COMMAND must be either "get" or "set".
+ * The UUID must be a 16 octet sequence represented as 32 hexadecimal digits in
+ * canonical textual representation, e.g. output from `uuidgen`.
+ *
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <uuid/uuid.h>
+#include <linux/fs.h>
+
+struct fsuuid {
+ __u32 fsu_len;
+ __u32 fsu_flags;
+ __u8 fsu_uuid[];
+};
+
+#ifndef EXT4_IOC_GETFSUUID
+#define EXT4_IOC_GETFSUUID _IOR('f', 44, struct fsuuid)
+#endif
+
+#ifndef EXT4_IOC_SETFSUUID
+#define EXT4_IOC_SETFSUUID _IOW('f', 44, struct fsuuid)
+#endif
+
+int main(int argc, char **argv)
+{
+ int error, fd;
+ struct fsuuid *fsuuid = NULL;
+
+ if (argc < 3) {
+ fprintf(stderr, "Invalid arguments\n");
+ return 1;
+ }
+
+ fd = open(argv[2], O_RDONLY);
+ if (!fd) {
+ perror(argv[2]);
+ return 1;
+ }
+
+ fsuuid = malloc(sizeof(*fsuuid) + sizeof(uuid_t));
+ if (!fsuuid) {
+ perror("malloc");
+ return 1;
+ }
+ fsuuid->fsu_len = sizeof(uuid_t);
+ fsuuid->fsu_flags = 0;
+
+ if (strcmp(argv[1], "get") == 0) {
+ uuid_t uuid;
+ char uuid_str[37];
+
+ if (ioctl(fd, EXT4_IOC_GETFSUUID, fsuuid)) {
+ fprintf(stderr, "%s while trying to get fs uuid\n",
+ strerror(errno));
+ return 1;
+ }
+
+ memcpy(&uuid, fsuuid->fsu_uuid, sizeof(uuid));
+ uuid_unparse(uuid, uuid_str);
+ printf("%s\n", uuid_str);
+ } else if (strcmp(argv[1], "set") == 0) {
+ uuid_t uuid;
+
+ if (argc != 4) {
+ fprintf(stderr, "UUID argument missing.\n");
+ return 1;
+ }
+
+ error = uuid_parse(argv[3], uuid);
+ if (error < 0) {
+ fprintf(stderr, "Invalid UUID. The UUID should be in "
+ "canonical format. Example: "
+ "8c628557-6987-42b2-ba16-b7cc79ddfb43\n");
+ return 1;
+ }
+
+ memcpy(&fsuuid->fsu_uuid, uuid, sizeof(uuid));
+ if (ioctl(fd, EXT4_IOC_SETFSUUID, fsuuid)) {
+ fprintf(stderr, "%s while trying to set fs uuid\n",
+ strerror(errno));
+ return 1;
+ }
+ } else {
+ fprintf(stderr, "Invalid command\n");
+ return 1;
+ }
+
+ return 0;
+}