[Ocfs-tools-commits] smushran commits r235 - in trunk/format: . inc

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Oct 30 16:52:02 PDT 2007


Author: smushran
Date: 2007-10-30 16:52:01 -0700 (Tue, 30 Oct 2007)
New Revision: 235

Added:
   trunk/format/bug6468701.c
Modified:
   trunk/format/Makefile
   trunk/format/inc/format.h
Log:
bug6468701 added to add the facility to clear incorrectly set global bitmap bits

Modified: trunk/format/Makefile
===================================================================
--- trunk/format/Makefile	2006-10-09 21:04:31 UTC (rev 234)
+++ trunk/format/Makefile	2007-10-30 23:52:01 UTC (rev 235)
@@ -11,7 +11,7 @@
 
 CFLAGS = $(OPTS) -fno-strict-aliasing $(WARNINGS) -pthread $(GLIB_CFLAGS)
 
-SBIN_PROGRAMS = mkfs.ocfs tuneocfs
+SBIN_PROGRAMS = mkfs.ocfs tuneocfs bug6468701
 
 INCLUDES = -I$(TOPDIR)/libocfs/Common/inc -I$(TOPDIR)/libocfs/Linux/inc -Iinc -I$(TOPDIR)/libocfs
 DEFINES = -DLINUX -DUSERSPACE_TOOL -DFORMAT_OCFS
@@ -32,7 +32,7 @@
 
 CFLAGS += $(OPTIMIZE)
 
-VERSION_FILES = format.c frmtport.c inc/format.h inc/frmtport.h journal.c mounted.c system.c tune.c inc/tune.h inc/jfs_compat.h inc/kernel-jbd.h inc/kernel-list.h
+VERSION_FILES = format.c frmtport.c inc/format.h inc/frmtport.h journal.c mounted.c system.c tune.c inc/tune.h inc/jfs_compat.h inc/kernel-jbd.h inc/kernel-list.h bug6468701.c
 VERSION_SRC = frmtport.c
 VERSION_PREFIX = OCFS
 
@@ -65,6 +65,9 @@
 tuneocfs: tune.o frmtport.o $(TOPDIR)/libocfs/libocfs.a
 	$(LINK) -L$(TOPDIR)/libocfs -locfs
 
+bug6468701: bug6468701.o frmtport.o $(TOPDIR)/libocfs/libocfs.a
+	$(LINK) -L$(TOPDIR)/libocfs -locfs
+
 dist-incdir:
 	$(TOPDIR)/mkinstalldirs $(DIST_DIR)/inc
 

