fence-agents: master - fence_dummy: Add a 'fail' test dummy agent
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=3d9e3c...
Commit: 3d9e3cf41f11da188e3f927ceb4b9f39435bc0a9
Parent: d7378e8c4b986fa490b31d53526edf24c6b0c9e1
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Fri Jun 7 13:01:43 2013 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Fri Jun 7 13:01:43 2013 +0200
fence_dummy: Add a 'fail' test dummy agent
---
fence/agents/dummy/fence_dummy.py | 77 ++++++++++++++++++++++++++++++++++---
1 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py
index ccf7f20..e24a0cc 100644
--- a/fence/agents/dummy/fence_dummy.py
+++ b/fence/agents/dummy/fence_dummy.py
@@ -10,7 +10,9 @@ REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
-def get_power_status(conn, options):
+plug_status="on"
+
+def get_power_status_file(conn, options):
try:
status_file = open(options["--status-file"], 'r')
except:
@@ -21,7 +23,7 @@ def get_power_status(conn, options):
return status.lower()
-def set_power_status(conn, options):
+def set_power_status_file(conn, options):
if not (options["--action"] in [ "on", "off" ]):
return
@@ -29,21 +31,80 @@ def set_power_status(conn, options):
status_file.write(options["--action"])
status_file.close()
+def get_power_status_fail(conn, options):
+ outlets = get_outlets_fail(conn,options)
+
+ if len(outlets) == 0 or options.has_key("--plug") == 0:
+ fail_usage("Failed: You have to enter existing machine!")
+ else:
+ return outlets[options["--plug"]][0]
+
+def set_power_status_fail(conn, options):
+ global plug_status
+
+ plug_status = "unknown"
+ if options["--action"] == "on":
+ plug_status = "off"
+
+def get_outlets_fail(conn, options):
+ result = {}
+ global plug_status
+
+ if options["--action"] == "on":
+ plug_status = "off"
+
+ # This fake agent has no port data to list, so we have to make
+ # something up for the list action.
+ if options.has_key("--action") and options["--action"] == "list":
+ result["fake_port_1"] = [plug_status, "fake"]
+ result["fake_port_2"] = [plug_status, "fake"]
+ elif (options.has_key("--plug") == 0):
+ fail_usage("Failed: You have to enter existing machine!")
+ else:
+ port = options["--plug"]
+ result[port] = [plug_status, "fake"]
+
+ return result
+
def main():
- device_opt = [ "no_password", "status_file" ]
+ device_opt = [ "no_password", "status_file", "random_sleep_range", "type", "port" ]
atexit.register(atexit_handler)
all_opt["status_file"] = {
"getopt" : "s:",
"longopt" : "status-file",
- "help":"--status-file=<file> Name of file that holds current status",
+ "help":"--status-file=[file] Name of file that holds current status",
"required" : "0",
"shortdesc" : "File with status",
"default" : "/tmp/fence_dummy.status",
"order": 1
}
+ all_opt["random_sleep_range"] = {
+ "getopt" : "R:",
+ "longopt" : "random_sleep_range",
+ "help":"--random_sleep_range=[seconds] Issue a sleep between 1 and [seconds]",
+ "required" : "0",
+ "shortdesc" : "Issue a sleep between 1 and X seconds. Used for testing.",
+ "order": 1
+ }
+
+ all_opt["type"] = {
+ "getopt" : "t:",
+ "longopt" : "type",
+ "help":"--type=[type] Possible types are: file and fail",
+ "required" : "0",
+ "shortdesc" : "Type of the dummy fence agent",
+ "default" : "file",
+ "order": 1
+ }
+
+ pinput = process_input(device_opt)
+ if (pinput.has_key("--type") and pinput["--type"] == "file") or (pinput.has_key("--type") == False):
+ # hack to have fence agents that require ports 'fail' and one that do not 'file'
+ device_opt.remove("port")
+
options = check_input(device_opt, process_input(device_opt))
docs = { }
@@ -51,8 +112,12 @@ def main():
docs["longdesc"] = "fence_dummy"
docs["vendorurl"] = "http://www.example.com"
show_docs(options, docs)
-
- result = fence_action(None, options, set_power_status, get_power_status, None)
+
+ if options["--type"] == "fail":
+ result = fence_action(None, options, set_power_status_fail, get_power_status_fail, get_outlets_fail)
+ else:
+ result = fence_action(None, options, set_power_status_file, get_power_status_file, None)
+
sys.exit(result)
if __name__ == "__main__":
10 years, 10 months
gfs2-utils: master - mkfs.gfs2: Add align option and update docs
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=96c12f26...
Commit: 96c12f26eb0c68c2722e01ccd8a269c91069471e
Parent: 34dd1fdbffee4154a9318420e983795be0a4f112
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Jun 6 12:47:26 2013 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jun 6 17:35:42 2013 +0100
mkfs.gfs2: Add align option and update docs
Add an 'align' extended option for enabling and disabling resource group
alignment and update the mkfs.gfs2 man page to document the new extended
options.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/man/mkfs.gfs2.8 | 31 +++++++++++++++++++++++++++++
gfs2/mkfs/main_mkfs.c | 51 +++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/gfs2/man/mkfs.gfs2.8 b/gfs2/man/mkfs.gfs2.8
index 4613305..ceb6f38 100644
--- a/gfs2/man/mkfs.gfs2.8
+++ b/gfs2/man/mkfs.gfs2.8
@@ -48,6 +48,37 @@ storage).
This option prevents gfs2_mkfs from asking for confirmation before writing
the filesystem.
.TP
+\fB-o\fP
+Specify extended options. Multiple options can be separated by commas. Valid extended options are:
+.RS 1.0i
+.TP
+.BI help
+Display an extended options help summary, then exit.
+.TP
+.BI sunit= bytes
+This is used to specify the stripe unit for a RAID device or striped logical
+volume. This option ensures that resource groups will be stripe unit aligned
+and overrides the stripe unit value obtained by probing the device. This value
+must be a multiple of the file system block size and must be specified with the
+.I swidth
+option.
+.TP
+.BI swidth= bytes
+This is used to specify the stripe width for a RAID device or striped logical
+volume. This option ensures that resource groups will be stripe aligned and overrides the stripe width value obtained by probing the device. This value must be a multiple of the
+.I sunit
+option and must also be specified with it.
+.TP
+.BI align= [0|1]
+Disable or enable the alignment of resource groups. The default behaviour is to
+align resource groups to the stripe width and stripe unit values obtained from
+probing the device or specified with the
+.I swidth
+and
+.I sunit
+extended options.
+.RE
+.TP
\fB-p\fP \fILockProtoName\fR
LockProtoName is the name of the locking protocol to use. Acceptable
locking protocols are \fIlock_dlm\fR (for shared storage) or if you are
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 4e28e08..a5078b6 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -57,7 +57,7 @@ static void print_usage(const char *prog_name)
"-j", _("<number>"), _("Number of journals"),
"-K", NULL, _("Don't try to discard unused blocks"),
"-O", NULL, _("Don't ask for confirmation"),
- "-o", _("<key>[=<value>][,...]"), _("Specify extended options"),
+ "-o", _("<key>[=<value>][,...]"), _("Specify extended options. See '-o help'."),
"-p", _("<name>"), _("Name of the locking protocol"),
"-q", NULL, _("Don't print anything"),
"-r", _("<size>"), _("Size of resource groups, in megabytes"),
@@ -74,12 +74,28 @@ static void print_usage(const char *prog_name)
for (i = 0; options[i] != NULL; i += 3) {
option = options[i];
- param = options[i+1];
- desc = options[i+2];
+ param = options[i + 1];
+ desc = options[i + 2];
printf("%3s %-22s %s\n", option, param ? param : "", desc);
}
}
+static void print_ext_opts(void)
+{
+ int i;
+ const char *options[] = {
+ "help", _("Display this help, then exit"),
+ "swidth=N", _("Specify the stripe width of the device, overriding probed values"),
+ "sunit=N", _("Specify the stripe unit of the device, overriding probed values"),
+ "align=[0|1]", _("Disable or enable alignment of resource groups"),
+ NULL, NULL
+ };
+ printf(_("Extended options:\n"));
+ for (i = 0; options[i] != NULL; i += 2) {
+ printf("%15s %-22s\n", options[i], options[i + 1]);
+ }
+}
+
struct mkfs_opts {
unsigned bsize;
unsigned qcsize;
@@ -111,6 +127,7 @@ struct mkfs_opts {
unsigned expert:1;
unsigned debug:1;
unsigned confirm:1;
+ unsigned align:1;
};
/**
@@ -165,6 +182,7 @@ static void opts_init(struct mkfs_opts *opts)
opts->lockproto = "lock_dlm";
opts->locktable = "";
opts->confirm = 1;
+ opts->align = 1;
}
#ifndef BLKDISCARD
@@ -250,6 +268,18 @@ static unsigned long parse_ulong(struct mkfs_opts *opts, const char *key, const
return (unsigned long)l;
}
+static unsigned parse_bool(struct mkfs_opts *opts, const char *key, const char *val)
+{
+ if (strnlen(val, 2) == 1) {
+ if (*val == '0')
+ return 0;
+ if (*val == '1')
+ return 1;
+ }
+ fprintf(stderr, _("Option '%s' must be either 1 or 0\n"), key);
+ exit(-1);
+}
+
static void opt_parse_extended(char *str, struct mkfs_opts *opts)
{
char *opt;
@@ -266,6 +296,11 @@ static void opt_parse_extended(char *str, struct mkfs_opts *opts)
} else if (strcmp("swidth", key) == 0) {
opts->swidth = parse_ulong(opts, "swidth", val);
opts->got_swidth = 1;
+ } else if (strcmp("align", key) == 0) {
+ opts->align = parse_bool(opts, "align", val);
+ } else if (strcmp("help", key) == 0) {
+ print_ext_opts();
+ exit(0);
} else {
fprintf(stderr, _("Invalid option '%s'\n"), key);
exit(-1);
@@ -603,7 +638,7 @@ static uint64_t align_block(const uint64_t base, const uint64_t align)
static void rgs_init(struct mkfs_rgs *rgs, struct mkfs_opts *opts, struct mkfs_dev *dev, struct gfs2_sbd *sdp)
{
memset(rgs, 0, sizeof(*rgs));
- if (opts->got_sunit) {
+ if (opts->align && opts->got_sunit) {
if ((opts->sunit % sdp->bsize) != 0) {
fprintf(stderr, _("Stripe unit (%lu) must be a multiple of block size (%u)\n"),
opts->sunit, sdp->bsize);
@@ -616,7 +651,7 @@ static void rgs_init(struct mkfs_rgs *rgs, struct mkfs_opts *opts, struct mkfs_d
rgs->align = opts->swidth / sdp->bsize;
rgs->align_off = opts->sunit / sdp->bsize;
}
- } else {
+ } else if (opts->align) {
if ((dev->minimum_io_size > dev->physical_sector_size) &&
(dev->optimal_io_size > dev->physical_sector_size)) {
rgs->align = dev->optimal_io_size / sdp->bsize;
@@ -871,7 +906,11 @@ void main_mkfs(int argc, char *argv[])
printf(" fssize = %"PRIu64"\n", opts.fssize);
printf(" sunit = %lu\n", opts.sunit);
printf(" swidth = %lu\n", opts.swidth);
- printf(" rgrp align = %lu+%lu blocks\n", rgs.align, rgs.align_off);
+ printf(" rgrp align = ");
+ if (opts.align)
+ printf("%lu+%lu blocks\n", rgs.align, rgs.align_off);
+ else
+ printf("(disabled)\n");
}
warn_of_destruction(opts.device);
10 years, 10 months
gfs2-utils: master - mkfs.gfs2: Create new resource groups on-demand
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=34dd1fdb...
Commit: 34dd1fdbffee4154a9318420e983795be0a4f112
Parent: 4d8ffb95aadaca3ca9c47188f4e653fc3a968b37
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Mon Jun 3 15:19:23 2013 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jun 6 17:31:53 2013 +0100
mkfs.gfs2: Create new resource groups on-demand
Adds a structure to encapsulate the state of resource group creation so
that the new rg_append() function can be called at any time. rg_append()
takes the number of data blocks required as a parameter so that future
enhancements can request a given number of free data blocks.
place_rgrps() now becomes a simple loop to call rg_append() and
writerg() until the end of the device.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/main_mkfs.c | 250 +++++++++++++++++++++++++++----------------------
1 files changed, 139 insertions(+), 111 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 9f15dce..4e28e08 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -134,6 +134,25 @@ struct mkfs_dev {
unsigned int got_topol:1;
};
+/**
+ * A representation of the state of resource group calculation. Allows mkfs to create
+ * resource groups at any point instead of creating them all in one batch.
+ */
+struct mkfs_rgs {
+ struct osi_root *root;
+ uint64_t nextaddr;
+ unsigned bsize;
+ unsigned long align;
+ unsigned long align_off;
+ unsigned long curr_offset;
+ uint64_t maxrgsz;
+ uint64_t minrgsz;
+ uint64_t devlen;
+ uint64_t rgsize;
+ uint64_t count;
+ uint64_t blks_total;
+};
+
static void opts_init(struct mkfs_opts *opts)
{
memset(opts, 0, sizeof(*opts));
@@ -499,12 +518,6 @@ static void opts_check(struct mkfs_opts *opts)
fprintf(stderr, _("Stripe unit and stripe width must be specified together\n"));
exit(1);
}
-
- if (opts->got_sunit && (opts->swidth % opts->sunit)) {
- fprintf(stderr, _("Stripe width (%lu) must be a multiple of stripe unit (%lu)\n"),
- opts->swidth, opts->sunit);
- exit(1);
- }
}
static void print_results(struct gfs2_sbd *sdp, uint64_t real_device_size,
@@ -587,96 +600,125 @@ static uint64_t align_block(const uint64_t base, const uint64_t align)
return base;
}
-static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts, const struct mkfs_dev *dev)
+static void rgs_init(struct mkfs_rgs *rgs, struct mkfs_opts *opts, struct mkfs_dev *dev, struct gfs2_sbd *sdp)
{
- struct rgrp_tree *rgt = NULL;
- uint64_t rgaddr = 0;
- uint64_t nextaddr = 0;
- uint64_t rglen = (sdp->rgsize << 20) / sdp->bsize;
- const uint64_t maxrgsz = (GFS2_MAX_RGSIZE << 20) / sdp->bsize;
- const uint64_t minrgsz = (GFS2_MIN_RGSIZE << 20) / sdp->bsize;
- unsigned sunit_blocks = opts->sunit / sdp->bsize;
- unsigned swidth_blocks = opts->swidth / opts->bsize;
- unsigned stripe_offset = 0;
- int err = 0;
-
- sdp->new_rgrps = 0;
- rgaddr = align_block(sdp->sb_addr + 1, swidth_blocks);
-
- while (rgaddr > 0) {
- rgt = rgrp_insert(&sdp->rgtree, rgaddr);
- if (rgt == NULL)
- return -1;
-
- stripe_offset += sunit_blocks;
- if (stripe_offset >= swidth_blocks)
- stripe_offset = 0;
-
- /* The next rg might not fit into the remaining space so calculate it now
- in order to make decisions about the current rg */
- nextaddr = align_block(rgaddr + rglen, swidth_blocks) + stripe_offset;
- if (!opts->got_rgsize && (nextaddr - rgaddr) <= maxrgsz)
- /* Use up gap left by alignment if possible */
- rgt->length = nextaddr - rgaddr;
- else
- rgt->length = rglen;
-
- /* If the next rg would overflow the device, either shrink it or expand
- the current rg to use the remaining space */
- if (nextaddr + rglen > sdp->device.length) {
- /* Squeeze the last 1 or 2 rgs into the remaining space */
- if ((nextaddr < sdp->device.length) && (sdp->device.length - nextaddr >= minrgsz)) {
- rglen = sdp->device.length - nextaddr;
- } else {
- if (sdp->device.length - rgaddr <= maxrgsz)
- rgt->length = sdp->device.length - rgaddr;
- else
- rgt->length = maxrgsz;
- /* This is the last rg */
- nextaddr = 0;
- }
+ memset(rgs, 0, sizeof(*rgs));
+ if (opts->got_sunit) {
+ if ((opts->sunit % sdp->bsize) != 0) {
+ fprintf(stderr, _("Stripe unit (%lu) must be a multiple of block size (%u)\n"),
+ opts->sunit, sdp->bsize);
+ exit(1);
+ } else if ((opts->swidth % opts->sunit) != 0) {
+ fprintf(stderr, _("Stripe width (%lu) must be a multiple of stripe unit (%lu)\n"),
+ opts->swidth, opts->sunit);
+ exit(1);
+ } else {
+ rgs->align = opts->swidth / sdp->bsize;
+ rgs->align_off = opts->sunit / sdp->bsize;
}
-
- /* Build the rindex entry */
- rgt->ri.ri_length = rgblocks2bitblocks(sdp->bsize, rgt->length, &rgt->ri.ri_data);
- rgt->ri.ri_addr = rgaddr;
- rgt->ri.ri_data0 = rgaddr + rgt->ri.ri_length;
- rgt->ri.ri_bitbytes = rgt->ri.ri_data / GFS2_NBBY;
-
- /* Build the rgrp header */
- memset(&rgt->rg, 0, sizeof(rgt->rg));
- rgt->rg.rg_header.mh_magic = GFS2_MAGIC;
- rgt->rg.rg_header.mh_type = GFS2_METATYPE_RG;
- rgt->rg.rg_header.mh_format = GFS2_FORMAT_RG;
- rgt->rg.rg_free = rgt->ri.ri_data;
-
- if (opts->debug) {
- gfs2_rindex_print(&rgt->ri);
- printf(" stripe_offset: %u\n", stripe_offset);
+ } else {
+ if ((dev->minimum_io_size > dev->physical_sector_size) &&
+ (dev->optimal_io_size > dev->physical_sector_size)) {
+ rgs->align = dev->optimal_io_size / sdp->bsize;
+ rgs->align_off = dev->minimum_io_size / sdp->bsize;
}
+ }
+ rgs->bsize = sdp->bsize;
+ rgs->maxrgsz = (GFS2_MAX_RGSIZE << 20) / sdp->bsize;
+ rgs->minrgsz = (GFS2_MIN_RGSIZE << 20) / sdp->bsize;
+ rgs->nextaddr = align_block(sdp->sb_addr + 1, rgs->align);
+ rgs->rgsize = (sdp->rgsize << 20) / sdp->bsize;
+ rgs->devlen = sdp->device.length;
+ rgs->root = &sdp->rgtree;
+}
- /* TODO: This call allocates buffer heads and bitmap pointers
- * in rgt. We really shouldn't need to do that. */
- err = gfs2_compute_bitstructs(sdp->bsize, rgt);
- if (err != 0) {
- fprintf(stderr, _("Could not compute bitmaps. "
- "Check resource group and block size options.\n"));
- return -1;
+static unsigned rgsize_for_data(uint64_t blksreq, unsigned bsize)
+{
+ const uint32_t blks_rgrp = GFS2_NBBY * (bsize - sizeof(struct gfs2_rgrp));
+ const uint32_t blks_meta = GFS2_NBBY * (bsize - sizeof(struct gfs2_meta_header));
+ unsigned bitblocks = 1;
+ if (blksreq > blks_rgrp)
+ bitblocks += ((blksreq - blks_rgrp) + blks_meta - 1) / blks_meta;
+ return bitblocks + blksreq;
+}
+
+static struct rgrp_tree *rg_append(struct mkfs_rgs *rgs, const struct mkfs_opts *opts, uint64_t freerq)
+{
+ int err = 0;
+ uint64_t length = rgsize_for_data(freerq, rgs->bsize);
+ struct rgrp_tree *rgt = rgrp_insert(rgs->root, rgs->nextaddr);
+ if (rgt == NULL)
+ return NULL;
+
+ rgs->curr_offset += rgs->align_off;
+ if (rgs->curr_offset >= rgs->align)
+ rgs->curr_offset = 0;
+
+ if (rgs->rgsize > length)
+ length = rgs->rgsize;
+
+ rgs->nextaddr = align_block(rgt->ri.ri_addr + rgs->rgsize, rgs->align) + rgs->curr_offset;
+ /* Use up gap left by alignment if possible */
+ if (!opts->got_rgsize && ((rgs->nextaddr - rgt->ri.ri_addr) <= rgs->maxrgsz))
+ length = rgs->nextaddr - rgt->ri.ri_addr;
+
+ if ((rgs->nextaddr + rgs->rgsize) > rgs->devlen) {
+ /* Squeeze the last 1 or 2 rgs into the remaining space */
+ if ((rgs->nextaddr < rgs->devlen) && ((rgs->devlen - rgs->nextaddr) >= rgs->minrgsz)) {
+ rgs->rgsize = rgs->devlen - rgs->nextaddr;
+ } else {
+ if (rgs->devlen - rgt->ri.ri_addr <= rgs->maxrgsz)
+ length = rgs->devlen - rgt->ri.ri_addr;
+ else
+ length = rgs->maxrgsz;
+ /* This is the last rg */
+ rgs->nextaddr = 0;
}
+ }
+
+ rgt->ri.ri_length = rgblocks2bitblocks(rgs->bsize, length, &rgt->ri.ri_data);
+ rgt->ri.ri_data0 = rgt->ri.ri_addr + rgt->ri.ri_length;
+ rgt->ri.ri_bitbytes = rgt->ri.ri_data / GFS2_NBBY;
+ rgt->rg.rg_header.mh_magic = GFS2_MAGIC;
+ rgt->rg.rg_header.mh_type = GFS2_METATYPE_RG;
+ rgt->rg.rg_header.mh_format = GFS2_FORMAT_RG;
+ rgt->rg.rg_free = rgt->ri.ri_data;
- err = writerg(sdp->device_fd, rgt, sdp->bsize);
+ if (opts->debug) {
+ gfs2_rindex_print(&rgt->ri);
+ printf(" offset: %"PRIu64"\n", rgs->curr_offset);
+ }
+
+ err = gfs2_compute_bitstructs(rgs->bsize, rgt);
+ if (err != 0) {
+ fprintf(stderr, _("Could not compute bitmaps. "
+ "Check resource group and block size options.\n"));
+ return NULL;
+ }
+ rgs->blks_total += rgt->ri.ri_data;
+ rgs->count++;
+ return rgt;
+}
+
+static uint64_t place_rgrps(struct mkfs_rgs *rgs, int fd, const struct mkfs_opts *opts, const struct mkfs_dev *dev)
+{
+ int err = 0;
+ struct rgrp_tree *rgt = NULL;
+
+ while (rgs->nextaddr > 0) {
+ rgt = rg_append(rgs, opts, 0);
+ if (rgt == NULL) {
+ perror(_("Failed to create resource group"));
+ return 0;
+ }
+ err = writerg(fd, rgt, rgs->bsize);
if (err != 0) {
perror(_("Failed to write resource group"));
- return -1;
+ return 0;
}
- sdp->new_rgrps++;
- sdp->blks_total += rgt->ri.ri_data;
- rgaddr = nextaddr;
}
- sdp->rgrps = sdp->new_rgrps;
- sdp->fssize = rgt->ri.ri_data0 + rgt->ri.ri_data;
- return 0;
+ return rgt->ri.ri_data0 + rgt->ri.ri_data;
}
static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_dev *dev, unsigned bsize)
@@ -793,29 +835,12 @@ static void open_dev(const char *path, struct mkfs_dev *dev)
exit(1);
}
-static void opts_set_stripe(struct mkfs_opts *opts, const struct mkfs_dev *dev, unsigned bsize)
-{
- if (!opts->got_swidth && dev->optimal_io_size > dev->physical_sector_size) {
- opts->swidth = dev->optimal_io_size;
- opts->got_swidth = 1;
- }
-
- if (!opts->got_sunit && dev->minimum_io_size > dev->physical_sector_size) {
- opts->sunit = dev->minimum_io_size;
- opts->got_sunit = 1;
- }
-
- if (opts->got_sunit && (opts->sunit % bsize) != 0) {
- fprintf(stderr, "Stripe unit (%lu) is not a multiple of the block size (%u)\n", opts->sunit, bsize);
- exit(1);
- }
-}
-
void main_mkfs(int argc, char *argv[])
{
struct gfs2_sbd sbd;
struct mkfs_opts opts;
struct mkfs_dev dev;
+ struct mkfs_rgs rgs;
int error;
unsigned char uuid[16];
unsigned bsize;
@@ -826,17 +851,16 @@ void main_mkfs(int argc, char *argv[])
open_dev(opts.device, &dev);
bsize = choose_blocksize(&opts, &dev);
- opts_set_stripe(&opts, &dev, bsize);
if (S_ISREG(dev.stat.st_mode)) {
opts.got_bsize = 1; /* Use default block size for regular files */
}
- warn_of_destruction(opts.device);
-
sbd_init(&sbd, &opts, &dev, bsize);
+ rgs_init(&rgs, &opts, &dev, &sbd);
+
if (opts.debug) {
- printf(_("Calculated file system options:\n"));
+ printf(_("File system options:\n"));
printf(" bsize = %u\n", sbd.bsize);
printf(" qcsize = %u\n", sbd.qcsize);
printf(" jsize = %u\n", sbd.jsize);
@@ -847,20 +871,24 @@ void main_mkfs(int argc, char *argv[])
printf(" fssize = %"PRIu64"\n", opts.fssize);
printf(" sunit = %lu\n", opts.sunit);
printf(" swidth = %lu\n", opts.swidth);
- printf(" rgrp align = %lu+%lu blocks\n", opts.swidth/sbd.bsize, opts.sunit/sbd.bsize);
+ printf(" rgrp align = %lu+%lu blocks\n", rgs.align, rgs.align_off);
}
+ warn_of_destruction(opts.device);
+
if (opts.confirm && !opts.override)
are_you_sure();
if (!S_ISREG(dev.stat.st_mode) && opts.discard)
- discard_blocks(dev.fd, sbd.bsize * sbd.device.length, opts.debug);
+ discard_blocks(dev.fd, dev.size, opts.debug);
- error = place_rgrps(&sbd, &opts, &dev);
- if (error) {
+ sbd.fssize = place_rgrps(&rgs, sbd.device_fd, &opts, &dev);
+ if (sbd.fssize == 0) {
fprintf(stderr, _("Failed to build resource groups\n"));
exit(1);
}
+ sbd.blks_total = rgs.blks_total;
+ sbd.rgrps = rgs.count;
build_root(&sbd);
build_master(&sbd);
error = build_jindex(&sbd);
10 years, 10 months
gfs2-utils: master - mkfs.gfs2: Align resource groups to RAID stripes
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=4d8ffb95...
Commit: 4d8ffb95aadaca3ca9c47188f4e653fc3a968b37
Parent: 623d8ff4a91f1ae4f09b0ca4f33be91a15ccaf4f
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Tue May 28 15:28:59 2013 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jun 6 17:21:29 2013 +0100
mkfs.gfs2: Align resource groups to RAID stripes
This patch uses the values provided by libblkid to align resource groups
to RAID stripes. The strategy we're using here is to give the start of
each rgrp an alignment to the stripe width and add an offset of one
stripe unit for the next rgrp and so on. This should ensure that the
rgrp headers are spread evenly over the array to minimise contention on
the bitmap blocks.
One challenge here was to avoid creating large gaps between rgrps and at
the end of the device due to the alignment padding. We get around this
by calculating the start and length of the next rgrp before fixing the
length of the current rgrp and extending it (or shrinking the final one)
as appropriate.
In order for this to work some relationships between block and stripe
sizes have been enforced: the stripe width must be a multiple of the
stripe unit and the stripe unit must be a multiple of the block size.
With this patch, specifying an rg size on the command line still gives
aligned rgrps but gaps will still be present.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/main_mkfs.c | 136 +++++++++++++++++++++++++++++++++----------------
1 files changed, 92 insertions(+), 44 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 12a259f..9f15dce 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -580,26 +580,62 @@ static int writerg(int fd, const struct rgrp_tree *rgt, const unsigned bsize)
return 0;
}
-static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts)
+static uint64_t align_block(const uint64_t base, const uint64_t align)
+{
+ if ((align > 0) && ((base % align) > 0))
+ return (base - (base % align)) + align;
+ return base;
+}
+
+static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts, const struct mkfs_dev *dev)
{
struct rgrp_tree *rgt = NULL;
uint64_t rgaddr = 0;
- unsigned int i = 0;
+ uint64_t nextaddr = 0;
+ uint64_t rglen = (sdp->rgsize << 20) / sdp->bsize;
+ const uint64_t maxrgsz = (GFS2_MAX_RGSIZE << 20) / sdp->bsize;
+ const uint64_t minrgsz = (GFS2_MIN_RGSIZE << 20) / sdp->bsize;
+ unsigned sunit_blocks = opts->sunit / sdp->bsize;
+ unsigned swidth_blocks = opts->swidth / opts->bsize;
+ unsigned stripe_offset = 0;
int err = 0;
- sdp->device.length -= sdp->sb_addr + 1;
- sdp->new_rgrps = how_many_rgrps(sdp, &sdp->device, opts->got_rgsize);
- rgaddr = sdp->sb_addr + 1;
+ sdp->new_rgrps = 0;
+ rgaddr = align_block(sdp->sb_addr + 1, swidth_blocks);
- for (i = 0; i < sdp->new_rgrps; i++) {
- /* TODO: align to RAID stripes, etc. */
+ while (rgaddr > 0) {
rgt = rgrp_insert(&sdp->rgtree, rgaddr);
if (rgt == NULL)
return -1;
- if (i == 0)
- rgt->length = sdp->device.length - ((sdp->new_rgrps - 1) * (sdp->device.length / sdp->new_rgrps));
+
+ stripe_offset += sunit_blocks;
+ if (stripe_offset >= swidth_blocks)
+ stripe_offset = 0;
+
+ /* The next rg might not fit into the remaining space so calculate it now
+ in order to make decisions about the current rg */
+ nextaddr = align_block(rgaddr + rglen, swidth_blocks) + stripe_offset;
+ if (!opts->got_rgsize && (nextaddr - rgaddr) <= maxrgsz)
+ /* Use up gap left by alignment if possible */
+ rgt->length = nextaddr - rgaddr;
else
- rgt->length = sdp->device.length / sdp->new_rgrps;
+ rgt->length = rglen;
+
+ /* If the next rg would overflow the device, either shrink it or expand
+ the current rg to use the remaining space */
+ if (nextaddr + rglen > sdp->device.length) {
+ /* Squeeze the last 1 or 2 rgs into the remaining space */
+ if ((nextaddr < sdp->device.length) && (sdp->device.length - nextaddr >= minrgsz)) {
+ rglen = sdp->device.length - nextaddr;
+ } else {
+ if (sdp->device.length - rgaddr <= maxrgsz)
+ rgt->length = sdp->device.length - rgaddr;
+ else
+ rgt->length = maxrgsz;
+ /* This is the last rg */
+ nextaddr = 0;
+ }
+ }
/* Build the rindex entry */
rgt->ri.ri_length = rgblocks2bitblocks(sdp->bsize, rgt->length, &rgt->ri.ri_data);
@@ -614,6 +650,11 @@ static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts)
rgt->rg.rg_header.mh_format = GFS2_FORMAT_RG;
rgt->rg.rg_free = rgt->ri.ri_data;
+ if (opts->debug) {
+ gfs2_rindex_print(&rgt->ri);
+ printf(" stripe_offset: %u\n", stripe_offset);
+ }
+
/* TODO: This call allocates buffer heads and bitmap pointers
* in rgt. We really shouldn't need to do that. */
err = gfs2_compute_bitstructs(sdp->bsize, rgt);
@@ -628,8 +669,9 @@ static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts)
perror(_("Failed to write resource group"));
return -1;
}
+ sdp->new_rgrps++;
sdp->blks_total += rgt->ri.ri_data;
- rgaddr += rgt->length;
+ rgaddr = nextaddr;
}
sdp->rgrps = sdp->new_rgrps;
@@ -637,7 +679,7 @@ static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts)
return 0;
}
-static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_dev *dev)
+static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_dev *dev, unsigned bsize)
{
memset(sdp, 0, sizeof(struct gfs2_sbd));
sdp->time = time(NULL);
@@ -647,7 +689,7 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_d
sdp->jsize = opts->jsize;
sdp->md.journals = opts->journals;
sdp->device_fd = dev->fd;
- sdp->bsize = choose_blocksize(opts, dev);
+ sdp->bsize = bsize;
if (compute_constants(sdp)) {
perror(_("Failed to compute file system constants"));
@@ -666,19 +708,6 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_d
}
strcpy(sdp->lockproto, opts->lockproto);
strcpy(sdp->locktable, opts->locktable);
- if (opts->debug) {
- printf(_("Calculated file system options:\n"));
- printf(" bsize = %u\n", sdp->bsize);
- printf(" qcsize = %u\n", sdp->qcsize);
- printf(" jsize = %u\n", sdp->jsize);
- printf(" journals = %u\n", sdp->md.journals);
- printf(" proto = %s\n", sdp->lockproto);
- printf(" rgsize = %u\n", sdp->rgsize);
- printf(" table = %s\n", sdp->locktable);
- printf(" fssize = %"PRIu64"\n", opts->fssize);
- printf(" sunit = %lu\n", opts->sunit);
- printf(" swidth = %lu\n", opts->swidth);
- }
}
static int probe_contents(struct mkfs_dev *dev)
@@ -764,6 +793,24 @@ static void open_dev(const char *path, struct mkfs_dev *dev)
exit(1);
}
+static void opts_set_stripe(struct mkfs_opts *opts, const struct mkfs_dev *dev, unsigned bsize)
+{
+ if (!opts->got_swidth && dev->optimal_io_size > dev->physical_sector_size) {
+ opts->swidth = dev->optimal_io_size;
+ opts->got_swidth = 1;
+ }
+
+ if (!opts->got_sunit && dev->minimum_io_size > dev->physical_sector_size) {
+ opts->sunit = dev->minimum_io_size;
+ opts->got_sunit = 1;
+ }
+
+ if (opts->got_sunit && (opts->sunit % bsize) != 0) {
+ fprintf(stderr, "Stripe unit (%lu) is not a multiple of the block size (%u)\n", opts->sunit, bsize);
+ exit(1);
+ }
+}
+
void main_mkfs(int argc, char *argv[])
{
struct gfs2_sbd sbd;
@@ -771,28 +818,15 @@ void main_mkfs(int argc, char *argv[])
struct mkfs_dev dev;
int error;
unsigned char uuid[16];
+ unsigned bsize;
opts_init(&opts);
opts_get(argc, argv, &opts);
opts_check(&opts);
open_dev(opts.device, &dev);
- if (!opts.got_swidth) {
- if (dev.optimal_io_size > 0)
- opts.swidth = dev.optimal_io_size;
- else
- opts.swidth = dev.logical_sector_size;
- }
-
- if (!opts.got_sunit) {
- if (dev.minimum_io_size > 0)
- opts.sunit = dev.minimum_io_size;
- else
- opts.sunit = dev.logical_sector_size;
- }
-
- if (opts.debug)
- printf("Resource group alignment: %"PRIu64" bytes\n", opts.swidth);
+ bsize = choose_blocksize(&opts, &dev);
+ opts_set_stripe(&opts, &dev, bsize);
if (S_ISREG(dev.stat.st_mode)) {
opts.got_bsize = 1; /* Use default block size for regular files */
@@ -800,7 +834,21 @@ void main_mkfs(int argc, char *argv[])
warn_of_destruction(opts.device);
- sbd_init(&sbd, &opts, &dev);
+ sbd_init(&sbd, &opts, &dev, bsize);
+ if (opts.debug) {
+ printf(_("Calculated file system options:\n"));
+ printf(" bsize = %u\n", sbd.bsize);
+ printf(" qcsize = %u\n", sbd.qcsize);
+ printf(" jsize = %u\n", sbd.jsize);
+ printf(" journals = %u\n", sbd.md.journals);
+ printf(" proto = %s\n", sbd.lockproto);
+ printf(" rgsize = %u\n", sbd.rgsize);
+ printf(" table = %s\n", sbd.locktable);
+ printf(" fssize = %"PRIu64"\n", opts.fssize);
+ printf(" sunit = %lu\n", opts.sunit);
+ printf(" swidth = %lu\n", opts.swidth);
+ printf(" rgrp align = %lu+%lu blocks\n", opts.swidth/sbd.bsize, opts.sunit/sbd.bsize);
+ }
if (opts.confirm && !opts.override)
are_you_sure();
@@ -808,7 +856,7 @@ void main_mkfs(int argc, char *argv[])
if (!S_ISREG(dev.stat.st_mode) && opts.discard)
discard_blocks(dev.fd, sbd.bsize * sbd.device.length, opts.debug);
- error = place_rgrps(&sbd, &opts);
+ error = place_rgrps(&sbd, &opts, &dev);
if (error) {
fprintf(stderr, _("Failed to build resource groups\n"));
exit(1);
10 years, 10 months
gfs2-utils: master - mkfs.gfs2: Set sunit and swidth from probed io limits
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=623d8ff4...
Commit: 623d8ff4a91f1ae4f09b0ca4f33be91a15ccaf4f
Parent: 921cff7fc9a390f450c93f8b2b43b393bb823c24
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Mon May 20 18:30:18 2013 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jun 6 16:51:09 2013 +0100
mkfs.gfs2: Set sunit and swidth from probed io limits
If sunit and swidth are given, use the io limits probed with libblkid to
provide the alignment values. Also improves validation of the sunit and
swidth options.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/main_mkfs.c | 44 +++++++++++++++++++++++++++++++++++---------
1 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 80b2782..12a259f 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -85,8 +85,8 @@ struct mkfs_opts {
unsigned qcsize;
unsigned jsize;
unsigned rgsize;
- unsigned sunit;
- unsigned swidth;
+ unsigned long sunit;
+ unsigned long swidth;
uint64_t fssize;
uint32_t journals;
const char *lockproto;
@@ -216,7 +216,7 @@ static long long cvtnum(unsigned int blocksize, unsigned int sectorsize, const c
return -1LL;
}
-static void parse_unsigned(struct mkfs_opts *opts, const char *key, const char *val, unsigned *n)
+static unsigned long parse_ulong(struct mkfs_opts *opts, const char *key, const char *val)
{
long long l;
if (val == NULL || *val == '\0') {
@@ -224,11 +224,11 @@ static void parse_unsigned(struct mkfs_opts *opts, const char *key, const char *
exit(-1);
}
l = cvtnum(opts->bsize, 0, val);
- if (l > UINT_MAX || l < 0) {
+ if (l > ULONG_MAX || l < 0) {
fprintf(stderr, _("Value of '%s' is invalid\n"), key);
exit(-1);
}
- *n = (unsigned)l;
+ return (unsigned long)l;
}
static void opt_parse_extended(char *str, struct mkfs_opts *opts)
@@ -242,10 +242,10 @@ static void opt_parse_extended(char *str, struct mkfs_opts *opts)
exit(-1);
}
if (strcmp("sunit", key) == 0) {
- parse_unsigned(opts, "sunit", val, &opts->sunit);
+ opts->sunit = parse_ulong(opts, "sunit", val);
opts->got_sunit = 1;
} else if (strcmp("swidth", key) == 0) {
- parse_unsigned(opts, "swidth", val, &opts->swidth);
+ opts->swidth = parse_ulong(opts, "swidth", val);
opts->got_swidth = 1;
} else {
fprintf(stderr, _("Invalid option '%s'\n"), key);
@@ -495,6 +495,16 @@ static void opts_check(struct mkfs_opts *opts)
if (!opts->qcsize || opts->qcsize > 64)
die( _("bad quota change size\n"));
+ if ((opts->got_sunit && !opts->got_swidth) || (!opts->got_sunit && opts->got_swidth)) {
+ fprintf(stderr, _("Stripe unit and stripe width must be specified together\n"));
+ exit(1);
+ }
+
+ if (opts->got_sunit && (opts->swidth % opts->sunit)) {
+ fprintf(stderr, _("Stripe width (%lu) must be a multiple of stripe unit (%lu)\n"),
+ opts->swidth, opts->sunit);
+ exit(1);
+ }
}
static void print_results(struct gfs2_sbd *sdp, uint64_t real_device_size,
@@ -666,8 +676,8 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_d
printf(" rgsize = %u\n", sdp->rgsize);
printf(" table = %s\n", sdp->locktable);
printf(" fssize = %"PRIu64"\n", opts->fssize);
- printf(" sunit = %u\n", opts->sunit);
- printf(" swidth = %u\n", opts->swidth);
+ printf(" sunit = %lu\n", opts->sunit);
+ printf(" swidth = %lu\n", opts->swidth);
}
}
@@ -767,6 +777,22 @@ void main_mkfs(int argc, char *argv[])
opts_check(&opts);
open_dev(opts.device, &dev);
+ if (!opts.got_swidth) {
+ if (dev.optimal_io_size > 0)
+ opts.swidth = dev.optimal_io_size;
+ else
+ opts.swidth = dev.logical_sector_size;
+ }
+
+ if (!opts.got_sunit) {
+ if (dev.minimum_io_size > 0)
+ opts.sunit = dev.minimum_io_size;
+ else
+ opts.sunit = dev.logical_sector_size;
+ }
+
+ if (opts.debug)
+ printf("Resource group alignment: %"PRIu64" bytes\n", opts.swidth);
if (S_ISREG(dev.stat.st_mode)) {
opts.got_bsize = 1; /* Use default block size for regular files */
10 years, 10 months
fence-agents: master - fencing: Action 'monitor' is not working properly for fence agents without '--plugs'
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=d7378e...
Commit: d7378e8c4b986fa490b31d53526edf24c6b0c9e1
Parent: 8900e3ed1446a8b882cc6eed7fd3595b0f4d3ffb
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Fri Jun 7 10:05:17 2013 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Fri Jun 7 10:10:06 2013 +0200
fencing: Action 'monitor' is not working properly for fence agents without '--plugs'
The bug was introduced when support for multiple ports was added.
commit 0097e806545d722270b739f31a754d65994b18c9
---
fence/agents/lib/fencing.py.py | 27 +++++++++++++++------------
1 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index b7ea3d9..1424111 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -731,18 +731,21 @@ def wait_power_status(tn, options, get_power_fn):
def get_multi_power_fn(tn, options, get_power_fn):
status = "off"
- for plug in options["--plugs"]:
- try:
- options["--uuid"] = str(uuid.UUID(plug))
- except ValueError:
- pass
- except KeyError:
- pass
+ if options.has_key("--plugs"):
+ for plug in options["--plugs"]:
+ try:
+ options["--uuid"] = str(uuid.UUID(plug))
+ except ValueError:
+ pass
+ except KeyError:
+ pass
- options["--plug"] = plug
- plug_status = get_power_fn(tn, options)
- if plug_status == "on":
- status = plug_status
+ options["--plug"] = plug
+ plug_status = get_power_fn(tn, options)
+ if plug_status == "on":
+ status = plug_status
+ else:
+ status = get_power_fn(tn, options)
return status
10 years, 10 months
gfs2-utils: master - gfs2_lockcapture: Various script and man page updates
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=921cff7f...
Commit: 921cff7fc9a390f450c93f8b2b43b393bb823c24
Parent: d36cfaca3670770656abab245913b7addd274be9
Author: Shane Bradley <sbradley(a)redhat.com>
AuthorDate: Wed Jun 5 15:49:12 2013 -0400
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jun 6 09:55:46 2013 +0100
gfs2_lockcapture: Various script and man page updates
Added an option to disable process data gathering, added gathering of
dlm_tool lockdebug, df, lsof, DLM hash table sizes.
The script no longer requires GFS2 mounts to capture data which allows
the capturing of dlm data without having a GFS2 mount. Added -P option
so that process gathering can be disabled. The following commands will
have their output saved: dlm_tool lockdebug, df -h, lsof, and contents
of /sys/kernel/config/dlm/cluster/*_size. The -t option was removed and
all output directories are .tar.bz2. The man page was updated with list
of all the files or command outputs that will be in the output
directory.
Signed-off-by: Shane Bradley <sbradley(a)redhat.com>
---
gfs2/man/gfs2_lockcapture.8 | 87 ++++++++---
gfs2/scripts/gfs2_lockcapture | 366 +++++++++++++++++++++++++++++++----------
2 files changed, 347 insertions(+), 106 deletions(-)
diff --git a/gfs2/man/gfs2_lockcapture.8 b/gfs2/man/gfs2_lockcapture.8
index acd9113..231207e 100644
--- a/gfs2/man/gfs2_lockcapture.8
+++ b/gfs2/man/gfs2_lockcapture.8
@@ -1,22 +1,21 @@
.TH gfs2_lockcapture 8
.SH NAME
-gfs2_lockcapture \- will capture locking information from GFS2 file systems and DLM.
+gfs2_lockcapture \- capture locking information from GFS2 file systems and DLM.
.SH SYNOPSIS
-.B gfs2_lockcapture \fR[-dqyt] [-o \fIoutput directory]\fR [-r \fInumber of runs]\fR [-s \fIseconds to sleep]\fR [-n \fIname of GFS2 filesystem]\fP
+.B gfs2_lockcapture \fR[-dqyP] [-o \fIoutput directory]\fR [-r \fInumber of runs]\fR [-s \fIseconds to sleep]\fR [-n \fIname of GFS2 file system]\fP
.PP
.B gfs2_lockcapture \fR[-dqyi]
.SH DESCRIPTION
-\fIgfs2_lockcapture\fR is used to capture all the GFS2 lockdump data and
-corresponding DLM data. The command can be configured to capture the data
-multiple times and how much time to sleep between each iteration of capturing
-the data. By default all of the mounted GFS2 filesystems will have their data
-collected unless GFS2 filesystems are specified.
+\fIgfs2_lockcapture\fR is used to capture the GFS2 lockdump data and
+corresponding DLM data for GFS2 file systems. The number of captures and their
+frequency can be configured. By default all of the mounted GFS2 file systems
+will have their data collected unless GFS2 file systems are specified.
.PP
-Please note that sysrq -t and -m events are trigger or the pid directories in /proc are
-collected on each iteration of capturing the data.
+Please note that sysrq -t (thread) and -m (memory) dumps and the pid
+directories in /proc are collected unless they are disabled with the -P option.
.SH OPTIONS
.TP
@@ -24,31 +23,79 @@ collected on each iteration of capturing the data.
Prints out a short usage message and exits.
.TP
\fB-d, --debug\fP
-enables debug logging.
+Enables debug logging.
.TP
\fB-q, --quiet\fP
-disables logging to console.
+Disables logging to console.
.TP
\fB-y, --no_ask\fP
-disables all questions and assumes yes.
+Disables all questions and assumes yes.
.TP
\fB-i, --info\fP
-prints information about the mounted GFS2 file systems.
+Prints information about the mounted GFS2 file systems.
.TP
-\fB-t, --archive\fP
-the output directory will be archived(tar) and compressed(.bz2).
+\fB-P, --disable_process_gather\fP
+The gathering of process information will be disabled.
.TP
\fB-o \fI<output directory>, \fB--path_to_output_dir\fR=\fI<output directory>\fP
-the directory where all the collect data will stored.
+The directory where all the collect data will stored.
.TP
\fB-r \fI<number of runs>, \fB--num_of_runs\fR=\fI<number of runs>\fP
-number of runs capturing the lockdump data.
+The number of runs capturing the lockdump data. The default is 3 runs.
.TP
\fB-s \fI<seconds to sleep>, \fB--seconds_sleep\fR=\fI<seconds to sleep>\fP
-number of seconds to sleep between runs of capturing the lockdump data.
+The number of seconds to sleep between runs of capturing the lockdump data. The default is 120 seconds.
.TP
\fB-n \fI<name of GFS2 filesystem>, \fB--fs_name\fR=\fI<name of GFS2 filesystem>\fP
-name of the GFS2 filesystem(s) that will have their lockdump data captured.
+The name of the GFS2 filesystem(s) that will have their lockdump data captured. By default, all mounted GFS2 file systems will have their data captured.
.
+.SH NOTES
+The output of the following commands will be captured:
+.IP \(bu 2
+uname -a
+.IP \(bu 2
+uptime
+.IP \(bu 2
+ps h -AL -o "tid,s,cmd"
+.IP \(bu 2
+df -h
+.IP \(bu 2
+lsof
+.IP \(bu 2
+mount -l
+.IP \(bu 2
+dlm_tool ls
+.IP \(bu 2
+dlm_tool lockdebug -v -s -w <lockspace name>
+.IP \(bu 2
+echo "t" > /proc/sysrq-trigger (If /proc/1/stack does not exist)
+.IP \(bu 2
+echo "m" > /proc/sysrq-trigger (If /proc/1/stack does not exist)
+
+.SH AUTHOR
+.nf
+Shane Bradley <sbradley(a)fedoraproject.org>
+.fi
+.SH FILES
+.I /proc/mounts
+.br
+.I /proc/slabinfo
+.br
+.I /sys/kernel/config/dlm/cluster/lkbtbl_size
+.br
+.I /sys/kernel/config/dlm/cluster/dirtbl_size
+.br
+.I /sys/kernel/config/dlm/cluster/rsbtbl_size
+.br
+.I /sys/kernel/debug/gfs2/
+.br
+.I /sys/kernel/debug/dlm/
+.br
+.I /proc/<int>/
+(If /proc/1/stack does exists)
+.br
+.I /var/log/messages
+.br
+.I /var/log/cluster/
+.br
.SH SEE ALSO
-gfs2_lockanalyze(8)
diff --git a/gfs2/scripts/gfs2_lockcapture b/gfs2/scripts/gfs2_lockcapture
index 6a63fc8..81a0aeb 100644
--- a/gfs2/scripts/gfs2_lockcapture
+++ b/gfs2/scripts/gfs2_lockcapture
@@ -1,6 +1,6 @@
#!/usr/bin/env python
"""
-The script gfs2_lockcapture will capture locking information from GFS2 file
+The script "gfs2_lockcapture" will capture locking information from GFS2 file
systems and DLM.
@author : Shane Bradley
@@ -12,6 +12,7 @@ import sys
import os
import os.path
import logging
+import logging.handlers
from optparse import OptionParser, Option
import time
import platform
@@ -33,7 +34,7 @@ import tarfile
sure only 1 instance of this script is running at any time.
@type PATH_TO_PID_FILENAME: String
"""
-VERSION_NUMBER = "0.9-3"
+VERSION_NUMBER = "0.9-7"
MAIN_LOGGER_NAME = "%s" %(os.path.basename(sys.argv[0]))
PATH_TO_DEBUG_DIR="/sys/kernel/debug"
PATH_TO_PID_FILENAME = "/var/run/%s.pid" %(os.path.basename(sys.argv[0]))
@@ -43,7 +44,7 @@ PATH_TO_PID_FILENAME = "/var/run/%s.pid" %(os.path.basename(sys.argv[0]))
# #####################################################################
class ClusterNode:
"""
- This class represents a cluster node that is a current memeber in a cluster.
+ This class represents a cluster node that is a current member in a cluster.
"""
def __init__(self, clusternodeName, clusternodeID, clusterName, mapOfMountedFilesystemLabels):
"""
@@ -115,7 +116,7 @@ class ClusterNode:
mounted GFS2 filesystems. If includeClusterName is False it will only
return a list of all the mounted GFS2 filesystem names(ex. mygfs2vol1).
- @return: Returns a list of all teh mounted GFS2 filesystem names.
+ @return: Returns a list of all the mounted GFS2 filesystem names.
@rtype: Array
@param includeClusterName: By default this option is True and will
@@ -134,6 +135,24 @@ class ClusterNode:
listOfGFS2MountedFilesystemLabels.append(fsLabelSplit[1])
return listOfGFS2MountedFilesystemLabels
+ def getMountedGFS2FilesystemPaths(self):
+ """
+ Returns a map of all the mounted GFS2 filesystem paths. The key is the
+ GFS2 fs name(clustername:fs name) and value is the mountpoint.
+
+ @return: Returns a map of all the mounted GFS2 filesystem paths. The key
+ is the GFS2 fs name(clustername:fs name) and value is the mountpoint.
+ Returns a list of all the mounted GFS2 filesystem paths.
+ @rtype: Map
+ """
+ mapOfGFS2MountedFilesystemPaths = {}
+ for fsLabel in self.__mapOfMountedFilesystemLabels.keys():
+ value = self.__mapOfMountedFilesystemLabels.get(fsLabel)
+ mountPoint = value.split("type", 1)[0].split("on")[1]
+ if (len(mountPoint) > 0):
+ mapOfGFS2MountedFilesystemPaths[fsLabel] = mountPoint
+ return mapOfGFS2MountedFilesystemPaths
+
# #####################################################################
# Helper functions.
# #####################################################################
@@ -328,7 +347,7 @@ def archiveData(pathToSrcDir):
message = "A compressed archvied file already exists and will be removed: %s" %(pathToTarFilename)
logging.getLogger(MAIN_LOGGER_NAME).status(message)
try:
- os.remove(PATH_TO_PID_FILENAME)
+ os.remove(pathToTarFilename)
except IOError:
message = "There was an error removing the file: %s." %(pathToTarFilename)
logging.getLogger(MAIN_LOGGER_NAME).error(message)
@@ -508,6 +527,32 @@ def backupOutputDirectory(pathToOutputDir):
# existing output directory.
return (not os.path.exists(pathToOutputDir))
+def mountFilesystem(filesystemType, pathToDevice, pathToMountPoint):
+ """
+ This function will attempt to mount a filesystem. If the filesystem is
+ already mounted or the filesystem was successfully mounted then True is
+ returned, otherwise False is returned.
+
+ @return: If the filesystem is already mounted or the filesystem was
+ successfully mounted then True is returned, otherwise False is returned.
+ @rtype: Boolean
+
+ @param filesystemType: The type of filesystem that will be mounted.
+ @type filesystemType: String
+ @param pathToDevice: The path to the device that will be mounted.
+ @type pathToDevice: String
+ @param pathToMountPoint: The path to the directory that will be used as the
+ mount point for the device.
+ @type pathToMountPoint: String
+ """
+ if (os.path.ismount(PATH_TO_DEBUG_DIR)):
+ return True
+ listOfCommandOptions = ["-t", filesystemType, pathToDevice, pathToMountPoint]
+ if (not runCommand("mount", listOfCommandOptions)):
+ message = "There was an error mounting the filesystem type %s for the device %s to the mount point %s." %(filesystemType, pathToDevice, pathToMountPoint)
+ logging.getLogger(MAIN_LOGGER_NAME).error(message)
+ return os.path.ismount(PATH_TO_DEBUG_DIR)
+
def exitScript(removePidFile=True, errorCode=0):
"""
This function will cause the script to exit or quit. It will return an error
@@ -615,6 +660,89 @@ def getClusterNode(listOfGFS2Names):
else:
return None
+
+def getDLMToolDLMLockspaces():
+ """
+ This function returns the names of all the dlm lockspace names found with the
+ command: "dlm_tool ls".
+
+ @return: A list of all the dlm lockspace names.
+ @rtype: Array
+ """
+ dlmLockspaces = []
+ stdout = runCommandOutput("dlm_tool", ["ls"])
+ if (not stdout == None):
+ stdout = stdout.replace("dlm lockspaces\n", "")
+ dlmToolLSKeys = ["name", "id", "flags", "change", "members"]
+ # Split on newlines
+ stdoutSections = stdout.split("\n\n")
+ for section in stdoutSections:
+ # Create tmp map to hold data
+ dlmToolLSMap = dict.fromkeys(dlmToolLSKeys)
+ lines = section.split("\n")
+ for line in lines:
+ for dlmToolLSKey in dlmToolLSMap.keys():
+ if (line.startswith(dlmToolLSKey)):
+ value = line.replace(dlmToolLSKey, " ", 1).strip().rstrip()
+ dlmToolLSMap[dlmToolLSKey] = value
+ if ((not dlmToolLSMap.get("name") == None) and (not dlmToolLSMap.get("id") == None)):
+ dlmLockspaces.append(dlmToolLSMap.get("name"))
+ return dlmLockspaces
+
+def getGroupToolDLMLockspaces():
+ """
+ This function returns the names of all the dlm lockspace names found with the
+ command: "group_tool ls".
+
+ @return: A list of all the dlm lockspace names.
+ @rtype: Array
+ """
+ dlmLockspaces = []
+ stdout = runCommandOutput("group_tool", ["ls"])
+ if (not stdout == None):
+ lines = stdout.split("\n")
+ for line in lines:
+ if (line.startswith("dlm")):
+ dlmLockspaces.append(line.split()[2])
+ return dlmLockspaces
+
+def getDLMLockspaces():
+ """
+ Returns a list of the dlm lockspace names.
+
+ @return: Returns a list of dlm lockspace names.
+ @rtype: Array
+ """
+ message = "Gathering the DLM Lockspace Names."
+ logging.getLogger(MAIN_LOGGER_NAME).debug(message)
+ dlmLockspaces = getDLMToolDLMLockspaces()
+ if (not len(dlmLockspaces) > 0):
+ dlmLockspaces = getGroupToolDLMLockspaces()
+ return dlmLockspaces
+
+def getVerifiedDLMLockspaceNames(lockspaceNames):
+ """
+ Returns a list of DLM lockspaces that have been verified to exists in the
+ command output of $(dlm_tool ls).
+
+ @return: Returns a list of DLM lockspaces that have been verified to exists
+ in the command output of $(dlm_tool ls).
+ @rtype: Array
+
+ @param lockspaceNames: This is the list of DLM lockspaces that will have
+ their debug directory copied.
+ @type lockspaceNames: Array
+ """
+ # Get a list of all the DLM lockspaces names.
+ dlmLockspaces = getDLMLockspaces()
+ # Verify the lockspaceNames are lockspaces that exist.
+ verifiedLockspaceNames = []
+ for lockspaceName in lockspaceNames:
+ if ((lockspaceName in dlmLockspaces) and
+ (not lockspaceName in verifiedLockspaceNames)):
+ verifiedLockspaceNames.append(lockspaceName)
+ return verifiedLockspaceNames
+
def getMountedGFS2Filesystems():
"""
This function returns a list of all the mounted GFS2 filesystems.
@@ -659,32 +787,9 @@ def getLabelMapForMountedFilesystems(clusterName, listOfMountedFilesystems):
mapOfMountedFilesystemLabels[fsLabel] = mountedFilesystem
return mapOfMountedFilesystemLabels
-def mountFilesystem(filesystemType, pathToDevice, pathToMountPoint):
- """
- This function will attempt to mount a filesystem. If the filesystem is
- already mounted or the filesystem was successfully mounted then True is
- returned, otherwise False is returned.
-
- @return: If the filesystem is already mounted or the filesystem was
- successfully mounted then True is returned, otherwise False is returned.
- @rtype: Boolean
-
- @param filesystemType: The type of filesystem that will be mounted.
- @type filesystemType: String
- @param pathToDevice: The path to the device that will be mounted.
- @type pathToDevice: String
- @param pathToMountPoint: The path to the directory that will be used as the
- mount point for the device.
- @type pathToMountPoint: String
- """
- if (os.path.ismount(PATH_TO_DEBUG_DIR)):
- return True
- listOfCommandOptions = ["-t", filesystemType, pathToDevice, pathToMountPoint]
- if (not runCommand("mount", listOfCommandOptions)):
- message = "There was an error mounting the filesystem type %s for the device %s to the mount point %s." %(filesystemType, pathToDevice, pathToMountPoint)
- logging.getLogger(MAIN_LOGGER_NAME).error(message)
- return os.path.ismount(PATH_TO_DEBUG_DIR)
-
+# #####################################################################
+# Gather output from command functions
+# #####################################################################
def gatherGeneralInformation(pathToDSTDir):
"""
This function will gather general information about the cluster and write
@@ -712,7 +817,15 @@ def gatherGeneralInformation(pathToDSTDir):
pathToSrcFile = "/proc/slabinfo"
copyFile(pathToSrcFile, os.path.join(pathToDSTDir, pathToSrcFile.strip("/")))
+ # Copy the DLM hash table sizes:
+ pathToHashTableFiles = ["/sys/kernel/config/dlm/cluster/lkbtbl_size", "/sys/kernel/config/dlm/cluster/dirtbl_size",
+ "/sys/kernel/config/dlm/cluster/rsbtbl_size"]
+ for pathToSrcFile in pathToHashTableFiles:
+ if (os.path.exists(pathToSrcFile)):
+ copyFile(pathToSrcFile, os.path.join(pathToDSTDir, pathToSrcFile.strip("/")))
+
# Get "ps -eo user,pid,%cpu,%mem,vsz,rss,tty,stat,start,time,comm,wchan" data.
+ # Get " ps h -AL -o tid,s,cmd
command = "ps"
pathToCommandOutput = os.path.join(pathToDSTDir, "ps_hALo-tid.s.cmd")
try:
@@ -721,7 +834,29 @@ def gatherGeneralInformation(pathToDSTDir):
runCommand(command, ["h", "-AL", "-o", "tid,s,cmd"], standardOut=fout)
fout.close()
except IOError:
- message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
+ message = "There was an error writing the command output for %s to the file %s." %(command, pathToCommandOutput)
+ logging.getLogger(MAIN_LOGGER_NAME).error(message)
+
+ # Get df -h ouput
+ command = "df"
+ pathToCommandOutput = os.path.join(pathToDSTDir, "df-h.cmd")
+ try:
+ fout = open(pathToCommandOutput, "w")
+ runCommand(command, ["-h"], standardOut=fout)
+ fout.close()
+ except IOError:
+ message = "There was an error writing the command output for %s to the file %s." %(command, pathToCommandOutput)
+ logging.getLogger(MAIN_LOGGER_NAME).error(message)
+
+ # Get lsof ouput
+ command = "lsof"
+ pathToCommandOutput = os.path.join(pathToDSTDir, "lsof.cmd")
+ try:
+ fout = open(pathToCommandOutput, "w")
+ runCommand(command, [], standardOut=fout)
+ fout.close()
+ except IOError:
+ message = "There was an error writing the command output for %s to the file %s." %(command, pathToCommandOutput)
logging.getLogger(MAIN_LOGGER_NAME).error(message)
# Write the status of all the nodes in the cluster out.
@@ -746,7 +881,9 @@ def gatherGeneralInformation(pathToDSTDir):
message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
logging.getLogger(MAIN_LOGGER_NAME).error(message)
-
+# #####################################################################
+# Gather Process Information
+# #####################################################################
def isProcPidStackEnabled(pathToPidData):
"""
Returns true if the init process has the file "stack" in its pid data
@@ -810,6 +947,9 @@ def triggerSysRQEvents():
message = "There was an error writing the command output for %s to the file %s." %(command, pathToSysrqTriggerFile)
logging.getLogger(MAIN_LOGGER_NAME).error(message)
+# #####################################################################
+# Gather lockdumps and logs
+# #####################################################################
def gatherLogs(pathToDSTDir):
"""
This function will copy all the cluster logs(/var/log/cluster) and the
@@ -828,29 +968,46 @@ def gatherLogs(pathToDSTDir):
pathToDSTLogDir = os.path.join(pathToDSTDir, os.path.basename(pathToLogDir))
copyDirectory(pathToLogDir, pathToDSTDir)
-def gatherDLMLockDumps(pathToDSTDir, listOfGFS2Filesystems):
+def gatherDLMLockDumps(pathToDSTDir, lockspaceNames):
"""
- This function copies the debug files for dlm for a GFS2 filesystem in the
- list to a directory. The list of GFS2 filesystems will only include the
- filesystem name for each item in the list. For example: "mygfs2vol1"
+ This function copies all the debug files for dlm and sorts them into their
+ own directory based on name of dlm lockspace.
@param pathToDSTDir: This is the path to directory where the files will be
copied to.
@type pathToDSTDir: String
- @param listOfGFS2Filesystems: This is the list of the GFS2 filesystems that
- will have their debug directory copied.
- @type listOfGFS2Filesystems: Array
+ @param lockspaceNames: This is the list of DLM lockspaces that will have
+ their debug directory copied.
+ @type lockspaceNames: Array
"""
+ # This function assumes that verifiedLockspaceNames has already been called
+ # to verify the lockspace does exist.
lockDumpType = "dlm"
pathToSrcDir = os.path.join(PATH_TO_DEBUG_DIR, lockDumpType)
pathToOutputDir = os.path.join(pathToDSTDir, lockDumpType)
message = "Copying the files in the %s lockdump data directory %s." %(lockDumpType.upper(), pathToSrcDir)
logging.getLogger(MAIN_LOGGER_NAME).debug(message)
- for filename in os.listdir(pathToSrcDir):
- for name in listOfGFS2Filesystems:
- if (filename.startswith(name)):
- copyFile(os.path.join(pathToSrcDir, filename),
- os.path.join(os.path.join(pathToOutputDir, name), filename))
+
+ # Get list of all the dlm lockspaces
+ if (os.path.exists(pathToSrcDir)):
+ for filename in os.listdir(pathToSrcDir):
+ for lockspaceName in lockspaceNames:
+ if (filename.startswith(lockspaceName)):
+ copyFile(os.path.join(pathToSrcDir, filename),
+ os.path.join(os.path.join(pathToOutputDir, lockspaceName), filename))
+
+ # Run dlm_tool lockdebug against the lockspace names and write to file.
+ for lockspaceName in lockspaceNames:
+ dstDir = os.path.join(pathToOutputDir, lockspaceName)
+ if (mkdirs(dstDir)):
+ pathToCommandOutput = os.path.join(dstDir,"%s_lockdebug" %(lockspaceName))
+ try:
+ fout = open(pathToCommandOutput, "w")
+ runCommand("dlm_tool", ["lockdebug", "-v", "-s", "-w", lockspaceName], standardOut=fout)
+ fout.close()
+ except IOError:
+ message = "There was an error writing the command output to the file %s." %(pathToCommandOutput)
+ logging.getLogger(MAIN_LOGGER_NAME).error(message)
def gatherGFS2LockDumps(pathToDSTDir, listOfGFS2Filesystems):
"""
@@ -875,6 +1032,8 @@ def gatherGFS2LockDumps(pathToDSTDir, listOfGFS2Filesystems):
pathToOutputDir = os.path.join(pathToDSTDir, lockDumpType)
# The number of files that were copied
fileCopiedCount = 0
+ if (not os.path.exists(pathToSrcDir)):
+ return False
for dirName in os.listdir(pathToSrcDir):
pathToCurrentDir = os.path.join(pathToSrcDir, dirName)
if ((os.path.isdir(pathToCurrentDir)) and (dirName in listOfGFS2Filesystems)):
@@ -886,6 +1045,7 @@ def gatherGFS2LockDumps(pathToDSTDir, listOfGFS2Filesystems):
# If the number of files(not directories) copied was greater than zero then files were copied
# succesfully.
return (fileCopiedCount > 0)
+
# ##############################################################################
# Get user selected options
# ##############################################################################
@@ -922,12 +1082,12 @@ def __getOptions(version) :
cmdParser.add_option("-i", "--info",
action="store_true",
dest="enablePrintInfo",
- help="prints information about the mounted GFS2 file systems",
+ help="prints information about the mounted GFS2 file-systems",
default=False)
- cmdParser.add_option("-t", "--archive",
+ cmdParser.add_option("-P", "--disable_process_gather",
action="store_true",
- dest="enableArchiveOutputDir",
- help="the output directory will be archived(tar) and compressed(.bz2)",
+ dest="disableProcessGather",
+ help="the gathering of process information will be disabled",
default=False)
cmdParser.add_option("-o", "--path_to_output_dir",
action="store",
@@ -939,21 +1099,21 @@ def __getOptions(version) :
cmdParser.add_option("-r", "--num_of_runs",
action="store",
dest="numberOfRuns",
- help="number of runs capturing the lockdump data",
+ help="number of runs capturing the lockdump data(default: 3 runs)",
type="int",
metavar="<number of runs>",
- default=2)
+ default=3)
cmdParser.add_option("-s", "--seconds_sleep",
action="store",
dest="secondsToSleep",
- help="number of seconds to sleep between runs of capturing the lockdump data",
+ help="number of seconds to sleep between runs of capturing the lockdump data(default: 120 seconds)",
type="int",
metavar="<seconds to sleep>",
default=120)
cmdParser.add_option("-n", "--fs_name",
action="extend",
dest="listOfGFS2Names",
- help="name of the GFS2 filesystem(s) that will have their lockdump data captured",
+ help="name of the GFS2 filesystem(s) that will have their lockdump data captured(default: all GFS2 file-systems will be captured)",
type="string",
metavar="<name of GFS2 filesystem>",
default=[])
@@ -994,14 +1154,15 @@ class OptionParserExtended(OptionParser):
examplesMessage += "\nIt will do 3 runs of gathering the lockdump information in 10 second intervals for only the"
examplesMessage += "\nGFS2 filesystems with the names myGFS2vol2,myGFS2vol1. Then it will archive and compress"
- examplesMessage += "\nthe data collected. All of the lockdump data will be written to the directory: "
- examplesMessage += "\n/tmp/2012-11-12_095556-gfs2_lockcapture and all the questions will be answered with yes.\n"
- examplesMessage += "\n# %s -r 3 -s 10 -t -n myGFS2vol2,myGFS2vol1 -o /tmp/2012-11-12_095556-gfs2_lockcapture -y\n" %(self.__commandName)
+ examplesMessage += "\nthe data collected in the output directory:"
+ examplesMessage += "\n/tmp/cluster42-gfs2_lockcapture and all the questions will be answered with yes.\n"
+ examplesMessage += "\n# %s -r 3 -s 10 -n myGFS2vol2,myGFS2vol1 -o /tmp/cluster42-gfs2_lockcapture -y\n" %(self.__commandName)
examplesMessage += "\nIt will do 2 runs of gathering the lockdump information in 25 second intervals for all the"
- examplesMessage += "\nmounted GFS2 filesystems. Then it will archive and compress the data collected. All of the"
- examplesMessage += "\nlockdump data will be written to the directory: /tmp/2012-11-12_095556-gfs2_lockcapture.\n"
- examplesMessage += "\n# %s -r 2 -s 25 -t -o /tmp/2012-11-12_095556-gfs2_lockcapture\n" %(self.__commandName)
+ examplesMessage += "\nmounted GFS2 filesystems. The gathering process data will be disabled. Then it will archive and compress"
+ examplesMessage += "\nthe data collected in the output directory:"
+ examplesMessage += "\n/tmp/cluster42-gfs2_lockcapture and all the questions will be answered with yes.\n"
+ examplesMessage += "\n# %s -r 2 -s 25 -P -o /tmp/cluster42-gfs2_lockcapture\n" %(self.__commandName)
OptionParser.print_help(self)
print examplesMessage
@@ -1073,6 +1234,14 @@ if __name__ == "__main__":
# Create a new status function and level.
logging.STATUS = logging.INFO + 2
logging.addLevelName(logging.STATUS, "STATUS")
+
+ # Log to main system logger that script has started then close the
+ # handler before the other handlers are created.
+ sysLogHandler = logging.handlers.SysLogHandler(address = '/dev/log')
+ logger.addHandler(sysLogHandler)
+ logger.info("Capturing of the data to analyze GFS2 lockdumps.")
+ logger.removeHandler(sysLogHandler)
+
# Create a function for the STATUS_LEVEL since not defined by python. This
# means you can call it like the other predefined message
# functions. Example: logging.getLogger("loggerName").status(message)
@@ -1128,7 +1297,6 @@ if __name__ == "__main__":
message += " %s" %(name)
message += "."
logging.getLogger(MAIN_LOGGER_NAME).error(message)
- exitScript(removePidFile=True, errorCode=1)
if (cmdLineOpts.enablePrintInfo):
logging.disable(logging.CRITICAL)
print "List of all the mounted GFS2 filesystems that can have their lockdump data captured:"
@@ -1231,27 +1399,48 @@ if __name__ == "__main__":
# Going to sleep for 2 seconds, so that TIMESTAMP should be in the
# past in the logs so that capturing sysrq data will be guaranteed.
time.sleep(2)
- # Gather the backtraces for all the pids, by grabbing the /proc/<pid
- # number> or triggering sysrq events to capture task bask traces
- # from log.
- message = "Pass (%d/%d): Triggering the sysrq events for the host." %(i, cmdLineOpts.numberOfRuns)
- logging.getLogger(MAIN_LOGGER_NAME).debug(message)
- # Gather the data in the /proc/<pid> directory if the file
- # </proc/<pid>/stack exists. If file exists we will not trigger
- # sysrq events.
- pathToPidData = "/proc"
- if (isProcPidStackEnabled(pathToPidData)):
- gatherPidData(pathToPidData, os.path.join(pathToOutputRunDir, pathToPidData.strip("/")))
- else:
- triggerSysRQEvents()
+
+ # If enabled then gather the process data.
+ if (not cmdLineOpts.disableProcessGather):
+ # Gather the backtraces for all the pids, by grabbing the /proc/<pid
+ # number> or triggering sysrq events to capture task bask traces
+ # from log.
+ # Gather the data in the /proc/<pid> directory if the file
+ # </proc/<pid>/stack exists. If file exists we will not trigger
+ # sysrq events.
+
+ # Should I gather anyhow and only capture sysrq if needed.
+ pathToPidData = "/proc"
+ if (isProcPidStackEnabled(pathToPidData)):
+ message = "Pass (%d/%d): Triggering the capture of all pid directories in %s." %(i, cmdLineOpts.numberOfRuns, pathToPidData)
+ logging.getLogger(MAIN_LOGGER_NAME).debug(message)
+ gatherPidData(pathToPidData, os.path.join(pathToOutputRunDir, pathToPidData.strip("/")))
+ else:
+ message = "Pass (%d/%d): Triggering the sysrq events for the host since stack was not captured in pid directory." %(i, cmdLineOpts.numberOfRuns)
+ logging.getLogger(MAIN_LOGGER_NAME).debug(message)
+ triggerSysRQEvents()
+
+ # #######################################################################
+ # Gather the DLM data and lock-dumps
+ # #######################################################################
+ # Gather data for the DLM lockspaces that are found.
+ lockspaceNames = clusternode.getMountedGFS2FilesystemNames(includeClusterName=False)
+ # In addition always gather these lockspaces(if they exist).
+ lockspaceNames.append("clvmd")
+ lockspaceNames.append("rgmanager")
+ # Verify that these lockspace names exist.
+ lockspaceNames = getVerifiedDLMLockspaceNames(lockspaceNames)
# Gather the dlm locks.
- lockDumpType = "dlm"
- message = "Pass (%d/%d): Gathering the %s lock dumps for the host." %(i, cmdLineOpts.numberOfRuns, lockDumpType.upper())
+ message = "Pass (%d/%d): Gathering the DLM lock-dumps for the host." %(i, cmdLineOpts.numberOfRuns)
logging.getLogger(MAIN_LOGGER_NAME).debug(message)
- gatherDLMLockDumps(pathToOutputRunDir, clusternode.getMountedGFS2FilesystemNames(includeClusterName=False))
+ # Add other notable lockspace names that should be captured if they exist.
+ gatherDLMLockDumps(pathToOutputRunDir, lockspaceNames)
+
+ # #######################################################################
+ # Gather the GFS2 data and lock-dumps
+ # #######################################################################
# Gather the glock locks from gfs2.
- lockDumpType = "gfs2"
- message = "Pass (%d/%d): Gathering the %s lock dumps for the host." %(i, cmdLineOpts.numberOfRuns, lockDumpType.upper())
+ message = "Pass (%d/%d): Gathering the GFS2 lock-dumps for the host." %(i, cmdLineOpts.numberOfRuns)
logging.getLogger(MAIN_LOGGER_NAME).debug(message)
if(gatherGFS2LockDumps(pathToOutputRunDir, clusternode.getMountedGFS2FilesystemNames())):
exitCode = 0
@@ -1274,16 +1463,21 @@ if __name__ == "__main__":
# #######################################################################
message = "All the files have been gathered and this directory contains all the captured data: %s" %(pathToOutputDir)
logging.getLogger(MAIN_LOGGER_NAME).info(message)
- if (cmdLineOpts.enableArchiveOutputDir):
- message = "The lockdump data will now be archived. This could some time depending on the size of the data collected."
+ message = "The lockdump data will now be archive. This could some time depending on the size of the data collected."
+ logging.getLogger(MAIN_LOGGER_NAME).info(message)
+ pathToTarFilename = archiveData(pathToOutputDir)
+ if (os.path.exists(pathToTarFilename)):
+ message = "The compressed archvied file was created: %s" %(pathToTarFilename)
logging.getLogger(MAIN_LOGGER_NAME).info(message)
- pathToTarFilename = archiveData(pathToOutputDir)
- if (os.path.exists(pathToTarFilename)):
- message = "The compressed archvied file was created: %s" %(pathToTarFilename)
- logging.getLogger(MAIN_LOGGER_NAME).info(message)
- else:
- message = "The compressed archvied failed to be created: %s" %(pathToTarFilename)
+ # Do some cleanup by removing the directory of the data if file archived file was created.
+ try:
+ shutil.rmtree(pathToOutputDir)
+ except OSError:
+ message = "There was an error removing the directory: %s." %(pathToOutputDir)
logging.getLogger(MAIN_LOGGER_NAME).error(message)
+ else:
+ message = "The compressed archvied failed to be created: %s" %(pathToTarFilename)
+ logging.getLogger(MAIN_LOGGER_NAME).error(message)
# #######################################################################
except KeyboardInterrupt:
print ""
10 years, 10 months
gfs2-utils: master - gfs2_edit: print formal inode numbers and hash value on dir display
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=d36cfaca...
Commit: d36cfaca3670770656abab245913b7addd274be9
Parent: 8c1297bf8cbb8f34bb2b635dd92d4cf5c3357363
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Jun 4 11:58:06 2013 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jun 4 11:58:06 2013 -0500
gfs2_edit: print formal inode numbers and hash value on dir display
This patch changes the directory display screen of gfs2_edit so that
it prints out the hash value and formal inode number. This makes it
easier to debug directory problems.
---
gfs2/edit/extended.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 17372ae..27c32a9 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -319,7 +319,7 @@ static int display_leaf(struct iinfo *ind)
break;
total_dirents++;
if (ind->ii[0].dirents >= 1) {
- eol(5);
+ eol(3);
if (termlines) {
if (edit_row[dmode] >=0 &&
line - start_line - 1 ==
@@ -330,9 +330,12 @@ static int display_leaf(struct iinfo *ind)
strcpy(edit_fmt, "%llx");
}
}
- print_gfs2("%d. (%d). %lld (0x%llx): ",
+ print_gfs2("%d/%d [%08x] %lld/%lld (0x%llx/0x%llx): ",
total_dirents, d + 1,
+ ind->ii[0].dirent[d].dirent.de_hash,
+ ind->ii[0].dirent[d].dirent.de_inum.no_formal_ino,
ind->ii[0].dirent[d].block,
+ ind->ii[0].dirent[d].dirent.de_inum.no_formal_ino,
ind->ii[0].dirent[d].block);
}
print_inode_type(ind->ii[0].dirent[d].dirent.de_type);
10 years, 10 months
gfs2-utils: master - libgfs2: Remove dinode_alloc
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=8c1297bf...
Commit: 8c1297bf8cbb8f34bb2b635dd92d4cf5c3357363
Parent: 98af5fe66d6a82dbf8aa4ca41d987ba005299c1e
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Tue Jun 4 11:24:37 2013 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Tue Jun 4 11:56:19 2013 +0100
libgfs2: Remove dinode_alloc
Switch the remaining users of dinode_alloc() to lgfs2_dinode_alloc and
remove it.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/fs_ops.c | 6 ------
gfs2/libgfs2/libgfs2.h | 1 -
gfs2/libgfs2/structures.c | 10 ++++++++--
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 36cd789..4a84687 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -237,12 +237,6 @@ uint64_t meta_alloc(struct gfs2_inode *ip)
return x;
}
-uint64_t dinode_alloc(struct gfs2_sbd *sdp)
-{
- sdp->dinodes_alloced++;
- return blk_alloc_i(sdp, DINODE);
-}
-
/**
* Allocate a dinode block in a bitmap. In order to plan ahead we look for a
* resource group with blksreq free blocks but only allocate the one dinode block.
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 0d2f87f..8502abf 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -435,7 +435,6 @@ extern struct gfs2_inode *is_system_inode(struct gfs2_sbd *sdp,
extern void inode_put(struct gfs2_inode **ip);
extern uint64_t data_alloc(struct gfs2_inode *ip);
extern uint64_t meta_alloc(struct gfs2_inode *ip);
-extern uint64_t dinode_alloc(struct gfs2_sbd *sdp);
extern int lgfs2_dinode_alloc(struct gfs2_sbd *sdp, const uint64_t blksreq, uint64_t *blkno);
extern int gfs2_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
unsigned int size);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 46fd8df..2a8c6f7 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -19,8 +19,11 @@ int build_master(struct gfs2_sbd *sdp)
struct gfs2_inum inum;
uint64_t bn;
struct gfs2_buffer_head *bh;
+ int err = lgfs2_dinode_alloc(sdp, 1, &bn);
+
+ if (err != 0)
+ return -1;
- bn = dinode_alloc(sdp);
inum.no_formal_ino = sdp->md.next_inum++;
inum.no_addr = bn;
@@ -425,8 +428,11 @@ int build_root(struct gfs2_sbd *sdp)
struct gfs2_inum inum;
uint64_t bn;
struct gfs2_buffer_head *bh;
+ int err = lgfs2_dinode_alloc(sdp, 1, &bn);
+
+ if (err != 0)
+ return -1;
- bn = dinode_alloc(sdp);
inum.no_formal_ino = sdp->md.next_inum++;
inum.no_addr = bn;
10 years, 10 months
cluster: RHEL510 - fencing: remove additional code
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=75f10d2cb45...
Commit: 75f10d2cb456040124adf819adbe077d9954b320
Parent: 0c3782fd3fa61e9ceea938cc4f61e8572c6916c8
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Jun 3 16:22:26 2013 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jun 3 16:22:26 2013 +0200
fencing: remove additional code
When resolving bug #904195 - additional code that removes fence_manual
and changes configure was added. This was not intended, so this patch
removes it.
---
configure | 8 ++++----
fence/agents/Makefile | 6 +++---
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/configure b/configure
index 0bcbcc2..05fc58e 100755
--- a/configure
+++ b/configure
@@ -33,8 +33,8 @@ echo "configure gnbd"
echo "configure rgmanager"
(cd rgmanager; ./configure $@)
-#echo "configure cmirror"
-#(cd cmirror; ./configure $@)
+echo "configure cmirror"
+(cd cmirror; ./configure $@)
-#echo "configure cmirror-kernel"
-#(cd cmirror-kernel; ./configure $@)
+echo "configure cmirror-kernel"
+(cd cmirror-kernel; ./configure $@)
diff --git a/fence/agents/Makefile b/fence/agents/Makefile
index e1d7eb4..669e291 100644
--- a/fence/agents/Makefile
+++ b/fence/agents/Makefile
@@ -33,7 +33,7 @@ all:
${MAKE} -C ipdu all
${MAKE} -C ipmilan all
${MAKE} -C lpar all
-# ${MAKE} -C manual all
+ ${MAKE} -C manual all
${MAKE} -C mcdata all
# ${MAKE} -C rackswitch all
${MAKE} -C rhevm all
@@ -69,7 +69,7 @@ install: all
${MAKE} -C ipdu install
${MAKE} -C ipmilan install
${MAKE} -C lpar install
-# ${MAKE} -C manual install
+ ${MAKE} -C manual install
${MAKE} -C mcdata install
# ${MAKE} -C rackswitch install
${MAKE} -C rhevm install
@@ -105,7 +105,7 @@ clean:
${MAKE} -C ipdu clean
${MAKE} -C ipmilan clean
${MAKE} -C lpar clean
-# ${MAKE} -C manual clean
+ ${MAKE} -C manual clean
${MAKE} -C mcdata clean
# ${MAKE} -C rackswitch clean
${MAKE} -C rhevm clean
10 years, 11 months