gfs2-utils: master - mkfs.gfs2: Fix the resource group layout strategy, again
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=b57c362a...
Commit: b57c362a3eab9fb6225f098f1c33e4afec6ad0ce
Parent: 80c78200ee0bdfbc0e54ca49b79f9470cfe90da1
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Mar 13 02:00:23 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Sat Mar 29 23:20:29 2014 +0000
mkfs.gfs2: Fix the resource group layout strategy, again
The previous attempt at improving the resource group layout and
alignment fell somewhat short of the mark and left some issues, such as
the possibility of leaving a small resource group at the end of the
device which gfs2_grow could wrongly use as the file system's resource
group size.
The core of this patch is the new lgfs2_rgrps_plan() function which
calculates a sensible resource group size given a target maximum (which
we now default to 2GB instead of 256MB). In order to avoid leaving a gap
or a small rgrp at the end of the device, we adjust the rgrp length down
until a further adjustment would leave a gap, then apply a constant
adjustment to the size of a subset of the resource groups.
The rest of the patch aims to clean up libgfs2's resource group API and
give more control to the application rather than storing a lot of the
resource group layout parameters in the lgfs2_rgrps_t. This should make
it easier to use the same functions in gfs2_grow, fsck.gfs2 and any
other tools which might need to manipulate resource groups.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 16 ++---
gfs2/libgfs2/rgrp.c | 206 +++++++++++++++++++++++++++++++++---------------
gfs2/mkfs/main_mkfs.c | 104 ++++++++++++++++--------
3 files changed, 218 insertions(+), 108 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index ce51e8c..24947c2 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -186,19 +186,16 @@ struct rgrp_tree {
struct gfs2_buffer_head **bh;
};
-struct lgfs2_rgrp_align {
- uint64_t base;
- uint64_t offset;
-};
-
typedef struct rgrp_tree *lgfs2_rgrp_t;
typedef struct _lgfs2_rgrps *lgfs2_rgrps_t;
-extern lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t start, uint64_t devlen, uint32_t rglen, struct lgfs2_rgrp_align *al);
+extern lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align, uint64_t offset);
+extern uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr);
+extern uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len);
extern unsigned lgfs2_rgsize_for_data(uint64_t blksreq, unsigned bsize);
-extern lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand);
-extern int lgfs2_rgrp_write(int fd, lgfs2_rgrp_t rg, unsigned bsize);
-extern int lgfs2_rgrps_end(lgfs2_rgrps_t rgs);
+extern uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize);
+extern lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint64_t addr, uint32_t rglen, uint64_t *nextaddr);
+extern int lgfs2_rgrp_write(lgfs2_rgrps_t rgs, int fd, lgfs2_rgrp_t rg);
extern struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg);
// Temporary function to aid API migration
extern struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs) __attribute__((deprecated));
@@ -350,7 +347,6 @@ struct metapath {
#define GFS2_EXP_MIN_RGSIZE (1)
#define GFS2_MIN_RGSIZE (32)
-/* Look at this! Why can't we go bigger than 2GB? */
#define GFS2_MAX_RGSIZE (2048)
/* meta.c */
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 0752772..1242385 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -223,6 +223,11 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
}
}
+struct rgplan {
+ uint32_t num;
+ uint32_t len;
+};
+
/**
* This structure is defined in libgfs2.h as an opaque type. It stores the
* constants and context required for creating resource groups from any point
@@ -230,17 +235,11 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
*/
struct _lgfs2_rgrps {
struct osi_root root;
- uint64_t nextaddr;
+ struct rgplan plan[2];
unsigned bsize;
unsigned long align;
unsigned long align_off;
- unsigned long curr_offset;
- uint64_t maxrgsz;
- uint64_t minrgsz;
uint64_t devlen;
- uint64_t count;
- uint64_t blks_total;
- uint32_t rgsize;
};
static uint64_t align_block(const uint64_t base, const uint64_t align)
@@ -251,29 +250,121 @@ static uint64_t align_block(const uint64_t base, const uint64_t align)
}
/**
+ * Calculate the aligned block address of a resource group.
+ * rgs: The resource groups handle
+ * base: The base address of the first resource group address, in blocks
+ * Returns the aligned address of the first resource group.
+ */
+uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr)
+{
+ return align_block(addr, rgs->align);
+}
+
+/**
+ * Calculate the aligned relative address of the next resource group (and thus
+ * the aligned length of this one).
+ * rgs: The resource groups handle
+ * base: The base length of the current resource group, in blocks
+ * Returns the length of the resource group (the aligned relative address of
+ * the next one)
+ */
+uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len)
+{
+ return align_block(len, rgs->align) + rgs->align_off;
+}
+
+/**
+ * Plan the sizes of resource groups for remaining free space, based on a
+ * target maximum size. In order to make best use of the space while keeping
+ * the resource groups aligned appropriately we need to either reduce the
+ * length of every resource group or of a subset of the resource groups, so
+ * we're left with either one or two resource group sizes. We keep track of
+ * both of these and the numbers of each size of resource group inside the
+ * resource groups descriptor.
+ * rgs: The resource groups descriptor
+ * space: The number of remaining blocks to be allocated
+ * tgtsize: The target resource group size in blocks
+ * Returns the larger of the calculated resource group sizes or 0 if the
+ * smaller would be less than GFS2_MIN_RGSIZE.
+ */
+uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize)
+{
+ uint32_t maxlen = (GFS2_MAX_RGSIZE << 20) / rgs->bsize;
+ uint32_t minlen = (GFS2_MIN_RGSIZE << 20) / rgs->bsize;
+
+ /* Apps should already have checked that the rg size is <=
+ GFS2_MAX_RGSIZE but just in case alignment pushes it over we clamp
+ it back down while calculating the initial rgrp length. */
+ do {
+ rgs->plan[0].len = lgfs2_rgrp_align_len(rgs, tgtsize);
+ tgtsize -= (rgs->align + 1);
+ } while (rgs->plan[0].len > maxlen);
+
+ rgs->plan[0].num = space / rgs->plan[0].len;
+
+ if ((space - (rgs->plan[0].num * rgs->plan[0].len)) > rgs->align) {
+ unsigned adj = (rgs->align > 0) ? rgs->align : 1;
+
+ /* Spread the adjustment required to fit a new rgrp at the end
+ over all of the rgrps so that we don't end with a single
+ tiny one. */
+ while (((rgs->plan[0].len - adj) * (rgs->plan[0].num + 1)) >= space)
+ rgs->plan[0].len -= adj;
+
+ /* We've adjusted the size of the rgrps down as far as we can
+ without leaving a large gap at the end of the device now,
+ but we still need to reduce the size of some rgrps in order
+ to make everything fit, so we use the second rgplan to
+ specify a second length for a subset of the resource groups.
+ If plan[0].len already divides the space with no remainder,
+ plan[1].num will stay 0 and it won't be used. */
+ rgs->plan[1].len = rgs->plan[0].len - adj;
+ rgs->plan[1].num = 0;
+
+ while (((rgs->plan[0].len * rgs->plan[0].num) +
+ (rgs->plan[1].len * rgs->plan[1].num)) > space) {
+ /* Total number of rgrps stays constant now. We just
+ need to shift some weight around */
+ rgs->plan[0].num--;
+ rgs->plan[1].num++;
+ }
+ }
+
+ /* Once we've reached this point,
+ (plan[0].num * plan[0].len) + (plan[1].num * plan[1].len)
+ will be less than one adjustment smaller than 'space'. */
+
+ if (rgs->plan[0].len < minlen)
+ return 0;
+
+ return rgs->plan[0].len;
+}
+
+/**
* Create and initialise an empty set of resource groups
* bsize: The block size of the fs
- * start: The block address of the first resource group
* devlen: The length of the device, in fs blocks
- * rglen: Default rg size, in blocks
- * al: The required alignment of the resource groups
+ * align: The required stripe alignment of the resource groups. Must be a multiple of 'offset'.
+ * offset: The required stripe offset of the resource groups
* Returns an initialised lgfs2_rgrps_t or NULL if unsuccessful with errno set
*/
-lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t start, uint64_t devlen, uint32_t rglen, struct lgfs2_rgrp_align *al)
+lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align, uint64_t offset)
{
- lgfs2_rgrps_t rgs = calloc(1, sizeof(*rgs));
+ lgfs2_rgrps_t rgs;
+
+ errno = EINVAL;
+ if (offset != 0 && (align % offset) != 0)
+ return NULL;
+
+ rgs = calloc(1, sizeof(*rgs));
if (rgs == NULL)
return NULL;
rgs->bsize = bsize;
- rgs->maxrgsz = (GFS2_MAX_RGSIZE << 20) / bsize;
- rgs->minrgsz = (GFS2_MIN_RGSIZE << 20) / bsize;
- rgs->rgsize = rglen;
rgs->devlen = devlen;
- rgs->align = al->base;
- rgs->align_off = al->offset;
+ rgs->align = align;
+ rgs->align_off = offset;
memset(&rgs->root, 0, sizeof(rgs->root));
- rgs->nextaddr = align_block(start, rgs->align);
return rgs;
}
@@ -287,14 +378,6 @@ struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
}
/**
- * Return non-zero if there is space left for more resource groups or zero if not
- */
-int lgfs2_rgrps_end(lgfs2_rgrps_t rgs)
-{
- return (rgs->nextaddr == 0);
-}
-
-/**
* Returns the total resource group size, in blocks, required to give blksreq data blocks
*/
unsigned lgfs2_rgsize_for_data(uint64_t blksreq, unsigned bsize)
@@ -316,43 +399,38 @@ struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs)
/**
* Create a new resource group after the last resource group in a set.
* rgs: The set of resource groups
- * rglen: The required length of the resource group. If its is 0 the default rgsize
- * passed to lgfs2_rgrps_init() is used.
- * expand: Whether to expand the resource group when alignment would leave a gap.
- * Returns the new resource group on success or NULL on failure.
+ * addr: The address at which to place this resource group
+ * rglen: The required length of the resource group, in fs blocks.
+ * Returns the new resource group on success or NULL on failure with errno set.
+ * If errno is ENOSPC on a NULL return from this function, it could be
+ * interpreted as 'finished' unless you expected there to be enough space on
+ * the device for the resource group.
*/
-lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand)
+lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint64_t addr, uint32_t rglen, uint64_t *nextaddr)
{
int err = 0;
- lgfs2_rgrp_t rg = rgrp_insert(&rgs->root, rgs->nextaddr);
- if (rg == NULL)
- return NULL;
-
- rgs->curr_offset += rgs->align_off;
- if (rgs->curr_offset >= rgs->align)
- rgs->curr_offset = 0;
-
- if (rgs->rgsize > rglen)
- rglen = rgs->rgsize;
-
- rgs->nextaddr = align_block(rg->ri.ri_addr + rgs->rgsize, rgs->align) + rgs->curr_offset;
- /* Use up gap left by alignment if possible */
- if (expand && ((rgs->nextaddr - rg->ri.ri_addr) <= rgs->maxrgsz))
- rglen = rgs->nextaddr - rg->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;
+ lgfs2_rgrp_t rg;
+
+ if (rglen == 0) {
+ if (rgs->plan[0].num > 0) {
+ rglen = rgs->plan[0].len;
+ rgs->plan[0].num--;
+ } else if (rgs->plan[1].num > 0) {
+ rglen = rgs->plan[1].len;
+ rgs->plan[1].num--;
} else {
- if (rgs->devlen - rg->ri.ri_addr <= rgs->maxrgsz)
- rglen = rgs->devlen - rg->ri.ri_addr;
- else
- rglen = rgs->maxrgsz;
- /* This is the last rg */
- rgs->nextaddr = 0;
+ errno = ENOSPC;
+ return NULL;
}
}
+ if (addr + rglen > rgs->devlen) {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ rg = rgrp_insert(&rgs->root, addr);
+ if (rg == NULL)
+ return NULL;
rg->ri.ri_length = rgblocks2bitblocks(rgs->bsize, rglen, &rg->ri.ri_data);
rg->ri.ri_data0 = rg->ri.ri_addr + rg->ri.ri_length;
@@ -361,12 +439,12 @@ lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand)
rg->rg.rg_header.mh_type = GFS2_METATYPE_RG;
rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
rg->rg.rg_free = rg->ri.ri_data;
-
err = gfs2_compute_bitstructs(rgs->bsize, rg);
if (err != 0)
return NULL;
- rgs->blks_total += rg->ri.ri_data;
- rgs->count++;
+
+ if (nextaddr)
+ *nextaddr = rg->ri.ri_addr + rglen;
return rg;
}
@@ -374,10 +452,10 @@ lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand)
* Write a resource group to a file descriptor.
* Returns 0 on success or non-zero on failure with errno set
*/
-int lgfs2_rgrp_write(int fd, lgfs2_rgrp_t rg, unsigned bsize)
+int lgfs2_rgrp_write(const lgfs2_rgrps_t rgs, int fd, const lgfs2_rgrp_t rg)
{
ssize_t ret = 0;
- size_t len = rg->ri.ri_length * bsize;
+ size_t len = rg->ri.ri_length * rgs->bsize;
unsigned int i;
const struct gfs2_meta_header bmh = {
.mh_magic = GFS2_MAGIC,
@@ -390,9 +468,9 @@ int lgfs2_rgrp_write(int fd, lgfs2_rgrp_t rg, unsigned bsize)
gfs2_rgrp_out(&rg->rg, buff);
for (i = 1; i < rg->ri.ri_length; i++)
- gfs2_meta_header_out(&bmh, buff + (i * bsize));
+ gfs2_meta_header_out(&bmh, buff + (i * rgs->bsize));
- ret = pwrite(fd, buff, len, rg->ri.ri_addr * bsize);
+ ret = pwrite(fd, buff, len, rg->ri.ri_addr * rgs->bsize);
if (ret != len) {
free(buff);
return -1;
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 40f4766..ae82c9f 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -160,7 +160,7 @@ static void opts_init(struct mkfs_opts *opts)
opts->bsize = GFS2_DEFAULT_BSIZE;
opts->jsize = GFS2_DEFAULT_JSIZE;
opts->qcsize = GFS2_DEFAULT_QCSIZE;
- opts->rgsize = GFS2_DEFAULT_RGSIZE;
+ opts->rgsize = GFS2_MAX_RGSIZE;
opts->lockproto = "lock_dlm";
opts->locktable = "";
opts->confirm = 1;
@@ -583,9 +583,9 @@ static void warn_of_destruction(const char *path)
static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
{
- uint64_t rgsize = (opts->rgsize << 20) / sdp->bsize;
- struct lgfs2_rgrp_align align = {.base = 0, .offset = 0};
lgfs2_rgrps_t rgs;
+ uint64_t al_base = 0;
+ uint64_t al_off = 0;
if (opts->align && opts->got_sunit) {
if ((opts->sunit % sdp->bsize) != 0) {
@@ -597,18 +597,18 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
opts->swidth, opts->sunit);
exit(1);
} else {
- align.base = opts->swidth / sdp->bsize;
- align.offset = opts->sunit / sdp->bsize;
+ al_base = opts->swidth / sdp->bsize;
+ al_off = opts->sunit / sdp->bsize;
}
} else if (opts->align) {
if ((opts->dev.minimum_io_size > opts->dev.physical_sector_size) &&
(opts->dev.optimal_io_size > opts->dev.physical_sector_size)) {
- align.base = opts->dev.optimal_io_size / sdp->bsize;
- align.offset = opts->dev.minimum_io_size / sdp->bsize;
+ al_base = opts->dev.optimal_io_size / sdp->bsize;
+ al_off = opts->dev.minimum_io_size / sdp->bsize;
}
}
- rgs = lgfs2_rgrps_init(sdp->bsize, sdp->sb_addr + 1, sdp->device.length, rgsize, &align);
+ rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, al_base, al_off);
if (rgs == NULL) {
perror(_("Could not initialise resource groups"));
exit(-1);
@@ -617,7 +617,7 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
if (opts->debug) {
printf(" rgrp align = ");
if (opts->align)
- printf("%lu+%lu blocks\n", align.base, align.offset);
+ printf("%lu+%lu blocks\n", al_base, al_off);
else
printf("(disabled)\n");
}
@@ -625,36 +625,71 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
return rgs;
}
-static uint64_t place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
+static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t rgaddr, uint32_t len, uint64_t *next)
{
int err = 0;
lgfs2_rgrp_t rg = NULL;
struct gfs2_rindex *ri = NULL;
- while (!lgfs2_rgrps_end(rgs)) {
- rg = lgfs2_rgrp_append(rgs, 0, !opts->got_rgsize);
- if (rg == NULL) {
- perror(_("Failed to create resource group"));
- return 0;
- }
- err = lgfs2_rgrp_write(sdp->device_fd, rg, sdp->bsize);
- if (err != 0) {
- perror(_("Failed to write resource group"));
- return 0;
- }
- ri = lgfs2_rgrp_index(rg);
- if (opts->debug) {
- gfs2_rindex_print(ri);
- printf("\n");
- }
- sdp->blks_total += ri->ri_data;
- sdp->rgrps++;
+ rg = lgfs2_rgrp_append(rgs, rgaddr, len, next);
+ if (rg == NULL) {
+ if (errno == ENOSPC)
+ return 1;
+ perror(_("Failed to create resource group"));
+ return -1;
+ }
+ err = lgfs2_rgrp_write(rgs, sdp->device_fd, rg);
+ if (err != 0) {
+ perror(_("Failed to write resource group"));
+ return -1;
+ }
+ ri = lgfs2_rgrp_index(rg);
+ if (sdp->debug) {
+ gfs2_rindex_print(ri);
+ printf("\n");
}
+ sdp->blks_total += ri->ri_data;
+ sdp->fssize = ri->ri_data0 + ri->ri_data;
+ sdp->rgrps++;
+ return 0;
+}
- if (ri == NULL)
- return 0;
- else
- return ri->ri_data0 + ri->ri_data;
+static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
+{
+ uint64_t jfsize = lgfs2_space_for_data(sdp, sdp->bsize, opts->jsize << 20);
+ uint32_t jrgsize = lgfs2_rgsize_for_data(jfsize, sdp->bsize);
+ uint64_t rgaddr = lgfs2_rgrp_align_addr(rgs, sdp->sb_addr + 1);
+ uint32_t rgsize = lgfs2_rgrps_plan(rgs, sdp->device.length - rgaddr, ((opts->rgsize << 20) / sdp->bsize));
+ unsigned j;
+
+ if (rgsize >= jrgsize)
+ jrgsize = rgsize;
+
+ if (rgsize < ((GFS2_MIN_RGSIZE << 20) / sdp->bsize)) {
+ fprintf(stderr, _("Resource group size is too small\n"));
+ return -1;
+ } else if (rgsize < ((GFS2_DEFAULT_RGSIZE << 20) / sdp->bsize)) {
+ fprintf(stderr, _("Warning: small resource group size could impact performance\n"));
+ }
+
+ for (j = 0; j < opts->journals; j++) {
+ int result = place_rgrp(sdp, rgs, rgaddr, jrgsize, NULL);
+ if (result != 0)
+ return result;
+ rgaddr = rgaddr + jrgsize;
+ }
+
+ if (rgsize != jrgsize)
+ lgfs2_rgrps_plan(rgs, sdp->device.length - rgaddr, ((opts->rgsize << 20) / sdp->bsize));
+
+ while (1) {
+ int result = place_rgrp(sdp, rgs, rgaddr, 0, &rgaddr);
+ if (result < 0)
+ return result;
+ if (result > 0)
+ break; /* Done */
+ }
+ return 0;
}
static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsize)
@@ -668,6 +703,7 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsiz
sdp->md.journals = opts->journals;
sdp->device_fd = opts->dev.fd;
sdp->bsize = bsize;
+ sdp->debug = opts->debug;
if (compute_constants(sdp)) {
perror(_("Failed to compute file system constants"));
@@ -812,8 +848,8 @@ void main_mkfs(int argc, char *argv[])
if (!S_ISREG(opts.dev.stat.st_mode) && opts.discard)
discard_blocks(opts.dev.fd, opts.dev.size, opts.debug);
- sbd.fssize = place_rgrps(&sbd, rgs, &opts);
- if (sbd.fssize == 0) {
+ error = place_rgrps(&sbd, rgs, &opts);
+ if (error) {
fprintf(stderr, _("Failed to build resource groups\n"));
exit(1);
}
10 years, 2 months
gfs2-utils: master - libgfs2: Don't try to read more than IOV_MAX iovecs
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=80c78200...
Commit: 80c78200ee0bdfbc0e54ca49b79f9470cfe90da1
Parent: 4fc17a616077cb60180cb1831c461c3d4a8164a0
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Mar 12 15:23:59 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Sat Mar 29 23:20:29 2014 +0000
libgfs2: Don't try to read more than IOV_MAX iovecs
Reading large collections of blocks, as gfs2_rgrp_read may do with large
rgrps and small block sizes, can cause preadv() to fail with EINVAL in
breadm(). This patch splits large reads into IOV_MAX chunks to avoid
reads failing in that way. It also includes a test to exercise these
changes.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/buf.c | 57 +++++++++++++++++++++++++++++++---------------------
tests/mkfs.at | 4 +++
2 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 6fcdd17..92cd393 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -15,6 +15,14 @@
#include "libgfs2.h"
+#ifndef IOV_MAX
+ #ifdef UIO_MAXIOV
+ #define IOV_MAX UIO_MAXIOV
+ #else
+ #define IOV_MAX (1024)
+ #endif
+#endif
+
struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)
{
struct gfs2_buffer_head *bh;
@@ -34,31 +42,34 @@ struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)
int __breadm(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhs, size_t n,
uint64_t block, int line, const char *caller)
{
- struct iovec *iov = alloca(n * sizeof(struct iovec));
+ size_t v = (n < IOV_MAX) ? n : IOV_MAX;
+ struct iovec *iov = alloca(v * sizeof(struct iovec));
struct iovec *iovbase = iov;
- uint64_t b = block;
- size_t size = 0;
- size_t i;
- int ret;
-
- for (i = 0; i < n; i++) {
- bhs[i] = bget(sdp, b++);
- if (bhs[i] == NULL)
- return -1;
- *iov++ = bhs[i]->iov;
- size += bhs[i]->iov.iov_len;
+ size_t i = 0;
+
+ while (i < n) {
+ int j;
+ ssize_t ret;
+ ssize_t size = 0;
+
+ for (j = 0; (i + j < n) && (j < IOV_MAX); j++) {
+ bhs[i + j] = bget(sdp, block + i + j);
+ if (bhs[i + j] == NULL)
+ return -1;
+ iov[j] = bhs[i + j]->iov;
+ size += bhs[i + j]->iov.iov_len;
+ }
+
+ ret = preadv(sdp->device_fd, iovbase, j, (block + i) * sdp->bsize);
+ if (ret != size) {
+ fprintf(stderr, "bad read: %s from %s:%d: block %llu (0x%llx) "
+ "count: %d size: %zd ret: %zd\n", strerror(errno),
+ caller, line, (unsigned long long)block,
+ (unsigned long long)block, j, size, ret);
+ exit(-1);
+ }
+ i += j;
}
-
- ret = preadv(sdp->device_fd, iovbase, n, block * sdp->bsize);
-
- if (ret != size) {
- fprintf(stderr, "bad read: %s from %s:%d: block "
- "%llu (0x%llx)\n", strerror(errno),
- caller, line, (unsigned long long)block,
- (unsigned long long)block);
- exit(-1);
- }
-
return 0;
}
diff --git a/tests/mkfs.at b/tests/mkfs.at
index 2616109..ff99bb1 100644
--- a/tests/mkfs.at
+++ b/tests/mkfs.at
@@ -54,6 +54,10 @@ AT_SETUP([Min. resource group size])
GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT])
AT_CLEANUP
+AT_SETUP([Max. resource group size, min. block size])
+GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 -b 512 $GFS_TGT])
+AT_CLEANUP
+
AT_SETUP([Max. journal size])
GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 1024 $GFS_TGT])
AT_CLEANUP
10 years, 2 months
gfs2-utils: master - libgfs2: Add lgfs2_space_for_data()
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=4fc17a61...
Commit: 4fc17a616077cb60180cb1831c461c3d4a8164a0
Parent: fc8f16fe894145c36425f4c16bd2f022bf094810
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Feb 20 16:54:48 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Sat Mar 29 23:20:29 2014 +0000
libgfs2: Add lgfs2_space_for_data()
Add a function which calculates the total number of blocks required for
a file given the size of its contents.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/fs_ops.c | 18 ++++++++++++++++++
gfs2/libgfs2/libgfs2.h | 2 ++
2 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 198f6eb..b95f2ed 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -273,6 +273,24 @@ void unstuff_dinode(struct gfs2_inode *ip)
ip->i_di.di_height = 1;
}
+/**
+ * Calculate the total number of blocks required by a file containing 'bytes' bytes of data.
+ */
+uint64_t lgfs2_space_for_data(const struct gfs2_sbd *sdp, const unsigned bsize, const uint64_t bytes)
+{
+ uint64_t blks = (bytes + bsize - 1) / bsize;
+ uint64_t ptrs = blks;
+
+ if (bytes <= bsize - sizeof(struct gfs2_dinode))
+ return 1;
+
+ while (ptrs > sdp->sd_diptrs) {
+ ptrs = (ptrs + sdp->sd_inptrs - 1) / sdp->sd_inptrs;
+ blks += ptrs;
+ }
+ return blks + 1;
+}
+
unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
{
struct gfs2_sbd *sdp = ip->i_sbd;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 6248e4b..ce51e8c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -450,6 +450,8 @@ extern void inode_put(struct gfs2_inode **ip);
extern uint64_t data_alloc(struct gfs2_inode *ip);
extern int lgfs2_meta_alloc(struct gfs2_inode *ip, uint64_t *blkno);
extern int lgfs2_dinode_alloc(struct gfs2_sbd *sdp, const uint64_t blksreq, uint64_t *blkno);
+extern uint64_t lgfs2_space_for_data(const struct gfs2_sbd *sdp, unsigned bsize, uint64_t bytes);
+
extern int gfs2_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
unsigned int size);
#define gfs2_writei(ip, buf, offset, size) \
10 years, 2 months
gfs2-utils: master - mkfs.gfs2: Make dev a member of mkfs_opts
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=fc8f16fe...
Commit: fc8f16fe894145c36425f4c16bd2f022bf094810
Parent: c6d2155f68d45e603d772884fc75f53e7b651d9f
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Feb 19 21:53:18 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Sat Mar 29 23:20:29 2014 +0000
mkfs.gfs2: Make dev a member of mkfs_opts
As most of the functions which accept a struct mkfs_dev* also require a
struct mkfs_opts* it makes sense to move the device path string into the
mkfs_dev and add a struct mkfs_dev member to the struct mkfs_opts.
Nothing much to see here, just refactoring.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/main_mkfs.c | 125 ++++++++++++++++++++++++-------------------------
1 files changed, 62 insertions(+), 63 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index e58de68..40f4766 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -96,6 +96,28 @@ static void print_ext_opts(void)
}
}
+/**
+ * Values probed by libblkid:
+ * alignment_offset: offset, in bytes, of the start of the dev from its natural alignment
+ * logical_sector_size: smallest addressable unit
+ * minimum_io_size: device's preferred unit of I/O. RAID stripe unit.
+ * optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width.
+ * physical_sector_size: the smallest unit we can write atomically
+ */
+struct mkfs_dev {
+ int fd;
+ const char *path;
+ struct stat stat;
+ uint64_t size;
+ unsigned long alignment_offset;
+ unsigned long logical_sector_size;
+ unsigned long minimum_io_size;
+ unsigned long optimal_io_size;
+ unsigned long physical_sector_size;
+
+ unsigned int got_topol:1;
+};
+
struct mkfs_opts {
unsigned bsize;
unsigned qcsize;
@@ -107,7 +129,7 @@ struct mkfs_opts {
uint32_t journals;
const char *lockproto;
const char *locktable;
- const char *device;
+ struct mkfs_dev dev;
unsigned discard:1;
unsigned got_bsize:1;
@@ -130,27 +152,6 @@ struct mkfs_opts {
unsigned align:1;
};
-/**
- * Values probed by libblkid:
- * alignment_offset: offset, in bytes, of the start of the dev from its natural alignment
- * logical_sector_size: smallest addressable unit
- * minimum_io_size: device's preferred unit of I/O. RAID stripe unit.
- * optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width.
- * physical_sector_size: the smallest unit we can write atomically
- */
-struct mkfs_dev {
- int fd;
- struct stat stat;
- uint64_t size;
- unsigned long alignment_offset;
- unsigned long logical_sector_size;
- unsigned long minimum_io_size;
- unsigned long optimal_io_size;
- unsigned long physical_sector_size;
-
- unsigned int got_topol:1;
-};
-
static void opts_init(struct mkfs_opts *opts)
{
memset(opts, 0, sizeof(*opts));
@@ -362,7 +363,7 @@ static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)
if (strcmp(optarg, "gfs2") == 0)
continue;
if (!opts->got_device) {
- opts->device = optarg;
+ opts->dev.path = optarg;
opts->got_device = 1;
} else if (!opts->got_fssize && isdigit(optarg[0])) {
opts->fssize = atol(optarg);
@@ -457,10 +458,11 @@ static void are_you_sure(void)
free(line);
}
-static unsigned choose_blocksize(struct mkfs_opts *opts, const struct mkfs_dev *dev)
+static unsigned choose_blocksize(struct mkfs_opts *opts)
{
unsigned int x;
unsigned int bsize = opts->bsize;
+ struct mkfs_dev *dev = &opts->dev;
if (dev->got_topol && opts->debug) {
printf("alignment_offset: %lu\n", dev->alignment_offset);
@@ -536,15 +538,14 @@ static void opts_check(struct mkfs_opts *opts)
}
}
-static void print_results(struct gfs2_sb *sb, struct mkfs_dev *dev, struct mkfs_opts *opts,
- uint64_t rgrps, uint64_t fssize)
+static void print_results(struct gfs2_sb *sb, struct mkfs_opts *opts, uint64_t rgrps, uint64_t fssize)
{
- printf("%-27s%s\n", _("Device:"), opts->device);
+ printf("%-27s%s\n", _("Device:"), opts->dev.path);
printf("%-27s%u\n", _("Block size:"), sb->sb_bsize);
printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Device size:"),
/* Translators: "GB" here means "gigabytes" */
- (dev->size / ((float)(1 << 30))), _("GB"),
- (dev->size / sb->sb_bsize), _("blocks"));
+ (opts->dev.size / ((float)(1 << 30))), _("GB"),
+ (opts->dev.size / sb->sb_bsize), _("blocks"));
printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Filesystem size:"),
(fssize / ((float)(1 << 30)) * sb->sb_bsize), _("GB"), fssize, _("blocks"));
printf("%-27s%u\n", _("Journals:"), opts->journals);
@@ -580,7 +581,7 @@ static void warn_of_destruction(const char *path)
free(abspath);
}
-static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct mkfs_dev *dev, struct gfs2_sbd *sdp)
+static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
{
uint64_t rgsize = (opts->rgsize << 20) / sdp->bsize;
struct lgfs2_rgrp_align align = {.base = 0, .offset = 0};
@@ -600,10 +601,10 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct mkfs_dev *dev, stru
align.offset = opts->sunit / sdp->bsize;
}
} else if (opts->align) {
- if ((dev->minimum_io_size > dev->physical_sector_size) &&
- (dev->optimal_io_size > dev->physical_sector_size)) {
- align.base = dev->optimal_io_size / sdp->bsize;
- align.offset = dev->minimum_io_size / sdp->bsize;
+ if ((opts->dev.minimum_io_size > opts->dev.physical_sector_size) &&
+ (opts->dev.optimal_io_size > opts->dev.physical_sector_size)) {
+ align.base = opts->dev.optimal_io_size / sdp->bsize;
+ align.offset = opts->dev.minimum_io_size / sdp->bsize;
}
}
@@ -624,7 +625,7 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct mkfs_dev *dev, stru
return rgs;
}
-static uint64_t place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts, const struct mkfs_dev *dev)
+static uint64_t place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
{
int err = 0;
lgfs2_rgrp_t rg = NULL;
@@ -656,7 +657,7 @@ static uint64_t place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs
return ri->ri_data0 + ri->ri_data;
}
-static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_dev *dev, unsigned bsize)
+static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsize)
{
memset(sdp, 0, sizeof(struct gfs2_sbd));
sdp->time = time(NULL);
@@ -665,20 +666,20 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_d
sdp->qcsize = opts->qcsize;
sdp->jsize = opts->jsize;
sdp->md.journals = opts->journals;
- sdp->device_fd = dev->fd;
+ sdp->device_fd = opts->dev.fd;
sdp->bsize = bsize;
if (compute_constants(sdp)) {
perror(_("Failed to compute file system constants"));
exit(1);
}
- sdp->device.length = dev->size / sdp->bsize;
+ sdp->device.length = opts->dev.size / sdp->bsize;
if (opts->got_fssize) {
if (opts->fssize > sdp->device.length) {
fprintf(stderr, _("Specified size is bigger than the device."));
die("%s %.2f %s (%"PRIu64" %s)\n", _("Device size:"),
- dev->size / ((float)(1 << 30)), _("GB"),
- dev->size / sdp->bsize, _("blocks"));
+ opts->dev.size / ((float)(1 << 30)), _("GB"),
+ opts->dev.size / sdp->bsize, _("blocks"));
}
/* TODO: Check if the fssize is too small, somehow */
sdp->device.length = opts->fssize;
@@ -733,20 +734,19 @@ static int probe_contents(struct mkfs_dev *dev)
return 0;
}
-static void open_dev(const char *path, struct mkfs_dev *dev)
+static void open_dev(struct mkfs_dev *dev)
{
int error;
- memset(dev, 0, sizeof(*dev));
- dev->fd = open(path, O_RDWR | O_CLOEXEC);
+ dev->fd = open(dev->path, O_RDWR | O_CLOEXEC);
if (dev->fd < 0) {
- perror(path);
+ perror(dev->path);
exit(1);
}
error = fstat(dev->fd, &dev->stat);
if (error < 0) {
- perror(path);
+ perror(dev->path);
exit(1);
}
@@ -755,11 +755,11 @@ static void open_dev(const char *path, struct mkfs_dev *dev)
} else if (S_ISBLK(dev->stat.st_mode)) {
dev->size = lseek(dev->fd, 0, SEEK_END);
if (dev->size < 1) {
- fprintf(stderr, _("Device '%s' is too small\n"), path);
+ fprintf(stderr, _("Device '%s' is too small\n"), dev->path);
exit(1);
}
} else {
- fprintf(stderr, _("'%s' is not a block device or regular file\n"), path);
+ fprintf(stderr, _("'%s' is not a block device or regular file\n"), dev->path);
exit(1);
}
@@ -773,7 +773,6 @@ void main_mkfs(int argc, char *argv[])
struct gfs2_sbd sbd;
struct gfs2_sb sb;
struct mkfs_opts opts;
- struct mkfs_dev dev;
lgfs2_rgrps_t rgs;
int error;
unsigned bsize;
@@ -782,14 +781,14 @@ void main_mkfs(int argc, char *argv[])
opts_get(argc, argv, &opts);
opts_check(&opts);
- open_dev(opts.device, &dev);
- bsize = choose_blocksize(&opts, &dev);
+ open_dev(&opts.dev);
+ bsize = choose_blocksize(&opts);
- if (S_ISREG(dev.stat.st_mode)) {
+ if (S_ISREG(opts.dev.stat.st_mode)) {
opts.got_bsize = 1; /* Use default block size for regular files */
}
- sbd_init(&sbd, &opts, &dev, bsize);
+ sbd_init(&sbd, &opts, bsize);
lgfs2_sb_init(&sb, bsize);
if (opts.debug) {
printf(_("File system options:\n"));
@@ -804,16 +803,16 @@ void main_mkfs(int argc, char *argv[])
printf(" sunit = %lu\n", opts.sunit);
printf(" swidth = %lu\n", opts.swidth);
}
- rgs = rgs_init(&opts, &dev, &sbd);
- warn_of_destruction(opts.device);
+ rgs = rgs_init(&opts, &sbd);
+ warn_of_destruction(opts.dev.path);
if (opts.confirm && !opts.override)
are_you_sure();
- if (!S_ISREG(dev.stat.st_mode) && opts.discard)
- discard_blocks(dev.fd, dev.size, opts.debug);
+ if (!S_ISREG(opts.dev.stat.st_mode) && opts.discard)
+ discard_blocks(opts.dev.fd, opts.dev.size, opts.debug);
- sbd.fssize = place_rgrps(&sbd, rgs, &opts, &dev);
+ sbd.fssize = place_rgrps(&sbd, rgs, &opts);
if (sbd.fssize == 0) {
fprintf(stderr, _("Failed to build resource groups\n"));
exit(1);
@@ -872,24 +871,24 @@ void main_mkfs(int argc, char *argv[])
gfs2_rgrp_free(&sbd.rgtree);
- error = lgfs2_sb_write(&sb, dev.fd, sbd.bsize);
+ error = lgfs2_sb_write(&sb, opts.dev.fd, sbd.bsize);
if (error) {
perror(_("Failed to write superblock\n"));
exit(EXIT_FAILURE);
}
- error = fsync(dev.fd);
+ error = fsync(opts.dev.fd);
if (error){
- perror(opts.device);
+ perror(opts.dev.path);
exit(EXIT_FAILURE);
}
- error = close(dev.fd);
+ error = close(opts.dev.fd);
if (error){
- perror(opts.device);
+ perror(opts.dev.path);
exit(EXIT_FAILURE);
}
if (!opts.quiet)
- print_results(&sb, &dev, &opts, sbd.rgrps, sbd.fssize);
+ print_results(&sb, &opts, sbd.rgrps, sbd.fssize);
}
10 years, 2 months
fence-agents: v4.0.8 annotated tag has been created
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=be56a5...
Commit: be56a5995f1f16b3d1a5129bf736af6923387205
Parent: 0000000000000000000000000000000000000000
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: 2014-04-07 11:43 +0000
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: 2014-04-07 11:43 +0000
annotated tag: v4.0.8 has been created
at be56a5995f1f16b3d1a5129bf736af6923387205 (tag)
tagging 84dbfb5274eed041d0c78c1302f184b54b083ff4 (commit)
replaces v4.0.7.1
v4.0.8 release
Fabio M. Di Nitto (3):
Allow ssl connections to fallback to SSL3.0 negotiation
vmware_soap: drop warning from python suds when error occours
fence_vmware_soap: fix short/long option parsing traceback
Marek 'marx' Grac (5):
testing: Extend tests of using invalid keys for "options"
fence_wti: Respect --delay in telnet connection
[cleanup] Remove messages 'Due to limitations,binary dependencies ...'
fence_raritan: new fence agent for Raritan Dominion PX
fencing: Replace printing to stderr with proper logging solution
Ondrej Mular (3):
fencing: correct default values in manual pages for symlinks
fencing: accept only options used in fence-agent
fencing: fixed pexpect TypeError exception, when using identity file for login via ssh
10 years, 2 months
cluster: RHEL511 - rgmanager: oralistener.sh: Return success on stop if already stopped
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=700ec50c22d...
Commit: 700ec50c22d2135d2cdbd93eaa90c4b6983dc7ca
Parent: 18776f9a3fbe382bae4bd6c0bb78cfd245e751ab
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Thu Apr 3 18:07:06 2014 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Thu Apr 3 18:07:06 2014 -0400
rgmanager: oralistener.sh: Return success on stop if already stopped
If an oralistener resource is already stopped, stopping it should return
success.
Resolves: rhbz#1047989
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/resources/oralistener.sh | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/rgmanager/src/resources/oralistener.sh b/rgmanager/src/resources/oralistener.sh
old mode 100755
new mode 100644
index 30b8e06..4ee0ad1
--- a/rgmanager/src/resources/oralistener.sh
+++ b/rgmanager/src/resources/oralistener.sh
@@ -106,6 +106,12 @@ start() {
stop() {
ocf_log info "Stopping listener $LISTENER"
+ lsnrctl status "$LISTENER" >& /dev/null
+ if [ $? -ne 0 ]; then
+ ocf_log debug "Listener $LISTENER already not running"
+ return 0
+ fi
+
lsnrctl_stdout=$(lsnrctl stop "$LISTENER")
if [ $? -ne 0 ]; then
ocf_log debug "stop listener $LISTENER failed $lsnrctl_stdout"
10 years, 2 months
cluster: RHEL65 - libfenced: make fenced_external() also write to fifo
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=aec36b98ca3...
Commit: aec36b98ca34a4ad75711e6a5534e6959390c2d8
Parent: 56e76f76f1249b81c7926054f53eb52ae17135a4
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Mon Mar 10 10:05:06 2014 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Thu Apr 3 10:04:55 2014 +0100
libfenced: make fenced_external() also write to fifo
fenced doesn't listen to the library socket (or anything) else
while in fence_victions(). So if pacemaker tries to acknowledge
a manual fence using that call it will not reach the daemon while
it is failing to fence a node.
This patch adds code to fence_external() to also write to the
fence_ack_manual FIFO soo, which fenced *does* poll, so that the
message gets through.
rhbz#105926910592691059269
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
fence/fenced/recover.c | 29 ++++++++++++++---------------
fence/libfenced/main.c | 18 ++++++++++++++++++
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/fence/fenced/recover.c b/fence/fenced/recover.c
index 0b5e2b2..c9786fe 100644
--- a/fence/fenced/recover.c
+++ b/fence/fenced/recover.c
@@ -1,6 +1,7 @@
#include "fd.h"
#include "config.h"
+
void free_node_list(struct list_head *head)
{
struct node *node;
@@ -80,14 +81,11 @@ static int reduce_victims(struct fd *fd)
return num_victims;
}
-static inline void close_override(int *fd, const char *path)
+static inline void close_override(int fd, const char *path)
{
unlink(path);
- if (fd) {
- if (*fd >= 0)
- close(*fd);
- *fd = -1;
- }
+ if (fd >= 0)
+ close(fd);
}
static int open_override(const char *path)
@@ -339,7 +337,7 @@ void fence_victims(struct fd *fd)
{
struct node *node;
int error, i, ll, flog_count, prev_flog_count;
- int override = -1;
+ int override_fd = -1;
int cluster_member, cpg_member, ext;
unsigned int limit, retries;
@@ -404,6 +402,9 @@ void fence_victims(struct fd *fd)
if (!limit)
log_level(LOG_INFO, "fencing node %s", node->name);
+ if (override_fd == -1)
+ override_fd = open_override(cfgd_override_path);
+
query_unlock();
error = fence_node(node->name, flog, FL_SIZE, &flog_count);
query_lock();
@@ -447,7 +448,7 @@ void fence_victims(struct fd *fd)
continue;
}
- if (!cfgd_override_path) {
+ if (!cfgd_override_path || (override_fd == -1)) {
query_unlock();
sleep(5);
query_lock();
@@ -456,22 +457,20 @@ void fence_victims(struct fd *fd)
}
/* Check for manual intervention */
- override = open_override(cfgd_override_path);
- if (check_override(override, node->name,
- cfgd_override_time) > 0) {
- log_level(LOG_WARNING, "fence %s overridden by "
- "administrator intervention", node->name);
+ if (check_override(override_fd, node->name, cfgd_override_time) > 0) {
+ log_level(LOG_WARNING, "fence %s overridden by administrator intervention", node->name);
node->local_victim_done = 1;
victim_done(fd, node->nodeid, VIC_DONE_OVERRIDE);
- close_override(&override, cfgd_override_path);
continue;
} else {
- close_override(&override, cfgd_override_path);
retries++;
goto retry;
}
}
fd->current_victim = 0;
+
+ if (override_fd >= 0)
+ close_override(override_fd, cfgd_override_path);
}
diff --git a/fence/libfenced/main.c b/fence/libfenced/main.c
index 9537953..319a2d6 100644
--- a/fence/libfenced/main.c
+++ b/fence/libfenced/main.c
@@ -3,6 +3,7 @@
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -119,6 +120,19 @@ int fenced_leave(void)
return rv;
}
+static void local_override(char *name)
+{
+ int fd;
+
+ fd = open("/var/run/cluster/fenced_override", O_WRONLY|O_NONBLOCK);
+ if (fd < 0)
+ return;
+
+ write(fd, name, strlen(name));
+
+ close(fd);
+}
+
int fenced_external(char *name)
{
char msg[sizeof(struct fenced_header) + MAX_NODENAME_LEN + 1];
@@ -143,6 +157,10 @@ int fenced_external(char *name)
rv = do_write(fd, hd, sizeof(msg));
close(fd);
+
+ /* When fenced is busy fencing it won't receive/process messages,
+ but it does check the local override fifo. */
+ local_override(name);
out:
return rv;
}
10 years, 2 months
cluster: RHEL65 - cman: fix some typos and English phrasing in cman defaults file
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=56e76f76f12...
Commit: 56e76f76f1249b81c7926054f53eb52ae17135a4
Parent: e158b2a7dd24e6144611157b69e30e4f6bc6d700
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Fri Dec 20 10:35:54 2013 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Fri Dec 20 10:35:54 2013 +0000
cman: fix some typos and English phrasing in cman defaults file
The cman.init.defaults file had some typos and odd non-English phrasing.
I've also fixed a inconsistent punctuation in a few places too
rhbz#1035929
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
cman/init.d/cman.init.defaults.in | 32 ++++++++++++++++----------------
1 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/cman/init.d/cman.init.defaults.in b/cman/init.d/cman.init.defaults.in
index 835b44f..c42672c 100644
--- a/cman/init.d/cman.init.defaults.in
+++ b/cman/init.d/cman.init.defaults.in
@@ -1,23 +1,23 @@
-# CMAN_CLUSTER_TIMEOUT -- amount of time to wait for joinging a cluster
+# CMAN_CLUSTER_TIMEOUT -- amount of time to wait to join a cluster
# before giving up. If CMAN_CLUSTER_TIMEOUT is positive, then we will
-# wait CMAN_CLUSTER_TIMEOUT seconds before giving up and failing when
-# a cluster is not joined. If CMAN_CLUSTER_TIMEOUT is zero, then
-# wait indefinately for a cluster join. If CMAN_CLUSTER_TIMEOUT is
-# negative, do not check to see that the cluster has been joined
+# wait CMAN_CLUSTER_TIMEOUT seconds before giving up and failing if
+# we can't join a cluster. If CMAN_CLUSTER_TIMEOUT is zero, then we
+# will wait indefinitely for a cluster join. If CMAN_CLUSTER_TIMEOUT is
+# negative, do not check to see if we have joined a cluster.
#CMAN_CLUSTER_TIMEOUT=60
# CMAN_QUORUM_TIMEOUT -- amount of time to wait for a quorate cluster on
-# startup quorum is needed by many other applications, so we may as
+# startup. Quorum is needed by many other applications, so we may as
# well wait here. If CMAN_QUORUM_TIMEOUT is zero, quorum will
# be ignored.
#CMAN_QUORUM_TIMEOUT=45
# CMAN_SHUTDOWN_TIMEOUT -- amount of time to wait for cman to become a
-# cluster member before calling cman_tool leave during shutdown.
+# cluster member before calling 'cman_tool' leave during shutdown.
# The default is 60 seconds
#CMAN_SHUTDOWN_TIMEOUT=60
-# CMAN_NOTIFYD_START - control the startup behaviour for cmannotifyd
+# CMAN_NOTIFYD_START - control the startup behaviour for cmannotifyd,
# the variable can take 3 values:
# yes | will always start cmannotifyd
# no | will never start cmannotifyd
@@ -25,7 +25,7 @@
# are found in @NOTIFYDDIR@
#CMAN_NOTIFYD_START=conditional
-# CMAN_SSHD_START - control sshd startup behaviour
+# CMAN_SSHD_START -- control sshd startup behaviour,
# the variable can take 2 values:
# yes | cman will start sshd as early as possible
# no (default) | cman will not start sshd
@@ -74,7 +74,7 @@
# CLUSTERNAME -- override clustername as specified in cluster.conf
#CLUSTERNAME=""
-# NODENAME -- specify the nodename of this node. Default autodetected
+# NODENAME -- specify the nodename of this node. Default autodetected.
#NODENAME=""
# CONFIG_LOADER -- select default config parser.
@@ -83,21 +83,21 @@
# config propagation method. (default)
#CONFIG_LOADER=xmlconfig
-# CONFIG_VALIDATION -- select default config validation behaviour
+# CONFIG_VALIDATION -- select default config validation behaviour.
# This can be:
# FAIL - Use a very strict checking. The config will not be loaded if there
-# for any kind of warnings/errors.
-# WARN - Same as FAIL, but will allow the config to load (this is temporary
+# are any kind of warnings/errors
+# WARN - Same as FAIL, but will allow the config to load (this is temporarily
# the default behaviour)
-# NONE - Disable config validation. Highly discouraged.
+# NONE - Disable config validation. Highly discouraged
#CONFIG_VALIDATION=WARN
# CMAN_LEAVE_OPTS -- allows extra options to be passed to cman_tool when leave
# operation is performed.
#CMAN_LEAVE_OPTS=""
-# INITLOGLEVEL -- select how verbose the init script should be
-# possible values:
+# INITLOGLEVEL -- select how verbose the init script should be.
+# Possible values:
# quiet - only one line notification for start/stop operations
# terse (default) - show only required activity
# full - show everything
10 years, 2 months
fence-agents: master - fence_raritan: new fence agent for Raritan Dominion PX
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=ef85cb...
Commit: ef85cb7d44f4772b258c03352b6d8ca75c6107df
Parent: 5901c326a39f68582fd0d5f5d465ced87b9e230d
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Apr 2 15:06:55 2014 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Wed Apr 2 15:06:55 2014 +0200
fence_raritan: new fence agent for Raritan Dominion PX
Written by David Smith <dsmith(a)mypchelp.com>
---
.gitignore | 1 +
configure.ac | 1 +
fence/agents/raritan/Makefile.am | 17 ++++++
fence/agents/raritan/fence_raritan.py | 98 +++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
index a711b3a..74198b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,7 @@ fence/agents/node_assassin/fence_na.pod
fence/agents/nss_wrapper/fence_nss_wrapper
fence/agents/rackswitch/fence_rackswitch
fence/agents/rhevm/fence_rhevm
+fence/agents/raritan/fence_raritan
fence/agents/rsa/fence_rsa
fence/agents/rsb/fence_rsb
fence/agents/sanbox2/fence_sanbox2
diff --git a/configure.ac b/configure.ac
index eaef1d8..c24198c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,6 +283,7 @@ AC_CONFIG_FILES([Makefile
fence/agents/netio/Makefile
fence/agents/rackswitch/Makefile
fence/agents/ovh/Makefile
+ fence/agents/raritan/Makefile
fence/agents/rhevm/Makefile
fence/agents/rsa/Makefile
fence/agents/rsb/Makefile
diff --git a/fence/agents/raritan/Makefile.am b/fence/agents/raritan/Makefile.am
new file mode 100644
index 0000000..f41ba56
--- /dev/null
+++ b/fence/agents/raritan/Makefile.am
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+TARGET = fence_raritan
+
+SRC = $(TARGET).py
+
+EXTRA_DIST = $(SRC)
+
+sbin_SCRIPTS = $(TARGET)
+
+man_MANS = $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+
+clean-local: clean-man
+ rm -f $(TARGET)
diff --git a/fence/agents/raritan/fence_raritan.py b/fence/agents/raritan/fence_raritan.py
new file mode 100644
index 0000000..c8137b0
--- /dev/null
+++ b/fence/agents/raritan/fence_raritan.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+
+import sys, re, pexpect, exceptions
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+# --plug should include path to the outlet # such as port 1:
+# /system1/outlet1
+
+def get_power_status(conn, options):
+ conn.send_eol("show -d properties=powerState %s" % options["--plug"])
+ re_status = re.compile(".*powerState is [12].*")
+ conn.log_expect(options, re_status, int(options["--shell-timeout"]))
+ status = {
+ #"0" : "off",
+ "1" : "on",
+ "2" : "off",
+ }[conn.after.split()[2]]
+
+ return status
+
+def set_power_status(conn, options):
+ action = {
+ "on" : "on",
+ "off" : "off",
+ }[options["--action"]]
+
+ conn.send_eol("set %s powerState=%s" % (options["--plug"], action))
+
+def main():
+ device_opt = [ "ipaddr", "login", "passwd", "port" ]
+
+ atexit.register(atexit_handler)
+
+ opt = process_input(device_opt)
+
+ all_opt["ipport"]["default"] = "23"
+
+ opt["eol"] = "\r\n"
+ options = check_input(device_opt, opt)
+
+ docs = { }
+ docs["shortdesc"] = "I/O Fencing agent for Raritan Dominion PX"
+ docs["longdesc"] = "fence_raritan is an I/O Fencing agent which can be \
+used with the Raritan DPXS12-20 Power Distribution Unit. It logs into \
+device via telnet and reboots a specified outlet. Lengthy telnet connections \
+should be avoided while a GFS cluster is running because the connection will \
+block any necessary fencing actions."
+ docs["vendorurl"] = "http://www.raritan.com/"
+ show_docs(options, docs)
+
+ # add support also for delay before login which is very useful for 2-node clusters
+ if options["--action"] in ["off", "reboot"]:
+ time.sleep(int(options["--delay"]))
+
+ ##
+ ## Operate the fencing device
+ ## We can not use fence_login(), username and passwd are sent on one line
+ ####
+ try:
+ conn = fspawn(options, TELNET_PATH)
+ conn.send("set binary\n")
+ conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
+ screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+ conn.log_expect(options, "Login.*", int(options["--shell-timeout"]))
+ conn.send_eol("%s" % (options["--username"]))
+ conn.log_expect(options, "Password.*", int(options["--shell-timeout"]))
+ conn.send_eol("%s" % (options["--password"]))
+ conn.log_expect(options, "clp.*", int(options["--shell-timeout"]))
+ except pexpect.EOF:
+ fail(EC_LOGIN_DENIED)
+ except pexpect.TIMEOUT:
+ fail(EC_LOGIN_DENIED)
+ result = fence_action(conn, options, set_power_status, get_power_status)
+
+ ##
+ ## Logout from system
+ ##
+ ## In some special unspecified cases it is possible that
+ ## connection will be closed before we run close(). This is not
+ ## a problem because everything is checked before.
+ ######
+ try:
+ conn.send("exit\n")
+ conn.close()
+ except:
+ pass
+
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()
10 years, 2 months
dlm: master - dlm_stonith: use kick_helper result
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=dlm.git;a=commitdiff;h=fb61984c9388cbb...
Commit: fb61984c9388cbbcc02c6a09c09948b21320412d
Parent: 090026f33031c1b46dfe3e2e077c6cb0aa149378
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Apr 1 11:53:20 2014 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Apr 1 11:58:03 2014 -0500
dlm_stonith: use kick_helper result
Don't depend on the fence time being later than
the fail time after using the kick helper function.
Make fail_time optional.
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
fence/dlm_stonith.8 | 7 +++----
fence/stonith_helper.c | 22 ++++++----------------
2 files changed, 9 insertions(+), 20 deletions(-)
diff --git a/fence/dlm_stonith.8 b/fence/dlm_stonith.8
index 14993d9..36b9d67 100644
--- a/fence/dlm_stonith.8
+++ b/fence/dlm_stonith.8
@@ -26,10 +26,9 @@ The nodeid of the target node. (stdin key is "node")
.BI \-t " fail_time"
-The wall time at which the target node failed. The wall time at which the
-node is fenced must be later than this for fencing to succeed. (stdin key
-is "fail_time") For "wall time" see
-.BR time (2).
+The time(2) at which the target node failed.
+If this option is provided, and the last fencing time is
+later, then a new fencing request is not made.
.SH SEE ALSO
.BR dlm_controld (8),
diff --git a/fence/stonith_helper.c b/fence/stonith_helper.c
index c2821ec..3a0768a 100644
--- a/fence/stonith_helper.c
+++ b/fence/stonith_helper.c
@@ -56,11 +56,6 @@ static int get_options(int argc, char *argv[])
return -1;
}
- if (!fail_time) {
- fprintf(stderr, "no fail_time\n");
- return -1;
- }
-
return 0;
}
@@ -73,9 +68,11 @@ int main(int argc, char *argv[])
if (rv)
return rv;
- t = stonith_api_time_helper(nodeid, 0);
- if (t >= fail_time)
- return 0;
+ if (fail_time) {
+ t = stonith_api_time_helper(nodeid, 0);
+ if (t >= fail_time)
+ return 0;
+ }
rv = stonith_api_kick_helper(nodeid, 300, 0);
if (rv) {
@@ -85,13 +82,6 @@ int main(int argc, char *argv[])
return rv;
}
- while (1) {
- t = stonith_api_time_helper(nodeid, 0);
- if (t >= fail_time)
- return 0;
- sleep(1);
- }
-
- return -1;
+ return 0;
}
10 years, 2 months