Added: trunk/format/bug6468701.c
===================================================================
--- trunk/format/bug6468701.c	                        (rev 0)
+++ trunk/format/bug6468701.c	2007-10-30 23:52:01 UTC (rev 235)
@@ -0,0 +1,392 @@
+/*
+ * bug6468701.c
+ *
+ * Copyright (C) 2002, 2007 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Sunil Mushran
+ */
+
+/*
+ * This is a temporary tool to unset bits in the global bitmap.
+ * Fixes bug#6468701.
+ *
+ * User will input ranges of bits as outputed by fsck.ocfs -W.
+ * This tool will load the global bitmap, unset the bits and
+ * write it back. It will also change the summary as kept in
+ * the bitmap block (3rd block).
+ */
+
+#include <format.h>
+#include <tune.h>
+#include <stdio_ext.h>
+
+#define VOL_BITMAP_BYTES         (1024 * 1024)
+
+/* getopt stuff */
+int getopt(int argc, char *const argv[], const char *optstring);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+ocfs_super *osb = NULL;
+struct super_block sb;
+ocfs_vol_disk_hdr *vdh = NULL;
+ocfs_global_ctxt OcfsGlobalCtxt;
+
+ocfs_options opts = {
+	.device = "",
+	.block_size = 0,
+	.clear_data_blocks = false,
+	.force_op = false,
+	.gid = 0,
+	.volume_label = "",
+	.mount_point = "",
+	.query_only = false,
+	.perms = 0755,
+	.quiet = false,
+	.uid = 0,
+	.print_progress = false,
+	.slot_num = OCFS_INVALID_NODE_NUM,
+	.device_size = 0,
+	.start_bit = -1,
+	.end_bit = -1
+};
+
+bool ignore_signal = false;
+int file = 0;
+int rawminor = 0;
+char rawdev[FILE_NAME_SIZE];
+
+char *usage_string =
+"usage: %s [-S bitnum] [-E bitnum] [-h?] device\n"
+"	-S Start bit\n"
+"	-E End bit\n"
+"	-h Help\n";
+
+/*
+ * main()
+ *
+ */
+int main(int argc, char **argv)
+{
+	ocfs_vol_disk_hdr *volhdr = NULL;
+	ocfs_bitmap_lock *bmblck = NULL;
+	char *vol_bm = NULL;
+	__u32 sect_size = OCFS_SECTOR_SIZE;
+	bool ocfs_vol = false;
+	int proceed;
+	char *node_names[OCFS_MAXIMUM_NODES];
+	__u32 nodemap = 0;
+	int i;
+	__u64 bit;
+	__u64 vol_size = 0;
+
+	for (i = 0; i < OCFS_MAXIMUM_NODES; ++i)
+		node_names[i] = NULL;
+
+#define INSTALL_SIGNAL(sig) 						\
+	do { 								\
+		if (signal(sig, handle_signal) == SIG_ERR) {		\
+			fprintf(stderr, "Could not set " #sig "\n");	\
+			goto bail;					\
+		}							\
+	} while(0)
+
+	INSTALL_SIGNAL(SIGTERM);
+	INSTALL_SIGNAL(SIGINT);
+
+	init_raw_cleanup_message();
+
+	/* Read the options */
+	if (!read_options(argc, argv))
+		goto bail;
+
+	/* Validate the options */
+	if (!validate_options(argv[0]))
+		goto bail;
+
+	printf("*** WARNING *** This is a tool to fix bug#6468701 to clear bits in the global bitmap.\n");
+	printf("Proceed (y/N): ");
+	proceed = getchar();
+	if (toupper(proceed) != 'Y') {
+		printf("Aborting operation.\n");
+		goto bail;
+	}
+	__fpurge(stdin);
+
+	/* Open the disk */
+	if (!(file = OpenDisk(opts.device)))
+		goto bail;
+
+	/* Allocate mem */
+	volhdr = MemAlloc(OCFS_SECTOR_SIZE);
+	bmblck = MemAlloc(OCFS_SECTOR_SIZE);
+	if (!volhdr || !bmblck)
+		goto bail;
+
+	if ((vol_bm = MemAlloc(VOL_BITMAP_BYTES)) == NULL) {
+		goto bail;
+	}
+	memset(vol_bm, 0, VOL_BITMAP_BYTES);
+
+	/* Is this an existing ocfs volume */
+	if (!is_ocfs_volume(file, volhdr, &ocfs_vol, sect_size))
+		goto bail;
+
+	/* Abort if not an ocfs volume */
+	if (!ocfs_vol) {
+		fprintf(stderr, "%s is not an ocfs volume.\nAborting.\n", opts.device);
+		goto bail;
+	}
+
+	/* Get the partition Information */
+	if (!(GetDiskGeometry(file, &vol_size, &sect_size)))
+		goto bail;
+
+	/* close and open after binding to raw */
+	safeclose(file);
+
+	/* bind device to raw */
+	if (bind_raw(opts.device, &rawminor, rawdev, sizeof(rawdev)))
+		goto bail;
+
+	/* Open the disk */
+	if (!(file = OpenDisk(rawdev)))
+		goto bail;
+
+	/* read volume header */
+	if (!read_sectors(file, 0, 1, sect_size, (void *)volhdr))
+		goto bail;
+
+	vdh = volhdr;
+
+	/* confirm bits are valid */
+	if (opts.start_bit == -1 || opts.start_bit > vdh->num_clusters) {
+		fprintf(stderr, "Error: Invalid start bit. Aborting\n");
+		goto bail;
+	}
+
+	if (opts.end_bit != -1) {
+		if (opts.end_bit < opts.start_bit || opts.end_bit > vdh->num_clusters) {
+			fprintf(stderr, "Error: Invalid end bit. Aborting\n");
+			goto bail;
+		}
+	}
+
+	if (opts.end_bit == -1)
+		printf("Clear bit %d\n", opts.start_bit);
+	else
+		printf("Clear bits %d to %d\n", opts.start_bit,  opts.end_bit);
+	printf("Proceed (y/N): ");
+	proceed = 0;
+	proceed = getchar();
+	if (toupper(proceed) != 'Y') {
+		printf("Aborting operation.\n");
+		goto bail;
+	}
+
+	/* Check for heartbeat for any write operation */
+	if (!check_heart_beat(&file, rawdev, volhdr, &nodemap, sect_size))
+		goto bail;
+
+	if (nodemap) {
+		/* Exit as device is mounted on some node */
+		get_node_names(file, volhdr, node_names, sect_size);
+		printf("%s mounted on nodes:", opts.device);
+		print_node_names(node_names, nodemap);
+		printf("Aborting.\n");
+		goto bail;
+	}
+
+	/* read bitmap lock block */
+	if (!read_sectors(file, 1024, 1, sect_size, (void *)bmblck))
+		goto bail;
+
+	/* read global bitmap */
+	printf("Reading Global bitmap\n");
+	if (!read_sectors(file, volhdr->bitmap_off, 1, VOL_BITMAP_BYTES, (void *)vol_bm))
+		goto bail;
+
+	printf("Used bits = %u\n", bmblck->used_bits);
+
+	/* do not allow interrupts */
+	ignore_signal = true;
+
+	printf("Clearing bits in Global bitmap\n");
+	for (bit = opts.start_bit; bit <= opts.end_bit; ++bit) {
+		if(__test_and_clear_bit(bit, vol_bm))
+			bmblck->used_bits--;
+	}
+
+	/* write global bitmap */
+	printf("Writing Global bitmap\n");
+	if (!write_sectors(file, volhdr->bitmap_off, 1, VOL_BITMAP_BYTES, (void *)vol_bm))
+		goto bail;
+
+	/* Write bitmap lock block */
+	if (!write_sectors(file, 1024, 1, sect_size, (void *)bmblck))
+		goto bail;
+
+	printf("Changes written to disk.\n");
+	printf("New used bits = %u\n", bmblck->used_bits);
+
+bail:
+	safefree(vol_bm);
+	safefree(bmblck);
+	safefree(volhdr);
+
+	for (i = 0; i < OCFS_MAXIMUM_NODES; ++i)
+		safefree(node_names[i]);
+
+	safeclose(file);
+	unbind_raw(rawminor);
+	return 0;
+}				/* main */
+
+
+static void do_help()
+{
+
+	printf("*** WARNING *** This is a tool to fix bug#6468701 to clear bits in the global bitmap.\n"
+	       "Usage instructions:\n"
+	       "1. Run fsck.ocfs -Wn /dev/sdX to see if there are any unused set bits.\n"
+	       "\t$ fsck.ocfs -Wn /dev/sdb1\n"
+	       "\tfsck.ocfs 1.1.7-PROD1 Mon Oct  9 14:06:13 PDT 2006 (build 7ea9920f5e15e0266a3587b907c9d794)\n"
+	       "\tChecking Global Bitmap...\n"
+	       "\tWARNING: Unused bits (wasted space) detected in the global bitmap.\n"
+	       "\tList of unused bits in the global bitmap: 16232-16335, 16848-16951, 20416-20487\n"
+	       "\t/dev/sdb1: clean, 11285 objects, 12523/2174973 blocks\n"
+	       "2. Run bug6468701 with the bit numbers.\n"
+	       "\t$ ./bug6468701 -S 20416 -E 20487 /dev/sdb3\n"
+	       "\t*** WARNING *** This is a tool to fix bug#6468701 to clear bits in the global bitmap.\n"
+	       "\tProceed (y/N): y\n"
+	       "\tClear bits 20416 to 20487\n"
+	       "\tProceed (y/N): y\n"
+	       "\tReading Global bitmap\n"
+	       "\tUsed bits = 12211\n"
+	       "\tClearing bits in Global bitmap\n"
+	       "\tWriting Global bitmap\n"
+	       "\tChanges written to disk.\n"
+	       "\tNew used bits = 12139\n"
+	       "3. Rerun for the other unused range. If single bit, specify it with -S.\n"
+	       "4. After this is done, rerun fsck.ocfs -Wn to check\n"
+	       "\t$ fsck.ocfs -Wn /dev/sdb3\n"
+	       "\tfsck.ocfs 1.1.7-PROD1 Mon Oct  9 14:06:13 PDT 2006 (build 7ea9920f5e15e0266a3587b907c9d794)\n"
+	       "\t/dev/sdb3: clean, 11285 objects, 12523/2174973 blocks\n\n");
+	exit(1);
+}
+
+/*
+ * read_options()
+ *
+ * "usage: %s [-S bitnum] [-E bitnum] device\n\n"
+ *
+ */
+int read_options(int argc, char **argv)
+{
+	int ret = 1;
+	int c;
+
+	if (argc < 2) {
+		version(argv[0]);
+		usage(argv[0]);
+		ret = 0;					  
+		goto bail;
+	}
+
+	while(1) {
+		c = getopt(argc, argv, "h?S:E:");
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'S':	/* start bit */
+			opts.start_bit = strtoull(optarg, NULL, 0);
+			break;
+
+		case 'E':	/* End bit */
+			opts.end_bit = strtoull(optarg, NULL, 0);
+			break;
+
+		case 'h':
+		case '?':
+			do_help();
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (ret && optind < argc && argv[optind])
+			strncpy(opts.device, argv[optind], sizeof(opts.device)-1);
+
+bail:
+	return ret;
+}				/* read_options */
+
+
+/*
+ * validate_options()
+ *
+ */
+bool validate_options(char *progname)
+{
+	if (opts.device[0] == '\0') {
+		fprintf(stderr, "Error: Device not specified.\n");
+		usage(progname);
+		return 0;
+	}
+
+	if (opts.start_bit == -1) {
+		fprintf(stderr, "Error: Invalid start bit.\n");
+		usage(progname);
+		return 0;
+	}
+
+	if (opts.end_bit != -1) {
+		if (opts.end_bit < opts.start_bit) {
+			fprintf(stderr, "Error: Invalid end bit.\n");
+			usage(progname);
+			return 0;
+		}
+	}
+
+	return 1;
+}				/* validate_options */
+
+/*
+ * handle_signal()
+ */
+void handle_signal(int sig)
+{
+	switch (sig) {
+	case SIGTERM:
+	case SIGINT:
+		if (!ignore_signal) {
+			fprintf(stderr, "\nOperation interrupted.\nAborting.\n");
+			safeclose(file);
+			unbind_raw(rawminor);
+			exit(1);
+		}
+		else
+		{
+			signal(sig, handle_signal);
+		}
+		break;
+	}
+}				/* handle_signal */

Modified: trunk/format/inc/format.h
===================================================================
--- trunk/format/inc/format.h	2006-10-09 21:04:31 UTC (rev 234)
+++ trunk/format/inc/format.h	2007-10-30 23:52:01 UTC (rev 235)
@@ -160,6 +160,8 @@
 	int convert;
 	__u32 disk_hb;
 	__u32 hb_timeo;
+	__u32 start_bit;
+	__u32 end_bit;
 }
 ocfs_options;
 




More information about the Ocfs-tools-commits mailing list