lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1406533405-6899-5-git-send-email-a3at.mail@gmail.com>
Date:	Mon, 28 Jul 2014 11:43:25 +0400
From:	Azat Khuzhin <a3at.mail@...il.com>
To:	linux-ext4@...r.kernel.org
Cc:	tytso@....edu, darrick.wong@...cle.com, adilger@...ger.ca,
	Azat Khuzhin <a3at.mail@...il.com>
Subject: [PATCH 4/4 v3] tune2fs: update journal users while updating fs UUID (with external journal)

When we have fs with external journal device, and updating it's UUID, we
should update UUID in users list for that external journal device.

Before:
$ tune2fs -U clear /tmp/dev
tune2fs 1.42.10 (18-May-2014)
$ dumpe2fs /tmp/dev | fgrep UUID
dumpe2fs 1.42.10 (18-May-2014)
Filesystem UUID:          <none>
Journal UUID:             da1f2ed0-60f6-aaaa-92fd-738701418523
$ dumpe2fs /tmp/journal | fgrep users -A10
dumpe2fs 1.42.10 (18-May-2014)
Journal number of users:  2
Journal users:            0707762d-638e-4bc6-944e-ae8ee7a3359e
                          0ad849df-1041-4f0a-b1c1-2f949d6a1e37

After:
$ sudo tune2fs -U clear /tmp/dev
tune2fs 1.43-WIP (18-May-2014)
$ dumpe2fs /tmp/dev | fgrep UUID
dumpe2fs 1.42.10 (18-May-2014)
Filesystem UUID:          <none>
Journal UUID:             da1f2ed0-60f6-aaaa-92fd-738701418523
$ dumpe2fs /tmp/journal | fgrep users -A10
dumpe2fs 1.42.10 (18-May-2014)
Journal number of users:  2
Journal users:            0707762d-638e-4bc6-944e-ae8ee7a3359e
                          00000000-0000-0000-0000-000000000000

Also add some consts to avoid *magic numbers*:
- UUID_STR_SIZE
- UUID_SIZE
- JFS_USERS_MAX
- JFS_USERS_SIZE

Proposed-by: Andreas Dilger <adilger@...ger.ca>
Signed-off-by: Azat Khuzhin <a3at.mail@...il.com>
---
 lib/ext2fs/ext2fs.h     |  2 ++
 lib/ext2fs/kernel-jbd.h |  6 +++-
 misc/tune2fs.c          | 90 +++++++++++++++++++++++++++++++++++++++++++++----
 misc/uuidd.c            |  3 +-
 4 files changed, 93 insertions(+), 8 deletions(-)

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index ab57534..d3a34d5 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -39,6 +39,8 @@ extern "C" {
 #define SUPERBLOCK_OFFSET	1024
 #define SUPERBLOCK_SIZE		1024
 
+#define UUID_STR_SIZE 37
+
 /*
  * The last ext2fs revision level that this version of the library is
  * able to support.
diff --git a/lib/ext2fs/kernel-jbd.h b/lib/ext2fs/kernel-jbd.h
index 059bf8f..2baae73 100644
--- a/lib/ext2fs/kernel-jbd.h
+++ b/lib/ext2fs/kernel-jbd.h
@@ -164,6 +164,9 @@ typedef struct journal_revoke_header_s
 #define JFS_FLAG_LAST_TAG	8	/* last tag in this descriptor block */
 
 
+#define UUID_SIZE 16
+#define JFS_USERS_MAX 48
+#define JFS_USERS_SIZE (UUID_SIZE * JFS_USERS_MAX)
 /*
  * The journal superblock.  All fields are in big-endian byte order.
  */
@@ -208,7 +211,8 @@ typedef struct journal_superblock_s
 	__u32	s_padding[44];
 
 /* 0x0100 */
-	__u8	s_users[16*48];		/* ids of all fs'es sharing the log */
+	__u8	s_users[JFS_USERS_SIZE];		/* ids of all fs'es sharing the log */
+
 /* 0x0400 */
 } journal_superblock_t;
 
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 74e57ae..0c1feb1 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -207,6 +207,18 @@ static int get_journal_sb(ext2_filsys jfs, char buf[SUPERBLOCK_SIZE])
 	return 0;
 }
 
+static void *
+journal_user(char uuid[UUID_SIZE], char s_users[JFS_USERS_SIZE], int nr_users)
+{
+	int i;
+	for (i = 0; i < nr_users; i++) {
+		if (memcmp(uuid, &s_users[i * UUID_SIZE], UUID_SIZE) == 0)
+			return &s_users[i * UUID_SIZE];
+	}
+
+	return NULL;
+}
+
 /*
  * Remove an external journal from the filesystem
  */
@@ -261,11 +273,8 @@ static int remove_journal_device(ext2_filsys fs)
 	jsb = (journal_superblock_t *) buf;
 	/* Find the filesystem UUID */
 	nr_users = ntohl(jsb->s_nr_users);
