[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, §_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