fence-agents: master - fence agents: Some agents do not support action=metadata on STDIN
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=efcf34...
Commit: efcf34f5156385c397509f9fe40ae08ca74a96a0
Parent: 723b70ae3f2930e26a7646a4eac881ae1f8e8f10
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Jul 12 18:30:48 2012 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Jul 12 18:30:48 2012 +0200
fence agents: Some agents do not support action=metadata on STDIN
Resolves rhbz#837174
---
fence/agents/baytech/fence_baytech.pl | 9 +++++----
fence/agents/brocade/fence_brocade.pl | 5 +++++
fence/agents/bullpap/fence_bullpap.pl | 7 ++++++-
fence/agents/cpint/fence_cpint.pl | 10 ++++++++++
fence/agents/drac/fence_drac.pl | 5 +++++
fence/agents/egenera/fence_egenera.pl | 9 +++++----
fence/agents/mcdata/fence_mcdata.pl | 7 ++++++-
fence/agents/rackswitch/do_rack.c | 9 +++++++++
fence/agents/xcat/fence_xcat.pl | 5 +++++
fence/agents/zvm/fence_zvm.pl | 10 ++++++++++
10 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/fence/agents/baytech/fence_baytech.pl b/fence/agents/baytech/fence_baytech.pl
index c978ec5..e218b78 100644
--- a/fence/agents/baytech/fence_baytech.pl
+++ b/fence/agents/baytech/fence_baytech.pl
@@ -166,14 +166,15 @@ sub get_options
fail_usage "Unkown parameter." if (@ARGV > 0);
- if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
- print_metadata();
- exit 0;
- }
} else {
get_options_stdin();
}
+ if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "failed: must specify hostname" unless defined $opt_a;
$host=$opt_a;
$port=23 unless ($opt_a =~ /:/);
diff --git a/fence/agents/brocade/fence_brocade.pl b/fence/agents/brocade/fence_brocade.pl
index e3d1612..e3f7290 100644
--- a/fence/agents/brocade/fence_brocade.pl
+++ b/fence/agents/brocade/fence_brocade.pl
@@ -162,6 +162,11 @@ if (@ARGV > 0) {
} else {
get_options_stdin();
+ if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "failed: no IP address" unless defined $opt_a;
fail "failed: no plug number" unless defined $opt_n;
fail "failed: no login name" unless defined $opt_l;
diff --git a/fence/agents/bullpap/fence_bullpap.pl b/fence/agents/bullpap/fence_bullpap.pl
index 3309c18..e31ab6d 100644
--- a/fence/agents/bullpap/fence_bullpap.pl
+++ b/fence/agents/bullpap/fence_bullpap.pl
@@ -179,7 +179,7 @@ sub get_options_stdin
{
$login = $val;
}
- elsif ($name eq "option" )
+ elsif (($name eq "option" ) || ($name eq "action"))
{
$action = $val;
}
@@ -312,6 +312,11 @@ else
{
get_options_stdin();
+ if ((defined $action) && ($action =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "failed: no IP address" unless defined $host;
fail "failed: no domain" unless defined $domain;
fail "failed: no login name" unless defined $login;
diff --git a/fence/agents/cpint/fence_cpint.pl b/fence/agents/cpint/fence_cpint.pl
index d3c016a..eb2ad3a 100644
--- a/fence/agents/cpint/fence_cpint.pl
+++ b/fence/agents/cpint/fence_cpint.pl
@@ -142,6 +142,11 @@ sub get_options_stdin
$opt_u = $val;
}
+ elsif ($name eq "action" )
+ {
+ $opt_o = $val;
+ }
+
else
{
print stderr "parse error: unknown option \"$opt\"\n";
@@ -166,6 +171,11 @@ if (@ARGV > 0){
} else {
get_options_stdin();
+ if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "no userid" unless defined $opt_u;
}
diff --git a/fence/agents/drac/fence_drac.pl b/fence/agents/drac/fence_drac.pl
index 825391f..b26fbcb 100644
--- a/fence/agents/drac/fence_drac.pl
+++ b/fence/agents/drac/fence_drac.pl
@@ -717,6 +717,11 @@ if (@ARGV > 0) {
} else {
get_options_stdin();
+ if ((defined $action) && ($action =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "failed: no IP address" unless defined $address;
fail "failed: no login name" unless defined $login;
diff --git a/fence/agents/egenera/fence_egenera.pl b/fence/agents/egenera/fence_egenera.pl
index 30eaca1..308338b 100644
--- a/fence/agents/egenera/fence_egenera.pl
+++ b/fence/agents/egenera/fence_egenera.pl
@@ -139,10 +139,6 @@ if (@ARGV > 0)
fail_usage "Unkown parameter." if (@ARGV > 0);
- if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
- print_metadata();
- exit 0;
- }
$cserv = $opt_c if defined $opt_c;
$lpan = $opt_l if defined $opt_l;
@@ -156,6 +152,11 @@ else
get_options_stdin();
}
+if (((defined $opt_o) && ($opt_o =~ /metadata/i)) || ((defined $action) && ($action =~ /metadata/i))) {
+ print_metadata();
+ exit 0;
+}
+
$action = "reboot" unless defined $action;
$user = "root" unless defined $user;
diff --git a/fence/agents/mcdata/fence_mcdata.pl b/fence/agents/mcdata/fence_mcdata.pl
index a469a1c..5bc9dcf 100644
--- a/fence/agents/mcdata/fence_mcdata.pl
+++ b/fence/agents/mcdata/fence_mcdata.pl
@@ -176,7 +176,7 @@ sub get_options_stdin
{
$opt_l = $val;
}
- elsif ($name eq "option" )
+ elsif (($name eq "option" ) || ($name eq "action"))
{
$opt_o = $val;
}
@@ -235,6 +235,11 @@ if (@ARGV > 0) {
} else {
get_options_stdin();
+ if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "failed: no IP address" unless defined $opt_a;
fail "failed: no plug number" unless defined $opt_n;
fail "failed: no login name" unless defined $opt_l;
diff --git a/fence/agents/rackswitch/do_rack.c b/fence/agents/rackswitch/do_rack.c
index 67d24a2..d8050bf 100644
--- a/fence/agents/rackswitch/do_rack.c
+++ b/fence/agents/rackswitch/do_rack.c
@@ -301,6 +301,15 @@ static void get_options(int argc, char **argv)
strcpy(name, pname);
if (!strcmp(arg, "ipaddr"))
strcpy(ipaddr, value);
+
+ if (!strcmp(arg, "action"))
+ if (strncasecmp(value, "metadata", 254) == 0) {
+ print_metadata();
+ exit(DID_SUCCESS);
+ } else {
+ fprintf(stderr, "Only 'metadata' option is aviable for this fence agent\n");
+ exit(DID_FAILURE);
+ }
if (!strcmp(arg, "portnumber"))
strcpy(portnumber, value);
diff --git a/fence/agents/xcat/fence_xcat.pl b/fence/agents/xcat/fence_xcat.pl
index f984ec1..3cd16aa 100644
--- a/fence/agents/xcat/fence_xcat.pl
+++ b/fence/agents/xcat/fence_xcat.pl
@@ -184,6 +184,11 @@ if (@ARGV > 0) {
} else {
get_options_stdin();
+ if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "failed: no plug number" unless defined $opt_n;
$opt_o=lc($opt_o);
fail "failed: unrecognised action: $opt_o"
diff --git a/fence/agents/zvm/fence_zvm.pl b/fence/agents/zvm/fence_zvm.pl
index e6386e4..04a29e2 100644
--- a/fence/agents/zvm/fence_zvm.pl
+++ b/fence/agents/zvm/fence_zvm.pl
@@ -299,6 +299,11 @@ sub get_options_stdin
{
$opt_r = $val;
}
+
+ elsif ($name eq "action")
+ {
+ $opt_o = $val;
+ }
# FIXME -- depreicated residue of old fencing system
elsif ($name eq "name" ) { }
@@ -352,6 +357,11 @@ if (@ARGV > 0){
} else {
get_options_stdin();
+ if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
+ print_metadata();
+ exit 0;
+ }
+
fail "no IP address" unless defined $opt_a;
fail "no userid" unless defined $opt_u;
11 years, 9 months
cluster: RHEL59 - When the filesystem /etc lives on is completely full, umount will exit with exit status 16 if the umount syscall succeeded but it was unable to write a new mtab file because the disk is full. umount won't exit with status 16 under any other circumstances.
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=3290dff9b88...
Commit: 3290dff9b88992e913b28dd57c6b64a3c2b75c8a
Parent: 13005d1ff5246a332bfc6795ad443b0148cd11b2
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Mon Jul 16 11:21:43 2012 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon Jul 16 11:21:43 2012 -0400
When the filesystem /etc lives on is completely full, umount will exit with exit status 16 if the umount syscall succeeded but it was unable to write a new mtab file because the disk is full. umount won't exit with status 16 under any other circumstances.
This patch changes the fs.sh, clusterfs.sh, and netfs.sh resource agents
to check treat both exit status 0 and exit status 16 as success.
Resolves: rhbz#819595
Acked-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/resources/clusterfs.sh | 5 ++++-
rgmanager/src/resources/fs.sh | 5 ++++-
rgmanager/src/resources/netfs.sh | 5 ++++-
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/rgmanager/src/resources/clusterfs.sh b/rgmanager/src/resources/clusterfs.sh
index 49eb724..ff28e3d 100755
--- a/rgmanager/src/resources/clusterfs.sh
+++ b/rgmanager/src/resources/clusterfs.sh
@@ -792,8 +792,11 @@ stop: Could not match $OCF_RESKEY_device with a real device"
sync; sync; sync
ocf_log info "unmounting $dev ($mp)"
+ # umount will exit with status 16 iff the umount(2)
+ # succeeded, but /etc/mtab could not be written.
umount $mp
- if [ $? -eq 0 ]; then
+ retval=$?
+ if [ $retval -eq 0 -o $retval -eq 16 ]; then
umount_failed=
done=$YES
continue
diff --git a/rgmanager/src/resources/fs.sh b/rgmanager/src/resources/fs.sh
index a98cddc..9dec8d1 100755
--- a/rgmanager/src/resources/fs.sh
+++ b/rgmanager/src/resources/fs.sh
@@ -1102,8 +1102,11 @@ stop: Could not match $OCF_RESKEY_device with a real device"
fi
ocf_log info "unmounting $mp"
+ # umount will exit with status 16 iff the umount(2)
+ # succeeded, but /etc/mtab could not be written.
umount $mp
- if [ $? -eq 0 ]; then
+ retval=$?
+ if [ $retval -eq 0 -o $retval -eq 16 ]; then
umount_failed=
done=$YES
continue
diff --git a/rgmanager/src/resources/netfs.sh b/rgmanager/src/resources/netfs.sh
index 837a4c4..6089a0d 100755
--- a/rgmanager/src/resources/netfs.sh
+++ b/rgmanager/src/resources/netfs.sh
@@ -559,8 +559,11 @@ stopNFSFilesystem() {
sync; sync; sync
ocf_log info "unmounting $mp"
+ # umount will exit with status 16 iff the umount(2)
+ # succeeded, but /etc/mtab could not be written.
umount $umount_flag $mp
- if [ $? -eq 0 ]; then
+ retval=$?
+ if [ $retval -eq 0 -o $retval -eq 16 ]; then
umount_failed=
done=$YES
continue
11 years, 9 months
cluster: RHEL59 - rgmanager: Fix return code when relocation fails and svc is running on original node
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=13005d1ff52...
Commit: 13005d1ff5246a332bfc6795ad443b0148cd11b2
Parent: 467d015c53e5e2d00025708cda95b3df41ebda1f
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Wed Jul 11 09:11:33 2012 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon Jul 16 11:09:20 2012 -0400
rgmanager: Fix return code when relocation fails and svc is running on original node
Return RG_ERELO (Relocation failure; service running on original node) when
relocation failed and the service was restarted successfully on the original
node.
This is the behavior that's currently in the STABLE32 and RHEL6 branches.
Acked-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/daemons/rg_state.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/daemons/rg_state.c b/rgmanager/src/daemons/rg_state.c
index 4357d21..9000f1b 100644
--- a/rgmanager/src/daemons/rg_state.c
+++ b/rgmanager/src/daemons/rg_state.c
@@ -2061,7 +2061,7 @@ exhausted:
svcName);
if (svc_start(svcName, RG_START_RECOVER) == 0) {
*new_owner = me;
- return 0;
+ return RG_ERELO;
}
}
11 years, 9 months
cluster: RHEL59 - rgmanager: Fix for services stuck in recovery
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=467d015c53e...
Commit: 467d015c53e5e2d00025708cda95b3df41ebda1f
Parent: d88584bd640700c51692198d2f6aeda0e773165c
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Mon Jul 16 10:57:28 2012 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon Jul 16 11:05:26 2012 -0400
rgmanager: Fix for services stuck in recovery
Patch from John Ruemker <jruemker(a)redhat.com>:
"When starting rgmanager throughout the cluster around the same
time, multiple nodes may end up acting as the "root" for a particular
service. If that service happens to fail on startup, you can end up
with each of those nodes sending remote-start requests around the
cluster. Eventually the service will get stuck in a recovering state,
and cannot be modified in any way with clusvcadm. The only remedy we've
found is to kill rgmanager and start it back up.
Acked-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/daemons/groups.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/rgmanager/src/daemons/groups.c b/rgmanager/src/daemons/groups.c
index 20ed2e1..bd406c8 100644
--- a/rgmanager/src/daemons/groups.c
+++ b/rgmanager/src/daemons/groups.c
@@ -747,7 +747,8 @@ eval_groups(int local, uint32_t nodeid, int nodeStatus)
(svcStatus.rs_state == RG_STATE_STARTED ||
svcStatus.rs_state == RG_STATE_RECOVER ||
svcStatus.rs_state == RG_STATE_STARTING ||
- svcStatus.rs_state == RG_STATE_STOPPING )) {
+ svcStatus.rs_state == RG_STATE_STOPPING ||
+ svcStatus.rs_state == RG_STATE_ERROR)) {
clulog(LOG_DEBUG,
"Marking %s on down member %d as stopped",
@@ -789,7 +790,8 @@ eval_groups(int local, uint32_t nodeid, int nodeStatus)
/* Disabled/failed/in recovery? Do nothing */
if ((svcStatus.rs_state == RG_STATE_DISABLED) ||
(svcStatus.rs_state == RG_STATE_FAILED) ||
- (svcStatus.rs_state == RG_STATE_RECOVER)) {
+ (svcStatus.rs_state == RG_STATE_RECOVER) ||
+ (svcStatus.rs_state == RG_STATE_ERROR)) {
continue;
}
11 years, 9 months
cluster: STABLE32 - rgmanager: Fix for services stuck in recovery
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=03e2215bd27...
Commit: 03e2215bd277fd79b8a6ee70a49de711e0f343ad
Parent: e080a6249f25a3bc18a6c9028c9da06bf4ef14c6
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Mon Jul 16 10:57:28 2012 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon Jul 16 10:57:28 2012 -0400
rgmanager: Fix for services stuck in recovery
Patch from John Ruemker <jruemker(a)redhat.com>:
"When starting rgmanager throughout the cluster around the same
time, multiple nodes may end up acting as the "root" for a particular
service. If that service happens to fail on startup, you can end up
with each of those nodes sending remote-start requests around the
cluster. Eventually the service will get stuck in a recovering state,
and cannot be modified in any way with clusvcadm. The only remedy we've
found is to kill rgmanager and start it back up.
Acked-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/daemons/groups.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/rgmanager/src/daemons/groups.c b/rgmanager/src/daemons/groups.c
index 4a72cb7..4537cc8 100644
--- a/rgmanager/src/daemons/groups.c
+++ b/rgmanager/src/daemons/groups.c
@@ -731,7 +731,8 @@ eval_groups(int local, uint32_t nodeid, int nodeStatus)
(svcStatus.rs_state == RG_STATE_STARTED ||
svcStatus.rs_state == RG_STATE_RECOVER ||
svcStatus.rs_state == RG_STATE_STARTING ||
- svcStatus.rs_state == RG_STATE_STOPPING )) {
+ svcStatus.rs_state == RG_STATE_STOPPING ||
+ svcStatus.rs_state == RG_STATE_ERROR)) {
logt_print(LOG_DEBUG,
"Marking %s on down member %d as stopped",
@@ -773,7 +774,8 @@ eval_groups(int local, uint32_t nodeid, int nodeStatus)
/* Disabled/failed/in recovery? Do nothing */
if ((svcStatus.rs_state == RG_STATE_DISABLED) ||
(svcStatus.rs_state == RG_STATE_FAILED) ||
- (svcStatus.rs_state == RG_STATE_RECOVER)) {
+ (svcStatus.rs_state == RG_STATE_RECOVER) ||
+ (svcStatus.rs_state == RG_STATE_ERROR)) {
continue;
}
11 years, 9 months
cluster: RHEL59 - fsck.gfs2: Fix buffer overflow in get_lockproto_table
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=d88584bd640...
Commit: d88584bd640700c51692198d2f6aeda0e773165c
Parent: 5a1d50a8308bb5b40c6a8d990f628bdaa9c20a59
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Sat Jul 7 22:03:24 2012 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Mon Jul 16 14:18:08 2012 +0100
fsck.gfs2: Fix buffer overflow in get_lockproto_table
Coverity discovered a buffer overflow in this function where an overly
long cluster name in cluster.conf could cause a crash while repairing
the superblock. This patch fixes the bug by making sure the lock table
is composed sensibly, limiting the fsname to 16 chars as documented, and
only allowing the cluster name (which doesn't seem to have a documented
max size) to use the remaining space in the locktable name string.
Resolves: rhbz#838910
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/fsck/initialize.c | 42 ++++++++++++++++++++++--------------------
1 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index bd364e4..a26ed84 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -551,12 +551,13 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
static int get_lockproto_table(struct gfs2_sbd *sdp)
{
FILE *fp;
- char line[PATH_MAX], *p, *p2;
- char fsname[PATH_MAX];
+ char line[PATH_MAX];
+ char *cluname, *end;
+ const char *fsname, *cfgfile = "/etc/cluster/cluster.conf";
memset(sdp->lockproto, 0, sizeof(sdp->lockproto));
memset(sdp->locktable, 0, sizeof(sdp->locktable));
- fp = fopen("/etc/cluster/cluster.conf", "rt");
+ fp = fopen(cfgfile, "rt");
if (!fp) {
/* no cluster.conf; must be a stand-alone file system */
strcpy(sdp->lockproto, "lock_nolock");
@@ -569,28 +570,29 @@ static int get_lockproto_table(struct gfs2_sbd *sdp)
log_warn(_("Lock protocol assumed to be: " GFS2_DEFAULT_LOCKPROTO
"\n"));
strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
+
while (fgets(line, sizeof(line) - 1, fp)) {
- p = strstr(line,"<cluster name=");
- if (p) {
- p += 15;
- p2 = strchr(p,'"');
- strncpy(sdp->locktable, p, p2 - p);
+ cluname = strstr(line,"<cluster name=");
+ if (cluname) {
+ cluname += 15;
+ end = strchr(cluname,'"');
+ if (end)
+ *end = '\0';
break;
}
}
- if (sdp->locktable[0] == '\0') {
- log_err(_("Error: Unable to determine cluster name from "
- "/etc/cluster.conf\n"));
+ if (cluname == NULL || end == NULL || end - cluname < 1) {
+ log_err(_("Error: Unable to determine cluster name from %s\n"),
+ cfgfile);
} else {
- memset(fsname, 0, sizeof(fsname));
- p = strrchr(opts.device, '/');
- if (p) {
- p++;
- strncpy(fsname, p, sizeof(fsname));
- } else
- strcpy(fsname, "repaired");
- strcat(sdp->locktable, ":");
- strcat(sdp->locktable, fsname);
+ fsname = strrchr(opts.device, '/');
+ if (fsname)
+ fsname++;
+ else
+ fsname = "repaired";
+ snprintf(sdp->locktable, sizeof(sdp->locktable), "%.*s:%.16s",
+ (int)(sizeof(sdp->locktable) - strlen(fsname) - 2),
+ cluname, fsname);
log_warn(_("Lock table determined to be: %s\n"),
sdp->locktable);
}
11 years, 9 months
gfs2-utils: master - fsck.gfs2: Fix buffer overflow in get_lockproto_table
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=150b5160...
Commit: 150b51604f75c0de65cf3f837bc7b8ac30aa6d8b
Parent: 04bb1157cd4967c3d935a3c77c9ba0f176dcff43
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Sat Jul 7 22:03:24 2012 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Sat Jul 7 22:03:24 2012 +0100
fsck.gfs2: Fix buffer overflow in get_lockproto_table
Coverity discovered a buffer overflow in this function where an overly
long cluster name in cluster.conf could cause a crash while repairing
the superblock. This patch fixes the bug by making sure the lock table
is composed sensibly, limiting the fsname to 16 chars as documented, and
only allowing the cluster name (which doesn't seem to have a documented
max size) to use the remaining space in the locktable name string.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/fsck/initialize.c | 42 ++++++++++++++++++++++--------------------
1 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index f07e0b2..e56161e 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -753,12 +753,13 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
static int get_lockproto_table(struct gfs2_sbd *sdp)
{
FILE *fp;
- char line[PATH_MAX], *p, *p2;
- char fsname[PATH_MAX];
+ char line[PATH_MAX];
+ char *cluname, *end;
+ const char *fsname, *cfgfile = "/etc/cluster/cluster.conf";
memset(sdp->lockproto, 0, sizeof(sdp->lockproto));
memset(sdp->locktable, 0, sizeof(sdp->locktable));
- fp = fopen("/etc/cluster/cluster.conf", "rt");
+ fp = fopen(cfgfile, "rt");
if (!fp) {
/* no cluster.conf; must be a stand-alone file system */
strcpy(sdp->lockproto, "lock_nolock");
@@ -771,28 +772,29 @@ static int get_lockproto_table(struct gfs2_sbd *sdp)
log_warn(_("Lock protocol assumed to be: " GFS2_DEFAULT_LOCKPROTO
"\n"));
strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
+
while (fgets(line, sizeof(line) - 1, fp)) {
- p = strstr(line,"<cluster name=");
- if (p) {
- p += 15;
- p2 = strchr(p,'"');
- strncpy(sdp->locktable, p, p2 - p);
+ cluname = strstr(line,"<cluster name=");
+ if (cluname) {
+ cluname += 15;
+ end = strchr(cluname,'"');
+ if (end)
+ *end = '\0';
break;
}
}
- if (sdp->locktable[0] == '\0') {
- log_err(_("Error: Unable to determine cluster name from "
- "/etc/cluster.conf\n"));
+ if (cluname == NULL || end == NULL || end - cluname < 1) {
+ log_err(_("Error: Unable to determine cluster name from %s\n"),
+ cfgfile);
} else {
- memset(fsname, 0, sizeof(fsname));
- p = strrchr(opts.device, '/');
- if (p) {
- p++;
- strncpy(fsname, p, sizeof(fsname));
- } else
- strcpy(fsname, "repaired");
- strcat(sdp->locktable, ":");
- strcat(sdp->locktable, fsname);
+ fsname = strrchr(opts.device, '/');
+ if (fsname)
+ fsname++;
+ else
+ fsname = "repaired";
+ snprintf(sdp->locktable, sizeof(sdp->locktable), "%.*s:%.16s",
+ (int)(sizeof(sdp->locktable) - strlen(fsname) - 2),
+ cluname, fsname);
log_warn(_("Lock table determined to be: %s\n"),
sdp->locktable);
}
11 years, 9 months
gfs2-utils: master - mkfs.gfs2: Avoid a rename race when checking file contents
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=04bb1157...
Commit: 04bb1157cd4967c3d935a3c77c9ba0f176dcff43
Parent: aaa9d0c9f75936ef8cc19d8cfc4f48f8b4bfdd59
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jul 6 12:50:12 2012 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Jul 6 12:50:12 2012 +0100
mkfs.gfs2: Avoid a rename race when checking file contents
Currently there is a slight chance that mkfs.gfs2 could report the
incorrect contents of the target if another file is renamed into place.
This is because we pass the target name to the file command and file
opens it again. This patch tries to avoid that condition by using the
/proc/$pid/fd/$device_fd symlink, which changes when the open file is
renamed, instead.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/main_mkfs.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 957b144..2d529d7 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -426,7 +426,7 @@ static void check_dev_content(const char *devname)
char content[1024] = { 0, };
char * args[] = {
(char *)"/usr/bin/file",
- (char *)"-bs",
+ (char *)"-bsL",
(char *)devname,
NULL };
int p[2] = {-1, -1};
@@ -557,6 +557,7 @@ void main_mkfs(int argc, char *argv[])
int rgsize_specified = 0;
unsigned char uuid[16];
char *absname = NULL;
+ char *fdpath = NULL;
int islnk = 0;
memset(sdp, 0, sizeof(struct gfs2_sbd));
@@ -587,13 +588,19 @@ void main_mkfs(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ if (asprintf(&fdpath, "/proc/%d/fd/%d", getpid(), sdp->device_fd) < 0) {
+ perror(_("Failed to build string"));
+ exit(EXIT_FAILURE);
+ }
+
if (!sdp->override) {
islnk = is_symlink(sdp->device_name, &absname);
printf(_("This will destroy any data on %s.\n"), islnk ? absname : sdp->device_name);
- check_dev_content(islnk ? absname : sdp->device_name);
free(absname);
+ check_dev_content(fdpath);
are_you_sure();
}
+ free(fdpath);
if (sdp->bsize == -1) {
if (S_ISREG(sdp->dinfo.stat.st_mode))
11 years, 9 months
cluster: STABLE32 - cman: fix a couple of comments
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=e080a6249f2...
Commit: e080a6249f25a3bc18a6c9028c9da06bf4ef14c6
Parent: 88ab6a7b1e4da3802f64addc3d6f234e5cf82760
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Thu Jul 12 13:00:27 2012 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Thu Jul 12 13:00:27 2012 +0200
cman: fix a couple of comments
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
cman/daemon/cman-preconfig.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 22583fe..08b5ecf 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -1533,7 +1533,7 @@ static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const
objdb->object_destroy(cluster_parent_handle);
/*
- * create cluster.cman in the new config if it doesn't exists
+ * create cluster.cman in the new config if it doesn't exist
*/
objdb->object_find_create(cluster_parent_handle_new, "cman", strlen("cman"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle)) {
@@ -1543,7 +1543,7 @@ static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const
objdb->object_find_destroy(find_handle);
/*
- * readd cluster_id/two_node/nodename
+ * write cluster_id/two_node/nodename
*/
snprintf(str, sizeof(str) - 1, "%d", cluster_id);
objdb->object_key_create_typed(object_handle, "cluster_id",
11 years, 9 months
cluster: STABLE32 - cman: fix data copy and memory leak when reloading config
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=88ab6a7b1e4...
Commit: 88ab6a7b1e4da3802f64addc3d6f234e5cf82760
Parent: 8975bd6341b2d94c1f89279b1b00d4360da1f5ff
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Wed Jul 11 11:44:49 2012 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Wed Jul 11 11:44:49 2012 +0200
cman: fix data copy and memory leak when reloading config
cman.cluster_id,nodename,two_node information were not copied
from the old to the new config at reload time. This triggers
a problem when <cman is set in cluster.conf and we effectively
drop information from objdb (suboptimal).
Also fix a possible memory leak when we have reload issues.
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
cman/daemon/cman-preconfig.c | 31 +++++++++++++++++++++++++++++--
1 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 68fec22..22583fe 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -1478,6 +1478,7 @@ static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const
hdb_handle_t cluster_parent_handle_new;
unsigned int config_version = 0, config_version_new = 0;
char *config_value = NULL;
+ char str[255];
/* don't reload if we've been told to run configless */
if (getenv("CMAN_NOCONFIG")) {
@@ -1489,16 +1490,16 @@ static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const
/* find both /cluster entries */
objdb->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle);
objdb->object_find_next(find_handle, &cluster_parent_handle);
+ objdb->object_find_next(find_handle, &cluster_parent_handle_new);
+ objdb->object_find_destroy(find_handle);
if (!cluster_parent_handle) {
snprintf (error_reason, sizeof(error_reason) - 1, "Cannot find old /cluster/ key in configuration\n");
goto err;
}
- objdb->object_find_next(find_handle, &cluster_parent_handle_new);
if (!cluster_parent_handle_new) {
snprintf (error_reason, sizeof(error_reason) - 1, "Cannot find new /cluster/ key in configuration\n");
goto err;
}
- objdb->object_find_destroy(find_handle);
if (!objdb->object_key_get(cluster_parent_handle, "config_version", strlen("config_version"), (void *)&config_value, NULL)) {
if (config_value) {
@@ -1531,6 +1532,32 @@ static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const
/* destroy the old one */
objdb->object_destroy(cluster_parent_handle);
+ /*
+ * create cluster.cman in the new config if it doesn't exists
+ */
+ objdb->object_find_create(cluster_parent_handle_new, "cman", strlen("cman"), &find_handle);
+ if (objdb->object_find_next(find_handle, &object_handle)) {
+ objdb->object_create(cluster_parent_handle_new, &object_handle,
+ "cman", strlen("cman"));
+ }
+ objdb->object_find_destroy(find_handle);
+
+ /*
+ * readd cluster_id/two_node/nodename
+ */
+ snprintf(str, sizeof(str) - 1, "%d", cluster_id);
+ objdb->object_key_create_typed(object_handle, "cluster_id",
+ str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
+
+ if (two_node) {
+ snprintf(str, sizeof(str) - 1, "%d", 1);
+ objdb->object_key_create_typed(object_handle, "two_node",
+ str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
+ }
+
+ objdb->object_key_create_typed(object_handle, "nodename",
+ nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
+
/* update the reference to the new config */
cluster_parent_handle = cluster_parent_handle_new;
11 years, 9 months