-	for (i = 0; i < nr_users; i++) {
-		if (memcmp(fs->super->s_uuid, &jsb->s_users[i * 16], 16) == 0)
-			break;
-	}
-	if (i >= nr_users) {
+
+	if (!journal_user(fs->super->s_uuid, jsb->s_users, nr_users)) {
 		fputs(_("Filesystem's UUID not found on journal device.\n"),
 		      stderr);
 		commit_remove_journal = 1;
@@ -1915,6 +1924,68 @@ static int tune2fs_setup_tdb(const char *name, io_manager *io_ptr)
 	return retval;
 }
 
+int
+fs_update_journal_user(struct ext2_super_block *sb, char old_uuid[UUID_SIZE])
+{
+	int retval, nr_users, start;
+	journal_superblock_t *jsb;
+	ext2_filsys jfs;
+	char *j_uuid, *journal_path;
+	char uuid[UUID_STR_SIZE];
+	char buf[SUPERBLOCK_SIZE];
+
+	if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) ||
+		uuid_is_null(sb->s_journal_uuid))
+		return 0;
+
+	uuid_unparse(sb->s_journal_uuid, uuid);
+	journal_path = blkid_get_devname(NULL, "UUID", uuid);
+	if (!journal_path)
+		return 0;
+
+	retval = ext2fs_open2(journal_path, io_options,
+			      EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_RW,
+			      0, 0, unix_io_manager, &jfs);
+	if (retval) {
+		com_err(program_name, retval,
+			_("while trying to open %s"),
+			journal_path);
+		return retval;
+	}
+
+	if ((retval = get_journal_sb(jfs, buf))) {
+		if (retval == EXT2_ET_UNSUPP_FEATURE)
+			fprintf(stderr, _("%s is not a journal device.\n"),
+				journal_path);
+		return retval;
+	}
+
+	jsb = (journal_superblock_t *) buf;
+	/* Find the filesystem UUID */
+	nr_users = ntohl(jsb->s_nr_users);
+
+	if (!(j_uuid = journal_user(old_uuid, jsb->s_users, nr_users))) {
+		fputs(_("Filesystem's UUID not found on journal device.\n"),
+		      stderr);
+		return EXT2_ET_LOAD_EXT_JOURNAL;
+	}
+
+	memcpy(j_uuid, sb->s_uuid, UUID_SIZE);
+
+	start = ext2fs_journal_sb_start(jfs->blocksize);
+	/* Write back the journal superblock */
+	if ((retval = io_channel_write_blk64(jfs->io, start,
+	    -SUPERBLOCK_SIZE, buf))) {
+		com_err(program_name, retval,
+			"while writing journal superblock.");
+		return retval;
+	}
+
+	ext2fs_close(jfs);
+
+	return 0;
+}
+
 int main(int argc, char **argv)
 {
 	errcode_t retval;
@@ -2203,6 +2274,7 @@ retry_open:
 		int set_csum = 0;
 		dgrp_t i;
 		char buf[SUPERBLOCK_SIZE];
+		char old_uuid[UUID_SIZE];
 
 		if (sb->s_feature_ro_compat &
 		    EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
@@ -2230,6 +2302,8 @@ retry_open:
 			if (i >= fs->group_desc_count)
 				set_csum = 1;
 		}
+
+		memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
 		if ((strcasecmp(new_UUID, "null") == 0) ||
 		    (strcasecmp(new_UUID, "clear") == 0)) {
 			uuid_clear(sb->s_uuid);
@@ -2264,9 +2338,13 @@ retry_open:
 				goto closefs;
 		} else if (rc != EXT2_ET_UNSUPP_FEATURE)
 			goto closefs;
-		else
+		else {
 			rc = 0; /** Reset rc to avoid ext2fs_mmp_stop() */
 
+			if ((rc = fs_update_journal_user(sb, old_uuid)))
+				goto closefs;
+		}
+
 		ext2fs_mark_super_dirty(fs);
 	}
 	if (I_flag) {
diff --git a/misc/uuidd.c b/misc/uuidd.c
index 5a53138..02ca6be 100644
--- a/misc/uuidd.c
+++ b/misc/uuidd.c
@@ -36,6 +36,7 @@ extern int optind;
 #include "uuid/uuid.h"
 #include "uuid/uuidd.h"
 #include "nls-enable.h"
+#include "ext2fs/ext2fs.h"
 
 #ifdef __GNUC__
 #define CODE_ATTR(x) __attribute__(x)
@@ -236,7 +237,7 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
 	uuid_t			uu;
 	mode_t			save_umask;
 	char			reply_buf[1024], *cp;
-	char			op, str[37];
+	char			op, str[UUID_STR_SIZE];
 	int			i, s, ns, len, num;
 	int			fd_pidfile, ret;
 
-- 
2.0.1

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