Hello community,
here is the log from the commit of package ocfs2-tools for openSUSE:Factory checked in at 2015-04-25 09:53:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ocfs2-tools (Old)
and /work/SRC/openSUSE:Factory/.ocfs2-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ocfs2-tools"
Changes:
--------
--- /work/SRC/openSUSE:Factory/ocfs2-tools/ocfs2-tools.changes 2014-02-01 09:40:18.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.ocfs2-tools.new/ocfs2-tools.changes 2015-04-25 11:25:58.000000000 +0200
@@ -1,0 +2,33 @@
+Mon Feb 9 03:26:29 UTC 2015 - ghe@suse.com
+
+- Update ocfs2-tools.tar.bz2 to upstream v1.8.3
+- Drop patches (merged upstream):
+ - fix-indexed-dirs.patch
+ - 0001-fswreck-Create-a-loop-in-group-chains.patch
+ - 0002-Break-a-chain-loop-in-group-desc.patch
+ - restore-g_list_append.patch
+ - ocfs2console-libraries-include-aio.patch
+ - libocfs2-needs-libaio.patch
+ - libocfs2-Change-asserts-to-error.patch
+- Drop patches for ocfs2_controld
+ - force-debug.patch
+ - extra-debug.patch
+ - bug-805764-ocfs2-controld.patch
+ - bnc804707-reduce-RR-priority.patch
+ - use-symlink-in-udev-rules.patch
+
+-------------------------------------------------------------------
+Tue Feb 11 16:57:54 UTC 2014 - rgoldwyn@suse.com
+
+- Recommend ocfs2-kmp
+- Autosetup pcmk if no cluster stack found (bnc#862758)
+ + 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch
+- Err if cannot write to cluster_stack (cluster mismatch)
+ + 0003-Auto-setup-cluster_stack-based-on-what-is-on-disk.patch
+
+-------------------------------------------------------------------
+Mon Feb 10 12:32:37 UTC 2014 - rgoldwyn@suse.com
+
+- Update summary and description for the -o2cb package (bnc#862761)
+
+-------------------------------------------------------------------
Old:
----
0001-fswreck-Create-a-loop-in-group-chains.patch
0002-Break-a-chain-loop-in-group-desc.patch
bnc804707-reduce-RR-priority.patch
bug-805764-ocfs2-controld.patch
extra-debug.patch
fix-indexed-dirs.patch
force-debug.patch
libocfs2-Change-asserts-to-error.patch
libocfs2-needs-libaio.patch
ocfs2-tools-1.8.2+git.1361836695.ff84eb5.tar.gz
ocfs2console-libraries-include-aio.patch
restore-g_list_append.patch
use-symlink-in-udev-rules.patch
New:
----
0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch
ocfs2-tools-1.8.3+git.1418704844.65fac00.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ocfs2-tools.spec ++++++
--- /var/tmp/diff_new_pack.bF7rHq/_old 2015-04-25 11:25:59.000000000 +0200
+++ /var/tmp/diff_new_pack.bF7rHq/_new 2015-04-25 11:25:59.000000000 +0200
@@ -1,7 +1,7 @@
#
# spec file for package ocfs2-tools
#
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: ocfs2-tools
-Version: 1.8.2+git.1361836695.ff84eb5
+Version: 1.8.3+git.1418704844.65fac00
Release: 0
Summary: Oracle Cluster File System 2 Core Tools
License: GPL-2.0+
@@ -26,8 +26,6 @@
Source: ocfs2-tools-%{version}.tar.gz
Source1: o2cb.ocf
Source2: reflink.tar.bz2
-Patch101: force-debug.patch
-Patch102: extra-debug.patch
Patch103: debug-ocfs2_hb_ctl.patch
Patch105: bug-470741-debug_start_failures.patch
Patch106: ocfs2-devel.diff
@@ -37,21 +35,12 @@
Patch204: dont-use-var-lock-subsys.patch
Patch205: ocfs2-tools-kernel33.patch
Patch206: ocfs2-tools-resource.patch
-Patch207: fix-indexed-dirs.patch
-Patch208: 0001-fswreck-Create-a-loop-in-group-chains.patch
-Patch209: 0002-Break-a-chain-loop-in-group-desc.patch
-Patch210: restore-g_list_append.patch
-Patch212: bug-805764-ocfs2-controld.patch
-Patch213: bnc804707-reduce-RR-priority.patch
-Patch214: use-symlink-in-udev-rules.patch
-Patch215: ocfs2console-libraries-include-aio.patch
-Patch220: libocfs2-needs-libaio.patch
-Patch221: libocfs2-Change-asserts-to-error.patch
Patch222: 0001-Use-cmap-for-getting-cluster-name.patch
Patch223: 0002-Remove-controld-dependency-in-group_join-leave.patch
Patch224: 0003-Auto-setup-cluster_stack-based-on-what-is-on-disk.patch
Patch225: 0004-mkfs.ocfs2-Abort-if-cluster-information-is-not-detec.patch
Patch226: 0005-mkfs-Setup-cluster_stack-if-not-setup-based-on-what-.patch
+Patch227: 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch
BuildRequires: autoconf
BuildRequires: e2fsprogs-devel
@@ -75,8 +64,7 @@
Requires: modutils
Requires: net-tools
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-%if 0%{?suse_version} < 1120
-# There's no separate kmp for openSUSE 11.2
+%if 0%{?suse_version} < 1320
Recommends: ocfs2-kmp
%endif
@@ -130,20 +118,18 @@
OCFS2-aware applications.
%package o2cb
-Summary: Oracle Cluster File System 2 Core Tools
+Summary: Oracle Cluster File System 2 tools for the native o2cb stack
Group: System/Filesystems
Requires: ocfs2-tools = %{version}
%description o2cb
OCFS is the Oracle Cluster File System.
-This package contains the core user-space tools needed for creating and
-managing the file system.
+This package contains the tools to manage the native o2cb stack for the
+OCFS2 filesystem.
%prep
%setup -q -a 2
-%patch101 -p1
-%patch102 -p1
%patch103 -p1
%patch105 -p1
%patch106 -p1
@@ -153,21 +139,12 @@
%patch204 -p1
%patch205 -p1
%patch206 -p1
-%patch207 -p1
-%patch208 -p1
-%patch209 -p1
-%patch210 -p1
-%patch212 -p1
-%patch213 -p1
-%patch214 -p1
-%patch215 -p1
-%patch220 -p1
-%patch221 -p1
%patch222 -p1
%patch223 -p1
%patch224 -p1
%patch225 -p1
%patch226 -p1
+%patch227 -p1
%build
export PROJECT="ocfs2-tools"
++++++ 0001-Use-cmap-for-getting-cluster-name.patch ++++++
--- /var/tmp/diff_new_pack.bF7rHq/_old 2015-04-25 11:25:59.000000000 +0200
+++ /var/tmp/diff_new_pack.bF7rHq/_new 2015-04-25 11:25:59.000000000 +0200
@@ -3,7 +3,6 @@
Date: Sat, 21 Dec 2013 18:41:04 -0600
Subject: [PATCH] Use cmap for getting cluster name
-Signed-off-by: Goldwyn Rodrigues
---
debugfs.ocfs2/Makefile | 2 +-
libo2cb/o2cb_abi.c | 79 +++++++++++++++++++++++++++-----------------------
++++++ 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch ++++++
From 1e041fdfb09bfc39aa37bea7d491bcf56794fa1c Mon Sep 17 00:00:00 2001
From: Goldwyn Rodrigues
Date: Tue, 11 Feb 2014 10:54:23 -0600
Subject: [PATCH] Auto setup pcmk stack as default if no stack is setup
Note: This changes the default behavior from classic stack to pcmk
---
libo2cb/o2cb_abi.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/libo2cb/o2cb_abi.c b/libo2cb/o2cb_abi.c
index 5e0c4fb..26ea03e 100644
--- a/libo2cb/o2cb_abi.c
+++ b/libo2cb/o2cb_abi.c
@@ -172,7 +172,9 @@ static errcode_t determine_stack(void)
ssize_t len;
char line[100];
errcode_t err = O2CB_ET_SERVICE_UNAVAILABLE;
+ int setup_performed = 0;
+redo:
len = read_stack_file(line, sizeof(line));
if (len > 0) {
if (line[len - 1] == '\n') {
@@ -192,8 +194,11 @@ static errcode_t determine_stack(void)
err = 0;
}
} else if (len == -ENOENT) {
- current_stack = &classic_stack;
- err = 0;
+ if (!setup_performed) {
+ o2cb_setup_stack(OCFS2_PCMK_CLUSTER_STACK);
+ setup_performed = 1;
+ goto redo;
+ }
}
return err;
--
1.8.4
++++++ _service ++++++
--- /var/tmp/diff_new_pack.bF7rHq/_old 2015-04-25 11:25:59.000000000 +0200
+++ /var/tmp/diff_new_pack.bF7rHq/_new 2015-04-25 11:25:59.000000000 +0200
@@ -3,7 +3,7 @@
<param name="url">git://oss.oracle.com/git/ocfs2-tools.git</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="versionformat">1.8.2+git.%ct.%h</param>
+ <param name="versionformat">1.8.3+git.%ct.%h</param>
<param name="revision">master</param>
</service>
++++++ ocfs2-tools-1.8.2+git.1361836695.ff84eb5.tar.gz -> ocfs2-tools-1.8.3+git.1418704844.65fac00.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/configure.in new/ocfs2-tools-1.8.3+git.1418704844.65fac00/configure.in
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/configure.in 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/configure.in 2015-01-27 10:04:16.000000000 +0100
@@ -9,7 +9,7 @@
# Adjust these for the software version.
MAJOR_VERSION=1
MINOR_VERSION=8
-MICRO_VERSION=2
+MICRO_VERSION=3
EXTRA_VERSION=
DIST_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/commands.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/commands.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/commands.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/commands.c 2015-01-27 10:04:16.000000000 +0100
@@ -64,6 +64,7 @@
static void do_frag(char **args);
static void do_fs_locks(char **args);
static void do_group(char **args);
+static void do_grpextents(char **args);
static void do_hb(char **args);
static void do_help(char **args);
static void do_icheck(char **args);
@@ -188,6 +189,11 @@
"group ",
"Show chain group",
},
+ { "grpextents",
+ do_grpextents,
+ "grpextents ",
+ "Show free extents in a chain group",
+ },
{ "hb",
do_hb,
"hb",
@@ -1243,6 +1249,36 @@
return ;
}
+static void do_grpextents(char **args)
+{
+ struct ocfs2_group_desc *grp;
+ uint64_t blkno;
+ char *buf = NULL;
+ FILE *out;
+ errcode_t ret = 0;
+
+ if (process_inodestr_args(args, 1, &blkno) != 1)
+ return;
+
+ buf = gbls.blockbuf;
+ out = open_pager(gbls.interactive);
+ while (blkno) {
+ ret = ocfs2_read_group_desc(gbls.fs, blkno, buf);
+ if (ret) {
+ com_err(args[0], ret, "while reading block group "
+ "descriptor %"PRIu64"", blkno);
+ close_pager(out);
+ return;
+ }
+
+ grp = (struct ocfs2_group_desc *)buf;
+ dump_group_extents(out, grp);
+ blkno = grp->bg_next_group;
+ }
+
+ close_pager(out);
+}
+
static int dirblocks_proxy(ocfs2_filesys *fs, uint64_t blkno,
uint64_t bcount, uint16_t ext_flags,
void *priv_data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/dump.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/dump.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/dump.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/dump.c 2015-01-27 10:04:16.000000000 +0100
@@ -157,87 +157,30 @@
}
/*
- * dump_block_check
+ * dump_block_check()
*
+ * As the checksum is computed in the disk format, we have to swap_from_cpu
+ * before computing it.
*/
void dump_block_check(FILE *out, struct ocfs2_block_check *bc, void *block)
{
struct ocfs2_block_check tmp = *bc;
int crc_fail;
- enum ocfs2_block_type bt = ocfs2_detect_block(block);
- /* Swap block to little endian for compute_meta_ecc */
- switch (bt) {
- case OCFS2_BLOCK_INODE:
- case OCFS2_BLOCK_SUPERBLOCK:
- ocfs2_swap_inode_from_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_EXTENT_BLOCK:
- ocfs2_swap_extent_block_from_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_GROUP_DESCRIPTOR:
- ocfs2_swap_group_desc_from_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_DIR_BLOCK:
- ocfs2_swap_dir_entries_from_cpu(block,
- gbls.fs->fs_blocksize);
- break;
- case OCFS2_BLOCK_XATTR:
- ocfs2_swap_xattr_block_from_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_REFCOUNT:
- ocfs2_swap_refcount_block_from_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_DXROOT:
- ocfs2_swap_dx_root_from_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_DXLEAF:
- ocfs2_swap_dx_leaf_from_cpu(block);
- break;
- default:
- fprintf(out, "Unable to determine block type");
- return;
+ fprintf(out, "\tCRC32: %.8"PRIx32" ECC: %.4"PRIx16"\n",
+ le32_to_cpu(tmp.bc_crc32e), le16_to_cpu(tmp.bc_ecc));
+
+ /* Cannot validate unknown blocks */
+ if (ocfs2_detect_block(block) == OCFS2_BLOCK_UNKNOWN) {
+ fprintf(out, "\t**UNKNOWN BLOCK** (Cannot validate checksum)\n");
+ return;
}
- /* Re-compute based on what we got from disk */
+ ocfs2_swap_block_from_cpu(gbls.fs, block);
ocfs2_compute_meta_ecc(gbls.fs, block, bc);
-
- /* Swap block back to CPU */
- switch (bt) {
- case OCFS2_BLOCK_INODE:
- case OCFS2_BLOCK_SUPERBLOCK:
- ocfs2_swap_inode_to_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_EXTENT_BLOCK:
- ocfs2_swap_extent_block_to_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_GROUP_DESCRIPTOR:
- ocfs2_swap_group_desc_to_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_DIR_BLOCK:
- ocfs2_swap_dir_entries_to_cpu(block,
- gbls.fs->fs_blocksize);
- break;
- case OCFS2_BLOCK_XATTR:
- ocfs2_swap_xattr_block_to_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_REFCOUNT:
- ocfs2_swap_refcount_block_to_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_DXROOT:
- ocfs2_swap_dx_root_to_cpu(gbls.fs, block);
- break;
- case OCFS2_BLOCK_DXLEAF:
- ocfs2_swap_dx_leaf_to_cpu(block);
- break;
- default:
- break;
- }
+ ocfs2_swap_block_to_cpu(gbls.fs, block);
crc_fail = memcmp(bc, &tmp, sizeof(*bc));
-
- fprintf(out, "\tCRC32: %.8"PRIx32" ECC: %.4"PRIx16"\n",
- le32_to_cpu(tmp.bc_crc32e), le16_to_cpu(tmp.bc_ecc));
if (crc_fail)
fprintf(out, "\t**FAILED CHECKSUM** Computed CRC32: %.8"
PRIx32" ECC: %.4"PRIx16"\n",
@@ -547,6 +490,15 @@
return ;
}
+void dump_group_extents(FILE *out, struct ocfs2_group_desc *grp)
+{
+ fprintf(out, "\tGroup# %"PRIu64" Total: %u Used: %u Free: %u\n",
+ (uint64_t)grp->bg_blkno, grp->bg_bits,
+ (grp->bg_bits - grp->bg_free_bits_count),
+ grp->bg_free_bits_count);
+ print_contig_bits(out, grp);
+}
+
/*
* dump_dir_entry()
*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/dump.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/dump.h
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/dump.h 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/dump.h 2015-01-27 10:04:16.000000000 +0100
@@ -42,6 +42,7 @@
void dump_chain_list (FILE *out, struct ocfs2_chain_list *cl);
void dump_extent_block (FILE *out, struct ocfs2_extent_block *blk);
void dump_group_descriptor (FILE *out, struct ocfs2_group_desc *grp, int index);
+void dump_group_extents(FILE *out, struct ocfs2_group_desc *grp);
int dump_dir_entry (struct ocfs2_dir_entry *rec, uint64_t blocknr, int offset, int blocksize,
char *buf, void *priv_data);
void dump_dx_root (FILE *out, struct ocfs2_dx_root_block *dx_root);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/utils.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/utils.h
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/utils.h 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/utils.h 2015-01-27 10:04:16.000000000 +0100
@@ -64,6 +64,7 @@
const char *dumproot, int verbose);
void crunch_strsplit(char **args);
void find_max_contig_free_bits(struct ocfs2_group_desc *gd, int *max_contig_free_bits);
+void print_contig_bits(FILE *out, struct ocfs2_group_desc *gd);
errcode_t get_debugfs_path(char *debugfs_path, int len);
errcode_t open_debugfs_file(const char *debugfs_path, const char *dirname,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/utils.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/utils.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/utils.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/utils.c 2015-01-27 10:04:16.000000000 +0100
@@ -816,6 +816,65 @@
}
}
+void print_contig_bits(FILE *out, struct ocfs2_group_desc *gd)
+{
+ int x, free_bits, start, end = 0, avg = 0, found = 0, total = 0;
+ int max_contig_free_bits = 0;
+
+#define HEADER_FORMAT "%-3s %-6s %-6s"
+#define DATA_FORMAT "%-3d %-6d %-6d"
+
+#define LEFT_HEADER "\t"HEADER_FORMAT" "
+#define MIDDLE_HEADER HEADER_FORMAT" "
+#define RIGHT_HEADER HEADER_FORMAT"\n"
+
+#define LEFT_DATA "\t"DATA_FORMAT" "
+#define MIDDLE_DATA DATA_FORMAT" "
+#define RIGHT_DATA DATA_FORMAT"\n"
+
+ while (end < gd->bg_bits) {
+ start = ocfs2_find_next_bit_clear(gd->bg_bitmap, gd->bg_bits,
+ end);
+ if (start >= gd->bg_bits)
+ break;
+
+ end = ocfs2_find_next_bit_set(gd->bg_bitmap, gd->bg_bits, start);
+ free_bits = end - start;
+
+ if (!free_bits)
+ continue;
+
+ if (!found) {
+ fprintf(out, LEFT_HEADER, "###", "Start", "Length");
+ fprintf(out, MIDDLE_HEADER, "###", "Start", "Length");
+ fprintf(out, RIGHT_HEADER, "###", "Start", "Length");
+ }
+
+ found++;
+ x = found % 3;
+ if (x == 1)
+ fprintf(out, LEFT_DATA, found, start, free_bits);
+ else if (x == 2)
+ fprintf(out, MIDDLE_DATA, found, start, free_bits);
+ else
+ fprintf(out, RIGHT_DATA, found, start, free_bits);
+
+ total += free_bits;
+
+ if (max_contig_free_bits < free_bits)
+ max_contig_free_bits = free_bits;
+ }
+
+ if (found) {
+ avg = total / found;
+ if (found % 3)
+ fprintf(out, "\n");
+ }
+
+ fprintf(out, "\tFree Extent Count: %d Longest: %d Average: %d\n\n",
+ found, max_contig_free_bits, avg);
+}
+
#define SYSFS_BASE "/sys/kernel/"
#define DEBUGFS_PATH SYSFS_BASE "debug"
#define DEBUGFS_ALTERNATE_PATH "/debug"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/fsck.ocfs2.checks.8.in new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/fsck.ocfs2.checks.8.in
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/fsck.ocfs2.checks.8.in 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/fsck.ocfs2.checks.8.in 2015-01-27 10:04:16.000000000 +0100
@@ -202,6 +202,15 @@
Answering yes decreases the number of recorded free bits so that it equals
the total number of bits in the group descriptor's bitmap.
+.SS "GROUP_CHAIN_LOOP"
+A chain may loop if the next field of the group descriptor points to one of
+the previous group descriptors in the chain. This causes the ocfs2 code, both
+user space and kernel module to loop forever.
+
+Answering yes breaks the loop at an optimum location so that all the existing
+group descriptors are in the chain. However, it cannot re-connect stray group
+descriptors and must rely on the rest of the fsck code to fix it.
+
.SS "CHAIN_COUNT"
The chain list embedded in an inode is limited by the block size and the
number of bytes consumed by the rest of the inode. A chain list header was
@@ -1149,6 +1158,23 @@
Answering yes will serialize the extents.
+.SS "DX_TREE_CORRUPT"
+The index tree of the directory is corrupt.
+
+Answering yes will rebuild the directory index, in pass 2.
+
+
+.SS "DX_TREE_MISSING"
+The index of this directory is missing.
+
+Answering yes will rebuild the directory index.
+
+.SS "BAD_CRC32"
+The metadata block has a bad CRC32, which means either the block or the
+crc32 field is corrupted.
+
+Answering yes will recalculate the CRC32.
+
.SH "SEE ALSO"
.BR debugfs.ocfs2(8)
.BR fsck.ocfs2(8)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass0.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass0.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass0.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass0.c 2015-01-27 10:04:16.000000000 +0100
@@ -666,6 +666,46 @@
return ret;
}
+static errcode_t break_loop(o2fsck_state *ost, struct ocfs2_chain_rec *chain,
+ unsigned int max_depth)
+{
+ uint64_t *list;
+ int i;
+ unsigned int depth = 0;
+ uint64_t blkno = chain->c_blkno;
+ char *buf;
+ struct ocfs2_group_desc *gd;
+ errcode_t ret = ocfs2_malloc0(sizeof(uint64_t) * max_depth, &list);
+ if (ret)
+ goto out;
+ ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf);
+ if (ret)
+ goto out;
+ gd = (struct ocfs2_group_desc *)buf;
+
+ while (blkno && (depth<=max_depth)) {
+ list[depth++] = blkno;
+ ret = ocfs2_read_group_desc(ost->ost_fs, blkno, buf);
+ if (ret)
+ goto out;
+ blkno = gd->bg_next_group;
+ for (i=0; ibg_next_group = 0;
+ verbosef("Breaking gd loop %"PRIu64"\n", blkno);
+ ret = ocfs2_write_group_desc(ost->ost_fs,
+ blkno, buf);
+ goto out;
+ }
+ }
+out:
+ if (list)
+ ocfs2_free(&list);
+ if (buf)
+ ocfs2_free(&buf);
+ return ret;
+}
+
/* this takes a slightly ridiculous number of arguments :/ */
static errcode_t check_chain(o2fsck_state *ost,
struct ocfs2_dinode *di,
@@ -675,7 +715,8 @@
char *buf2,
int *chain_changed,
ocfs2_bitmap *allowed,
- ocfs2_bitmap *forbidden)
+ ocfs2_bitmap *forbidden,
+ unsigned int max_depth)
{
struct ocfs2_group_desc *bg1 = (struct ocfs2_group_desc *)buf1;
struct ocfs2_group_desc *bg2 = (struct ocfs2_group_desc *)buf2;
@@ -792,6 +833,14 @@
/* the loop will now start by reading bg1->next_group */
memcpy(buf1, buf2, ost->ost_fs->fs_blocksize);
depth++;
+ if (depth > max_depth) {
+ if (prompt(ost, PY, PR_GROUP_CHAIN_LOOP,
+ "Loop detected in chain %d at block %"PRIu64
+ ". Break the loop?",cs->cs_chain_no,
+ (uint64_t) chain->c_blkno))
+ ret = break_loop(ost, chain, max_depth);
+ break;
+ }
}
/* we hit the premature end of a chain.. clear the last
@@ -854,6 +903,7 @@
int changed = 0, trust_next_free = 1;
errcode_t ret = 0;
uint64_t chain_bytes;
+ unsigned int num_gds, max_chain_len;
if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
strlen(OCFS2_INODE_SIGNATURE))) {
@@ -883,9 +933,12 @@
/* XXX should we check suballoc_node? */
cl = &di->id2.i_chain;
+ num_gds = (di->i_clusters + cl->cl_cpg)/cl->cl_cpg;
+ max_chain_len = (num_gds + cl->cl_count)/cl->cl_count;
- verbosef("cl cpg %u bpc %u count %u next %u\n",
- cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec);
+ verbosef("cl cpg %u bpc %u count %u next %u gds %u max_ch_len %u\n",
+ cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec,
+ num_gds, max_chain_len);
max_count = ocfs2_chain_recs_per_inode(ost->ost_fs->fs_blocksize);
@@ -948,7 +1001,7 @@
.cs_cpg = cl->cl_cpg,
};
ret = check_chain(ost, di, &cs, cr, buf1, buf2, &changed,
- allowed, forbidden);
+ allowed, forbidden, max_chain_len);
/* XXX what? not checking ret? */
if (cr->c_blkno != 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1.c 2015-01-27 10:04:16.000000000 +0100
@@ -917,10 +917,14 @@
}
ret = o2fsck_check_dx_dir(ost, di);
- if (ret) {
- com_err(whoami, ret, "while iterating over the dir indexed "
- "tree for directory inode %"PRIu64, (uint64_t)di->i_blkno);
- goto out;
+ if (ret && prompt(ost, PY, PR_DX_TREE_CORRUPT,
+ "Inode %"PRIu64" has invalid dx tree. "
+ "Reset for later rebuild?", (uint64_t)di->i_blkno)) {
+ ocfs2_dx_dir_truncate(fs, di->i_blkno);
+ di->i_dx_root = 0ULL;
+ di->i_dyn_features &= ~OCFS2_INDEXED_DIR_FL;
+ o2fsck_write_inode(ost, di->i_blkno, di);
+ ret = 0;
}
if (S_ISLNK(di->i_mode))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1b.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1b.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1b.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1b.c 2015-01-27 10:04:16.000000000 +0100
@@ -961,12 +961,20 @@
static void walk_cwd(struct dir_scan_context *scan)
{
errcode_t ret;
- struct ocfs2_dir_entry de;
+ struct ocfs2_dir_entry *de;
+ int len = sizeof(struct ocfs2_dir_entry);
- memcpy(de.name, scan->ds_cwd, scan->ds_cwdlen);
- de.name_len = scan->ds_cwdlen;
- name_inode(scan, &de);
+ if (scan->ds_cwdlen > OCFS2_MAX_FILENAME_LEN)
+ len = sizeof(struct ocfs2_dir_entry) + scan->ds_cwdlen
+ - OCFS2_MAX_FILENAME_LEN;
+ ret = ocfs2_malloc(len, &de);
+
+ memcpy(de->name, scan->ds_cwd, scan->ds_cwdlen);
+ de->name_len = scan->ds_cwdlen;
+ name_inode(scan, de);
+ free(de);
+
ret = ocfs2_dir_iterate(scan->ds_ost->ost_fs, scan->ds_ino,
OCFS2_DIRENT_FLAG_EXCLUDE_DOTS, NULL,
walk_iterate, scan);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass2.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass2.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass2.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass2.c 2015-01-27 10:04:16.000000000 +0100
@@ -664,6 +664,15 @@
ret = ocfs2_lookup(dd->fs, dbe->e_ino, dirent->name,
dirent->name_len, NULL, &ino);
if (ret) {
+ if ((ret == OCFS2_ET_DIR_CORRUPTED) &&
+ prompt(dd->ost, PY, PR_DX_LOOKUP_FAILED,
+ "Directory inode %"PRIu64" has invalid index. "
+ "Rebuild index tree?", dbe->e_ino)) {
+ *flags |= OCFS2_DIRENT_CHANGED;
+ ret = 0;
+ goto out;
+ }
+
if (ret != OCFS2_ET_FILE_NOT_FOUND)
goto out;
ret = 0;
@@ -722,7 +731,15 @@
ret = ocfs2_read_inode(dd->ost->ost_fs, dbe->e_ino,
dd->inoblock_buf);
- if (ret) {
+ if (ret == OCFS2_ET_BAD_CRC32) {
+ if (prompt(dd->ost, PY, PR_BAD_CRC32,
+ "Directory inode %"PRIu64" "
+ "has bad CRC32. Recalculate CRC32 "
+ "and write inode block?", dbe->e_ino)) {
+ ocfs2_write_inode(dd->ost->ost_fs, dbe->e_ino,
+ dd->inoblock_buf);
+ }
+ } else if (ret) {
com_err(whoami, ret, "while reading dir inode %"PRIu64,
dbe->e_ino);
ret_flags |= OCFS2_DIRENT_ABORT;
@@ -735,9 +752,11 @@
/* Set the flag for index rebuilding */
if (ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super))
&& !(di->i_dyn_features & OCFS2_INLINE_DATA_FL)
- && !(di->i_dyn_features & OCFS2_INDEXED_DIR_FL)) {
- ret_flags |= OCFS2_DIRENT_CHANGED;
- }
+ && !(di->i_dyn_features & OCFS2_INDEXED_DIR_FL)
+ && prompt(dd->ost, PY, PR_DX_TREE_MISSING,
+ "Directory %"PRIu64" is missing index. "
+ "Rebuild?", dbe->e_ino))
+ ret_flags |= OCFS2_DIRENT_CHANGED;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/corrupt.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/corrupt.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/corrupt.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/corrupt.c 2015-01-27 10:04:16.000000000 +0100
@@ -331,6 +331,9 @@
case GROUP_FREE_BITS:
func = mess_up_group_minor;
break;
+ case GROUP_CHAIN_LOOP:
+ func = mess_up_group_minor;
+ break;
case GROUP_GEN:
func = mess_up_group_gen;
break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/group.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/group.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/group.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/group.c 2015-01-27 10:04:16.000000000 +0100
@@ -176,6 +176,12 @@
bg->bg_chain, (bg->bg_chain + 10));
bg->bg_chain += 10;
break;
+ case GROUP_CHAIN_LOOP:
+ fprintf(stdout, "Corrput GROUP_LOOP: "
+ "change group next from %"PRIu64" to %"PRIu64"\n",
+ bg->bg_next_group, cr->c_blkno);
+ bg->bg_next_group = cpu_to_le64(cr->c_blkno);
+ break;
case GROUP_FREE_BITS:
fprintf(stdout, "Corrput GROUP_FREE_BITS: "
"change group free bits from %u to %u\n",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/include/fsck_type.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/include/fsck_type.h
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/include/fsck_type.h 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/include/fsck_type.h 2015-01-27 10:04:16.000000000 +0100
@@ -57,6 +57,7 @@
GROUP_BLKNO,
GROUP_CHAIN,
GROUP_FREE_BITS,
+ GROUP_CHAIN_LOOP,
CHAIN_COUNT,
CHAIN_NEXT_FREE,
CHAIN_EMPTY,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/main.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/main.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/main.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/main.c 2015-01-27 10:04:16.000000000 +0100
@@ -102,6 +102,8 @@
"Corrupt chain group's blkno"),
define_prompt_code(GROUP_CHAIN, corrupt_group_desc, "", 1,
"Corrupt chain group's chain where it was in"),
+ define_prompt_code(GROUP_CHAIN_LOOP, corrupt_group_desc, "", 1,
+ "Corrupt group's chain to form a loop"),
define_prompt_code(GROUP_FREE_BITS, corrupt_group_desc, "", 1,
"Corrupt chain group's free bits"),
define_prompt_code(CHAIN_COUNT, corrupt_sys_file, "", 1,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2/ocfs2.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2/ocfs2.h
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2/ocfs2.h 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2/ocfs2.h 2015-01-27 10:04:16.000000000 +0100
@@ -1656,5 +1656,7 @@
uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len);
enum ocfs2_block_type ocfs2_detect_block(char *buf);
+void ocfs2_swap_block_from_cpu(ocfs2_filesys *fs, void *block);
+void ocfs2_swap_block_to_cpu(ocfs2_filesys *fs, void *block);
#endif /* _FILESYS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2-kernel/ocfs2_fs.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2-kernel/ocfs2_fs.h
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2-kernel/ocfs2_fs.h 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2-kernel/ocfs2_fs.h 2015-01-27 10:04:16.000000000 +0100
@@ -1682,7 +1682,7 @@
}
static inline void ocfs2_set_de_type(struct ocfs2_dir_entry *de,
- umode_t mode)
+ unsigned short mode)
{
de->file_type = ocfs2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libo2cb/o2cb_abi.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libo2cb/o2cb_abi.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libo2cb/o2cb_abi.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libo2cb/o2cb_abi.c 2015-01-27 10:04:16.000000000 +0100
@@ -1762,9 +1762,9 @@
void o2cb_free_cluster_desc(struct o2cb_cluster_desc *cluster)
{
if (cluster->c_stack)
- free(cluster->c_stack);
+ ocfs2_free(&cluster->c_stack);
if (cluster->c_cluster)
- free(cluster->c_cluster);
+ ocfs2_free(&cluster->c_cluster);
}
errcode_t o2cb_running_cluster_desc(struct o2cb_cluster_desc *cluster)
@@ -1815,10 +1815,8 @@
out:
if (clusters)
o2cb_free_cluster_list(clusters);
- if (err) {
- free(cluster->c_stack);
- free(cluster->c_cluster);
- }
+ if (err)
+ o2cb_free_cluster_desc(cluster);
return err;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blockcheck.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blockcheck.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blockcheck.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blockcheck.c 2015-01-27 10:04:16.000000000 +0100
@@ -360,7 +360,7 @@
if (crc == check.bc_crc32e)
goto out;
- err = OCFS2_ET_IO;
+ err = OCFS2_ET_BAD_CRC32;
out:
bc->bc_crc32e = cpu_to_le32(check.bc_crc32e);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blocktype.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blocktype.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blocktype.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blocktype.c 2015-01-27 10:04:16.000000000 +0100
@@ -82,3 +82,78 @@
return OCFS2_BLOCK_UNKNOWN;
}
+
+static void ocfs2_swap_block(ocfs2_filesys *fs, void *block, int to_cpu)
+{
+ enum ocfs2_block_type bt = ocfs2_detect_block(block);
+
+ switch (bt) {
+ case OCFS2_BLOCK_INODE:
+ case OCFS2_BLOCK_SUPERBLOCK:
+ if (to_cpu)
+ ocfs2_swap_inode_to_cpu(fs, block);
+ else
+ ocfs2_swap_inode_from_cpu(fs, block);
+ break;
+ case OCFS2_BLOCK_EXTENT_BLOCK:
+ if (to_cpu)
+ ocfs2_swap_extent_block_to_cpu(fs, block);
+ else
+ ocfs2_swap_extent_block_from_cpu(fs, block);
+ break;
+ case OCFS2_BLOCK_GROUP_DESCRIPTOR:
+ if (to_cpu)
+ ocfs2_swap_group_desc_to_cpu(fs, block);
+ else
+ ocfs2_swap_group_desc_from_cpu(fs, block);
+ break;
+ case OCFS2_BLOCK_DIR_BLOCK:
+ if (to_cpu)
+ ocfs2_swap_dir_entries_to_cpu(block,
+ fs->fs_blocksize);
+ else
+ ocfs2_swap_dir_entries_from_cpu(block,
+ fs->fs_blocksize);
+ break;
+ case OCFS2_BLOCK_XATTR:
+ if (to_cpu)
+ ocfs2_swap_xattr_block_to_cpu(fs, block);
+ else
+ ocfs2_swap_xattr_block_from_cpu(fs, block);
+ break;
+ case OCFS2_BLOCK_REFCOUNT:
+ if (to_cpu)
+ ocfs2_swap_refcount_block_to_cpu(fs, block);
+ else
+ ocfs2_swap_refcount_block_from_cpu(fs, block);
+ break;
+ case OCFS2_BLOCK_DXROOT:
+ if (to_cpu)
+ ocfs2_swap_dx_root_to_cpu(fs, block);
+ else
+ ocfs2_swap_dx_root_from_cpu(fs, block);
+ break;
+ case OCFS2_BLOCK_DXLEAF:
+ if (to_cpu)
+ ocfs2_swap_dx_leaf_to_cpu(block);
+ else
+ ocfs2_swap_dx_leaf_from_cpu(block);
+ break;
+ }
+
+ return ;
+}
+
+/*
+ * ocfs2_swap_block...() silently ignores unknown block types. The caller
+ * needs to detect unknown blocks.
+ */
+void ocfs2_swap_block_from_cpu(ocfs2_filesys *fs, void *block)
+{
+ ocfs2_swap_block(fs, block, 0);
+}
+
+void ocfs2_swap_block_to_cpu(ocfs2_filesys *fs, void *block)
+{
+ ocfs2_swap_block(fs, block, 1);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/dir_indexed.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/dir_indexed.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/dir_indexed.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/dir_indexed.c 2015-01-27 10:04:16.000000000 +0100
@@ -1247,6 +1247,9 @@
goto out;
dx_root = (struct ocfs2_dx_root_block *)dx_buf;
+ /* set inode to use indexed-dirs */
+ di->i_dyn_features |= OCFS2_INDEXED_DIR_FL;
+
ret = ocfs2_init_dir_trailers(fs, di, dx_root);
if (ret)
goto out;
@@ -1281,8 +1284,6 @@
ret = ocfs2_read_inode(fs, dir, di_buf);
if (ret)
goto out;
- /* set inode to use indexed-dirs */
- di->i_dyn_features |= OCFS2_INDEXED_DIR_FL;
ret = ocfs2_write_inode(fs, dir, di_buf);
if(ret)
@@ -1436,10 +1437,12 @@
entry_list = &dx_leaf->dl_list;
}
- assert(entry_list->de_count > 0);
- assert(entry_list->de_num_used > 0);
- assert(dx_root->dr_num_entries > 0);
-
+ if ((entry_list->de_count == 0) || (entry_list->de_num_used == 0) ||
+ (dx_root->dr_num_entries == 0)) {
+ ret = OCFS2_ET_DIR_CORRUPTED;
+ goto out;
+ }
+
ret = ocfs2_malloc_block(fs->fs_io, &dir_buf);
if (ret)
goto out;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/inode.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/inode.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/inode.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/inode.c 2015-01-27 10:04:16.000000000 +0100
@@ -231,6 +231,10 @@
if (bytes > max_inline)
bytes = max_inline;
+ /* if inode is empty do not swap */
+ if (di->i_size == 0)
+ return;
+
if (to_cpu)
ocfs2_swap_dir_entries_to_cpu(de_buf, bytes);
else
@@ -297,9 +301,6 @@
goto out;
di = (struct ocfs2_dinode *)blk;
- ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check);
- if (ret)
- goto out;
ret = OCFS2_ET_BAD_INODE_MAGIC;
if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
@@ -308,6 +309,10 @@
memcpy(inode_buf, blk, fs->fs_blocksize);
+ ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check);
+ if (ret)
+ goto out;
+
di = (struct ocfs2_dinode *) inode_buf;
ocfs2_swap_inode_to_cpu(fs, di);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/ocfs2_err.et new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/ocfs2_err.et
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/ocfs2_err.et 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/ocfs2_err.et 2015-01-27 10:04:16.000000000 +0100
@@ -195,4 +195,7 @@
ec OCFS2_ET_NONEMTY_QUOTA_HASH,
"Freeing non-empty quota hash"
+ec OCFS2_ET_BAD_CRC32,
+ "Bad CRC32"
+
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/mount.ocfs2.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/mount.ocfs2.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/mount.ocfs2.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/mount.ocfs2.c 2015-01-27 10:04:16.000000000 +0100
@@ -312,6 +312,7 @@
int clustered = 1;
int group_join = 0;
struct stat statbuf;
+ const char *spec;
initialize_ocfs_error_table();
initialize_o2dl_error_table();
@@ -414,8 +415,8 @@
}
group_join = 1;
}
-
- ret = mount(mo.dev, mo.dir, OCFS2_FS_NAME, mo.flags & ~MS_NOSYS,
+ spec = canonicalize(mo.dev);
+ ret = mount(spec, mo.dir, OCFS2_FS_NAME, mo.flags & ~MS_NOSYS,
mo.xtra_opts);
if (ret) {
ret = errno;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/sundries.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/sundries.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/sundries.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/sundries.c 2015-01-27 10:04:16.000000000 +0100
@@ -223,6 +223,37 @@
return 1;
}
+/*
+ * Converts private "dm-N" names to "/dev/mapper/<name>"
+ *
+ * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
+ * provides the real DM device names in /sys/block/<ptname>/dm/name
+ */
+char *
+canonicalize_dm_name(const char *ptname)
+{
+ FILE *f;
+ size_t sz;
+ char path[256], name[256], *res = NULL;
+ int err;
+
+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
+ f = fopen(path, "r");
+ if (!f)
+ return NULL;
+
+ /* read "<name>\n" from sysfs */
+ err = fgets(name, sizeof(name), f);
+ sz = strlen(name);
+ if (!err && sz > 1) {
+ name[sz - 1] = '\0';
+ snprintf(path, sizeof(path), "/dev/mapper/%s", name);
+ res = strdup(path);
+ }
+ fclose(f);
+ return res;
+}
+
/* Make a canonical pathname from PATH. Returns a freshly malloced string.
It is up the *caller* to ensure that the PATH is sensible. i.e.
canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
@@ -231,6 +262,7 @@
char *
canonicalize (const char *path) {
char canonical[PATH_MAX+2];
+ char *p;
if (path == NULL)
return NULL;
@@ -241,8 +273,13 @@
streq(path, "devpts"))
return xstrdup(path);
#endif
- if (myrealpath (path, canonical, PATH_MAX+1))
- return xstrdup(canonical);
-
- return xstrdup(path);
+ if (!myrealpath(path, canonical, PATH_MAX+1))
+ return xstrdup(path);
+ p = strrchr(canonical, '/');
+ if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
+ p = canonicalize_dm_name(p+1);
+ if (p)
+ return p;
+ }
+ return xstrdup(canonical);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mounted.ocfs2/mounted.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mounted.ocfs2/mounted.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mounted.ocfs2/mounted.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mounted.ocfs2/mounted.c 2015-01-27 10:04:16.000000000 +0100
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -256,6 +257,58 @@
}
}
+static void list_rm_device(struct list_head *dev_list, int major, int minor)
+{
+ struct list_head *pos1, *pos2;
+ ocfs2_devices *dev;
+
+ list_for_each_safe(pos1, pos2, dev_list) {
+ dev = list_entry(pos1, ocfs2_devices, list);
+ if ((dev->maj_num == major) && (dev->min_num == minor)) {
+ if (dev->map)
+ ocfs2_free(&dev->map);
+ list_del(&(dev->list));
+ ocfs2_free(&dev);
+ }
+ }
+}
+
+static int is_partition(int major, int minor)
+{
+ char path[PATH_MAX + 1];
+ struct stat info;
+
+ snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/partition",
+ major, minor);
+
+ return !stat(path, &info);
+}
+
+static int find_whole_disk_minor(int major, int minor) {
+#ifndef SCSI_BLK_MAJOR
+#ifdef SCSI_DISK0_MAJOR
+#ifdef SCSI_DISK8_MAJOR
+#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
+ ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \
+ ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
+#else
+#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
+ ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR))
+#endif /* defined(SCSI_DISK8_MAJOR) */
+#define SCSI_BLK_MAJOR(M) (SCSI_DISK_MAJOR((M)) || (M) == SCSI_CDROM_MAJOR)
+#else
+#define SCSI_BLK_MAJOR(M) ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR)
+#endif /* defined(SCSI_DISK0_MAJOR) */
+#endif /* defined(SCSI_BLK_MAJOR) */
+ if (major == HD_MAJOR)
+ return (minor - (minor%64));
+
+ if (SCSI_BLK_MAJOR(major))
+ return (minor - (minor%16));
+ /* FIXME: Catch all */
+ return 0;
+}
+
static errcode_t build_partition_list(struct list_head *dev_list, char *device)
{
errcode_t ret = 0;
@@ -328,6 +381,11 @@
continue;
}
+ if (is_partition(major, minor)) {
+ int whole_minor = find_whole_disk_minor(major, minor);
+ list_rm_device(dev_list, major, whole_minor);
+ }
+
dev->maj_num = major;
dev->min_num = minor;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/jconfig.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/jconfig.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/jconfig.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/jconfig.c 2015-01-27 10:04:16.000000000 +0100
@@ -1082,6 +1082,8 @@
g_strdup(stanza_name),
elem);
}
+ else
+ g_list_append(elem, cfs);
return(cfs);
} /* j_config_add_stanza() */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/op_register.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/op_register.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/op_register.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/op_register.c 2015-01-27 10:04:16.000000000 +0100
@@ -225,10 +225,15 @@
{
errcode_t ret;
gchar *hbmode = NULL;
+ int localhb;
hbmode = o2cb_cluster_get_heartbeat_mode(cluster);
+ localhb = !strcmp(hbmode, O2CB_LOCAL_HEARTBEAT_TAG);
ret = o2cb_set_heartbeat_mode(clustername, hbmode);
+ if (ret && localhb)
+ ret = 0;
+
if (ret)
tcom_err(ret, "while registering heartbeat mode '%s'", hbmode);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2.pc.in new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2.pc.in
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2.pc.in 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2.pc.in 2015-01-27 10:04:16.000000000 +0100
@@ -7,5 +7,5 @@
Description: Userspace ocfs2 library
Version: @VERSION@
Requires: o2dlm o2cb com_err
-Libs: -L${libdir} -locfs2
+Libs: -L${libdir} -locfs2 -laio
Cflags: -I${includedir}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2_controld/main.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2_controld/main.c
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2_controld/main.c 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2_controld/main.c 2015-01-27 10:04:16.000000000 +0100
@@ -1154,7 +1154,7 @@
{
FILE *fp;
- fp = fopen("/proc/self/oom_adj", "w");
+ fp = fopen("/proc/self/oom_score_adj", "w");
if (!fp)
return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2console/ocfs2interface/Makefile new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2console/ocfs2interface/Makefile
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2console/ocfs2interface/Makefile 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2console/ocfs2interface/Makefile 2015-01-27 10:04:16.000000000 +0100
@@ -8,7 +8,7 @@
PYMOD_CFLAGS = -fno-strict-aliasing $(PYTHON_INCLUDES)
-LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
+LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2 -laio
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm $(DL_LIBS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/vendor/common/o2cb.init.sh new/ocfs2-tools-1.8.3+git.1418704844.65fac00/vendor/common/o2cb.init.sh
--- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/vendor/common/o2cb.init.sh 2013-04-02 11:38:06.000000000 +0200
+++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/vendor/common/o2cb.init.sh 2015-01-27 10:04:16.000000000 +0100
@@ -32,6 +32,8 @@
LOADED_PLUGINS_FILE="${OCFS2_SYS_DIR}/loaded_cluster_plugins"
CLUSTER_STACK_FILE="${OCFS2_SYS_DIR}/cluster_stack"
DLMFS_CAPABILITIES_FILE='/sys/module/ocfs2_dlmfs/parameters/capabilities'
+DLMFS_DIR="/dlm"
+DLMFS_MAGIC="76a9f425"
DEBUGFS_DIR="/sys/kernel/debug"
if [ -f /etc/sysconfig/o2cb ]
@@ -83,6 +85,21 @@
fi
}
+touch_lockfile()
+{
+ if [ -d /var/lock/subsys ]
+ then
+ touch /var/lock/subsys/o2cb
+ fi
+}
+
+remove_lockfile()
+{
+ if [ -e /var/lock/subsys/o2cb ]
+ then
+ rm /var/lock/subsys/o2cb
+ fi
+}
#
# if_fail()
@@ -600,6 +617,19 @@
return 0
}
+o2cbmounts()
+{
+ if [ "$#" != "1" -o -z "$1" ]
+ then
+ echo "o2cbmounts(): Missing arguments" >&2
+ exit 1
+ fi
+
+ FSNAME="$1"
+
+ LC_ALL=C awk -v FSNAME=$FSNAME 'BEGIN {fsname = FSNAME;} $3 == fsname { print $2 }' /proc/mounts
+}
+
#
# unmount_filesystem()
# Unmount a pseudo-filesystem of type $1 from mountpoint $2. It will
@@ -620,14 +650,34 @@
if check_filesystem "$FSNAME" "$MOUNTPOINT"
then
echo -n "Unmounting ${FSNAME} filesystem: "
- umount $MOUNTPOINT
- RC=$?
- if [ $RC != 0 ]
+ remaining=$(o2cbmounts $FSNAME)
+ sig=
+ retry=3
+ while [ -n "$remaining" -a "$retry" -gt 0 ]
+ do
+ if [ "$retry" -lt 3 ]; then
+ echo -n "Retry unmounting $FSNAME} filesystem: "
+ fi
+
+ umount $MOUNTPOINT
+ RC=$?
+ if_fail $RC
+
+ remaining=$(o2cbmounts $FSNAME)
+ [ -z "$remaining" ] && break
+
+ fuser -km $sig $remaining >/dev/null 2>&1
+ sleep 5
+ retry=$(($retry - 1))
+ sig=-9
+ done
+
+ remaining=$(o2cbmounts $FSNAME)
+ if [ -n "$remaining" ]
then
echo "Unable to unmount ${FSNAME} filesystem" >&2
return 1
fi
- if_fail $RC # For the success string
fi
unload_filesystem "$FSNAME"
@@ -953,12 +1003,60 @@
fi
fi
- mount_filesystem "ocfs2_dlmfs" "/dlm"
+ mount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
if_fail $?
return 0
}
+# Return the list of userdlm domains
+#
+userdlm_domains()
+{
+ magic=$(stat -f --printf="%t" ${DLMFS_DIR})
+ if [ "x$magic" = "x$DLMFS_MAGIC" ]
+ then
+ ls ${DLMFS_DIR}
+ fi
+}
+
+#
+# Print userdlm domains
+#
+userdlm_status()
+{
+ [ -n "$(userdlm_domains)" ] && {
+ echo "Active userdlm domains: " $(userdlm_domains)
+ }
+}
+
+#
+# Force removes all userdlm domains
+#
+clean_userdlm_domains()
+{
+ # Cleanup only if mounted
+ magic=$(stat -f --printf="%t" ${DLMFS_DIR})
+ if [ "x$magic" = "x$DLMFS_MAGIC" ]
+ then
+ echo -n "Clean userdlm domains: "
+ # Kill all processes accessing dlmfs
+ fuser -km -9 ${DLMFS_DIR} >/dev/null 2>&1
+
+ # Remove all domains and locks
+ for domain in $(userdlm_domains)
+ do
+ domain_path="${DLMFS_DIR}/${domain}"
+ magic=$(stat -f --printf="%t" ${domain_path})
+ if [ "x$magic" = "x$DLMFS_MAGIC" ]
+ then
+ rm -rf ${domain_path}
+ fi
+ done
+ echo "OK"
+ fi
+}
+
#
# dlmfs_user_capable()
# Check if dlmfs supports user stacks.
@@ -1021,7 +1119,7 @@
if dlmfs_user_capable
then
- mount_filesystem "ocfs2_dlmfs" "/dlm"
+ mount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
if_fail $?
fi
@@ -1078,7 +1176,7 @@
fi
fi
- unmount_filesystem "ocfs2_dlmfs" "/dlm"
+ unmount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
if_fail $?
unload_stack_plugins
@@ -1101,7 +1199,7 @@
exit 1
fi
- unmount_filesystem "ocfs2_dlmfs" "/dlm"
+ unmount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
if_fail $?
unload_stack_plugins
@@ -1133,7 +1231,7 @@
status_stack_o2cb()
{
status_stack_plugin
- status_filesystem "ocfs2_dlmfs" "/dlm"
+ status_filesystem "ocfs2_dlmfs" $DLMFS_DIR
}
status_stack_user()
@@ -1221,6 +1319,8 @@
{
PLUGIN="$(select_stack_plugin)"
+ touch_lockfile
+
# XXX: SPECIAL CASE! We must load configfs for configfs_path() to work
load_filesystem "configfs"
if_fail $?
@@ -1605,6 +1705,8 @@
FORCE=0
fi
+ clean_userdlm_domains
+
offline_$PLUGIN "$CLUSTER" "$FORCE"
unload_filesystem "ocfs2"
@@ -1628,6 +1730,8 @@
unload_stack_$PLUGIN
+ remove_lockfile
+
# Only unmount configfs if there are no other users
if [ -z "$(ls -1 "$(configfs_path)" 2>/dev/null)" ]
then
@@ -1727,9 +1831,39 @@
fi
online_status "$CLUSTER"
+
+ userdlm_status
}
+#
+# online_status()
+#
+# Return codes to userspace. ** Do not change. **
+# 0 is online, 1 is offline, 2 is error
+#
+online-status()
+{
+ CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
+ if [ -z "$CLUSTER" ]
+ then
+ return 2
+ fi
+ check_online "$CLUSTER"
+ RC=$?
+ if [ "$RC" = "2" ]
+ then
+ echo "online"
+ exit 0
+ elif [ "$RC" = "0" ]
+ then
+ echo "offline"
+ exit 1
+ else
+ echo "error"
+ exit 2
+ fi
+}
case "$1" in
start)
@@ -1763,6 +1897,10 @@
online "$2"
;;
+ online-status)
+ online-status "$2"
+ ;;
+
offline)
offline "$2"
;;
@@ -1801,7 +1939,7 @@
;;
*)
- echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|force-offline|status}"
+ echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|force-offline|status|online-status}"
exit 1
;;
esac