cluster: RHEL55 - fence_egenera: insecure temporary file
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 1441b5d066bc362b44573bee69d793403067ef2e
Parent: 7ce660b860982feb4a4c0c08e3e778111d0700aa
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Sun Dec 20 13:54:19 2009 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Sun Dec 20 16:27:33 2009 +0100
fence_egenera: insecure temporary file
Log directory changed to /var/log/cluster instead of /tmp. Directory
is created in fence agent Makefile if needed.
Resolves: rhbz#519682
---
fence/agents/egenera/Makefile | 3 +++
fence/agents/egenera/fence_egenera.pl | 2 +-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/fence/agents/egenera/Makefile b/fence/agents/egenera/Makefile
index 7158702..0318646 100644
--- a/fence/agents/egenera/Makefile
+++ b/fence/agents/egenera/Makefile
@@ -13,6 +13,7 @@
SOURCE= fence_egenera.pl
TARGET= fence_egenera
+LOGDIR= /var/log/cluster
top_srcdir=../..
include ${top_srcdir}/make/defines.mk
@@ -26,6 +27,7 @@ fence_egenera: fence_egenera.pl
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET)
echo "\$$BUILD_DATE=\"(built `date`)\";" >> $(TARGET)
awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET)
+ sed -ie 's#@''LOGDIR@#${LOGDIR}#g' $(TARGET)
chmod +x $(TARGET)
install: all
@@ -33,6 +35,7 @@ install: all
install -d ${sbindir}; \
fi
install -m755 ${TARGET} ${sbindir}
+ install -d ${DESTDIR}/${LOGDIR}
clean:
rm -f $(TARGET)
diff --git a/fence/agents/egenera/fence_egenera.pl b/fence/agents/egenera/fence_egenera.pl
index 928ebb2..8607919 100755
--- a/fence/agents/egenera/fence_egenera.pl
+++ b/fence/agents/egenera/fence_egenera.pl
@@ -306,7 +306,7 @@ sub pserver_shutdown
{
my $rtrn=1;
local *egen_log;
- open(egen_log,">>/tmp/eglog");
+ open(egen_log,">>/@LOGDIR@/eglog");
print egen_log "Attempting shutdown at ".`date`."\n";
for (my $trys=0; $trys<20; $trys++)
{
14 years, 5 months
cluster: RHEL55 - GFS2: gfs2_edit savemeta bugs
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 7ce660b860982feb4a4c0c08e3e778111d0700aa
Parent: e956129acaab0ab20b96b53b8ac0a494428806a1
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Dec 17 17:27:04 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Thu Dec 17 17:27:49 2009 -0600
GFS2: gfs2_edit savemeta bugs
This patch fixes a problem whereby directory hash tables were not
being saved by gfs2_edit's savemeta option. Also, this introduces
a new option to print individual records from a savemeta file:
gfs2_edit printsavedmeta /home/bob/my.meta 0x12345
rhbz#528786
---
gfs2/edit/hexedit.c | 26 +++++---
gfs2/edit/hexedit.h | 4 +-
gfs2/edit/savemeta.c | 162 +++++++++++++++++++++++++++-----------------------
3 files changed, 106 insertions(+), 86 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 0d3af3e..49577f9 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -51,7 +51,7 @@ const char *allocdesc[2][5] = {
int display(int identify_only);
extern void savemeta(const char *out_fn, int slow);
extern void restoremeta(const char *in_fn, const char *out_device,
- int printblocksonly);
+ uint64_t printblocksonly);
/* for assigning numeric fields: */
#define checkassign(strfield, struct, member, value) do { \
@@ -1820,8 +1820,7 @@ int display(int identify_only)
if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) {
fprintf(stderr, "read error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__,
+ strerror(errno), __FUNCTION__, __LINE__,
(unsigned long long)dev_offset,
(unsigned long long)dev_offset);
exit(-1);
@@ -3256,17 +3255,22 @@ void parameterpass1(int argc, char *argv[], int i)
termlines = 0;
else if (!strcasecmp(argv[i], "savergs"))
termlines = 0;
- else if (!strcasecmp(argv[i], "printsavedmeta"))
- restoremeta(argv[i+1], argv[i+2],
- TRUE);
- else if (!strcasecmp(argv[i], "restoremeta"))
+ else if (!strcasecmp(argv[i], "printsavedmeta")) {
+ if (dmode == INIT_MODE)
+ dmode = GFS2_MODE;
+ restoremeta(argv[i+1], argv[i+2], TRUE);
+ } else if (!strcasecmp(argv[i], "restoremeta")) {
+ if (dmode == INIT_MODE)
+ dmode = HEX_MODE; /* hopefully not used */
restoremeta(argv[i+1], argv[i+2], FALSE);
- else if (!strcmp(argv[i], "rgcount"))
+ } else if (!strcmp(argv[i], "rgcount"))
termlines = 0;
else if (!strcmp(argv[i], "rgflags"))
termlines = 0;
else if (!strcmp(argv[i], "rg"))
termlines = 0;
+ else if (!strcasecmp(argv[i], "-x"))
+ dmode = HEX_MODE;
else if (!device[0] && strchr(argv[i],'/'))
strcpy(device, argv[i]);
}
@@ -3467,12 +3471,12 @@ int main(int argc, char *argv[])
memset(edit_col, 0, sizeof(edit_col));
memset(edit_size, 0, sizeof(edit_size));
memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen));
- dmode = HEX_MODE;
+ dmode = INIT_MODE;
sbd.bsize = 4096;
type_alloc(buf, char, sbd.bsize); /* allocate/malloc a new 4K buffer */
block = starting_blk = 0x10;
for (i = 0; i < BLOCK_STACK_SIZE; i++) {
- blockstack[i].dmode = dmode;
+ blockstack[i].dmode = HEX_MODE;
blockstack[i].block = block;
for (j = 0; j < DMODES; j++) {
blockstack[i].start_row[j] = 0;
@@ -3488,6 +3492,8 @@ int main(int argc, char *argv[])
memset(device, 0, sizeof(device));
termlines = 30; /* assume interactive mode until we find -p */
process_parameters(argc, argv, 0);
+ if (dmode == INIT_MODE)
+ dmode = HEX_MODE;
fd = open(device, O_RDWR);
if (fd < 0)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index d7dbe85..68116f5 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -42,7 +42,7 @@
#endif
#define DMODES 3
-enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2 };
+enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
#define BLOCK_STACK_SIZE 256
#define GFS_FORMAT_SB (100) /* Super-Block */
@@ -184,6 +184,8 @@ EXTERN void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
EXTERN void gfs_log_header_in(struct gfs_log_header *head, char *buf);
EXTERN void gfs_log_header_print(struct gfs_log_header *lh);
EXTERN void gfs_dinode_in(struct gfs_dinode *di, char *buf);
+EXTERN int display(int identify_only);
+EXTERN uint64_t check_keywords(const char *kword);
struct gfs2_dirents {
uint64_t block;
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index a2082ea..6c36b69 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -98,13 +98,7 @@ int get_gfs_struct_info(char *buf, int *block_type, int *struct_len)
*struct_len = sbd.bsize; /*sizeof(struct gfs_leaf);*/
break;
case GFS2_METATYPE_JD: /* 7 (journal data) */
- /* GFS1 keeps indirect pointers in GFS2_METATYPE_JD blocks
- so we need to save the whole block. For GFS2, we don't
- want to, or we might capture user data, which is bad. */
- if (gfs1)
- *struct_len = sbd.bsize;
- else
- *struct_len = sizeof(struct gfs2_meta_header);
+ *struct_len = sbd.bsize;
break;
case GFS2_METATYPE_LH: /* 8 (log header) */
if (gfs1)
@@ -325,11 +319,9 @@ void save_inode_data(int out_fd)
osi_list_t *prev_list, *cur_list, *tmp;
struct gfs2_buffer_head *metabh, *mybh;
int i;
- char *buf;
for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
osi_list_init(&metalist[i]);
- buf = malloc(sbd.bsize);
metabh = bread(&sbd.buf_list, block);
if (gfs1)
inode = inode_get(&sbd, metabh);
@@ -338,8 +330,15 @@ void save_inode_data(int out_fd)
height = inode->i_di.di_height;
/* If this is a user inode, we don't follow to the file height.
We stop one level less. That way we save off the indirect
- pointer blocks but not the actual file contents. */
- if (height && !block_is_systemfile())
+ pointer blocks but not the actual file contents. The exception
+ is directories, where the height represents the level at which
+ the hash table exists, and we have to save the directory data. */
+ if (inode->i_di.di_flags & GFS2_DIF_EXHASH &&
+ (S_ISDIR(inode->i_di.di_mode) ||
+ (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
+ height++;
+ else if (height && !block_is_systemfile() &&
+ !S_ISDIR(inode->i_di.di_mode))
height--;
osi_list_add(&metabh->b_altlist, &metalist[0]);
for (i = 1; i <= height; i++){
@@ -398,7 +397,6 @@ void save_inode_data(int out_fd)
brelse(metabh, not_updated);
}
inode_put(inode, not_updated);
- free(buf);
}
void get_journal_inode_blocks(void)
@@ -702,26 +700,26 @@ int restore_data(int fd, int in_fd, int printblocksonly)
uint64_t buf64, writes = 0, highest_valid_block = 0;
uint16_t buf16;
int first = 1, pos;
- char buf[256];
+ char rdbuf[256];
char gfs_superblock_id[8] = {0x01, 0x16, 0x19, 0x70,
0x00, 0x00, 0x00, 0x01};
if (!printblocksonly)
do_lseek(fd, 0);
do_lseek(in_fd, 0);
- rs = read(in_fd, buf, sizeof(buf));
- if (rs != sizeof(buf)) {
+ rs = read(in_fd, rdbuf, sizeof(rdbuf));
+ if (rs != sizeof(rdbuf)) {
fprintf(stderr, "Error: File is too small.\n");
return -1;
}
- for (pos = 0; pos < sizeof(buf) - sizeof(uint64_t) - sizeof(uint16_t);
+ for (pos = 0; pos < sizeof(rdbuf) - sizeof(uint64_t) - sizeof(uint16_t);
pos++) {
- if (!memcmp(&buf[pos + sizeof(uint64_t) + sizeof(uint16_t)],
+ if (!memcmp(&rdbuf[pos + sizeof(uint64_t) + sizeof(uint16_t)],
gfs_superblock_id, sizeof(gfs_superblock_id))) {
break;
}
}
- if (pos == sizeof(buf) - sizeof(uint64_t) - sizeof(uint16_t))
+ if (pos == sizeof(rdbuf) - sizeof(uint64_t) - sizeof(uint16_t))
pos = 0;
do_lseek(in_fd, pos);
blks_saved = total_out = 0;
@@ -749,68 +747,80 @@ int restore_data(int fd, int in_fd, int printblocksonly)
}
rs = read(in_fd, &buf16, sizeof(uint16_t));
savedata->siglen = be16_to_cpu(buf16);
- if (savedata->siglen <= sizeof(savedata->buf)) {
- if (savedata->siglen)
- do_read(in_fd, savedata->buf,
- savedata->siglen);
- if (first) {
- struct gfs2_sb bufsb;
-
- memcpy(&bufsb, savedata->buf, sizeof(bufsb));
- gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
- sbd1 = (struct gfs_sb *)&sbd.sd_sb;
- if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
- sbd1->sb_header.mh_type ==
- GFS_METATYPE_SB &&
- sbd1->sb_header.mh_format ==
- GFS_FORMAT_SB &&
- sbd1->sb_multihost_format ==
- GFS_FORMAT_MULTI) {
- gfs1 = TRUE;
- } else if (check_sb(&sbd.sd_sb)) {
- fprintf(stderr,"Error: Invalid superblock data.\n");
- return -1;
- }
- sbd.bsize = sbd.sd_sb.sb_bsize;
- if (!printblocksonly) {
- last_fs_block =
- lseek(fd, 0, SEEK_END) /
- sbd.bsize;
- printf("There are %" PRIu64 " blocks of " \
- "%u bytes in the destination" \
- " file system.\n\n",
- last_fs_block, sbd.bsize);
- } else {
- printf("This is %s metadata\n", gfs1 ?
- "gfs (not gfs2)" : "gfs2");
- }
- first = 0;
+ if (savedata->siglen > sizeof(savedata->buf)) {
+ fprintf(stderr, "\nBad record length: %d for block #%"
+ PRIu64 " (0x%" PRIx64").\n", savedata->siglen,
+ savedata->blk, savedata->blk);
+ return -1;
+ }
+ if (savedata->siglen &&
+ read(in_fd, savedata->buf, savedata->siglen) !=
+ savedata->siglen) {
+ fprintf(stderr, "read error: %s from %s:%d: "
+ "block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__, __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
+ if (first) {
+ struct gfs2_sb bufsb;
+
+ memcpy(&bufsb, savedata->buf, sizeof(bufsb));
+ gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
+ sbd1 = (struct gfs_sb *)&sbd.sd_sb;
+ if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
+ sbd1->sb_header.mh_type ==
+ GFS_METATYPE_SB &&
+ sbd1->sb_header.mh_format ==
+ GFS_FORMAT_SB &&
+ sbd1->sb_multihost_format ==
+ GFS_FORMAT_MULTI) {
+ gfs1 = TRUE;
+ } else if (check_sb(&sbd.sd_sb)) {
+ fprintf(stderr,"Error: Invalid superblock data.\n");
+ return -1;
}
- if (printblocksonly) {
+ sbd.bsize = sbd.sd_sb.sb_bsize;
+ if (!printblocksonly) {
+ last_fs_block =
+ lseek(fd, 0, SEEK_END) / sbd.bsize;
+ printf("There are %" PRIu64 " blocks of " \
+ "%u bytes in the destination" \
+ " file system.\n\n",
+ last_fs_block, sbd.bsize);
+ } else {
+ printf("This is %s metadata\n", gfs1 ?
+ "gfs (not gfs2)" : "gfs2");
+ }
+ first = 0;
+ }
+ if (printblocksonly) {
+ block = savedata->blk;
+ if (block > highest_valid_block)
+ highest_valid_block = block;
+ if (printblocksonly > 1 && printblocksonly == block) {
+ memcpy(buf, savedata->buf, sbd.bsize);
+ block_in_mem = block;
+ display(0);
+ return 0;
+ } else if (printblocksonly == 1) {
print_gfs2("%d (l=0x%x): ", blks_saved,
savedata->siglen);
- block = savedata->blk;
- if (block > highest_valid_block)
- highest_valid_block = block;
display_block_type(savedata->buf, TRUE);
- } else {
- warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
- if (savedata->blk >= last_fs_block) {
- printf("\nOut of space on the destination "
- "device; quitting.\n");
- break;
- }
- do_lseek(fd, savedata->blk * sbd.bsize);
- do_write(fd, savedata->buf, sbd.bsize);
- writes++;
}
- blks_saved++;
} else {
- fprintf(stderr, "\nBad record length: %d for block #%"
- PRIu64 " (0x%" PRIx64").\n", savedata->siglen,
- savedata->blk, savedata->blk);
- return -1;
+ warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
+ if (savedata->blk >= last_fs_block) {
+ printf("\nOut of space on the destination "
+ "device; quitting.\n");
+ break;
+ }
+ do_lseek(fd, savedata->blk * sbd.bsize);
+ do_write(fd, savedata->buf, sbd.bsize);
+ writes++;
}
+ blks_saved++;
}
if (!printblocksonly)
warm_fuzzy_stuff(savedata->blk, TRUE, FALSE);
@@ -830,7 +840,7 @@ void complain(const char *complaint)
}
void restoremeta(const char *in_fn, const char *out_device,
- int printblocksonly)
+ uint64_t printblocksonly)
{
int in_fd, error;
@@ -849,7 +859,9 @@ void restoremeta(const char *in_fn, const char *out_device,
if (sbd.device_fd < 0)
die("Can't open destination file system %s: %s\n",
out_device, strerror(errno));
- }
+ } else if (out_device) /* for printsavedmeta, the out_device is an
+ optional block no */
+ printblocksonly = check_keywords(out_device);
savedata = malloc(sizeof(struct saved_metablock));
if (!savedata)
die("Can't allocate memory for the restore operation.\n");
14 years, 5 months
cluster: STABLE3 - GFS2: gfs2_edit savemeta bugs
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: a26a9856c295be1de37186299eb52034a1c9cd66
Parent: baea48ccc79bbc3ef2723c2eae26b1d144dea645
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Dec 17 17:15:49 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Thu Dec 17 17:15:49 2009 -0600
GFS2: gfs2_edit savemeta bugs
This patch fixes a problem whereby directory hash tables were not
being saved by gfs2_edit's savemeta option. Also, this introduces
a new option to print individual records from a savemeta file:
gfs2_edit printsavedmeta /home/bob/my.meta 0x12345
rhbz#528786
---
gfs2/edit/hexedit.c | 30 ++++----
gfs2/edit/hexedit.h | 7 ++-
gfs2/edit/savemeta.c | 190 ++++++++++++++++++++++++++------------------------
3 files changed, 119 insertions(+), 108 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 8ba3d03..b6b8fe9 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -37,10 +37,6 @@ const char *allocdesc[2][5] = {
#define RGLIST_DUMMY_BLOCK -2
int display(int identify_only);
-extern void do_leaf_extended(char *buf, struct iinfo *indir);
-extern void savemeta(char *out_fn, int slow);
-extern void restoremeta(const char *in_fn, const char *out_device,
- int printblocksonly);
/* for assigning numeric fields: */
#define checkassign(strfield, struct, member, value) do { \
@@ -1816,8 +1812,7 @@ int display(int identify_only)
if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) {
fprintf(stderr, "read error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__,
+ strerror(errno), __FUNCTION__, __LINE__,
(unsigned long long)dev_offset,
(unsigned long long)dev_offset);
exit(-1);
@@ -2144,7 +2139,7 @@ static uint64_t find_metablockoftype(const char *strtype, int print)
/* Check if the word is a keyword such as "sb" or "rindex" */
/* Returns: block number if it is, else 0 */
/* ------------------------------------------------------------------------ */
-static uint64_t check_keywords(const char *kword)
+uint64_t check_keywords(const char *kword)
{
uint64_t blk = 0;
@@ -3251,17 +3246,22 @@ static void parameterpass1(int argc, char *argv[], int i)
termlines = 0;
else if (!strcasecmp(argv[i], "savergs"))
termlines = 0;
- else if (!strcasecmp(argv[i], "printsavedmeta"))
- restoremeta(argv[i+1], argv[i+2],
- TRUE);
- else if (!strcasecmp(argv[i], "restoremeta"))
+ else if (!strcasecmp(argv[i], "printsavedmeta")) {
+ if (dmode == INIT_MODE)
+ dmode = GFS2_MODE;
+ restoremeta(argv[i+1], argv[i+2], TRUE);
+ } else if (!strcasecmp(argv[i], "restoremeta")) {
+ if (dmode == INIT_MODE)
+ dmode = HEX_MODE; /* hopefully not used */
restoremeta(argv[i+1], argv[i+2], FALSE);
- else if (!strcmp(argv[i], "rgcount"))
+ } else if (!strcmp(argv[i], "rgcount"))
termlines = 0;
else if (!strcmp(argv[i], "rgflags"))
termlines = 0;
else if (!strcmp(argv[i], "rg"))
termlines = 0;
+ else if (!strcasecmp(argv[i], "-x"))
+ dmode = HEX_MODE;
else if (!device[0] && strchr(argv[i],'/'))
strcpy(device, argv[i]);
}
@@ -3460,12 +3460,12 @@ int main(int argc, char *argv[])
memset(edit_col, 0, sizeof(edit_col));
memset(edit_size, 0, sizeof(edit_size));
memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen));
- dmode = HEX_MODE;
+ dmode = INIT_MODE;
sbd.bsize = 4096;
type_alloc(buf, char, sbd.bsize); /* allocate/malloc a new 4K buffer */
block = starting_blk = 0x10;
for (i = 0; i < BLOCK_STACK_SIZE; i++) {
- blockstack[i].dmode = dmode;
+ blockstack[i].dmode = HEX_MODE;
blockstack[i].block = block;
for (j = 0; j < DMODES; j++) {
blockstack[i].start_row[j] = 0;
@@ -3481,6 +3481,8 @@ int main(int argc, char *argv[])
memset(device, 0, sizeof(device));
termlines = 30; /* assume interactive mode until we find -p */
process_parameters(argc, argv, 0);
+ if (dmode == INIT_MODE)
+ dmode = HEX_MODE;
fd = open(device, O_RDWR);
if (fd < 0)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index e4b0ea1..88964a2 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -18,7 +18,7 @@
#endif
#define DMODES 3
-enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2 };
+enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
#define BLOCK_STACK_SIZE 256
#define GFS_FORMAT_SB (100) /* Super-Block */
@@ -159,8 +159,11 @@ extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
extern void gfs_log_header_in(struct gfs_log_header *head, char *buf);
extern void gfs_log_header_print(struct gfs_log_header *lh);
extern void gfs_dinode_in(struct gfs_dinode *di, char *buf);
+extern int display(int identify_only);
+extern uint64_t check_keywords(const char *kword);
extern void savemeta(char *out_fn, int saveoption);
-extern void restoremeta(const char *in_fn, const char *out_device, int printblocksonly);
+extern void restoremeta(const char *in_fn, const char *out_device,
+ uint64_t printblocksonly);
extern uint64_t masterblock(const char *fn);
struct gfs2_dirents {
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index cfe8f82..85fcde7 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -84,13 +84,7 @@ static int get_gfs_struct_info(char *gbuf, int *block_type, int *gstruct_len)
*gstruct_len = sbd.bsize; /*sizeof(struct gfs_leaf);*/
break;
case GFS2_METATYPE_JD: /* 7 (journal data) */
- /* GFS1 keeps indirect pointers in GFS2_METATYPE_JD blocks
- so we need to save the whole block. For GFS2, we don't
- want to, or we might capture user data, which is bad. */
- if (gfs1)
- *gstruct_len = sbd.bsize;
- else
- *gstruct_len = sizeof(struct gfs2_meta_header);
+ *gstruct_len = sbd.bsize;
break;
case GFS2_METATYPE_LH: /* 8 (log header) */
if (gfs1)
@@ -358,8 +352,15 @@ static void save_inode_data(int out_fd)
height = inode->i_di.di_height;
/* If this is a user inode, we don't follow to the file height.
We stop one level less. That way we save off the indirect
- pointer blocks but not the actual file contents. */
- if (height && !block_is_systemfile())
+ pointer blocks but not the actual file contents. The exception
+ is directories, where the height represents the level at which
+ the hash table exists, and we have to save the directory data. */
+ if (inode->i_di.di_flags & GFS2_DIF_EXHASH &&
+ (S_ISDIR(inode->i_di.di_mode) ||
+ (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
+ height++;
+ else if (height && !block_is_systemfile() &&
+ !S_ISDIR(inode->i_di.di_mode))
height--;
osi_list_add(&metabh->b_altlist, &metalist[0]);
for (i = 1; i <= height; i++){
@@ -787,95 +788,98 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
}
rs = read(in_fd, &buf16, sizeof(uint16_t));
savedata->siglen = be16_to_cpu(buf16);
- if (savedata->siglen <= sizeof(savedata->buf)) {
- if (savedata->siglen &&
- read(in_fd, savedata->buf, savedata->siglen) !=
- savedata->siglen) {
- fprintf(stderr, "read error: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
+ if (savedata->siglen > sizeof(savedata->buf)) {
+ fprintf(stderr, "\nBad record length: %d for block #%"
+ PRIu64 " (0x%" PRIx64").\n", savedata->siglen,
+ savedata->blk, savedata->blk);
+ return -1;
+ }
+ if (savedata->siglen &&
+ read(in_fd, savedata->buf, savedata->siglen) !=
+ savedata->siglen) {
+ fprintf(stderr, "read error: %s from %s:%d: "
+ "block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__, __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
+ if (first) {
+ struct gfs2_sb bufsb;
+
+ memcpy(&bufsb, savedata->buf, sizeof(bufsb));
+ gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
+ sbd1 = (struct gfs_sb *)&sbd.sd_sb;
+ if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
+ sbd1->sb_header.mh_type ==
+ GFS_METATYPE_SB &&
+ sbd1->sb_header.mh_format ==
+ GFS_FORMAT_SB &&
+ sbd1->sb_multihost_format ==
+ GFS_FORMAT_MULTI) {
+ gfs1 = TRUE;
+ } else if (check_sb(&sbd.sd_sb)) {
+ fprintf(stderr,"Error: Invalid superblock data.\n");
+ return -1;
}
- if (first) {
- struct gfs2_sb bufsb;
-
- memcpy(&bufsb, savedata->buf, sizeof(bufsb));
- gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
- sbd1 = (struct gfs_sb *)&sbd.sd_sb;
- if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
- sbd1->sb_header.mh_type ==
- GFS_METATYPE_SB &&
- sbd1->sb_header.mh_format ==
- GFS_FORMAT_SB &&
- sbd1->sb_multihost_format ==
- GFS_FORMAT_MULTI) {
- gfs1 = TRUE;
- } else if (check_sb(&sbd.sd_sb)) {
- fprintf(stderr,"Error: Invalid superblock data.\n");
- return -1;
- }
- sbd.bsize = sbd.sd_sb.sb_bsize;
- if (!printblocksonly) {
- last_fs_block =
- lseek(fd, 0, SEEK_END) /
- sbd.bsize;
- printf("There are %" PRIu64 " blocks of " \
- "%u bytes in the destination" \
- " file system.\n\n",
- last_fs_block, sbd.bsize);
- } else {
- printf("This is %s metadata\n", gfs1 ?
- "gfs (not gfs2)" : "gfs2");
- }
- first = 0;
+ sbd.bsize = sbd.sd_sb.sb_bsize;
+ if (!printblocksonly) {
+ last_fs_block =
+ lseek(fd, 0, SEEK_END) / sbd.bsize;
+ printf("There are %" PRIu64 " blocks of " \
+ "%u bytes in the destination" \
+ " file system.\n\n",
+ last_fs_block, sbd.bsize);
+ } else {
+ printf("This is %s metadata\n", gfs1 ?
+ "gfs (not gfs2)" : "gfs2");
}
- if (printblocksonly) {
+ first = 0;
+ }
+ if (printblocksonly) {
+ block = savedata->blk;
+ if (block > highest_valid_block)
+ highest_valid_block = block;
+ if (printblocksonly > 1 && printblocksonly == block) {
+ memcpy(buf, savedata->buf, sbd.bsize);
+ block_in_mem = block;
+ display(0);
+ return 0;
+ } else if (printblocksonly == 1) {
print_gfs2("%d (l=0x%x): ", blks_saved,
savedata->siglen);
- block = savedata->blk;
- if (block > highest_valid_block)
- highest_valid_block = block;
display_block_type(savedata->buf, TRUE);
- } else {
- warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
- if (savedata->blk >= last_fs_block) {
- printf("\nOut of space on the destination "
- "device; quitting.\n");
- break;
- }
- if (lseek(fd, savedata->blk * sbd.bsize,
- SEEK_SET) !=
- savedata->blk * sbd.bsize) {
- fprintf(stderr, "bad seek: %s from %s:"
- "%d: block %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__, (unsigned long long)
- savedata->blk,
- (unsigned long long)
- savedata->blk);
- exit(-1);
- }
- if (write(fd, savedata->buf, sbd.bsize) !=
- sbd.bsize) {
- fprintf(stderr, "write error: %s from "
- "%s:%d: block %lld (0x%llx)\n",
- strerror(errno),
- __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
- }
- writes++;
}
- blks_saved++;
} else {
- fprintf(stderr, "\nBad record length: %d for block #%"
- PRIu64".\n", savedata->siglen, savedata->blk);
- return -1;
+ warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
+ if (savedata->blk >= last_fs_block) {
+ printf("\nOut of space on the destination "
+ "device; quitting.\n");
+ break;
+ }
+ if (lseek(fd, savedata->blk * sbd.bsize, SEEK_SET) !=
+ savedata->blk * sbd.bsize) {
+ fprintf(stderr, "bad seek: %s from %s:"
+ "%d: block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__,
+ __LINE__, (unsigned long long)
+ savedata->blk,
+ (unsigned long long)
+ savedata->blk);
+ exit(-1);
+ }
+ if (write(fd, savedata->buf, sbd.bsize) != sbd.bsize) {
+ fprintf(stderr, "write error: %s from "
+ "%s:%d: block %lld (0x%llx)\n",
+ strerror(errno),
+ __FUNCTION__, __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
+ writes++;
}
+ blks_saved++;
}
if (!printblocksonly)
warm_fuzzy_stuff(savedata->blk, TRUE, FALSE);
@@ -895,7 +899,7 @@ static void complain(const char *complaint)
}
void restoremeta(const char *in_fn, const char *out_device,
- int printblocksonly)
+ uint64_t printblocksonly)
{
int in_fd, error;
@@ -914,7 +918,9 @@ void restoremeta(const char *in_fn, const char *out_device,
if (sbd.device_fd < 0)
die("Can't open destination file system %s: %s\n",
out_device, strerror(errno));
- }
+ } else if (out_device) /* for printsavedmeta, the out_device is an
+ optional block no */
+ printblocksonly = check_keywords(out_device);
savedata = malloc(sizeof(struct saved_metablock));
if (!savedata)
die("Can't allocate memory for the restore operation.\n");
14 years, 5 months
gfs2-utils: master - GFS2: gfs2_edit savemeta bugs
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: a7617752851a33d75245ab20e58df9e966904b7b
Parent: 78c2c90520d9f20ac0c8879dc62e13816aad78d3
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Dec 17 17:15:49 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Thu Dec 17 17:22:24 2009 -0600
GFS2: gfs2_edit savemeta bugs
This patch fixes a problem whereby directory hash tables were not
being saved by gfs2_edit's savemeta option. Also, this introduces
a new option to print individual records from a savemeta file:
gfs2_edit printsavedmeta /home/bob/my.meta 0x12345
rhbz#528786
---
gfs2/edit/hexedit.c | 30 ++++----
gfs2/edit/hexedit.h | 7 ++-
gfs2/edit/savemeta.c | 190 ++++++++++++++++++++++++++------------------------
3 files changed, 119 insertions(+), 108 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 1b8ca7b..5ccb76e 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -39,10 +39,6 @@ const char *allocdesc[2][5] = {
#define RGLIST_DUMMY_BLOCK -2
int display(int identify_only);
-extern void do_leaf_extended(char *buf, struct iinfo *indir);
-extern void savemeta(char *out_fn, int slow);
-extern void restoremeta(const char *in_fn, const char *out_device,
- int printblocksonly);
/* for assigning numeric fields: */
#define checkassign(strfield, struct, member, value) do { \
@@ -1818,8 +1814,7 @@ int display(int identify_only)
if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) {
fprintf(stderr, "read error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__,
+ strerror(errno), __FUNCTION__, __LINE__,
(unsigned long long)dev_offset,
(unsigned long long)dev_offset);
exit(-1);
@@ -2146,7 +2141,7 @@ static uint64_t find_metablockoftype(const char *strtype, int print)
/* Check if the word is a keyword such as "sb" or "rindex" */
/* Returns: block number if it is, else 0 */
/* ------------------------------------------------------------------------ */
-static uint64_t check_keywords(const char *kword)
+uint64_t check_keywords(const char *kword)
{
uint64_t blk = 0;
@@ -3253,17 +3248,22 @@ static void parameterpass1(int argc, char *argv[], int i)
termlines = 0;
else if (!strcasecmp(argv[i], "savergs"))
termlines = 0;
- else if (!strcasecmp(argv[i], "printsavedmeta"))
- restoremeta(argv[i+1], argv[i+2],
- TRUE);
- else if (!strcasecmp(argv[i], "restoremeta"))
+ else if (!strcasecmp(argv[i], "printsavedmeta")) {
+ if (dmode == INIT_MODE)
+ dmode = GFS2_MODE;
+ restoremeta(argv[i+1], argv[i+2], TRUE);
+ } else if (!strcasecmp(argv[i], "restoremeta")) {
+ if (dmode == INIT_MODE)
+ dmode = HEX_MODE; /* hopefully not used */
restoremeta(argv[i+1], argv[i+2], FALSE);
- else if (!strcmp(argv[i], "rgcount"))
+ } else if (!strcmp(argv[i], "rgcount"))
termlines = 0;
else if (!strcmp(argv[i], "rgflags"))
termlines = 0;
else if (!strcmp(argv[i], "rg"))
termlines = 0;
+ else if (!strcasecmp(argv[i], "-x"))
+ dmode = HEX_MODE;
else if (!device[0] && strchr(argv[i],'/'))
strcpy(device, argv[i]);
}
@@ -3462,12 +3462,12 @@ int main(int argc, char *argv[])
memset(edit_col, 0, sizeof(edit_col));
memset(edit_size, 0, sizeof(edit_size));
memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen));
- dmode = HEX_MODE;
+ dmode = INIT_MODE;
sbd.bsize = 4096;
type_alloc(buf, char, sbd.bsize); /* allocate/malloc a new 4K buffer */
block = starting_blk = 0x10;
for (i = 0; i < BLOCK_STACK_SIZE; i++) {
- blockstack[i].dmode = dmode;
+ blockstack[i].dmode = HEX_MODE;
blockstack[i].block = block;
for (j = 0; j < DMODES; j++) {
blockstack[i].start_row[j] = 0;
@@ -3483,6 +3483,8 @@ int main(int argc, char *argv[])
memset(device, 0, sizeof(device));
termlines = 30; /* assume interactive mode until we find -p */
process_parameters(argc, argv, 0);
+ if (dmode == INIT_MODE)
+ dmode = HEX_MODE;
fd = open(device, O_RDWR);
if (fd < 0)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index e4b0ea1..88964a2 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -18,7 +18,7 @@
#endif
#define DMODES 3
-enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2 };
+enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
#define BLOCK_STACK_SIZE 256
#define GFS_FORMAT_SB (100) /* Super-Block */
@@ -159,8 +159,11 @@ extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
extern void gfs_log_header_in(struct gfs_log_header *head, char *buf);
extern void gfs_log_header_print(struct gfs_log_header *lh);
extern void gfs_dinode_in(struct gfs_dinode *di, char *buf);
+extern int display(int identify_only);
+extern uint64_t check_keywords(const char *kword);
extern void savemeta(char *out_fn, int saveoption);
-extern void restoremeta(const char *in_fn, const char *out_device, int printblocksonly);
+extern void restoremeta(const char *in_fn, const char *out_device,
+ uint64_t printblocksonly);
extern uint64_t masterblock(const char *fn);
struct gfs2_dirents {
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index ca56276..3985c45 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -86,13 +86,7 @@ static int get_gfs_struct_info(char *gbuf, int *block_type, int *gstruct_len)
*gstruct_len = sbd.bsize; /*sizeof(struct gfs_leaf);*/
break;
case GFS2_METATYPE_JD: /* 7 (journal data) */
- /* GFS1 keeps indirect pointers in GFS2_METATYPE_JD blocks
- so we need to save the whole block. For GFS2, we don't
- want to, or we might capture user data, which is bad. */
- if (gfs1)
- *gstruct_len = sbd.bsize;
- else
- *gstruct_len = sizeof(struct gfs2_meta_header);
+ *gstruct_len = sbd.bsize;
break;
case GFS2_METATYPE_LH: /* 8 (log header) */
if (gfs1)
@@ -360,8 +354,15 @@ static void save_inode_data(int out_fd)
height = inode->i_di.di_height;
/* If this is a user inode, we don't follow to the file height.
We stop one level less. That way we save off the indirect
- pointer blocks but not the actual file contents. */
- if (height && !block_is_systemfile())
+ pointer blocks but not the actual file contents. The exception
+ is directories, where the height represents the level at which
+ the hash table exists, and we have to save the directory data. */
+ if (inode->i_di.di_flags & GFS2_DIF_EXHASH &&
+ (S_ISDIR(inode->i_di.di_mode) ||
+ (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
+ height++;
+ else if (height && !block_is_systemfile() &&
+ !S_ISDIR(inode->i_di.di_mode))
height--;
osi_list_add(&metabh->b_altlist, &metalist[0]);
for (i = 1; i <= height; i++){
@@ -789,95 +790,98 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
}
rs = read(in_fd, &buf16, sizeof(uint16_t));
savedata->siglen = be16_to_cpu(buf16);
- if (savedata->siglen <= sizeof(savedata->buf)) {
- if (savedata->siglen &&
- read(in_fd, savedata->buf, savedata->siglen) !=
- savedata->siglen) {
- fprintf(stderr, "read error: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
+ if (savedata->siglen > sizeof(savedata->buf)) {
+ fprintf(stderr, "\nBad record length: %d for block #%"
+ PRIu64 " (0x%" PRIx64").\n", savedata->siglen,
+ savedata->blk, savedata->blk);
+ return -1;
+ }
+ if (savedata->siglen &&
+ read(in_fd, savedata->buf, savedata->siglen) !=
+ savedata->siglen) {
+ fprintf(stderr, "read error: %s from %s:%d: "
+ "block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__, __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
+ if (first) {
+ struct gfs2_sb bufsb;
+
+ memcpy(&bufsb, savedata->buf, sizeof(bufsb));
+ gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
+ sbd1 = (struct gfs_sb *)&sbd.sd_sb;
+ if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
+ sbd1->sb_header.mh_type ==
+ GFS_METATYPE_SB &&
+ sbd1->sb_header.mh_format ==
+ GFS_FORMAT_SB &&
+ sbd1->sb_multihost_format ==
+ GFS_FORMAT_MULTI) {
+ gfs1 = TRUE;
+ } else if (check_sb(&sbd.sd_sb)) {
+ fprintf(stderr,"Error: Invalid superblock data.\n");
+ return -1;
}
- if (first) {
- struct gfs2_sb bufsb;
-
- memcpy(&bufsb, savedata->buf, sizeof(bufsb));
- gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
- sbd1 = (struct gfs_sb *)&sbd.sd_sb;
- if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
- sbd1->sb_header.mh_type ==
- GFS_METATYPE_SB &&
- sbd1->sb_header.mh_format ==
- GFS_FORMAT_SB &&
- sbd1->sb_multihost_format ==
- GFS_FORMAT_MULTI) {
- gfs1 = TRUE;
- } else if (check_sb(&sbd.sd_sb)) {
- fprintf(stderr,"Error: Invalid superblock data.\n");
- return -1;
- }
- sbd.bsize = sbd.sd_sb.sb_bsize;
- if (!printblocksonly) {
- last_fs_block =
- lseek(fd, 0, SEEK_END) /
- sbd.bsize;
- printf("There are %" PRIu64 " blocks of " \
- "%u bytes in the destination" \
- " file system.\n\n",
- last_fs_block, sbd.bsize);
- } else {
- printf("This is %s metadata\n", gfs1 ?
- "gfs (not gfs2)" : "gfs2");
- }
- first = 0;
+ sbd.bsize = sbd.sd_sb.sb_bsize;
+ if (!printblocksonly) {
+ last_fs_block =
+ lseek(fd, 0, SEEK_END) / sbd.bsize;
+ printf("There are %" PRIu64 " blocks of " \
+ "%u bytes in the destination" \
+ " file system.\n\n",
+ last_fs_block, sbd.bsize);
+ } else {
+ printf("This is %s metadata\n", gfs1 ?
+ "gfs (not gfs2)" : "gfs2");
}
- if (printblocksonly) {
+ first = 0;
+ }
+ if (printblocksonly) {
+ block = savedata->blk;
+ if (block > highest_valid_block)
+ highest_valid_block = block;
+ if (printblocksonly > 1 && printblocksonly == block) {
+ memcpy(buf, savedata->buf, sbd.bsize);
+ block_in_mem = block;
+ display(0);
+ return 0;
+ } else if (printblocksonly == 1) {
print_gfs2("%d (l=0x%x): ", blks_saved,
savedata->siglen);
- block = savedata->blk;
- if (block > highest_valid_block)
- highest_valid_block = block;
display_block_type(savedata->buf, TRUE);
- } else {
- warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
- if (savedata->blk >= last_fs_block) {
- printf("\nOut of space on the destination "
- "device; quitting.\n");
- break;
- }
- if (lseek(fd, savedata->blk * sbd.bsize,
- SEEK_SET) !=
- savedata->blk * sbd.bsize) {
- fprintf(stderr, "bad seek: %s from %s:"
- "%d: block %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__, (unsigned long long)
- savedata->blk,
- (unsigned long long)
- savedata->blk);
- exit(-1);
- }
- if (write(fd, savedata->buf, sbd.bsize) !=
- sbd.bsize) {
- fprintf(stderr, "write error: %s from "
- "%s:%d: block %lld (0x%llx)\n",
- strerror(errno),
- __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
- }
- writes++;
}
- blks_saved++;
} else {
- fprintf(stderr, "\nBad record length: %d for block #%"
- PRIu64".\n", savedata->siglen, savedata->blk);
- return -1;
+ warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
+ if (savedata->blk >= last_fs_block) {
+ printf("\nOut of space on the destination "
+ "device; quitting.\n");
+ break;
+ }
+ if (lseek(fd, savedata->blk * sbd.bsize, SEEK_SET) !=
+ savedata->blk * sbd.bsize) {
+ fprintf(stderr, "bad seek: %s from %s:"
+ "%d: block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__,
+ __LINE__, (unsigned long long)
+ savedata->blk,
+ (unsigned long long)
+ savedata->blk);
+ exit(-1);
+ }
+ if (write(fd, savedata->buf, sbd.bsize) != sbd.bsize) {
+ fprintf(stderr, "write error: %s from "
+ "%s:%d: block %lld (0x%llx)\n",
+ strerror(errno),
+ __FUNCTION__, __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
+ writes++;
}
+ blks_saved++;
}
if (!printblocksonly)
warm_fuzzy_stuff(savedata->blk, TRUE, FALSE);
@@ -897,7 +901,7 @@ static void complain(const char *complaint)
}
void restoremeta(const char *in_fn, const char *out_device,
- int printblocksonly)
+ uint64_t printblocksonly)
{
int in_fd, error;
@@ -916,7 +920,9 @@ void restoremeta(const char *in_fn, const char *out_device,
if (sbd.device_fd < 0)
die("Can't open destination file system %s: %s\n",
out_device, strerror(errno));
- }
+ } else if (out_device) /* for printsavedmeta, the out_device is an
+ optional block no */
+ printblocksonly = check_keywords(out_device);
savedata = malloc(sizeof(struct saved_metablock));
if (!savedata)
die("Can't allocate memory for the restore operation.\n");
14 years, 5 months
cluster: STABLE3 - cluster.rng: fence_daemon updates
by David Teigland
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: baea48ccc79bbc3ef2723c2eae26b1d144dea645
Parent: 4427cd5736ce631ba7970e250df99b448e114f32
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Dec 16 17:18:45 2009 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Dec 16 17:18:45 2009 -0600
cluster.rng: fence_daemon updates
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
config/tools/xml/cluster.rng.in | 48 ++++++++++++++++----------------------
1 files changed, 20 insertions(+), 28 deletions(-)
diff --git a/config/tools/xml/cluster.rng.in b/config/tools/xml/cluster.rng.in
index d78685b..4344fda 100644
--- a/config/tools/xml/cluster.rng.in
+++ b/config/tools/xml/cluster.rng.in
@@ -340,45 +340,37 @@ To validate your cluster.conf against this schema, run:
<!-- fence_daemon block -->
<optional>
- <element name="fence_daemon" rha:description="This element and its
- attributes define cluster-wide parameters for basic fence timing
- properties used when a node joins a cluster or is fenced from
- the cluster.">
+ <element name="fence_daemon" rha:description="Configuration for fenced
+ daemon. fenced(8)">
<optional>
- <attribute name="post_join_delay" rha:description="The number of
- seconds the fence daemon (fenced) waits before fencing a node
- after the node joins the fence domain. A typical setting for
- post_join_delay is between 20 and 30 seconds, but can vary
- according to cluster and network performance requirements."
- rha:default="3" rha:sample="20"/>
+ <attribute name="post_join_delay" rha:description="Number of seconds
+ the daemon will wait before fencing any victims after a node joins
+ the fence domain. fenced(8)"/>
</optional>
<optional>
- <attribute name="post_fail_delay" rha:description="The the number of
- seconds the fence daemon (fenced) waits before fencing
- a node (a member of the fence domain) after the node has
- failed." rha:default="0" rha:sample="2"/>
+ <attribute name="post_fail_delay" rha:description="Number of seconds
+ the daemon will wait before fencing any victims after a node
+ fails. fenced(8)"/>
</optional>
<optional>
- <attribute name="override_path" rha:description="The location of a
- FIFO used for communication between fenced and fence_ack_manual"
- rha:default="/var/run/cluster/fenced_override"
- rha:sample="/opt/cluster/fenced_override"/>
+ <attribute name="override_path" rha:description="Location of a FIFO
+ used for communication between fenced and fence_ack_manual.
+ fenced(8)"/>
</optional>
<optional>
- <attribute name="override_time" rha:description="The location of a
- FIFO used for communication between fenced and fence_ack_manual"
- rha:default="/var/run/cluster/fenced_override"
- rha:sample="/opt/cluster/fenced_override"/>
+ <attribute name="override_time" rha:description="Number of seconds to
+ wait for a manual override after a failed fencing attempt before
+ the next attempt. fenced(8)"/>
</optional>
<optional>
- <attribute name="clean_start" rha:description="Clean-start is used
- to prevent any startup fencing the daemon might do." rha:default="0"
- rha:sample="1"/>
+ <attribute name="clean_start" rha:description="Set to 1 to disable
+ startup fencing. fenced(8)"/>
</optional>
+
<optional>
- <attribute name="skip_undefined" rha:description="Do not do startup
- fencing of nodes with no fence methods defined." rha:default="0"
- rha:sample="1"/>
+ <attribute name="skip_undefined" rha:description="Set to 1 to disable
+ startup fencing of nodes with no fence methods defined.
+ fenced(8)"/>
</optional>
</element>
</optional>
14 years, 5 months
cluster: RHEL55 - rgmanager: Make VF timeout scale with token timeout
by Lon Hohberger
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: e956129acaab0ab20b96b53b8ac0a494428806a1
Parent: c3fd533042a15a684206439e51a5377528e8b709
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Wed Dec 16 12:56:43 2009 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Wed Dec 16 16:31:54 2009 -0500
rgmanager: Make VF timeout scale with token timeout
Rgmanager was not waiting long enough to account for
failures mid-state transition, allowing the possibility
for services to enter the 'failed' state erroneously.
Resolves: rhbz#548133
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/include/vf.h | 2 +-
rgmanager/src/clulib/vft.c | 10 +++++++---
rgmanager/src/daemons/main.c | 22 +++++++++++++++++-----
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/rgmanager/include/vf.h b/rgmanager/include/vf.h
index abcca1b..3be7e15 100644
--- a/rgmanager/include/vf.h
+++ b/rgmanager/include/vf.h
@@ -170,7 +170,7 @@ typedef struct _key_node {
/*
* VF Stuff. VF only talks to peers.
*/
-int vf_init(int, uint16_t, vf_vote_cb_t, vf_commit_cb_t);
+int vf_init(int, uint16_t, vf_vote_cb_t, vf_commit_cb_t, int);
int vf_invalidate(void);
int vf_shutdown(void);
diff --git a/rgmanager/src/clulib/vft.c b/rgmanager/src/clulib/vft.c
index aed1d30..26191b5 100644
--- a/rgmanager/src/clulib/vft.c
+++ b/rgmanager/src/clulib/vft.c
@@ -45,6 +45,7 @@
static key_node_t *key_list = NULL; /** List of key nodes. */
static int _node_id = (int)-1;/** Our node ID, set with vf_init. */
static uint16_t _port = 0; /** Our daemon ID, set with vf_init. */
+static int _vf_timeout = 10;
/*
* TODO: We could make it thread safe, but this might be unnecessary work
@@ -104,7 +105,8 @@ static int tv_cmp(struct timeval *left, struct timeval *right);
static uint32_t vf_try_commit(key_node_t *key_node);
int vf_init(int my_node_id, uint16_t my_port,
- vf_vote_cb_t vote_cb, vf_commit_cb_t commit_cb);
+ vf_vote_cb_t vote_cb, vf_commit_cb_t commit_cb,
+ int cluster_timeout);
int vf_key_init(char *keyid, int timeout, vf_vote_cb_t vote_cb,
vf_commit_cb_t commit_cb);
static int vf_key_init_nt(char *keyid, int timeout, vf_vote_cb_t vote_cb,
@@ -910,7 +912,7 @@ vf_server(void *arg)
*/
int
vf_init(int my_node_id, uint16_t my_port, vf_vote_cb_t vcb,
- vf_commit_cb_t ccb)
+ vf_commit_cb_t ccb, int cluster_timeout)
{
struct vf_args *args;
msgctx_t *ctx;
@@ -937,6 +939,8 @@ vf_init(int my_node_id, uint16_t my_port, vf_vote_cb_t vcb,
pthread_mutex_lock(&vf_mutex);
_port = my_port;
_node_id = my_node_id;
+ if (cluster_timeout)
+ _vf_timeout = cluster_timeout;
default_vote_cb = vcb;
default_commit_cb = ccb;
pthread_mutex_unlock(&vf_mutex);
@@ -1248,7 +1252,7 @@ vf_write(cluster_member_list_t *membership, uint32_t flags, char *keyid,
* See if we have a consensus =)
*/
if ((rv = (vf_unanimous(&everyone, trans, remain,
- 5))) == VFR_OK) {
+ _vf_timeout))) == VFR_OK) {
vf_send_commit(&everyone, trans);
#ifdef DEBUG
printf("VF: Consensus reached!\n");
diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c
index 7f12f08..601e7d0 100644
--- a/rgmanager/src/daemons/main.c
+++ b/rgmanager/src/daemons/main.c
@@ -45,7 +45,7 @@
#ifdef WRAP_THREADS
void dump_thread_states(FILE *);
#endif
-int configure_rgmanager(int ccsfd, int debug);
+int configure_rgmanager(int ccsfd, int debug, int *cluster_timeout);
void node_event(int, int, int, int);
void node_event_q(int, int, int, int);
@@ -792,7 +792,7 @@ event_loop(msgctx_t *localctx, msgctx_t *clusterctx)
if (need_reconfigure || check_config_update(&oldver, &newver)) {
need_reconfigure = 0;
- configure_rgmanager(-1, 0);
+ configure_rgmanager(-1, 0, NULL);
config_event_q(oldver, newver);
return 0;
}
@@ -848,11 +848,12 @@ statedump(int __attribute__ ((unused)) sig)
* Configure logging based on data in cluster.conf
*/
int
-configure_rgmanager(int ccsfd, int dbg)
+configure_rgmanager(int ccsfd, int dbg, int *token_secs)
{
char *v;
char internal = 0;
int status_child_max = 0;
+ int tmp;
if (ccsfd == -1) {
internal = 1;
@@ -861,6 +862,16 @@ configure_rgmanager(int ccsfd, int dbg)
return -1;
}
+ if (token_secs && ccs_get(ccsfd, "/cluster/totem/@token", &v) == 0) {
+ tmp = atoi(v);
+ if (tmp >= 1000) {
+ *token_secs = tmp / 1000;
+ if (tmp % 1000)
+ ++(*token_secs);
+ }
+ free(v);
+ }
+
if (ccs_get(ccsfd, "/cluster/rm/@log_facility", &v) == 0) {
clu_set_facility(v);
free(v);
@@ -1011,6 +1022,7 @@ main(int argc, char **argv)
msgctx_t *local_ctx;
pthread_t th;
cman_handle_t clu = NULL;
+ int cluster_timeout = 10;
while ((rv = getopt(argc, argv, "wfdN")) != EOF) {
switch (rv) {
@@ -1089,7 +1101,7 @@ main(int argc, char **argv)
We know we're quorate. At this point, we need to
read the resource group trees from ccsd.
*/
- configure_rgmanager(-1, debug);
+ configure_rgmanager(-1, debug, &cluster_timeout);
clulog(LOG_NOTICE, "Resource Group Manager Starting\n");
if (init_resource_groups(0, do_init, 0) != 0) {
@@ -1132,7 +1144,7 @@ main(int argc, char **argv)
ds_key_init("rg_lockdown", 32, 10);
#else
- if (vf_init(me.cn_nodeid, port, NULL, NULL) != 0) {
+ if (vf_init(me.cn_nodeid, port, NULL, NULL, cluster_timeout) != 0) {
clulog(LOG_CRIT, "#11: Couldn't set up VF listen socket\n");
return -1;
}
14 years, 5 months
cluster: RHEL55 - cman: Make consensus 2*token timeout
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: c3fd533042a15a684206439e51a5377528e8b709
Parent: 31a310c603936867f651295358e31af6c2714f6a
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Wed Dec 16 13:07:11 2009 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Wed Dec 16 13:07:11 2009 +0000
cman: Make consensus 2*token timeout
If consensus is not specified in cluster.conf then make it twice
the token value. For full details of why, see the Bugzilla
rhbzbz#544482
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
cman/daemon/ais.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/cman/daemon/ais.c b/cman/daemon/ais.c
index 9a874a8..787f0bd 100644
--- a/cman/daemon/ais.c
+++ b/cman/daemon/ais.c
@@ -520,11 +520,16 @@ static int comms_init_ais(struct objdb_iface_ver0 *objdb)
global_objdb->object_key_create(object_handle, "join", strlen("join"),
"60", strlen("60")+1);
}
+ /* consensus should be 2*token, see bz#544482*/
if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
- global_objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
- "4800", strlen("4800")+1);
- }
+ unsigned int token=0;
+ char calc_consensus[32];
+ objdb_get_int(objdb, object_handle, "token", &token);
+ sprintf(calc_consensus, "%d", token*2);
+ objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
+ calc_consensus, strlen(calc_consensus)+1);
+ }
/* Set RRP mode appropriately */
if (num_interfaces > 1) {
14 years, 5 months
resource-agents: master - rgmanager: Fix ipv6 handling
by Lon Hohberger
Gitweb: http://git.fedorahosted.org/git/resource-agents.git?p=resource-agents.git...
Commit: f9d933d42f7a1c42ad54be3fdaf0887b0252c4ee
Parent: 26e9e538b22554d21ae43c4b379b664daf6f05d3
Author: Shane Bradley <sbradley(a)redhat.com>
AuthorDate: Tue Dec 15 16:55:51 2009 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Tue Dec 15 17:08:45 2009 -0500
rgmanager: Fix ipv6 handling
Resolves: rhbz#533461
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/ip.sh | 84 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/rgmanager/src/resources/ip.sh b/rgmanager/src/resources/ip.sh
index f974fa9..714da05 100644
--- a/rgmanager/src/resources/ip.sh
+++ b/rgmanager/src/resources/ip.sh
@@ -155,6 +155,7 @@ ipv6_expand()
typeset addr=$1
typeset maskbits
typeset -i x
+ typeset tempaddr
maskbits=${addr/*\//}
if [ "$maskbits" = "$addr" ]; then
@@ -164,6 +165,25 @@ ipv6_expand()
addr=${addr/\/*/}
fi
+ # grab each hex quad and expand it to 4 digits if it isn't already
+ # leave doublecolon in place for expansion out to the proper number of zeros later
+ tempaddr=""
+ for count in `seq 1 8`; do
+ quad=`echo $addr|awk -v count=$count -F : '{print $count}'`
+ quadlen=${#quad}
+ if [ $quadlen -eq 0 ]; then
+ quad=::
+ elif [ $quadlen -eq 1 ]; then
+ quad=000$quad
+ elif [ $quadlen -eq 2 ]; then
+ quad=00$quad
+ elif [ $quadlen -eq 3 ]; then
+ quad=0$quad
+ fi
+ tempaddr=$tempaddr$quad
+ done
+ addr=$tempaddr
+
# use space as placeholder
addr=${addr/::/\ }
@@ -711,8 +731,22 @@ check_interface_up()
{
declare dev
declare addr=${2/\/*/}
+ declare currentAddr caExpanded
+
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ dev=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $2}')
+ break
+ fi
+ done
+ else
+ dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ fi
- dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
if [ -z "$dev" ]; then
return 1
fi
@@ -730,12 +764,26 @@ address_configured()
{
declare line
declare addr
+ declare currentAddr caExpanded
# Chop off maxk bits
addr=${2/\/*/}
- line=$(/sbin/ip -f $1 -o addr | grep " $addr/")
- if [ -z "$line" ]; then
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ line=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}");
+ break
+ fi
+ done
+ else
+ line=$(/sbin/ip -f $1 -o addr | grep " $addr/")
+ fi
+
+ if [ -z "$line" ]; then
return 1
fi
return 0
@@ -751,13 +799,26 @@ ip_op()
declare dev
declare rtr
declare addr=${3/\/*/}
-
+ declare caExpanded currentAddr
if [ "$2" = "status" ]; then
ocf_log debug "Checking $3, Level $OCF_CHECK_LEVEL"
- dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ dev=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $2}')
+ break
+ fi
+ done
+ else
+ dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ fi
+
if [ -z "$dev" ]; then
ocf_log warn "$3 is not configured"
return 1
@@ -788,6 +849,19 @@ ip_op()
return $?
;;
inet6)
+ if [ "$2" = "del" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ addr6=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $4}')
+ ipv6 $2 $addr6
+ return $?
+ fi
+ done
+ fi
+
ipv6 $2 $3
return $?
;;
14 years, 5 months
cluster: STABLE3 - rgmanager: Fix ipv6 handling
by Lon Hohberger
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 4427cd5736ce631ba7970e250df99b448e114f32
Parent: 32bed24ef00dc5df5474d0287ffbb3e4eceb1226
Author: Shane Bradley <sbradley(a)redhat.com>
AuthorDate: Tue Dec 15 16:55:51 2009 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Tue Dec 15 17:08:00 2009 -0500
rgmanager: Fix ipv6 handling
Resolves: rhbz#533461
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/ip.sh | 84 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/rgmanager/src/resources/ip.sh b/rgmanager/src/resources/ip.sh
index f974fa9..714da05 100644
--- a/rgmanager/src/resources/ip.sh
+++ b/rgmanager/src/resources/ip.sh
@@ -155,6 +155,7 @@ ipv6_expand()
typeset addr=$1
typeset maskbits
typeset -i x
+ typeset tempaddr
maskbits=${addr/*\//}
if [ "$maskbits" = "$addr" ]; then
@@ -164,6 +165,25 @@ ipv6_expand()
addr=${addr/\/*/}
fi
+ # grab each hex quad and expand it to 4 digits if it isn't already
+ # leave doublecolon in place for expansion out to the proper number of zeros later
+ tempaddr=""
+ for count in `seq 1 8`; do
+ quad=`echo $addr|awk -v count=$count -F : '{print $count}'`
+ quadlen=${#quad}
+ if [ $quadlen -eq 0 ]; then
+ quad=::
+ elif [ $quadlen -eq 1 ]; then
+ quad=000$quad
+ elif [ $quadlen -eq 2 ]; then
+ quad=00$quad
+ elif [ $quadlen -eq 3 ]; then
+ quad=0$quad
+ fi
+ tempaddr=$tempaddr$quad
+ done
+ addr=$tempaddr
+
# use space as placeholder
addr=${addr/::/\ }
@@ -711,8 +731,22 @@ check_interface_up()
{
declare dev
declare addr=${2/\/*/}
+ declare currentAddr caExpanded
+
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ dev=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $2}')
+ break
+ fi
+ done
+ else
+ dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ fi
- dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
if [ -z "$dev" ]; then
return 1
fi
@@ -730,12 +764,26 @@ address_configured()
{
declare line
declare addr
+ declare currentAddr caExpanded
# Chop off maxk bits
addr=${2/\/*/}
- line=$(/sbin/ip -f $1 -o addr | grep " $addr/")
- if [ -z "$line" ]; then
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ line=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}");
+ break
+ fi
+ done
+ else
+ line=$(/sbin/ip -f $1 -o addr | grep " $addr/")
+ fi
+
+ if [ -z "$line" ]; then
return 1
fi
return 0
@@ -751,13 +799,26 @@ ip_op()
declare dev
declare rtr
declare addr=${3/\/*/}
-
+ declare caExpanded currentAddr
if [ "$2" = "status" ]; then
ocf_log debug "Checking $3, Level $OCF_CHECK_LEVEL"
- dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ dev=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $2}')
+ break
+ fi
+ done
+ else
+ dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ fi
+
if [ -z "$dev" ]; then
ocf_log warn "$3 is not configured"
return 1
@@ -788,6 +849,19 @@ ip_op()
return $?
;;
inet6)
+ if [ "$2" = "del" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ addr6=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $4}')
+ ipv6 $2 $addr6
+ return $?
+ fi
+ done
+ fi
+
ipv6 $2 $3
return $?
;;
14 years, 5 months
cluster: RHEL55 - rgmanager: Fix ipv6 handling
by Lon Hohberger
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 31a310c603936867f651295358e31af6c2714f6a
Parent: 23d5cbe5dfcf20040814a09aafa33faf9f6f66e9
Author: Shane Bradley <sbradley(a)redhat.com>
AuthorDate: Tue Dec 15 16:55:51 2009 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Tue Dec 15 16:55:51 2009 -0500
rgmanager: Fix ipv6 handling
Resolves: rhbz#533461
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/ip.sh | 84 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/rgmanager/src/resources/ip.sh b/rgmanager/src/resources/ip.sh
index 1e9bb2f..4f7e432 100755
--- a/rgmanager/src/resources/ip.sh
+++ b/rgmanager/src/resources/ip.sh
@@ -175,6 +175,7 @@ ipv6_expand()
typeset addr=$1
typeset maskbits
typeset -i x
+ typeset tempaddr
maskbits=${addr/*\//}
if [ "$maskbits" = "$addr" ]; then
@@ -184,6 +185,25 @@ ipv6_expand()
addr=${addr/\/*/}
fi
+ # grab each hex quad and expand it to 4 digits if it isn't already
+ # leave doublecolon in place for expansion out to the proper number of zeros later
+ tempaddr=""
+ for count in `seq 1 8`; do
+ quad=`echo $addr|awk -v count=$count -F : '{print $count}'`
+ quadlen=${#quad}
+ if [ $quadlen -eq 0 ]; then
+ quad=::
+ elif [ $quadlen -eq 1 ]; then
+ quad=000$quad
+ elif [ $quadlen -eq 2 ]; then
+ quad=00$quad
+ elif [ $quadlen -eq 3 ]; then
+ quad=0$quad
+ fi
+ tempaddr=$tempaddr$quad
+ done
+ addr=$tempaddr
+
# use space as placeholder
addr=${addr/::/\ }
@@ -732,8 +752,22 @@ check_interface_up()
{
declare dev
declare addr=${2/\/*/}
+ declare currentAddr caExpanded
+
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ dev=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $2}')
+ break
+ fi
+ done
+ else
+ dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ fi
- dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
if [ -z "$dev" ]; then
return 1
fi
@@ -751,12 +785,26 @@ address_configured()
{
declare line
declare addr
+ declare currentAddr caExpanded
# Chop off maxk bits
addr=${2/\/*/}
- line=$(/sbin/ip -f $1 -o addr | grep " $addr/")
- if [ -z "$line" ]; then
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ line=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}");
+ break
+ fi
+ done
+ else
+ line=$(/sbin/ip -f $1 -o addr | grep " $addr/")
+ fi
+
+ if [ -z "$line" ]; then
return 1
fi
return 0
@@ -772,13 +820,26 @@ ip_op()
declare dev
declare rtr
declare addr=${3/\/*/}
-
+ declare caExpanded currentAddr
if [ "$2" = "status" ]; then
ocf_log debug "Checking $3, Level $OCF_CHECK_LEVEL"
- dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ if [ "$1" == "inet6" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ dev=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $2}')
+ break
+ fi
+ done
+ else
+ dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}')
+ fi
+
if [ -z "$dev" ]; then
ocf_log warn "$3 is not configured"
return 1
@@ -809,6 +870,19 @@ ip_op()
return $?
;;
inet6)
+ if [ "$2" = "del" ]; then
+ addrExpanded=$(ipv6_expand $addr)
+ for currentAddr in `/sbin/ip -f $1 -o addr|awk '{print $4}'`; do
+ caExpanded=$(ipv6_expand $currentAddr)
+ caExpanded=${caExpanded/\/*/}
+ if [ "$addrExpanded" == "$caExpanded" ]; then
+ addr6=$(/sbin/ip -f $1 -o addr | grep " ${currentAddr/\/*/}" | awk '{print $4}')
+ ipv6 $2 $addr6
+ return $?
+ fi
+ done
+ fi
+
ipv6 $2 $3
return $?
;;
14 years, 5 months