gfs2-utils: master - gfs2_quota: Keep quota file length always sizeof(struct gfs2_quota) aligned
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 2d960dda19b87cb9e5c3c34e28f4dba5c22fbb9f
Parent: 3ec446ad397ab64d614e5f5a5cbca81f548cd78d
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Wed Apr 28 16:27:38 2010 -0500
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Wed Apr 28 16:33:43 2010 -0500
gfs2_quota: Keep quota file length always sizeof(struct gfs2_quota) aligned
This patch rounds up the quota filesize to the nearest
sizeof(struct gfs2_quota). It also fixes read/write of
quotas split across page boundaries that sometimes get
missed out.
Resolves: rhbz#585083
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/quota/check.c | 80 +++++++++++++++++++++++++++++++++++-----------------
gfs2/quota/main.c | 2 +-
2 files changed, 55 insertions(+), 27 deletions(-)
diff --git a/gfs2/quota/check.c b/gfs2/quota/check.c
index f5c1054..707eeae 100644
--- a/gfs2/quota/check.c
+++ b/gfs2/quota/check.c
@@ -177,10 +177,7 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
osi_list_t *uid, osi_list_t *gid)
{
int fd;
- char buf[sizeof(struct gfs2_quota)];
- struct gfs2_quota q;
- uint64_t offset = 0;
- uint32_t id, startid;
+ uint32_t id, startq;
int error = 0;
char quota_file[BUF_SIZE];
uint64_t quota_file_size = 0;
@@ -249,36 +246,51 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
int i;
for (i=0; i<fmap2->fm_mapped_extents; i++) {
struct fiemap_extent *fe = &fmap2->fm_extents[i];
- uint64_t end = fe->fe_logical + fe->fe_length;
+ uint64_t end = fe->fe_logical + fe->fe_length, val_off;
+ unsigned int v_off;
end = end > quota_file_size ? quota_file_size : end;
- startid = DIV_RU(fe->fe_logical, sizeof(struct gfs2_quota));
- offset = startid * sizeof(struct gfs2_quota);
- do {
- memset(buf, 0, sizeof(struct gfs2_quota));
+ /* we only need to get the value fields, not the whole quota
+ * This also works when struct gfs2_quota straddle page
+ * boundaries. Getting only the value field avoids the
+ * complexity of fetching two parts of the struct gfs2_quota
+ * from two successive pages
+ */
+ /* offset of the value field within struct gfs2_quota */
+ v_off = (unsigned long)(&((struct gfs2_quota *)NULL)->qu_value);
+ /* startq could be at the end of previous extent... */
+ startq = fe->fe_logical / sizeof(struct gfs2_quota);
+ /* but the value field could be in this extent */
+ if ((startq * sizeof(struct gfs2_quota) + v_off) >= fe->fe_logical)
+ val_off = startq * sizeof(struct gfs2_quota) + v_off;
+ else /* if the start of the extent doesn't have a split quota */
+ val_off = ++startq * sizeof(struct gfs2_quota) + v_off;
+
+ while ((val_off + sizeof(uint64_t)) <= end)
+ {
+ uint64_t value;
/* read hidden quota file here */
- lseek(fd, offset, SEEK_SET);
- error = read(fd, buf, sizeof(struct gfs2_quota));
+ lseek(fd, val_off, SEEK_SET);
+ error = read(fd, (unsigned char*)&value, sizeof(uint64_t));
if (error < 0) {
fprintf(stderr, "read error (%d): %s\n",
errno, strerror(errno));
goto fmap2_free;
}
- gfs2_quota_in(&q, buf);
- id = (offset / sizeof(struct gfs2_quota)) >> 1;
+ value = be64_to_cpu(value);
+ id = startq >> 1;
/* We want value in 512 byte blocks (1 << 9 = 512) */
- q.qu_value <<= sdp->sd_sb.sb_bsize_shift - 9;
-
- if (q.qu_value) {
- if (id * sizeof(struct gfs2_quota) * 2 == offset)
- add_value(uid, id, q.qu_value);
+ value <<= sdp->sd_sb.sb_bsize_shift - 9;
+ if (value) {
+ /* if startq is even, it's a uid, else gid */
+ if (startq % 2)
+ add_value(gid, id, value);
else
- add_value(gid, id, q.qu_value);
+ add_value(uid, id, value);
}
-
- offset += sizeof(struct gfs2_quota);
- } while ((offset + sizeof(struct gfs2_quota)) <=
- end);
+ startq++;
+ val_off += sizeof(struct gfs2_quota);
+ }
}
}
fmap2_free:
@@ -451,12 +463,13 @@ set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user,
int fd;
osi_list_t *tmp;
values_t *v;
- uint64_t offset;
+ uint64_t offset, max_off = 0;
int64_t value;
int error;
char quota_file[BUF_SIZE];
char id_str[16];
char *fs;
+ struct stat st;
strcpy(sdp->path_name, comline->filesystem);
if (check_for_gfs2(sdp)) {
@@ -490,6 +503,8 @@ set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user,
offset = (2 * (uint64_t)v->v_id + ((user) ? 0 : 1)) *
sizeof(struct gfs2_quota);
+ if (offset > max_off)
+ max_off = offset;
offset += (unsigned long)(&((struct gfs2_quota *)NULL)->qu_value);
value = v->v_blocks * multiplier;
@@ -520,7 +535,21 @@ set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user,
exit(-1);
}
}
-
+ /* If we wrote a value that extended the quota file size,
+ * round the size off to the nearest quota boundary
+ */
+ error = fstat(fd, &st);
+ if (error) {
+ fprintf(stderr, "can't stat quota file (%d): %s\n",
+ error, strerror(errno));
+ goto out;
+ }
+ if (st.st_size < (max_off + sizeof(struct gfs2_quota))) {
+ error = ftruncate(fd, (max_off + sizeof(struct gfs2_quota)));
+ if (error)
+ fprintf(stderr, "can't truncate quota file(%d): %s\n",
+ error, strerror(errno));
+ }
out:
close(fd);
close(sdp->metafs_fd);
@@ -568,6 +597,5 @@ do_quota_init(struct gfs2_sbd *sdp, commandline_t *comline)
set_list(sdp, comline, FALSE, &fs_gid, 1);
do_sync(sdp, comline);
-
do_check(sdp, comline);
}
diff --git a/gfs2/quota/main.c b/gfs2/quota/main.c
index d65e074..733f69d 100644
--- a/gfs2/quota/main.c
+++ b/gfs2/quota/main.c
@@ -338,7 +338,7 @@ read_quota_internal(int fd, uint32_t id, int id_type, struct gfs2_quota *q)
static inline void
write_quota_internal(int fd, uint32_t id, int id_type, struct gfs2_quota *q)
{
- /* seek to the appropriate offset in the quota file and read the
+ /* seek to the appropriate offset in the quota file and write the
quota info */
uint64_t offset;
char buf[256];
14 years
cluster: STABLE3 - gfs2_quota: Keep quota file length always sizeof(struct gfs2_quota) aligned
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 39f191de96a19cfb02a060a94f61ed17f306bbc0
Parent: 38a984c3b415a13142d2f65aa30edcdc60d70497
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Wed Apr 28 16:27:38 2010 -0500
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Wed Apr 28 16:27:38 2010 -0500
gfs2_quota: Keep quota file length always sizeof(struct gfs2_quota) aligned
This patch rounds up the quota filesize to the nearest
sizeof(struct gfs2_quota). It also fixes read/write of
quotas split across page boundaries that sometimes get
missed out.
Resolves: rhbz#585083
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/quota/check.c | 80 +++++++++++++++++++++++++++++++++++-----------------
gfs2/quota/main.c | 2 +-
2 files changed, 55 insertions(+), 27 deletions(-)
diff --git a/gfs2/quota/check.c b/gfs2/quota/check.c
index 86a941b..81a4364 100644
--- a/gfs2/quota/check.c
+++ b/gfs2/quota/check.c
@@ -175,10 +175,7 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
osi_list_t *uid, osi_list_t *gid)
{
int fd;
- char buf[sizeof(struct gfs2_quota)];
- struct gfs2_quota q;
- uint64_t offset = 0;
- uint32_t id, startid;
+ uint32_t id, startq;
int error = 0;
char quota_file[BUF_SIZE];
uint64_t quota_file_size = 0;
@@ -247,36 +244,51 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
int i;
for (i=0; i<fmap2->fm_mapped_extents; i++) {
struct fiemap_extent *fe = &fmap2->fm_extents[i];
- uint64_t end = fe->fe_logical + fe->fe_length;
+ uint64_t end = fe->fe_logical + fe->fe_length, val_off;
+ unsigned int v_off;
end = end > quota_file_size ? quota_file_size : end;
- startid = DIV_RU(fe->fe_logical, sizeof(struct gfs2_quota));
- offset = startid * sizeof(struct gfs2_quota);
- do {
- memset(buf, 0, sizeof(struct gfs2_quota));
+ /* we only need to get the value fields, not the whole quota
+ * This also works when struct gfs2_quota straddle page
+ * boundaries. Getting only the value field avoids the
+ * complexity of fetching two parts of the struct gfs2_quota
+ * from two successive pages
+ */
+ /* offset of the value field within struct gfs2_quota */
+ v_off = (unsigned long)(&((struct gfs2_quota *)NULL)->qu_value);
+ /* startq could be at the end of previous extent... */
+ startq = fe->fe_logical / sizeof(struct gfs2_quota);
+ /* but the value field could be in this extent */
+ if ((startq * sizeof(struct gfs2_quota) + v_off) >= fe->fe_logical)
+ val_off = startq * sizeof(struct gfs2_quota) + v_off;
+ else /* if the start of the extent doesn't have a split quota */
+ val_off = ++startq * sizeof(struct gfs2_quota) + v_off;
+
+ while ((val_off + sizeof(uint64_t)) <= end)
+ {
+ uint64_t value;
/* read hidden quota file here */
- lseek(fd, offset, SEEK_SET);
- error = read(fd, buf, sizeof(struct gfs2_quota));
+ lseek(fd, val_off, SEEK_SET);
+ error = read(fd, (unsigned char*)&value, sizeof(uint64_t));
if (error < 0) {
fprintf(stderr, "read error (%d): %s\n",
errno, strerror(errno));
goto fmap2_free;
}
- gfs2_quota_in(&q, buf);
- id = (offset / sizeof(struct gfs2_quota)) >> 1;
+ value = be64_to_cpu(value);
+ id = startq >> 1;
/* We want value in 512 byte blocks (1 << 9 = 512) */
- q.qu_value <<= sdp->sd_sb.sb_bsize_shift - 9;
-
- if (q.qu_value) {
- if (id * sizeof(struct gfs2_quota) * 2 == offset)
- add_value(uid, id, q.qu_value);
+ value <<= sdp->sd_sb.sb_bsize_shift - 9;
+ if (value) {
+ /* if startq is even, it's a uid, else gid */
+ if (startq % 2)
+ add_value(gid, id, value);
else
- add_value(gid, id, q.qu_value);
+ add_value(uid, id, value);
}
-
- offset += sizeof(struct gfs2_quota);
- } while ((offset + sizeof(struct gfs2_quota)) <=
- end);
+ startq++;
+ val_off += sizeof(struct gfs2_quota);
+ }
}
}
fmap2_free:
@@ -449,12 +461,13 @@ set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user,
int fd;
osi_list_t *tmp;
values_t *v;
- uint64_t offset;
+ uint64_t offset, max_off = 0;
int64_t value;
int error;
char quota_file[BUF_SIZE];
char id_str[16];
char *fs;
+ struct stat st;
strcpy(sdp->path_name, comline->filesystem);
if (check_for_gfs2(sdp)) {
@@ -488,6 +501,8 @@ set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user,
offset = (2 * (uint64_t)v->v_id + ((user) ? 0 : 1)) *
sizeof(struct gfs2_quota);
+ if (offset > max_off)
+ max_off = offset;
offset += (unsigned long)(&((struct gfs2_quota *)NULL)->qu_value);
value = v->v_blocks * multiplier;
@@ -518,7 +533,21 @@ set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user,
exit(-1);
}
}
-
+ /* If we wrote a value that extended the quota file size,
+ * round the size off to the nearest quota boundary
+ */
+ error = fstat(fd, &st);
+ if (error) {
+ fprintf(stderr, "can't stat quota file (%d): %s\n",
+ error, strerror(errno));
+ goto out;
+ }
+ if (st.st_size < (max_off + sizeof(struct gfs2_quota))) {
+ error = ftruncate(fd, (max_off + sizeof(struct gfs2_quota)));
+ if (error)
+ fprintf(stderr, "can't truncate quota file(%d): %s\n",
+ error, strerror(errno));
+ }
out:
close(fd);
close(sdp->metafs_fd);
@@ -566,6 +595,5 @@ do_quota_init(struct gfs2_sbd *sdp, commandline_t *comline)
set_list(sdp, comline, FALSE, &fs_gid, 1);
do_sync(sdp, comline);
-
do_check(sdp, comline);
}
diff --git a/gfs2/quota/main.c b/gfs2/quota/main.c
index 23ac9aa..0625b7d 100644
--- a/gfs2/quota/main.c
+++ b/gfs2/quota/main.c
@@ -336,7 +336,7 @@ read_quota_internal(int fd, uint32_t id, int id_type, struct gfs2_quota *q)
static inline void
write_quota_internal(int fd, uint32_t id, int id_type, struct gfs2_quota *q)
{
- /* seek to the appropriate offset in the quota file and read the
+ /* seek to the appropriate offset in the quota file and write the
quota info */
uint64_t offset;
char buf[256];
14 years
resource-agents: master - HA LVM: Use CLVM with local machine kernel targets (bz 585217)
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/resource-agents.git?p=resource-agents.git...
Commit: 9deb0cdb544086a9f053eeda21b6491ec3be1784
Parent: e4eece4a2210e7dcd59a8fbc087d5992bc8808b1
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Wed Apr 28 13:51:23 2010 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Wed Apr 28 13:51:23 2010 -0500
HA LVM: Use CLVM with local machine kernel targets (bz 585217)
When a logical volume is activated in a cluster exclusively,
the kernel targets used are single machine targets. This
means we can use CLVM to protect the LVM metadata and still
better align ourselves with active/passive application stacks.
Making this change also simplifies HA LVM setup. There is no
more setting up tags, volume_list entries, or updating the
initrd.
---
rgmanager/src/resources/lvm.sh | 52 ++-----------
rgmanager/src/resources/lvm_by_lv.sh | 75 +++++++++++++++++-
rgmanager/src/resources/lvm_by_vg.sh | 147 +++++++++++++++++++++++++++++++++-
3 files changed, 221 insertions(+), 53 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index b19a8ac..4b7155c 100644
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -17,19 +17,6 @@ export LC_ALL LANG PATH
rv=0
################################################################################
-# clvm_check
-#
-################################################################################
-function clvm_check
-{
- if [[ $(vgs -o attr --noheadings $1) =~ .....c ]]; then
- return 1
- fi
-
- return 0
-}
-
-################################################################################
# ha_lvm_proper_setup_check
#
################################################################################
@@ -87,18 +74,10 @@ function ha_lvm_proper_setup_check
case $1 in
start)
- ##
- # We can safely ignore clustered volume groups (VGs handled by CLVM)
- ##
- if ! clvm_check $OCF_RESKEY_vg_name; then
- ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..."
- exit 0
+ if ! [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ ha_lvm_proper_setup_check || exit 1
fi
- ha_lvm_proper_setup_check || exit 1
-
- rv=0
-
if [ -z $OCF_RESKEY_lv_name ]; then
vg_start || exit 1
else
@@ -114,20 +93,13 @@ status|monitor)
else
lv_status || exit 1
fi
- rv=0
;;
stop)
- ##
- # We can safely ignore clustered volume groups (VGs handled by CLVM)
- ##
- if ! clvm_check $OCF_RESKEY_vg_name; then
- ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..."
- exit 0
- fi
-
- if ! ha_lvm_proper_setup_check; then
- ocf_log err "WARNING: An improper setup can cause data corruption!"
+ if ! [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ if ! ha_lvm_proper_setup_check; then
+ ocf_log err "WARNING: An improper setup can cause data corruption!"
+ fi
fi
if [ -z $OCF_RESKEY_lv_name ]; then
@@ -135,35 +107,23 @@ stop)
else
lv_stop || exit 1
fi
- rv=0
;;
recover|restart)
$0 stop || exit $OCF_ERR_GENERIC
$0 start || exit $OCF_ERR_GENERIC
- rv=0
;;
meta-data)
cat `echo $0 | sed 's/^\(.*\)\.sh$/\1.metadata/'`
- rv=0
;;
validate-all|verify-all)
- ##
- # We can safely ignore clustered volume groups (VGs handled by CLVM)
- ##
- if ! clvm_check $OCF_RESKEY_vg_name; then
- ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..."
- exit 0
- fi
-
if [ -z $OCF_RESKEY_lv_name ]; then
vg_verify || exit 1
else
lv_verify || exit 1
fi
- rv=0
;;
*)
echo "usage: $0 {start|status|monitor|stop|restart|meta-data|validate-all}"
diff --git a/rgmanager/src/resources/lvm_by_lv.sh b/rgmanager/src/resources/lvm_by_lv.sh
index 54e67bf..759062a 100644
--- a/rgmanager/src/resources/lvm_by_lv.sh
+++ b/rgmanager/src/resources/lvm_by_lv.sh
@@ -82,10 +82,22 @@ lv_activate_resilient()
fi
}
+lv_status_clustered()
+{
+ #
+ # Check if device is active
+ #
+ if [[ ! $(lvs -o attr --noheadings $lv_path) =~ ....a. ]]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
# lv_status
#
# Is the LV active?
-lv_status()
+lv_status_single()
{
declare lv_path="$OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
declare dev="/dev/$lv_path"
@@ -148,6 +160,16 @@ lv_status()
return $OCF_SUCCESS
}
+function lv_status
+{
+ # We pass in the VG name to see of the logical volume is clustered
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ lv_status_clustered
+ else
+ lv_status_single
+ fi
+}
+
# lv_activate_and_tag
lv_activate_and_tag()
{
@@ -315,7 +337,29 @@ lv_activate()
return $OCF_SUCCESS
}
-function lv_start
+function lv_start_clustered
+{
+ if ! lvchange -aey $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name; then
+ ocf_log err "Failed to activate logical volume, $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+ ocf_log notice "Attempting cleanup of $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+
+ if ! lvconvert --repair --use-policies $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name; then
+ ocf_log err "Failed to cleanup $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+ return $OCF_ERR_GENERIC
+ fi
+
+ if ! lvchange -aey $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name; then
+ ocf_log err "Failed second attempt to activate $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+ return $OCF_ERR_GENERIC
+ fi
+
+ ocf_log notice "Second attempt to activate $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name successful"
+ return $OCF_SUCCESS
+ fi
+ return $OCF_SUCCESS
+}
+
+function lv_start_single
{
if ! lvs $OCF_RESKEY_vg_name >& /dev/null; then
lv_count=0
@@ -336,7 +380,22 @@ function lv_start
return 0
}
-function lv_stop
+function lv_start
+{
+ # We pass in the VG name to see of the logical volume is clustered
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ lv_start_clustered
+ else
+ lv_start_single
+ fi
+}
+
+function lv_stop_clustered
+{
+ lvchange -aln $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name
+}
+
+function lv_stop_single
{
if ! lv_activate stop; then
return 1
@@ -344,3 +403,13 @@ function lv_stop
return 0
}
+
+function lv_stop
+{
+ # We pass in the VG name to see of the logical volume is clustered
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ lv_stop_clustered
+ else
+ lv_stop_single
+ fi
+}
diff --git a/rgmanager/src/resources/lvm_by_vg.sh b/rgmanager/src/resources/lvm_by_vg.sh
index 0c1bf0b..f0ca671 100644
--- a/rgmanager/src/resources/lvm_by_vg.sh
+++ b/rgmanager/src/resources/lvm_by_vg.sh
@@ -66,14 +66,18 @@ function strip_and_add_tag
return $OCF_SUCCESS
}
+function vg_status_clustered
+{
+ return $OCF_SUCCESS
+}
+
# vg_status
#
# Are all the LVs active?
-function vg_status
+function vg_status_single
{
local i
local dev
- local readdev
local my_name=$(local_node_name)
#
@@ -125,13 +129,88 @@ function vg_status
return $OCF_SUCCESS
}
+##
+# Main status function for volume groups
+##
+function vg_status
+{
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ vg_status_clustered
+ else
+ vg_status_single
+ fi
+}
+
function vg_verify
{
# Anything to verify?
return $OCF_SUCCESS
}
-function vg_start
+function vg_start_clustered
+{
+ local a
+ local results
+ local all_pvs
+ local resilience
+
+ ocf_log info "Starting volume group, $OCF_RESKEY_vg_name"
+
+ if ! vgchange -aey $OCF_RESKEY_vg_name; then
+ ocf_log err "Failed to activate volume group, $OCF_RESKEY_vg_name"
+ ocf_log notice "Attempting cleanup of $OCF_RESKEY_vg_name"
+
+ if ! vgreduce --removemissing $OCF_RESKEY_vg_name; then
+ ocf_log err "Failed to make $OCF_RESKEY_vg_name consistent"
+ return $OCF_ERR_GENERIC
+ fi
+
+ if ! vgchange -aey $OCF_RESKEY_vg_name; then
+ ocf_log err "Failed second attempt to activate $OCF_RESKEY_vg_name"
+ return $OCF_ERR_GENERIC
+ fi
+
+ ocf_log notice "Second attempt to activate $OCF_RESKEY_vg_name successful"
+ return $OCF_SUCCESS
+ else
+ # The activation commands succeeded, but did they do anything?
+ # Make sure all the logical volumes are active
+ results=(`lvs -o name,attr --noheadings 2> /dev/null $OCF_RESKEY_vg_name`)
+ a=0
+ while [ ! -z ${results[$a]} ]; do
+ if [[ ! ${results[$(($a + 1))]} =~ ....a. ]]; then
+ all_pvs=(`pvs --noheadings -o name 2> /dev/null`)
+ resilience=" --config devices{filter=["
+ for i in ${all_pvs[*]}; do
+ resilience=$resilience'"a|'$i'|",'
+ done
+ resilience=$resilience"\"r|.*|\"]}"
+
+ vgchange -aey $OCF_RESKEY_vg_name $resilience
+ break
+ fi
+ a=$(($a + 2))
+ done
+
+ # We need to check the LVs again if we made the command resilient
+ if [ ! -z $resilience ]; then
+ results=(`lvs -o name,attr --noheadings $OCF_RESKEY_vg_name $resilience 2> /dev/null`)
+ a=0
+ while [ ! -z ${results[$a]} ]; do
+ if [[ ! ${results[$(($a + 1))]} =~ ....a. ]]; then
+ ocf_log err "Failed to activate $OCF_RESKEY_vg_name"
+ return $OCF_ERR_GENERIC
+ fi
+ a=$(($a + 2))
+ done
+ ocf_log err "Orphan storage device in $OCF_RESKEY_vg_name slowing operations"
+ fi
+ fi
+
+ return $OCF_SUCCESS
+}
+
+function vg_start_single
{
local a
local results
@@ -219,7 +298,55 @@ function vg_start
return $OCF_SUCCESS
}
-function vg_stop
+##
+# Main start function for volume groups
+##
+function vg_start
+{
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ vg_start_clustered
+ else
+ vg_start_single
+ fi
+}
+
+function vg_stop_clustered
+{
+ local a
+ local results
+ typeset self_fence=""
+
+ case ${OCF_RESKEY_self_fence} in
+ "yes") self_fence=1 ;;
+ 1) self_fence=1 ;;
+ *) self_fence="" ;;
+ esac
+
+ # Shut down the volume group
+ # Do we need to make this resilient?
+ vgchange -aln $OCF_RESKEY_vg_name
+
+ # Make sure all the logical volumes are inactive
+ results=(`lvs -o name,attr --noheadings $OCF_RESKEY_vg_name 2> /dev/null`)
+ a=0
+ while [ ! -z ${results[$a]} ]; do
+ if [[ ${results[$(($a + 1))]} =~ ....a. ]]; then
+ if [ "$self_fence" ]; then
+ ocf_log err "Unable to deactivate $lv_path REBOOT"
+ sync
+ reboot -fn
+ else
+ ocf_log err "Logical volume $OCF_RESKEY_vg_name/${results[$a]} failed to shutdown"
+ fi
+ return $OCF_ERR_GENERIC
+ fi
+ a=$(($a + 2))
+ done
+
+ return $OCF_SUCCESS
+}
+
+function vg_stop_single
{
local a
local results
@@ -260,3 +387,15 @@ function vg_stop
return $OCF_SUCCESS
}
+
+##
+# Main stop function for volume groups
+##
+function vg_stop
+{
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ vg_stop_clustered
+ else
+ vg_stop_single
+ fi
+}
14 years
cluster: STABLE3 - resource-agents: Clean up file system agents
by Lon Hohberger
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: a6b79cab22245bb7f87e10afd1b2a294fcecc82d
Parent: fa24b460c51aa0c47d0842703feea8bca0ed66b7
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Wed Apr 28 12:50:24 2010 -0400
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Wed Apr 28 12:51:13 2010 -0400
resource-agents: Clean up file system agents
- Make mountpoints with spaces work universally
- Use fuser -kvm in all agents to make force_unmount
work
- Eliminate duplicate code
Resolves: rhbz#581533 rhbz#582753 rhbz#582754
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/Makefile | 2 +-
rgmanager/src/resources/clusterfs.sh | 608 +-------------------
rgmanager/src/resources/fs.sh.in | 797 +-------------------------
rgmanager/src/resources/netfs.sh | 368 ++-----------
rgmanager/src/resources/utils/fs-lib.sh | 942 +++++++++++++++++++++++++++++++
5 files changed, 1038 insertions(+), 1679 deletions(-)
diff --git a/rgmanager/src/resources/Makefile b/rgmanager/src/resources/Makefile
index 049f3cb..9f8265f 100644
--- a/rgmanager/src/resources/Makefile
+++ b/rgmanager/src/resources/Makefile
@@ -27,7 +27,7 @@ GENERAL_TARGETS=ocf-shellfuncs svclib_nfslock lvm_by_lv.sh lvm_by_vg.sh
UTIL_TARGETS= \
utils/ra-skelet.sh utils/messages.sh \
utils/httpd-parse-config.pl utils/tomcat-parse-config.pl \
- utils/member_util.sh
+ utils/member_util.sh utils/fs-lib.sh
$(TARGET1):
mkdir -p utils
diff --git a/rgmanager/src/resources/clusterfs.sh b/rgmanager/src/resources/clusterfs.sh
index f90f865..06214d5 100644
--- a/rgmanager/src/resources/clusterfs.sh
+++ b/rgmanager/src/resources/clusterfs.sh
@@ -1,37 +1,12 @@
#!/bin/bash
#
-# File system (normal) mount/umount/fsck/etc. agent
+# Cluster File System mount/umount/fsck/etc. agent
#
-LC_ALL=C
-LANG=C
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-export LC_ALL LANG PATH
+. $(dirname $0)/utils/fs-lib.sh
-#
-# XXX todo - search and replace on these
-#
-SUCCESS=0
-FAIL=2
-YES=0
-NO=1
-YES_STR="yes"
-
-# Grab nfs lock tricks if available
-export NFS_TRICKS=1
-if [ -f "$(dirname $0)/svclib_nfslock" ]; then
- . $(dirname $0)/svclib_nfslock
- NFS_TRICKS=0
-else
- unset OCF_RESKEY_nfslock
-fi
-
-
-. $(dirname $0)/ocf-shellfuncs
-
-
-meta_data()
+do_metadata()
{
cat <<EOT
<?xml version="1.0" ?>
@@ -182,86 +157,6 @@ EOT
}
-verify_name()
-{
- [ -n "$OCF_RESKEY_name" ] || exit $OCF_ERR_ARGS
-}
-
-
-verify_mountpoint()
-{
- if [ -z "$OCF_RESKEY_mountpoint" ]; then
- ocf_log err "No mount point specified."
- return $OCF_ERR_ARGS
- fi
-
- if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
- ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "
- "created at mount time."
- return 0
- fi
-
- [ -d "$OCF_RESKEY_mountpoint" ] && return 0
-
- ocf_log err "$OCF_RESKEY_mountpoint is not a directory"
- return $OCF_ERR_ARGS
-}
-
-
-real_device()
-{
- declare dev=$1
- declare realdev
-
- [ -z "$dev" ] && return 1
-
- if [ -h "$dev" ]; then
- realdev=$(readlink -f $dev)
- if [ $? -ne 0 ]; then
- return 1
- fi
- echo $realdev
- return 0
- fi
-
- if [ -b "$dev" ]; then
- echo $dev
- return 0
- fi
-
- realdev=$(findfs $dev 2> /dev/null)
- if [ -n "$realdev" ] && [ -b "$realdev" ]; then
- echo $realdev
- return 0
- fi
-
- return 1
-}
-
-
-verify_device()
-{
- declare realdev
-
- if [ -z "$OCF_RESKEY_device" ]; then
- ocf_log err "No device or label specified."
- return $OCF_ERR_ARGS
- fi
-
- realdev=$(real_device $OCF_RESKEY_device)
- if [ -n "$realdev" ]; then
- if [ "$realdev" != "$OCF_RESKEY_device" ]; then
- echo "Specified $OCF_RESKEY_device maps to $realdev"
- fi
- return $OCF_SUCCESS
- fi
-
- ocf_log "Device or label \"$OCF_RESKEY_device\" not valid"
-
- return $OCF_ERR_ARGS
-}
-
-
verify_fstype()
{
# Auto detect?
@@ -328,7 +223,7 @@ verify_options()
}
-verify_all()
+do_verify()
{
verify_name || return $OCF_ERR_ARGS
verify_fstype || return $OCF_ERR_ARGS
@@ -338,361 +233,7 @@ verify_all()
}
-#
-# mountInUse device mount_point
-#
-# Check to see if either the device or mount point are in use anywhere on
-# the system. It is not required that the device be mounted on the named
-# moint point, just if either are in use.
-#
-mountInUse () {
- typeset mp tmp_mp
- typeset dev tmp_dev
- typeset junk
-
- if [ $# -ne 2 ]; then
- ocf_log err "Usage: mountInUse device mount_point".
- return $FAIL
- fi
-
- dev=$1
- mp=$2
-
- while read tmp_dev tmp_mp junk; do
- if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
- return $YES
- fi
-
- if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
- return $YES
- fi
- done < <(mount | awk '{print $1,$3}')
-
- return $NO
-}
-
-
-#
-# isMounted device mount_point
-#
-# Check to see if the device is mounted. Print a warning if its not
-# mounted on the directory we expect it to be mounted on.
-#
-isMounted () {
-
- typeset mp tmp_mp
- typeset dev tmp_dev
-
- if [ $# -ne 2 ]; then
- ocf_log err "Usage: isMounted device mount_point"
- return $FAIL
- fi
-
- dev=$(real_device $1)
- if [ -z "$dev" ]; then
- ocf_log err "isMounted: Could not match $1 with a real device"
- return $FAIL
- fi
- mp=$(readlink -f $2)
-
- while read tmp_dev tmp_mp
- do
- #echo "spec=$1 dev=$dev tmp_dev=$tmp_dev"
- tmp_dev=$(real_device $tmp_dev)
-
- if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
- #
- # Check to see if its mounted in the right
- # place
- #
- if [ -n "$tmp_mp" -a "$tmp_mp" != "$mp" ]; then
- ocf_log warn "\
-Device $dev is mounted on $tmp_mp instead of $mp"
- fi
- return $YES
- fi
- done < <(mount | awk '{print $1,$3}')
-
- return $NO
-}
-
-
-#
-# isAlive mount_point
-#
-# Check to see if mount_point is alive (testing read/write)
-#
-isAlive()
-{
- declare errcode
- declare mount_point
- declare file=".writable_test.$(hostname)"
- declare rw
-
- if [ $# -ne 1 ]; then
- ocf_log err "Usage: isAlive mount_point"
- return $FAIL
- fi
- mount_point=$1
-
- test -d $mount_point
- if [ $? -ne 0 ]; then
- ocf_log err "$mount_point is not a directory"
- return $FAIL
- fi
-
- [ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
-
- # depth 10 test (read test)
- ls $mount_point > /dev/null 2> /dev/null
- errcode=$?
- if [ $errcode -ne 0 ]; then
- ocf_log err "clusterfs:${OCF_RESKEY_name}: isAlive failed read test on [$mount_point]. Return code: $errcode"
- return $NO
- fi
-
- [ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
-
- # depth 20 check (write test)
- rw=$YES
- for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
- if [ "$o" = "ro" ]; then
- rw=$NO
- fi
- done
- if [ $rw -eq $YES ]; then
- file=$mount_point/$file
- while true; do
- if [ -e "$file" ]; then
- file=${file}_tmp
- continue
- else
- break
- fi
- done
- touch $file > /dev/null 2> /dev/null
- errcode=$?
- if [ $errcode -ne 0 ]; then
- ocf_log err "clusterfs:${OCF_RESKEY_name}: isAlive failed write test on [$mount_point]. Return code: $errcode"
- return $NO
- fi
- rm -f $file > /dev/null 2> /dev/null
- fi
-
- return $YES
-}
-
-
-#
-# startFilesystem
-#
-startFilesystem() {
- typeset -i ret_val=$SUCCESS
- typeset mp="" # mount point
- typeset dev="" # device
- typeset fstype=""
- typeset opts=""
- typeset device_in_use=""
- typeset mount_options=""
-
- #
- # Get the mount point, if it exists. If not, no need to continue.
- #
- mp=${OCF_RESKEY_mountpoint}
- case "$mp" in
- ""|"[ ]*") # nothing to mount
- return $SUCCESS
- ;;
- /*) # found it
- ;;
- *) # invalid format
- ocf_log err \
-"startFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
- return $FAIL
- ;;
- esac
-
- #
- # Get the device
- #
- dev=$(real_device $OCF_RESKEY_device)
- if [ -z "$dev" ]; then
- ocf_log err "\
-startFilesystem: Could not match $OCF_RESKEY_device with a real device"
- return $FAIL
- fi
-
- #
- # Ensure we've got a valid directory
- #
- if [ -e "$mp" ]; then
- if ! [ -d "$mp" ]; then
- ocf_log err "\
-startFilesystem: Mount point $mp exists but is not a directory"
- return $FAIL
- fi
- else
- ocf_log info "\
-startFilesystem: Creating mount point $mp for device $dev"
- mkdir -p "$mp"
- ret_val=$?
- if [ $ret_val -ne 0 ]; then
- ocf_log err "\
-startFilesystem: Unable to create $mp. Error code: $ret_val"
- return $OCF_ERR_GENERIC
- fi
- fi
-
- #
- # Get the filesystem type, if specified.
- #
- fstype_option=""
- fstype=${OCF_RESKEY_fstype}
- case "$fstype" in
- ""|"[ ]*")
- fstype=""
- ;;
- *) # found it
- fstype_option="-t $fstype"
- ;;
- esac
-
- #
- # See if the device is already mounted.
- #
- isMounted $dev $mp
- case $? in
- $YES) # already mounted
- ocf_log debug "$dev already mounted"
- return $SUCCESS
- ;;
- $NO) # not mounted, continue
- ;;
- $FAIL)
- return $FAIL
- ;;
- esac
-
-
- #
- # Make sure that neither the device nor the mount point are mounted
- # (i.e. they may be mounted in a different location). The'mountInUse'
- # function checks to see if either the device or mount point are in
- # use somewhere else on the system.
- #
- mountInUse $dev $mp
- case $? in
- $YES) # uh oh, someone is using the device or mount point
- ocf_log err "\
-Cannot mount $dev on $mp, the device or mount point is already in use!"
- return $FAIL
- ;;
- $NO) # good, no one else is using it
- ;;
- $FAIL)
- return $FAIL
- ;;
- *)
- ocf_log err "Unknown return from mountInUse"
- return $FAIL
- ;;
- esac
-
- #
- # Get the mount options, if they exist.
- #
- mount_options=""
- opts=${OCF_RESKEY_options}
- case "$opts" in
- ""|"[ ]*")
- opts=""
- ;;
- *) # found it
- mount_options="-o $opts"
- ;;
- esac
-
- #
- # Mount the device
- #
- ocf_log debug "mount $fstype_option $mount_options $dev $mp"
- mount $fstype_option $mount_options $dev $mp
- ret_val=$?
- if [ $ret_val -ne 0 ]; then
- ocf_log err "\
-'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val"
- return $FAIL
- fi
-
- return $SUCCESS
-}
-
-
-#
-# stopFilesystem serviceID deviceID
-#
-# Run the stop actions
-#
-stopFilesystem() {
- typeset -i ret_val=0
- typeset -i try=1
- typeset -i max_tries=3 # how many times to try umount
- typeset -i sleep_time=2 # time between each umount failure
- typeset -i refs=0
- typeset done=""
- typeset umount_failed=""
- typeset force_umount=""
- typeset self_fence=""
- typeset fstype=""
-
-
- #
- # Get the mount point, if it exists. If not, no need to continue.
- #
- mp=${OCF_RESKEY_mountpoint}
- case "$mp" in
- ""|"[ ]*") # nothing to mount
- return $SUCCESS
- ;;
- /*) # found it
- ;;
- *) # invalid format
- ocf_log err \
-"stopFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
- return $FAIL
- ;;
- esac
-
- #
- # Get the device
- #
- dev=$(real_device $OCF_RESKEY_device)
- if [ -z "$dev" ]; then
- ocf_log err "\
-stop: Could not match $OCF_RESKEY_device with a real device"
- return $FAIL
- fi
-
-
- #
- # Get the force unmount setting if there is a mount point.
- #
- if [ -n "$mp" ]; then
- case ${OCF_RESKEY_force_unmount} in
- $YES_STR) force_umount=$YES ;;
- 1) force_umount=$YES ;;
- *) force_umount="" ;;
- esac
- fi
-
- if [ -n "$mp" ]; then
- case ${OCF_RESKEY_self_fence} in
- $YES_STR) self_fence=$YES ;;
- 1) self_fence=$YES ;;
- *) self_fence="" ;;
- esac
- fi
-
+do_pre_unmount() {
#
# Check the rgmanager-supplied reference count if one exists.
# If the reference count is <= 1, we can safely proceed
@@ -701,10 +242,15 @@ stop: Could not match $OCF_RESKEY_device with a real device"
refs=$OCF_RESKEY_RGMANAGER_meta_refcnt
if [ $refs -gt 0 ]; then
ocf_log debug "Not unmounting $OCF_RESOURCE_INSTANCE - still in use by $refs other service(s)"
- return $OCF_SUCCESS
+ return 2
fi
fi
+ if [ -z "$force_umount" ]; then
+ ocf_log debug "Not umounting $dev (clustered file system)"
+ return 2
+ fi
+
#
# Always do this hackery on clustered file systems.
#
@@ -723,135 +269,7 @@ stop: Could not match $OCF_RESKEY_device with a real device"
# Always invalidate buffers on clusterfs resources
clubufflush -f $dev
- if [ -z "$force_umount" ]; then
- ocf_log debug "Not umounting $dev (clustered file system)"
- return $SUCCESS
- fi
-
- #
- # Unmount the device.
- #
- while [ ! "$done" ]; do
- isMounted $dev $mp
- case $? in
- $NO)
- ocf_log info "$dev is not mounted"
- umount_failed=
- done=$YES
- ;;
- $FAIL)
- return $FAIL
- ;;
- $YES)
- sync; sync; sync
- ocf_log info "unmounting $dev ($mp)"
-
- umount $mp
- if [ $? -eq 0 ]; then
- umount_failed=
- done=$YES
- continue
- fi
-
- umount_failed=yes
-
- if [ "$force_umount" ]; then
- if [ $try -eq 1 ]; then
- fuser -TERM -kvm "$mp"
- else
- fuser -kvm "$mp"
- fi
- fi
-
- if [ $try -ge $max_tries ]; then
- done=$YES
- else
- sleep $sleep_time
- let try=try+1
- fi
- ;;
- *)
- return $FAIL
- ;;
- esac
-
- if [ $try -ge $max_tries ]; then
- done=$YES
- else
- sleep $sleep_time
- let try=try+1
- fi
- done # while
-
- if [ -n "$umount_failed" ]; then
- ocf_log err "'umount $mp' failed, error=$ret_val"
-
- if [ "$self_fence" ]; then
- ocf_log alert "umount failed - REBOOTING"
- sync
- reboot -fn
- fi
- return $FAIL
- fi
-
- return $SUCCESS
+ return 0
}
-
-case $1 in
-start)
- declare tries=0
- declare rv
-
- while [ $tries -lt 3 ]; do
- startFilesystem
- rv=$?
- if [ $rv -eq 0 ]; then
- exit 0
- fi
-
- ((tries++))
- sleep 3
- done
- exit $rv
- ;;
-stop)
- stopFilesystem
- exit $?
- ;;
-status|monitor)
- isMounted ${OCF_RESKEY_device} ${OCF_RESKEY_mountpoint}
- [ $? -ne $YES ] && exit $OCF_ERR_GENERIC
-
- isAlive ${OCF_RESKEY_mountpoint}
- [ $? -ne $YES ] && exit $OCF_ERR_GENERIC
-
- exit 0
- ;;
-restart)
- stopFilesystem
- if [ $? -ne 0 ]; then
- exit $OCF_ERR_GENERIC
- fi
-
- startFilesystem
- if [ $? -ne 0 ]; then
- exit $OCF_ERR_GENERIC
- fi
-
- exit 0
- ;;
-meta-data)
- meta_data
- exit 0
- ;;
-validate-all)
- verify_all
- ;;
-*)
- echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
- exit $OCF_ERR_UNIMPLEMENTED
- ;;
-esac
-
-exit 0
+main $*
diff --git a/rgmanager/src/resources/fs.sh.in b/rgmanager/src/resources/fs.sh.in
index ffa721f..b63d53b 100644
--- a/rgmanager/src/resources/fs.sh.in
+++ b/rgmanager/src/resources/fs.sh.in
@@ -4,75 +4,9 @@
# File system (normal) mount/umount/fsck/etc. agent
#
-LC_ALL=C
-LANG=C
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-export LC_ALL LANG PATH
+. $(dirname $0)/utils/fs-lib.sh
-#
-# XXX todo - search and replace on these
-#
-SUCCESS=0
-FAIL=2
-YES=0
-NO=1
-YES_STR="yes"
-INVALIDATEBUFFERS="/bin/true"
-
-#
-# Using a global to contain the return value saves
-# clone() operations. This is important to reduce
-# resource consumption during status checks.
-#
-# There is no way to return a string from a function
-# in bash without cloning the process, which is exactly
-# what we are trying to avoid. So, we have to resort
-# to using a dedicated global variable. This one is
-# for the real_device() function below.
-#
-declare REAL_DEVICE
-
-#
-# Stub ocf_log function for when we are using
-# quick_status, since ocf_log generally forks (and
-# sourcing ocf-shellfuncs forks -a lot-).
-#
-ocf_log()
-{
- echo $*
-}
-
-#
-# Assume NFS_TRICKS are not available until we are
-# proved otherwise.
-#
-export NFS_TRICKS=1
-
-#
-# Quick status doesn't fork() or clone() when using
-# device files directly. (i.e. not symlinks, LABEL= or
-# UUID=
-#
-if [ "$1" = "status" -o "$1" = "monitor" ] &&
- [ "$OCF_RESKEY_quick_status" = "1" ]; then
- echo Using Quick Status
-
- # XXX maybe we can make ocf-shellfuncs have a 'quick' mode too?
- export OCF_SUCCESS=0
- export OCF_ERR_GENERIC=1
-else
- #
- # Grab nfs lock tricks if available
- #
- if [ -f "$(dirname $0)/svclib_nfslock" ]; then
- . $(dirname $0)/svclib_nfslock
- NFS_TRICKS=0
- fi
-
- . $(dirname $0)/ocf-shellfuncs
-fi
-
-meta_data()
+do_metadata()
{
cat <<EOT
<?xml version="1.0" encoding="ISO-8859-1" ?>
@@ -254,109 +188,6 @@ meta_data()
EOT
}
-verify_name()
-{
- if [ -z "$OCF_RESKEY_name" ]; then
- ocf_log err "No file system name specified."
- return $OCF_ERR_ARGS
- fi
- return $OCF_SUCCESS
-}
-
-
-verify_mountpoint()
-{
- if [ -z "$OCF_RESKEY_mountpoint" ]; then
- ocf_log err "No mount point specified."
- return $OCF_ERR_ARGS
- fi
-
- if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
- ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "\
- "created at mount time."
- return $OCF_SUCCESS
- fi
-
- [ -d "$OCF_RESKEY_mountpoint" ] && return $OCF_SUCCESS
-
- ocf_log err "$OCF_RESKEY_mountpoint exists but is not a directory."
-
- return $OCF_ERR_ARGS
-}
-
-
-#
-# This used to be called using $(...), but doing this causes bash
-# to set up a pipe and clone(). So, the output of this function is
-# stored in the global variable REAL_DEVICE, declared previously.
-#
-real_device()
-{
- declare dev=$1
- declare realdev
-
- REAL_DEVICE=""
-
- [ -z "$dev" ] && return $OCF_ERR_ARGS
-
- # If our provided blockdev is a device, we are done
- if [ -b "$dev" ]; then
- REAL_DEVICE="$dev"
- return $OCF_SUCCESS
- fi
-
- # Oops, we have a link. Sorry, this is going to fork.
- if [ -h "$dev" ]; then
- realdev=$(readlink -f $dev)
- if [ $? -ne 0 ]; then
- return $OCF_ERR_ARGS
- fi
- REAL_DEVICE="$realdev"
- return $OCF_SUCCESS
- fi
-
- # It's not a link, it's not a block device. If it also
- # does not match UUID= or LABEL=, then findfs is not
- # going to find anything useful, so we should quit now.
- if [ "${dev/UUID=/}" = "$dev" ] &&
- [ "${dev/LABEL=/}" = "$dev" ]; then
- return $OCF_ERR_GENERIC
- fi
-
- # When using LABEL= or UUID=, we can't save a fork.
- realdev=$(findfs $dev 2> /dev/null)
- if [ -n "$realdev" ] && [ -b "$realdev" ]; then
- REAL_DEVICE="$realdev"
- return $OCF_SUCCESS
- fi
-
- return $OCF_ERR_GENERIC
-}
-
-
-verify_device()
-{
- declare realdev
-
- if [ -z "$OCF_RESKEY_device" ]; then
- ocf_log err "No device or label specified."
- return $OCF_ERR_ARGS
- fi
-
- real_device $OCF_RESKEY_device
- realdev=$REAL_DEVICE
- if [ -n "$realdev" ]; then
- if [ "$realdev" != "$OCF_RESKEY_device" ]; then
- ocf_log info "Specified $OCF_RESKEY_device maps to $realdev"
- fi
- return $OCF_SUCCESS
- fi
-
- ocf_log err "Device or label \"$OCF_RESKEY_device\" not valid"
-
- return $OCF_ERR_ARGS
-}
-
verify_fstype()
{
@@ -396,6 +227,8 @@ verify_options()
;;
esac
+ do_verify_option $OCF_RESKEY_fstype "$o"
+
case $OCF_RESKEY_fstype in
ext2|ext3|ext4)
case $o in
@@ -500,7 +333,7 @@ verify_options()
}
-verify_all()
+do_validate()
{
verify_name || return $OCF_ERR_ARGS
verify_fstype || return $OCF_ERR_ARGS
@@ -510,389 +343,9 @@ verify_all()
}
-#
-# mountInUse device mount_point
-#
-# Check to see if either the device or mount point are in use anywhere on
-# the system. It is not required that the device be mounted on the named
-# moint point, just if either are in use.
-#
-mountInUse () {
- typeset mp tmp_mp
- typeset dev tmp_dev
- typeset junka junkb junkc junkd
-
- if [ $# -ne 2 ]; then
- ocf_log err "Usage: mountInUse device mount_point".
- return $FAIL
- fi
-
- dev=$1
- mp=$2
-
- while read tmp_dev tmp_mp junka junkb junkc junkd; do
- if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
- return $YES
- fi
-
- if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
- return $YES
- fi
- done < /proc/mounts
-
- return $NO
-}
-
-
-#
-# isMounted device mount_point
-#
-# Check to see if the device is mounted. Print a warning if its not
-# mounted on the directory we expect it to be mounted on.
-#
-isMounted () {
-
- typeset mp tmp_mp
- typeset dev tmp_dev
- typeset ret=$FAIL
- typeset found=1
- typeset poss_mp
-
- if [ $# -ne 2 ]; then
- ocf_log err "Usage: isMounted device mount_point"
- return $FAIL
- fi
-
- real_device $1
- dev=$REAL_DEVICE
- if [ -z "$dev" ]; then
- ocf_log err \
- "fs (isMounted): Could not match $1 with a real device"
- return $OCF_ERR_ARGS
- fi
-
- if [ -h "$2" ]; then
- mp=$(readlink -f $2)
- else
- mp=$2
- fi
-
- ret=$NO
-
- while read tmp_dev tmp_mp junk_a junk_b junk_c junk_d
- do
- real_device $tmp_dev
- tmp_dev=$REAL_DEVICE
-
- # This bash glyph simply removes a trailing slash
- # if one exists. /a/b/ -> /a/b; /a/b -> /a/b.
- tmp_mp=${tmp_mp%/}
- mp=${mp%/}
-
- if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
- #
- # Check to see if its mounted in the right
- # place
- #
- if [ -n "$tmp_mp" ]; then
- if [ "$tmp_mp" != "$mp" ]; then
- poss_mp=$tmp_mp
- else
- found=0
- fi
- fi
- ret=$YES
- fi
- done < /proc/mounts
-
- if [ $ret -eq $YES ] && [ $found -ne 0 ]; then
- ocf_log warn "Device $dev is mounted on $poss_mp instead of $mp"
- fi
-
- return $ret
-}
-
-
-#
-# isAlive mount_point
-#
-# Check to see if mount_point is alive (testing read/write)
-#
-isAlive()
+do_pre_mount()
{
- declare errcode
- declare mount_point
- declare file=".writable_test"
- declare rw
-
- if [ $# -ne 1 ]; then
- ocf_log err "Usage: isAlive mount_point"
- return $FAIL
- fi
- mount_point=$1
-
- test -d $mount_point
- if [ $? -ne 0 ]; then
- ocf_log err "fs (isAlive): $mount_point is not a directory"
- return $FAIL
- fi
-
- [ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
-
- # depth 10 test (read test)
- ls $mount_point > /dev/null 2> /dev/null
- errcode=$?
- if [ $errcode -ne 0 ]; then
- ocf_log err "fs:${OCF_RESKEY_name}: isAlive failed read test on [$mount_point]. Return code: $errcode"
- return $NO
- fi
-
- [ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
-
- # depth 20 check (write test)
- rw=$YES
- for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
- if [ "$o" = "ro" ]; then
- rw=$NO
- fi
- done
- if [ $rw -eq $YES ]; then
- file=$mount_point/$file
- while true; do
- if [ -e "$file" ]; then
- file=${file}_tmp
- continue
- else
- break
- fi
- done
- touch $file > /dev/null 2> /dev/null
- errcode=$?
- if [ $errcode -ne 0 ]; then
- ocf_log err "fs:${OCF_RESKEY_name}: isAlive failed write test on [$mount_point]. Return code: $errcode"
- return $NO
- fi
- rm -f $file > /dev/null 2> /dev/null
- fi
-
- return $YES
-}
-
-
-#
-# Decide which quota options are enabled and return a string
-# which we can pass to quotaon
-#
-quota_opts()
-{
- declare quotaopts=""
- declare opts=$1
- declare mopt
-
- for mopt in `echo $opts | sed -e s/,/\ /g`; do
- case $mopt in
- usrquota)
- quotaopts="u$quotaopts"
- continue
- ;;
- grpquota)
- quotaopts="g$quotaopts"
- continue
- ;;
- noquota)
- quotaopts=""
- return 0
- ;;
- esac
- done
-
- echo $quotaopts
- return 0
-}
-
-
-
-#
-# Enable quotas on the mount point if the user requested them
-#
-enable_fs_quotas()
-{
- declare -i need_check=0
- declare -i rv
- declare quotaopts=""
- declare mopt
- declare opts=$1
- declare mp=$2
-
- if [ -z "`which quotaon`" ]; then
- ocf_log err "quotaon not found in $PATH"
- return $OCF_ERR_GENERIC
- fi
-
- quotaopts=$(quota_opts $opts)
-
- ocf_log info "quotaopts = $quotaopts"
-
- [ -z "$quotaopts" ] && return 0
-
- # Ok, create quota files if they don't exist
- for f in quota.user aquota.user quota.group aquota.group; do
- if ! [ -f "$mp/$f" ]; then
- ocf_log info "$mp/$f was missing - creating"
- touch "$mp/$f"
- chmod 600 "$mp/$f"
- need_check=1
- fi
- done
-
- if [ $need_check -eq 1 ]; then
- ocf_log info "Checking quota info in $mp"
- quotacheck -$quotaopts "$mp"
- fi
-
- ocf_log info "Enabling Quotas on $mp"
- ocf_log debug "quotaon -$quotaopts \"$mp\""
- quotaon -$quotaopts "$mp"
- rv=$?
- if [ $rv -ne 0 ]; then
- # Just a warning
- ocf_log warn "Unable to turn on quotas for $mp; return = $rv"
- fi
-
- return $rv
-}
-
-
-#
-# startFilesystem
-#
-startFilesystem() {
- typeset -i ret_val=$SUCCESS
- typeset mp="" # mount point
- typeset dev="" # device
- typeset fstype=""
- typeset opts=""
- typeset device_in_use=""
- typeset mount_options=""
-
- #
- # Get the mount point, if it exists. If not, no need to continue.
- #
- mp=${OCF_RESKEY_mountpoint}
- case "$mp" in
- ""|"[ ]*") # nothing to mount
- return $OCF_SUCCESS
- ;;
- /*) # found it
- ;;
- *) # invalid format
- ocf_log err \
-"startFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
- return $OCF_ERR_ARGS
- ;;
- esac
-
- #
- # Get the device
- #
- real_device $OCF_RESKEY_device
- dev=$REAL_DEVICE
- if [ -z "$dev" ]; then
- ocf_log err "\
-startFilesystem: Could not match $OCF_RESKEY_device with a real device"
- return $OCF_ERR_ARGS
- fi
-
- #
- # Ensure we've got a valid directory
- #
- if [ -e "$mp" ]; then
- if ! [ -d "$mp" ]; then
- ocf_log err"\
-startFilesystem: Mount point $mp exists but is not a directory"
- return $OCF_ERR_ARGS
- fi
- else
- ocf_log err "\
-startFilesystem: Creating mount point $mp for device $dev"
- mkdir -p "$mp"
- ret_val=$?
- if [ $ret_val -ne 0 ]; then
- ocf_log err "\
-startFilesystem: Unable to create $mp. Error code: $ret_val"
- return $OCF_ERR_GENERIC
- fi
- fi
-
- #
- # Get the filesystem type, if specified.
- #
- fstype_option=""
- fstype=${OCF_RESKEY_fstype}
- case "$fstype" in
- ""|"[ ]*")
- fstype=""
- ;;
- *) # found it
- fstype_option="-t $fstype"
- ;;
- esac
-
- #
- # See if the device is already mounted.
- #
- isMounted $dev "$mp"
- case $? in
- $YES) # already mounted
- ocf_log debug "$dev already mounted"
- return $OCF_SUCCESS
- ;;
- $NO) # not mounted, continue
- ;;
- *)
- return $FAIL
- ;;
- esac
-
-
- #
- # Make sure that neither the device nor the mount point are mounted
- # (i.e. they may be mounted in a different location). The'mountInUse'
- # function checks to see if either the device or mount point are in
- # use somewhere else on the system.
- #
- mountInUse $dev "$mp"
- case $? in
- $YES) # uh oh, someone is using the device or mount point
- ocf_log err "\
-Cannot mount $dev on $mp, the device or mount point is already in use!"
- return $FAIL
- ;;
- $NO) # good, no one else is using it
- ;;
- $FAIL)
- return $FAIL
- ;;
- *)
- ocf_log err "Unknown return from mountInUse"
- return $FAIL
- ;;
- esac
-
- #
- # Get the mount options, if they exist.
- #
- mount_options=""
- opts=${OCF_RESKEY_options}
- case "$opts" in
- ""|"[ ]*")
- opts=""
- ;;
- *) # found it
- mount_options="-o $opts"
- ;;
- esac
-
+ declare fstype="$OCF_RESKEY_fstype"
#
# Check to determine if we need to fsck the filesystem.
@@ -936,24 +389,15 @@ Unknown file system type '$fstype' for device $dev. Assuming fsck is required."
'fsck -p $dev' failed, error=$ret_val; check $fsck_log for errors"
ocf_log debug "Invalidating buffers for $dev"
$INVALIDATEBUFFERS -f $dev
- return $FAIL
+ return $OCF_ERR_GENERIC
fi
rm -f $fsck_log
fi
- #
- # Mount the device
- #
- ocf_log info "mounting $dev on $mp"
- ocf_log debug "mount $fstype_option $mount_options $dev $mp"
- mount $fstype_option $mount_options $dev "$mp"
- ret_val=$?
- if [ $ret_val -ne 0 ]; then
- ocf_log err "\
-'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val"
- return $FAIL
- fi
+ return 0
+}
+do_post_mount() {
#
# Create this for the NFS NLM broadcast bit
#
@@ -965,218 +409,35 @@ Unknown file system type '$fstype' for device $dev. Assuming fsck is required."
fi
fi
- enable_fs_quotas $opts "$mp"
-
- return $SUCCESS
+ return 0
}
-#
-# stopFilesystem serviceID deviceID
-#
-# Run the stop actions
-#
-stopFilesystem() {
- typeset -i ret_val=0
- typeset -i try=1
- typeset -i max_tries=3 # how many times to try umount
- typeset -i sleep_time=5 # time between each umount failure
- typeset -i nfslock_reclaim=0
- typeset done=""
- typeset umount_failed=""
- typeset force_umount=""
- typeset self_fence=""
- typeset fstype=""
- typeset quotaopts=""
-
+do_force_unmount() {
+ if [ "$OCF_RESKEY_nfslock" = "yes" ] || \
+ [ "$OCF_RESKEY_nfslock" = "1" ]; then
+ ocf_log warning "Dropping node-wide NFS locks"
+ pkill -KILL -x lockd
+ mkdir -p "$mp"/.clumanager/statd
+ # Copy out the notify list; our
+ # IPs are already torn down
+ notify_list_store "$mp"/.clumanager/statd
- #
- # Get the mount point, if it exists. If not, no need to continue.
- #
- mp=${OCF_RESKEY_mountpoint}
- case "$mp" in
- ""|"[ ]*") # nothing to mount
- return $SUCCESS
- ;;
- /*) # found it
- ;;
- *) # invalid format
- ocf_log err \
-"stopFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
- return $FAIL
- ;;
- esac
-
-
- #
- # Get the device
- #
- real_device $OCF_RESKEY_device
- dev=$REAL_DEVICE
- if [ -z "$dev" ]; then
- ocf_log err "\
-stop: Could not match $OCF_RESKEY_device with a real device"
- return $FAIL
- fi
-
- #
- # Get the force unmount setting if there is a mount point.
- #
- if [ -n "$mp" ]; then
- case ${OCF_RESKEY_force_unmount} in
- $YES_STR) force_umount=$YES ;;
- 1) force_umount=$YES ;;
- *) force_umount="" ;;
- esac
- fi
-
- if [ -n "$mp" ]; then
- case ${OCF_RESKEY_self_fence} in
- $YES_STR) self_fence=$YES ;;
- 1) self_fence=$YES ;;
- *) self_fence="" ;;
- esac
+ # Save for post-umount phase
+ export nfslock_reclaim=1
fi
- #
- # Unmount the device.
- #
- while [ ! "$done" ]; do
- isMounted $dev "$mp"
- case $? in
- $NO)
- ocf_log info "$dev is not mounted"
- umount_failed=
- done=$YES
- ;;
- $FAIL)
- return $FAIL
- ;;
- $YES)
- sync; sync; sync
- quotaopts=$(quota_opts $OCF_RESKEY_options)
- if [ -n "$quotaopts" ]; then
- ocf_log debug "Turning off quotas for $mp"
- quotaoff -$quotaopts "$mp" &> /dev/null
- fi
-
-
- ocf_log info "unmounting $mp"
- umount "$mp"
- if [ $? -eq 0 ]; then
- umount_failed=
- done=$YES
- continue
- fi
-
- umount_failed=yes
-
- if [ "$force_umount" ]; then
- if [ $try -eq 1 ]; then
- fuser -TERM -kvm "$mp"
-
- if [ "$OCF_RESKEY_nfslock" = "yes" ] || \
- [ "$OCF_RESKEY_nfslock" = "1" ]; then
- ocf_log warning \
- "Dropping node-wide NFS locks"
- pkill -KILL -x lockd
- mkdir -p "$mp"/.clumanager/statd
- # Copy out the notify list; our
- # IPs are already torn down
- notify_list_store "$mp"/.clumanager/statd
- nfslock_reclaim=1
- fi
- else
- fuser -kvm "$mp"
- fi
- fi
-
- ;;
- *)
- return $FAIL
- ;;
- esac
+ return 0
+}
- if [ $try -ge $max_tries ]; then
- done=$YES
- elif [ "$done" != "$YES" ]; then
- sleep $sleep_time
- let try=try+1
- fi
- done # while
- if [ $nfslock_reclaim -eq 1 ]; then
+do_post_unmount() {
+ if [ "$nfslock_reclaim" = "1" ]; then
# If we have this flag set, do a full reclaim broadcast
notify_list_broadcast "$mp"/.clumanager/statd
fi
- if [ -n "$umount_failed" ]; then
- ocf_log err "'umount $mp' failed, error=$ret_val"
-
- if [ "$self_fence" ]; then
- ocf_log alert "umount failed - REBOOTING"
- sync
- reboot -fn
- fi
- return $FAIL
- else
- return $SUCCESS
- fi
+ return 0
}
-
-case $1 in
-start)
- startFilesystem
- exit $?
- ;;
-stop)
- stopFilesystem
- exit $?
- ;;
-status|monitor)
- isMounted ${OCF_RESKEY_device} ${OCF_RESKEY_mountpoint}
-
- if [ $? -ne $YES ]; then
- ocf_log err "fs:${OCF_RESKEY_name}: ${OCF_RESKEY_device} is not mounted on ${OCF_RESKEY_mountpoint}"
- exit $OCF_ERR_GENERIC
- fi
-
- if [ "$OCF_RESKEY_quick_status" = "1" ]; then
- exit 0
- fi
-
- isAlive ${OCF_RESKEY_mountpoint}
- [ $? -eq $YES ] && exit 0
-
- ocf_log err "fs:${OCF_RESKEY_name}: Mount point is not accessible!"
- exit $OCF_ERR_GENERIC
- ;;
-restart)
- stopFilesystem
- if [ $? -ne 0 ]; then
- exit $OCF_ERR_GENERIC
- fi
-
- startFilesystem
- if [ $? -ne 0 ]; then
- exit $OCF_ERR_GENERIC
- fi
-
- exit 0
- ;;
-meta-data)
- meta_data
- exit 0
- ;;
-validate-all)
- verify_all
- exit $?
- ;;
-*)
- echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
- exit $OCF_ERR_UNIMPLEMENTED
- ;;
-esac
-
-exit 0
+main $*
diff --git a/rgmanager/src/resources/netfs.sh b/rgmanager/src/resources/netfs.sh
index bb749f7..53eab98 100644
--- a/rgmanager/src/resources/netfs.sh
+++ b/rgmanager/src/resources/netfs.sh
@@ -4,25 +4,9 @@
# NFS/CIFS file system mount/umount/etc. agent
#
-LC_ALL=C
-LANG=C
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-export LC_ALL LANG PATH
+. $(dirname $0)/utils/fs-lib.sh
-#
-# XXX todo - search and replace on these
-#
-SUCCESS=0
-FAIL=2
-YES=0
-NO=1
-YES_STR="yes"
-
-
-. $(dirname $0)/ocf-shellfuncs
-
-
-meta_data()
+do_metadata()
{
cat <<EOT
<?xml version="1.0" ?>
@@ -154,33 +138,6 @@ EOT
}
-verify_name()
-{
- [ -n "$OCF_RESKEY_name" ] || exit $OCF_ERR_ARGS
-}
-
-
-verify_mountpoint()
-{
- if [ -z "$OCF_RESKEY_mountpoint" ]; then
- ocf_log err "No mount point specified."
- return $OCF_ERR_ARGS
- fi
-
- if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
- ocf_log info "Mount point $OCF_RESKEY_mountpoint will be created "\
- "at mount time."
- return 0
- fi
-
- [ -d "$OCF_RESKEY_mountpoint" ] && return 0
-
- ocf_log err "$OCF_RESKEY_mountpoint is not a directory"
-
- return 1
-}
-
-
verify_host()
{
if [ -z "$OCF_RESKEY_host" ]; then
@@ -298,116 +255,45 @@ verify_options()
}
-verify_all()
+do_validate()
{
verify_name || return $OCF_ERR_ARGS
verify_fstype|| return $OCF_ERR_ARGS
verify_host || return $OCF_ERR_ARGS
verify_mountpoint || return $OCF_ERR_ARGS
verify_options || return $OCF_ERR_ARGS
+ # verify_target || return $OCF_ERR_ARGS
}
-
#
-# isMounted fullpath mount_point
+# Override real_device to use fs-lib's functions for start/stop_filesystem
#
-# Check to see if the full path is mounted where we need it.
-#
-isMounted () {
-
- typeset mp tmp_mp
- typeset fullpath tmp_fullpath
-
- if [ $# -ne 2 ]; then
- ocf_log err "Usage: isMounted host:/export mount_point"
- return $FAIL
- fi
-
- fullpath=$1
- mp=$(readlink -f $2)
-
- while read tmp_fullpath tmp_mp
- do
- if [ "$tmp_fullpath" = "$fullpath" -a \
- "$tmp_mp" = "$mp" ]; then
- return $YES
- fi
- done < <(mount | awk '{print $1,$3}')
-
- return $NO
+real_device() {
+ export REAL_DEVICE="$1"
}
+
#
-# startNFSFilesystem
+# do_mount - nfs / cifs are mounted differently than blockdevs
#
-startNFSFilesystem() {
- typeset -i ret_val=$SUCCESS
- typeset mp="" # mount point
- typeset host=""
- typeset fullpath=""
- typeset exp=""
- typeset opts=""
- typeset mount_options=""
-
- #
- # Get the mount point, if it exists. If not, no need to continue.
- #
- mp=${OCF_RESKEY_mountpoint}
- case "$mp" in
- ""|"[ ]*") # nothing to mount
- return $SUCCESS
- ;;
- /*) # found it
- ;;
- *) # invalid format
- ocf_log err \
-"startFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
- return $FAIL
- ;;
- esac
- #
- # Get the device
- #
- host=${OCF_RESKEY_host}
- exp=${OCF_RESKEY_export}
-
- fullpath=$host:$exp
+do_mount() {
+ declare opts=""
+ declare mount_options=""
+ declare ret_val
+ declare mp="$OCF_RESKEY_mountpoint"
#
- # Ensure we've got a valid directory
+ # Get the filesystem type, if specified.
#
- if [ -e "$mp" ]; then
- if ! [ -d "$mp" ]; then
- ocf_log err "\
-startFilesystem: Mount point $mp exists but is not a directory"
- return $FAIL
- fi
- else
- ocf_log info "\
-startFilesystem: Creating mount point $mp for $fullpath"
- mkdir -p "$mp"
- ret_val=$?
- if [ $ret_val -ne 0 ]; then
- ocf_log err "\
-startFilesystem: Unable to create $mp. Error code: $ret_val"
- return $OCF_ERR_GENERIC
- fi
- fi
-
- #
- # See if the mount path is already mounted.
- #
- isMounted $fullpath $mp
- case $? in
- $YES) # already mounted
- ocf_log debug "$fullpath already mounted on $mp"
- return $SUCCESS
- ;;
- $NO) # not mounted, continue
+ fstype_option=""
+ fstype=${OCF_RESKEY_fstype}
+ case "$fstype" in
+ ""|"[ ]*")
+ fstype=""
;;
- $FAIL)
- return $FAIL
+ *) # found it
+ fstype_option="-t $fstype"
;;
esac
@@ -425,154 +311,37 @@ startFilesystem: Unable to create $mp. Error code: $ret_val"
;;
esac
- #
- # Mount the NFS export
- #
- ocf_log debug "mount $fstype_option $mount_options $fullpath $mp"
-
case $OCF_RESKEY_fstype in
- nfs|nfs4)
- mount -t $OCF_RESKEY_fstype $mount_options $host:$exp $mp
- ;;
- cifs)
- mount -t $OCF_RESKEY_fstype $mount_options //$host/$exp $mp
- ;;
+ nfs|nfs4)
+ mount -t $OCF_RESKEY_fstype $mount_options $OCF_RESKEY_host:"$OCF_RESKEY_export" "$mp"
+ ;;
+ cifs)
+ mount -t $OCF_RESKEY_fstype $mount_options //$OCF_RESKEY_host/"$OCF_RESKEY_export" "$mp"
+ ;;
esac
ret_val=$?
if [ $ret_val -ne 0 ]; then
ocf_log err "\
-'mount $fstype_option $mount_options $fullpath $mp' failed, error=$ret_val"
- return $FAIL
+'mount $fstype_option $mount_options $OCF_RESKEY_host:$OCF_RESKEY_export $mp' failed, error=$ret_val"
+ return 1
fi
- return $SUCCESS
+ return 0
}
-#
-# stopFilesystem serviceID deviceID
-#
-# Run the stop actions
-#
-stopNFSFilesystem() {
- typeset -i ret_val=0
- typeset -i try=1
- typeset -i max_tries=3 # how many times to try umount
- typeset -i sleep_time=2 # time between each umount failure
- typeset done=""
- typeset umount_failed=""
- typeset no_umount=""
- typeset force_umount=""
- typeset fstype=""
-
-
- #
- # Get the mount point, if it exists. If not, no need to continue.
- #
- mp=${OCF_RESKEY_mountpoint}
- case "$mp" in
- ""|"[ ]*") # nothing to mount
- return $SUCCESS
- ;;
- /*) # found it
- ;;
- *) # invalid format
- ocf_log err \
-"stopNFSFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
- return $FAIL
- ;;
- esac
-
- #
- # Get the host/path
- #
- fullpath="${OCF_RESKEY_host}:${OCF_RESKEY_export}"
-
- #
- # Get the force unmount setting if there is a mount point.
- #
- if [ -n "$mp" ]; then
- case ${OCF_RESKEY_force_unmount} in
- $YES_STR) force_umount="$YES" ;;
- 1) force_umount="$YES" ;;
- *) force_umount="" ;;
- esac
- fi
-
- #
- # Unmount
- #
- while [ ! "$done" ]; do
- isMounted $fullpath $mp
- case $? in
- $NO)
- ocf_log debug "$fullpath is not mounted"
- umount_failed=
- done=$YES
- ;;
- $FAIL)
- return $FAIL
- ;;
- $YES)
- case ${OCF_RESKEY_no_unmount} in
- $YES_STR) no_umount="$YES" ;;
- 1) no_umount="$YES" ;;
- *) no_umount="" ;;
- esac
-
- if [ "$no_umount" ]; then
- ocf_log info "skipping unmount operation of $mp"
- return $SUCCESS
- fi
-
- sync; sync; sync
- ocf_log info "unmounting $mp"
-
- umount $mp
- if [ $? -eq 0 ]; then
- umount_failed=
- done=$YES
- continue
- fi
-
- umount_failed=yes
-
- if [ "$force_umount" ]; then
- if [ $try -eq 1 ]; then
- fuser -TERM -kvm "$mp"
- else
- fuser -kvm "$mp"
- fi
- fi
-
-
- if [ $try -ge $max_tries ]; then
- done=$YES
- else
- sleep $sleep_time
- let try=try+1
- fi
+do_force_unmount() {
+ case $OCF_RESKEY_fstype in
+ nfs|nfs4)
+ ocf_log warning "Calling 'umount -f $mp'"
+ umount -f "$OCF_RESKEY_mountpoint"
;;
*)
- return $FAIL
;;
esac
- if [ $try -ge $max_tries ]; then
- done=$YES
- else
- sleep $sleep_time
- let try=try+1
- fi
- done # while
- if [ -n "$umount_failed" ]; then
- ocf_log err "'umount $fullpath' failed ($mp), error=$ret_val"
-
- return $FAIL
- fi
-
- return $SUCCESS
+ return 0 # Returning 0 lets stop_filesystem do add'l checks
}
@@ -582,57 +351,26 @@ populate_defaults()
export OCF_RESKEY_fstype=nfs
fi
- if [ -z "$OCF_RESKEY_options" ]; then
- export OCF_RESKEY_options=sync,soft,noac
- fi
+
+ case $OCF_RESKEY_fstype in
+ nfs|nfs4)
+ export OCF_RESKEY_device="$OCF_RESKEY_host:$OCF_RESKEY_export"
+ if [ -z "$OCF_RESKEY_options" ]; then
+ export OCF_RESKEY_options=sync,soft,noac
+ fi
+ ;;
+ cifs)
+ export OCF_RESKEY_device="//$OCF_RESKEY_host/$OCF_RESKEY_export"
+ if [ -z "$OCF_RESKEY_options" ]; then
+ export OCF_RESKEY_options=guest
+ fi
+ ;;
+ esac
}
#
# Main...
#
-
populate_defaults
-
-case $1 in
-start)
- startNFSFilesystem
- exit $?
- ;;
-stop)
- stopNFSFilesystem
- exit $?
- ;;
-status|monitor)
- isMounted ${OCF_RESKEY_host}:${OCF_RESKEY_export} \
- ${OCF_RESKEY_mountpoint}
- exit $?
- ;;
-restart)
- stopNFSFilesystem
- if [ $? -ne 0 ]; then
- exit $OCF_ERR_GENERIC
- fi
-
- startNFSFilesystem
- if [ $? -ne 0 ]; then
- exit $OCF_ERR_GENERIC
- fi
-
- exit 0
- ;;
-meta-data)
- meta_data
- exit 0
- ;;
-validate-all)
- verify_all
- exit $?
- ;;
-*)
- echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
- exit $OCF_ERR_UNIMPLEMENTED
- ;;
-esac
-
-exit 0
+main $*
diff --git a/rgmanager/src/resources/utils/fs-lib.sh b/rgmanager/src/resources/utils/fs-lib.sh
new file mode 100644
index 0000000..bc3877e
--- /dev/null
+++ b/rgmanager/src/resources/utils/fs-lib.sh
@@ -0,0 +1,942 @@
+#!/bin/bash
+
+#
+# File system common functions
+#
+
+LC_ALL=C
+LANG=C
+PATH=/bin:/sbin:/usr/bin:/usr/sbin
+export LC_ALL LANG PATH
+
+# Private return codes
+FAIL=2
+NO=1
+YES=0
+YES_STR="yes"
+
+[ -z "$OCF_RESOURCE_INSTANCE" ] && export OCF_RESOURCE_INSTANCE="filesystem:$OCF_RESKEY_name"
+
+#
+# Using a global to contain the return value saves
+# clone() operations. This is important to reduce
+# resource consumption during status checks.
+#
+# There is no way to return a string from a function
+# in bash without cloning the process, which is exactly
+# what we are trying to avoid. So, we have to resort
+# to using a dedicated global variable. This one is
+# for the real_device() function below.
+#
+declare REAL_DEVICE
+
+#
+# Stub ocf_log function for when we are using
+# quick_status, since ocf_log generally forks (and
+# sourcing ocf-shellfuncs forks -a lot-).
+#
+ocf_log()
+{
+ echo $*
+}
+
+#
+# Assume NFS_TRICKS are not available until we are
+# proved otherwise.
+#
+export NFS_TRICKS=1
+
+#
+# Quick status doesn't fork() or clone() when using
+# device files directly. (i.e. not symlinks, LABEL= or
+# UUID=
+#
+if [ "$1" = "status" -o "$1" = "monitor" ] &&
+ [ "$OCF_RESKEY_quick_status" = "1" ]; then
+ echo Using Quick Status
+
+ # XXX maybe we can make ocf-shellfuncs have a 'quick' mode too?
+ export OCF_SUCCESS=0
+ export OCF_ERR_GENERIC=1
+else
+ #
+ # Grab nfs lock tricks if available
+ #
+ if [ -f "$(dirname $0)/svclib_nfslock" ]; then
+ . $(dirname $0)/svclib_nfslock
+ NFS_TRICKS=0
+ fi
+
+ . $(dirname $0)/ocf-shellfuncs
+fi
+
+
+verify_name()
+{
+ if [ -z "$OCF_RESKEY_name" ]; then
+ ocf_log err "No file system name specified."
+ return $OCF_ERR_ARGS
+ fi
+ return $OCF_SUCCESS
+}
+
+
+verify_mountpoint()
+{
+ if [ -z "$OCF_RESKEY_mountpoint" ]; then
+ ocf_log err "No mount point specified."
+ return $OCF_ERR_ARGS
+ fi
+
+ if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
+ ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "\
+ "created at mount time."
+ return $OCF_SUCCESS
+ fi
+
+ [ -d "$OCF_RESKEY_mountpoint" ] && return $OCF_SUCCESS
+
+ ocf_log err "$OCF_RESKEY_mountpoint exists but is not a directory."
+
+ return $OCF_ERR_ARGS
+}
+
+
+#
+# This used to be called using $(...), but doing this causes bash
+# to set up a pipe and clone(). So, the output of this function is
+# stored in the global variable REAL_DEVICE, declared previously.
+#
+real_device()
+{
+ declare dev="$1"
+ declare realdev
+
+ REAL_DEVICE=""
+
+ [ -z "$dev" ] && return $OCF_ERR_ARGS
+
+ # If our provided blockdev is a device, we are done
+ if [ -b "$dev" ]; then
+ REAL_DEVICE="$dev"
+ return $OCF_SUCCESS
+ fi
+
+ # Oops, we have a link. Sorry, this is going to fork.
+ if [ -h "$dev" ]; then
+ realdev=$(readlink -f $dev)
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_ARGS
+ fi
+ REAL_DEVICE="$realdev"
+ return $OCF_SUCCESS
+ fi
+
+ # It's not a link, it's not a block device. If it also
+ # does not match UUID= or LABEL=, then findfs is not
+ # going to find anything useful, so we should quit now.
+ if [ "${dev/UUID=/}" = "$dev" ] &&
+ [ "${dev/LABEL=/}" = "$dev" ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ # When using LABEL= or UUID=, we can't save a fork.
+ realdev=$(findfs "$dev" 2> /dev/null)
+ if [ -n "$realdev" ] && [ -b "$realdev" ]; then
+ REAL_DEVICE="$realdev"
+ return $OCF_SUCCESS
+ fi
+
+ return $OCF_ERR_GENERIC
+}
+
+
+verify_device()
+{
+ declare realdev
+
+ if [ -z "$OCF_RESKEY_device" ]; then
+ ocf_log err "No device or label specified."
+ return $OCF_ERR_ARGS
+ fi
+
+ real_device "$OCF_RESKEY_device"
+ realdev="$REAL_DEVICE"
+ if [ -n "$realdev" ]; then
+ if [ "$realdev" != "$OCF_RESKEY_device" ]; then
+ ocf_log info "Specified $OCF_RESKEY_device maps to $realdev"
+ fi
+ return $OCF_SUCCESS
+ fi
+
+ ocf_log err "Device or label \"$OCF_RESKEY_device\" not valid"
+
+ return $OCF_ERR_ARGS
+}
+
+
+#
+# mount_in_use device mount_point
+#
+# Check to see if either the device or mount point are in use anywhere on
+# the system. It is not required that the device be mounted on the named
+# moint point, just if either are in use.
+#
+mount_in_use () {
+ declare mp tmp_mp
+ declare dev tmp_dev
+ declare junka junkb junkc junkd
+
+ if [ $# -ne 2 ]; then
+ ocf_log err "Usage: mount_in_use device mount_point".
+ return $FAIL
+ fi
+
+ dev="$1"
+ mp="$2"
+
+ while read -r tmp_dev tmp_mp junka junkb junkc junkd; do
+ # XXX fork/clone warning XXX
+ if [ "${tmp_dev:0:1}" != "-" ]; then
+ tmp_dev="$(printf "$tmp_dev")"
+ fi
+
+ if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
+ return $YES
+ fi
+
+ # Mountpoint from /proc/mounts containing spaces will
+ # have spaces represented in octal. printf takes care
+ # of this for us.
+ tmp_mp="$(printf "$tmp_mp")"
+
+ if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
+ return $YES
+ fi
+ done < /proc/mounts
+
+ return $NO
+}
+
+
+#
+# is_mounted device mount_point
+#
+# Check to see if the device is mounted. Print a warning if its not
+# mounted on the directory we expect it to be mounted on.
+#
+is_mounted () {
+
+ declare mp tmp_mp
+ declare dev tmp_dev
+ declare ret=$FAIL
+ declare found=1
+ declare poss_mp
+
+ if [ $# -ne 2 ]; then
+ ocf_log err "Usage: is_mounted device mount_point"
+ return $FAIL
+ fi
+
+ real_device "$1"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "$OCF_RESOURCE_INSTANCE: is_mounted: Could not match $1 with a real device"
+ return $OCF_ERR_ARGS
+ fi
+
+ if [ -h "$2" ]; then
+ mp="$(readlink -f $2)"
+ else
+ mp="$2"
+ fi
+
+ ret=$NO
+
+ # This bash glyph simply removes a trailing slash
+ # if one exists. /a/b/ -> /a/b; /a/b -> /a/b.
+ mp="${mp%/}"
+
+ while read -r tmp_dev tmp_mp junk_a junk_b junk_c junk_d
+ do
+ # XXX fork/clone warning XXX
+ if [ "${tmp_dev:0:1}" != "-" ]; then
+ tmp_dev="$(printf "$tmp_dev")"
+ fi
+
+ real_device "$tmp_dev"
+ tmp_dev="$REAL_DEVICE"
+
+ # XXX fork/clone warning XXX
+ # Mountpoint from /proc/mounts containing spaces will
+ # have spaces represented in octal. printf takes care
+ # of this for us.
+ tmp_mp="$(printf "$tmp_mp")"
+
+ if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
+ #
+ # Check to see if its mounted in the right
+ # place
+ #
+ if [ -n "$tmp_mp" ]; then
+ if [ "$tmp_mp" != "$mp" ]; then
+ poss_mp=$tmp_mp
+ else
+ found=0
+ fi
+ fi
+ ret=$YES
+ fi
+ done < /proc/mounts
+
+ if [ $ret -eq $YES ] && [ $found -ne 0 ]; then
+ ocf_log warn "Device $dev is mounted on $poss_mp instead of $mp"
+ fi
+
+ return $ret
+}
+
+
+#
+# is_alive mount_point
+#
+# Check to see if mount_point is alive (testing read/write)
+#
+is_alive()
+{
+ declare errcode
+ declare mount_point="$1"
+ declare file=".writable_test.$(hostname)"
+ declare rw
+
+ if [ $# -ne 1 ]; then
+ ocf_log err "Usage: is_alive mount_point"
+ return $FAIL
+ fi
+
+ [ -z "$OCF_CHECK_LEVEL" ] && export OCF_CHECK_LEVEL=0
+
+ test -d "$mount_point"
+ if [ $? -ne 0 ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: is_alive: $mount_point is not a directory"
+ return $FAIL
+ fi
+
+ [ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
+
+ # depth 10 test (read test)
+ ls "$mount_point" > /dev/null 2> /dev/null
+ errcode=$?
+ if [ $errcode -ne 0 ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: is_alive: failed read test on [$mount_point]. Return code: $errcode"
+ return $NO
+ fi
+
+ [ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
+
+ # depth 20 check (write test)
+ rw=$YES
+ for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
+ if [ "$o" = "ro" ]; then
+ rw=$NO
+ fi
+ done
+ if [ $rw -eq $YES ]; then
+ file="$mount_point"/$file
+ while true; do
+ if [ -e "$file" ]; then
+ file=${file}_tmp
+ continue
+ else
+ break
+ fi
+ done
+ touch $file > /dev/null 2> /dev/null
+ errcode=$?
+ if [ $errcode -ne 0 ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: is_alive: failed write test on [$mount_point]. Return code: $errcode"
+ return $NO
+ fi
+ rm -f $file > /dev/null 2> /dev/null
+ fi
+
+ return $YES
+}
+
+
+#
+# Decide which quota options are enabled and return a string
+# which we can pass to quotaon
+#
+quota_opts()
+{
+ declare quotaopts=""
+ declare opts="$1"
+ declare mopt
+
+ for mopt in `echo $opts | sed -e s/,/\ /g`; do
+ case $mopt in
+ quota)
+ quotaopts="gu"
+ break
+ ;;
+ usrquota)
+ quotaopts="u$quotaopts"
+ continue
+ ;;
+ grpquota)
+ quotaopts="g$quotaopts"
+ continue
+ ;;
+ noquota)
+ quotaopts=""
+ return 0
+ ;;
+ esac
+ done
+
+ echo $quotaopts
+ return 0
+}
+
+
+
+#
+# Enable quotas on the mount point if the user requested them
+#
+enable_fs_quotas()
+{
+ declare -i need_check=0
+ declare -i rv
+ declare quotaopts=""
+ declare mopt
+ declare opts="$1"
+ declare mp="$2"
+
+ if ! type quotaon &> /dev/null; then
+ ocf_log err "quotaon not found in $PATH"
+ return $OCF_ERR_GENERIC
+ fi
+
+ quotaopts=$(quota_opts $opts)
+ [ -z "$quotaopts" ] && return 0
+
+ ocf_log debug "quotaopts = $quotaopts"
+
+ # Ok, create quota files if they don't exist
+ for f in quota.user aquota.user quota.group aquota.group; do
+ if ! [ -f "$mp/$f" ]; then
+ ocf_log info "$mp/$f was missing - creating"
+ touch "$mp/$f"
+ chmod 600 "$mp/$f"
+ need_check=1
+ fi
+ done
+
+ if [ $need_check -eq 1 ]; then
+ ocf_log info "Checking quota info in $mp"
+ quotacheck -$quotaopts "$mp"
+ fi
+
+ ocf_log info "Enabling Quotas on $mp"
+ ocf_log debug "quotaon -$quotaopts \"$mp\""
+ quotaon -$quotaopts "$mp"
+ rv=$?
+ if [ $rv -ne 0 ]; then
+ # Just a warning
+ ocf_log warn "Unable to turn on quotas for $mp; return = $rv"
+ fi
+
+ return $rv
+}
+
+
+# Agent-specific actions to take before mounting
+# (if required). Typically things like fsck.
+do_pre_mount() {
+ return 0
+}
+
+# Default mount handler - for block devices
+#
+do_mount() {
+ declare dev="$1"
+ declare mp="$2"
+ declare mount_options=""
+ declare fstype_option=""
+ declare fstype
+
+ #
+ # Get the filesystem type, if specified.
+ #
+ fstype_option=""
+ fstype=${OCF_RESKEY_fstype}
+ case "$fstype" in
+ ""|"[ ]*")
+ fstype=""
+ ;;
+ *) # found it
+ fstype_option="-t $fstype"
+ ;;
+ esac
+
+ #
+ # Get the mount options, if they exist.
+ #
+ mount_options=""
+ opts=${OCF_RESKEY_options}
+ case "$opts" in
+ ""|"[ ]*")
+ opts=""
+ ;;
+ *) # found it
+ mount_options="-o $opts"
+ ;;
+ esac
+
+ #
+ # Mount the device
+ #
+ ocf_log info "mounting $dev on $mp"
+ ocf_log err "mount $fstype_option $mount_options $dev $mp"
+ mount $fstype_option $mount_options "$dev" "$mp"
+}
+
+
+# Agent-specific actions to take after mounting
+# (if required).
+do_post_mount() {
+ return 0
+}
+
+
+# Agent-specific actions to take before unmounting
+# (if required)
+do_pre_unmount() {
+ return 0
+}
+
+
+# Agent-specific actions to take after umount succeeds
+# (if required)
+do_post_unmount() {
+ return 0
+}
+
+
+# Agent-specific force-unmount logic, if required
+do_force_unmount() {
+ return 0
+}
+
+
+#
+# start_filesystem
+#
+start_filesystem() {
+ declare -i ret_val=$OCF_SUCCESS
+ declare mp="${OCF_RESKEY_mountpoint}"
+ declare dev="" # device
+ declare fstype=""
+ declare opts=""
+ declare mount_options=""
+
+ #
+ # Check if mount point was specified. If not, no need to continue.
+ #
+ case "$mp" in
+ ""|"[ ]*") # nothing to mount
+ return $OCF_SUCCESS
+ ;;
+ /*) # found it
+ ;;
+ *) # invalid format
+ ocf_log err \
+"start_filesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
+ return $OCF_ERR_ARGS
+ ;;
+ esac
+
+ #
+ # Get the device
+ #
+ real_device "$OCF_RESKEY_device"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "\
+start_filesystem: Could not match $OCF_RESKEY_device with a real device"
+ return $OCF_ERR_ARGS
+ fi
+
+ #
+ # Ensure we've got a valid directory
+ #
+ if [ -e "$mp" ]; then
+ if ! [ -d "$mp" ]; then
+ ocf_log err"\
+start_filesystem: Mount point $mp exists but is not a directory"
+ return $OCF_ERR_ARGS
+ fi
+ else
+ ocf_log err "\
+start_filesystem: Creating mount point $mp for device $dev"
+ mkdir -p "$mp"
+ ret_val=$?
+ if [ $ret_val -ne 0 ]; then
+ ocf_log err "\
+start_filesystem: Unable to create $mp. Error code: $ret_val"
+ return $OCF_ERR_GENERIC
+ fi
+ fi
+
+ #
+ # See if the device is already mounted.
+ #
+ is_mounted "$dev" "$mp"
+ case $? in
+ $YES) # already mounted
+ ocf_log debug "$dev already mounted"
+ return $OCF_SUCCESS
+ ;;
+ $NO) # not mounted, continue
+ ;;
+ *)
+ return $FAIL
+ ;;
+ esac
+
+
+ #
+ # Make sure that neither the device nor the mount point are mounted
+ # (i.e. they may be mounted in a different location). The'mount_in_use'
+ # function checks to see if either the device or mount point are in
+ # use somewhere else on the system.
+ #
+ mount_in_use "$dev" "$mp"
+ case $? in
+ $YES) # uh oh, someone is using the device or mount point
+ ocf_log err "\
+Cannot mount $dev on $mp, the device or mount point is already in use!"
+ return $FAIL
+ ;;
+ $NO) # good, no one else is using it
+ ;;
+ $FAIL)
+ return $FAIL
+ ;;
+ *)
+ ocf_log err "Unknown return from mount_in_use"
+ return $FAIL
+ ;;
+ esac
+
+ do_pre_mount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ do_mount "$dev" "$mp"
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ do_post_mount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ enable_fs_quotas "$opts" "$mp"
+
+ return $OCF_SUCCESS
+}
+
+
+#
+# stop_filesystem - unmount a file system; calls out to
+#
+stop_filesystem() {
+ declare -i ret_val=0
+ declare -i try
+ declare -i sleep_time=5 # time between each umount failure
+ declare umount_failed=""
+ declare force_umount=""
+ declare self_fence=""
+ declare quotaopts=""
+
+ #
+ # Get the mount point, if it exists. If not, no need to continue.
+ #
+ mp=${OCF_RESKEY_mountpoint}
+ case "$mp" in
+ ""|"[ ]*") # nothing to mount
+ return $OCF_SUCCESS
+ ;;
+ /*) # found it
+ ;;
+ *) # invalid format
+ ocf_log err \
+"stop_filesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
+ return $FAIL
+ ;;
+ esac
+
+ #
+ # Get the device
+ #
+ real_device "$OCF_RESKEY_device"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "\
+stop: Could not match $OCF_RESKEY_device with a real device"
+ return $FAIL
+ fi
+
+ #
+ # Get the force unmount setting if there is a mount point.
+ #
+ case ${OCF_RESKEY_force_unmount} in
+ $YES_STR) force_umount=$YES ;;
+ 1) force_umount=$YES ;;
+ *) force_umount="" ;;
+ esac
+
+ case ${OCF_RESKEY_self_fence} in
+ $YES_STR) self_fence=$YES ;;
+ 1) self_fence=$YES ;;
+ *) self_fence="" ;;
+ esac
+
+ do_pre_unmount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ #
+ # Preparations: sync, turn off quotas
+ #
+ sync
+
+ quotaopts=$(quota_opts $OCF_RESKEY_options)
+ if [ -n "$quotaopts" ]; then
+ ocf_log debug "Turning off quotas for $mp"
+ quotaoff -$quotaopts "$mp" &> /dev/null
+ fi
+
+ #
+ # Unmount the device.
+ #
+ for try in 1 2 3; do
+ if [ $try -ne 1 ]; then
+ sleep $sleep_time
+ fi
+
+ is_mounted "$dev" "$mp"
+ case $? in
+ $NO)
+ ocf_log info "$dev is not mounted"
+ umount_failed=
+ break
+ ;;
+ $YES) # fallthrough
+ ;;
+ *)
+ return $FAIL
+ ;;
+ esac
+
+ ocf_log info "unmounting $mp"
+ umount "$mp"
+ ret_val=$?
+ if [ $ret_val -eq 0 ]; then
+ umount_failed=
+ break
+ fi
+
+ ocf_log debug "umount failed: $ret_val"
+ umount_failed=yes
+
+ if [ -z "$force_umount" ]; then
+ continue
+ fi
+
+ # Force unmount: try #1: send SIGTERM
+ if [ $try -eq 1 ]; then
+ ocf_log warning "Sending SIGTERM to processes on $mp"
+ fuser -TERM -kvm "$mp"
+ continue
+ else
+ ocf_log warning "Sending SIGKILL to processes on $mp"
+ fuser -kvm "$mp"
+
+ do_force_unmount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ break
+ ;;
+ esac
+ fi
+ done # for
+
+ do_post_unmount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ if [ -n "$umount_failed" ]; then
+ ocf_log err "'umount $mp' failed, error=$ret_val"
+
+ if [ "$self_fence" ]; then
+ ocf_log alert "umount failed - REBOOTING"
+ sync
+ reboot -fn
+ fi
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+
+do_start() {
+ declare tries=0
+ declare rv
+
+ while [ $tries -lt 3 ]; do
+ start_filesystem
+ rv=$?
+ if [ $rv -eq 0 ]; then
+ return 0
+ fi
+
+ ((tries++))
+ sleep 3
+ done
+ return $rv
+}
+
+
+do_stop() {
+ stop_filesystem
+ return $?
+}
+
+
+do_monitor() {
+ is_mounted "${OCF_RESKEY_device}" "${OCF_RESKEY_mountpoint}"
+
+ if [ $? -ne $YES ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: ${OCF_RESKEY_device} is not mounted on ${OCF_RESKEY_mountpoint}"
+ return $OCF_NOT_RUNNING
+ fi
+
+ if [ "$OCF_RESKEY_quick_status" = "1" ]; then
+ return 0
+ fi
+
+ is_alive "${OCF_RESKEY_mountpoint}"
+ [ $? -eq $YES ] && return 0
+
+ ocf_log err "fs:${OCF_RESKEY_name}: Mount point is not accessible!"
+ return $OCF_ERR_GENERIC
+}
+
+
+do_restart() {
+ stop_filesystem
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ start_filesystem
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ return 0
+}
+
+
+# MUST BE OVERRIDDEN
+do_metadata() {
+ return 1
+}
+
+
+do_validate() {
+ return 1
+}
+
+
+main() {
+ case $1 in
+ start)
+ do_start
+ exit $?
+ ;;
+ stop)
+ do_stop
+ exit $?
+ ;;
+ status|monitor)
+ do_monitor
+ exit $?
+ ;;
+ restart)
+ do_restart
+ exit $?
+ ;;
+ meta-data)
+ do_metadata
+ exit $?
+ ;;
+ validate-all)
+ do_validate
+ ;;
+ *)
+ echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+ esac
+ exit 0
+}
+
14 years
dlm: master - dlm_controld.pcmk: Prevent use-of-NULL by checking the node has a valid address before adding it to configfs
by Andrew Beekhof
Gitweb: http://git.fedorahosted.org/git/dlm.git?p=dlm.git;a=commitdiff;h=6607f2d2...
Commit: 6607f2d209adb983b4642faef8a66f91ba9c727d
Parent: fae6ee3915d0d1ba3add3082ccd159955b120e45
Author: Andrew Beekhof <andrew(a)beekhof.net>
AuthorDate: Wed Apr 28 12:37:57 2010 +0200
Committer: Andrew Beekhof <andrew(a)beekhof.net>
CommitterDate: Wed Apr 28 13:55:11 2010 +0200
dlm_controld.pcmk: Prevent use-of-NULL by checking the node has a valid address before adding it to configfs
---
group/dlm_controld/pacemaker.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/group/dlm_controld/pacemaker.c b/group/dlm_controld/pacemaker.c
index 810c644..3150a1f 100644
--- a/group/dlm_controld/pacemaker.c
+++ b/group/dlm_controld/pacemaker.c
@@ -128,7 +128,7 @@ void dlm_process_node(gpointer key, gpointer value, gpointer user_data)
} else if(rc == 0) {
do_remove = TRUE;
- } else if(is_active) {
+ } else if(is_active && node->addr) {
do_add = TRUE;
}
14 years
cluster: STABLE3 - dlm_controld.pcmk: Prevent use-of-NULL by checking the node has a valid address before adding it to configfs
by Andrew Beekhof
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: fa24b460c51aa0c47d0842703feea8bca0ed66b7
Parent: f89866864bad9e2cc4f60e4f44dde888829fac19
Author: Andrew Beekhof <andrew(a)beekhof.net>
AuthorDate: Wed Apr 28 12:37:57 2010 +0200
Committer: Andrew Beekhof <andrew(a)beekhof.net>
CommitterDate: Wed Apr 28 12:37:57 2010 +0200
dlm_controld.pcmk: Prevent use-of-NULL by checking the node has a valid address before adding it to configfs
---
group/dlm_controld/pacemaker.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/group/dlm_controld/pacemaker.c b/group/dlm_controld/pacemaker.c
index c661343..93c1841 100644
--- a/group/dlm_controld/pacemaker.c
+++ b/group/dlm_controld/pacemaker.c
@@ -123,7 +123,7 @@ void dlm_process_node(gpointer key, gpointer value, gpointer user_data)
} else if(rc == 0) {
do_remove = TRUE;
- } else if(is_active) {
+ } else if(is_active && node->addr) {
do_add = TRUE;
}
14 years
cluster: STABLE3 - gfs2: Fix handling of mount points with spaces
by Lon Hohberger
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f89866864bad9e2cc4f60e4f44dde888829fac19
Parent: 38a984c3b415a13142d2f65aa30edcdc60d70497
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Mon Apr 26 15:33:57 2010 -0400
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Tue Apr 27 10:13:55 2010 -0400
gfs2: Fix handling of mount points with spaces
Mount points may contain spaces, tabs, newlines, and the
backslash character according to getmntent(3). Unfortunately,
while scanning /proc/mounts, mount.gfs2 was not unescaping
the escape sequences, causing mount.gfs2 to not update mtab
if a mount point contained any of these characters.
Utilities relying on mtab (e.g. fuser) would consequently
be unable to list processes holding references on the mount
point.
Resolves: rhbz#586100
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: David Teigland <teigland(a)redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho(a)redhat.com>
---
gfs2/mount/util.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/gfs2/mount/util.c b/gfs2/mount/util.c
index 16fc382..bc26daf 100644
--- a/gfs2/mount/util.c
+++ b/gfs2/mount/util.c
@@ -201,6 +201,48 @@ void parse_opts(struct mount_options *mo)
log_debug("parse_opts: locktable = \"%s\"", mo->locktable);
}
+/* Remove escape sequences from mount path. Per getmntent(3), there are
+ only four escape sequences we need to handle. Consequently, this does
+ not need to be a general-purpose unescape function */
+
+static int mnt_unescape(char *dest, size_t len, const char *src)
+{
+ unsigned i = 0, j = 0;
+ size_t srclen;
+ int ret = -1;
+
+ srclen = strlen(src);
+ while (i < srclen) {
+ if (src[i] != '\\') {
+ dest[j] = src[i];
+ ++i; ++j;
+ continue;
+ }
+
+ ++i;
+ if ((srclen - 3) < i)
+ return -1;
+
+ if (!strncmp(&src[i], "040", 3)) {
+ dest[j] = ' ';
+ } else if (!strncmp(&src[i], "011", 3)) {
+ dest[j] = '\t';
+ } else if (!strncmp(&src[i], "012", 3)) {
+ dest[j] = '\n';
+ } else if (!strncmp(&src[i], "134", 3)) {
+ dest[j] = '\\';
+ } else {
+ return -1;
+ }
+
+ i+=3;
+ j++;
+ }
+
+ return 0;
+}
+
+
/* - when unmounting, we don't know the dev and need this function to set it;
we also want to select the _last_ line with a matching dir since it will
be the top-most fs that the umount(2) will unmount
@@ -212,6 +254,7 @@ void read_proc_mounts(struct mount_options *mo)
FILE *file;
char line[PATH_MAX];
char path[PATH_MAX];
+ char unescaped_path[PATH_MAX];
char type[PATH_MAX];
char opts[PATH_MAX];
char device[PATH_MAX];
@@ -234,8 +277,16 @@ void read_proc_mounts(struct mount_options *mo)
while (fgets(line, PATH_MAX, file)) {
if (sscanf(line, "%s %s %s %s", device, path, type, opts) != 4)
continue;
- if (strcmp(path, mo->dir))
- continue;
+ if (strcmp(path, mo->dir)) {
+ if (!strchr(path, '\\'))
+ continue;
+ /* /proc/mounts entry may have escaped spaces */
+ if (mnt_unescape(unescaped_path, sizeof(unescaped_path),
+ path) < 0)
+ continue;
+ if (strcmp(unescaped_path, mo->dir))
+ continue;
+ }
if (mo->dev[0]) {
if (stat(device, &st_mounts_dev))
continue;
14 years
cluster: RHEL55 - fence_scsi: replace open3 calls with qx commands
by rohara
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: fee7b0d92edb3ed99bdbd6194b72103c22279e94
Parent: 78e7ffd2488b53e627482e78d9f7a23d0b4ba514
Author: Ryan O'Hara <rohara(a)redhat.com>
AuthorDate: Mon Apr 26 13:05:48 2010 -0500
Committer: Ryan O'Hara <rohara(a)redhat.com>
CommitterDate: Mon Apr 26 13:05:48 2010 -0500
fence_scsi: replace open3 calls with qx commands
The open3 calls will block when the buffer becomes full, which causes
fence_scsi to block. This can occur if fence_scsi needs to process
several devices. All open3 calls should be replaced with qx commands,
which does not suffer from this problem.
Resolves: rhbz#580158
Signed-off-by: Ryan O'Hara <rohara(a)redhat.com>
---
fence/agents/scsi/fence_scsi.pl | 100 ++++++++-------------------------------
1 files changed, 20 insertions(+), 80 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index 0c2ff51..91f113d 100755
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -2,7 +2,6 @@
use Getopt::Std;
use XML::LibXML;
-use IPC::Open3;
use POSIX;
my $ME = $0;
@@ -72,32 +71,23 @@ sub get_cluster_id
{
my $cluster_id;
- my ($in, $out, $err);
my $cmd = "cman_tool status";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
- my ($name, $value) = split(/\s*:\s*/, $_);
+ my ($param, $value) = split(/\s*:\s*/, $_);
- if (uc($name) eq "CLUSTER ID")
- {
+ if ($param =~ /^cluster\s+id/i) {
$cluster_id = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
print "[$pname]: get_cluster_id = $cluster_id\n" if $opt_v;
return $cluster_id;
@@ -130,32 +120,23 @@ sub get_host_id
{
my $host_id;
- my ($in, $out, $err);
my $cmd = "cman_tool status";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
- my ($name, $value) = split(/\s*:\s*/, $_);
+ my ($param, $value) = split(/\s*:\s*/, $_);
- if (uc($name) eq "NODE ID")
- {
+ if ($param =~ /^node\s+id/i) {
$host_id = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
print "[$pname]: get_host_id = $host_id\n" if $opt_v;
return $host_id;
@@ -165,32 +146,23 @@ sub get_host_name
{
my $host_name;
- my ($in, $out, $err);
my $cmd = "cman_tool status";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
- my ($name, $value) = split(/\s*:\s*/, $_);
+ my ($param, $value) = split(/\s*:\s*/, $_);
- if (uc($name) eq "NODE NAME")
- {
+ if ($param =~ /^node\s+name/i) {
$host_name = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
print "[$pname]: get_host_nam = $host_name\n" if $opt_v;
return $host_name;
@@ -269,18 +241,14 @@ sub get_key_list
{
($device) = @_;
- my ($in, $out, $err);
-
my $cmd = "sg_persist -d $device -i -k";
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute sg_persist.\n" if ($?>>8);
my %key_list;
- while (<$out>)
+ foreach (@out)
{
chomp;
@@ -309,33 +277,25 @@ sub get_key_list
}
}
- close($in);
- close($out);
- close($err);
-
return %key_list;
}
sub get_scsi_devices
{
- my ($in, $out, $err);
-
my $cmd = "vgs --config 'global { locking_type = 0 }'" .
- " --noheadings --separator : -o vg_attr,pv_name,pv_uuid 2> /dev/null";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+ " --noheadings --separator : -o vg_attr,pv_name,pv_uuid";
- waitpid($pid, 0);
+ my @out = qx { $cmd 2> /dev/null};
die "Unable to execute vgs.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
my ($vg_attrs, $pv_name, $pv_uuid) = split(/:/, $_);
- if ($vg_attrs =~ /.*c$/)
+ if ($vg_attrs =~ /c$/)
{
$device_list{"\U$pv_uuid"} = $pv_name;
}
@@ -356,26 +316,14 @@ sub get_scsi_devices
$index++;
}
}
-
- close($in);
- close($out);
- close($err);
}
sub check_sg_persist
{
- my ($in, $out, $err);
my $cmd = "sg_persist -V";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my $out = qx { $cmd };
die "Unable to execute sg_persist.\n" if ($?>>8);
-
- close($in);
- close($out);
- close($err);
}
sub fence_node
@@ -386,8 +334,6 @@ sub fence_node
my $host_key = get_key($host_name);
my $node_key = get_key($node_name);
- my ($in, $out, $err);
-
for $uuid (sort keys %device_list)
{
my $device = $device_list{$uuid};
@@ -412,15 +358,9 @@ sub fence_node
$cmd = "sg_persist -n -d $device -o -A -K $host_key -S $node_key -T 5";
}
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my $out = qx { $cmd };
die "Unable to execute sg_persist ($dev).\n" if ($?>>8);
-
- close($in);
- close($out);
- close($err);
}
}
14 years
cluster: RHEL54 - fence_scsi: replace open3 calls with qx commands
by rohara
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 351f6b71f4be272ad7d472b8299397e7b3442ae0
Parent: 971ae8c3478df85910f65ea26dd29b37c7ad0a06
Author: Ryan O'Hara <rohara(a)redhat.com>
AuthorDate: Mon Apr 26 12:50:17 2010 -0500
Committer: Ryan O'Hara <rohara(a)redhat.com>
CommitterDate: Mon Apr 26 12:50:17 2010 -0500
fence_scsi: replace open3 calls with qx commands
The open3 calls will block when the buffer becomes full, which causes
fence_scsi to block. This can occur if fence_scsi needs to process
several devices. All open3 calls should be replaced with qx commands,
which does not suffer from this problem.
Resolves: rhbz#580157
Signed-off-by: Ryan O'Hara <rohara(a)redhat.com>
---
fence/agents/scsi/fence_scsi.pl | 100 ++++++++-------------------------------
1 files changed, 20 insertions(+), 80 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index e452e7c..14641f9 100755
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -2,7 +2,6 @@
use Getopt::Std;
use XML::LibXML;
-use IPC::Open3;
use POSIX;
my $ME = $0;
@@ -72,32 +71,23 @@ sub get_cluster_id
{
my $cluster_id;
- my ($in, $out, $err);
my $cmd = "cman_tool status";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
- my ($name, $value) = split(/\s*:\s*/, $_);
+ my ($param, $value) = split(/\s*:\s*/, $_);
- if (uc($name) eq "CLUSTER ID")
- {
+ if ($param =~ /^cluster\s+id/i) {
$cluster_id = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
print "[$pname]: get_cluster_id = $cluster_id\n" if $opt_v;
return $cluster_id;
@@ -130,32 +120,23 @@ sub get_host_id
{
my $host_id;
- my ($in, $out, $err);
my $cmd = "cman_tool status";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
- my ($name, $value) = split(/\s*:\s*/, $_);
+ my ($param, $value) = split(/\s*:\s*/, $_);
- if (uc($name) eq "NODE ID")
- {
+ if ($param =~ /^node\s+id/i) {
$host_id = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
print "[$pname]: get_host_id = $host_id\n" if $opt_v;
return $host_id;
@@ -165,32 +146,23 @@ sub get_host_name
{
my $host_name;
- my ($in, $out, $err);
my $cmd = "cman_tool status";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
- my ($name, $value) = split(/\s*:\s*/, $_);
+ my ($param, $value) = split(/\s*:\s*/, $_);
- if (uc($name) eq "NODE NAME")
- {
+ if ($param =~ /^node\s+name/i) {
$host_name = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
print "[$pname]: get_host_nam = $host_name\n" if $opt_v;
return $host_name;
@@ -269,18 +241,14 @@ sub get_key_list
{
($device) = @_;
- my ($in, $out, $err);
-
my $cmd = "sg_persist -d $device -i -k";
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my @out = qx { $cmd };
die "Unable to execute sg_persist.\n" if ($?>>8);
my %key_list;
- while (<$out>)
+ foreach (@out)
{
chomp;
@@ -309,33 +277,25 @@ sub get_key_list
}
}
- close($in);
- close($out);
- close($err);
-
return %key_list;
}
sub get_scsi_devices
{
- my ($in, $out, $err);
-
my $cmd = "vgs --config 'global { locking_type = 0 }'" .
- " --noheadings --separator : -o vg_attr,pv_name,pv_uuid 2> /dev/null";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+ " --noheadings --separator : -o vg_attr,pv_name,pv_uuid";
- waitpid($pid, 0);
+ my @out = qx { $cmd 2> /dev/null};
die "Unable to execute vgs.\n" if ($?>>8);
- while (<$out>)
+ foreach (@out)
{
chomp;
my ($vg_attrs, $pv_name, $pv_uuid) = split(/:/, $_);
- if ($vg_attrs =~ /.*c$/)
+ if ($vg_attrs =~ /c$/)
{
$device_list{"\U$pv_uuid"} = $pv_name;
}
@@ -356,26 +316,14 @@ sub get_scsi_devices
$index++;
}
}
-
- close($in);
- close($out);
- close($err);
}
sub check_sg_persist
{
- my ($in, $out, $err);
my $cmd = "sg_persist -V";
-
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my $out = qx { $cmd };
die "Unable to execute sg_persist.\n" if ($?>>8);
-
- close($in);
- close($out);
- close($err);
}
sub fence_node
@@ -386,8 +334,6 @@ sub fence_node
my $host_key = get_key($host_name);
my $node_key = get_key($node_name);
- my ($in, $out, $err);
-
for $uuid (sort keys %device_list)
{
my $device = $device_list{$uuid};
@@ -412,15 +358,9 @@ sub fence_node
$cmd = "sg_persist -n -d $device -o -A -K $host_key -S $node_key -T 5";
}
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
+ my $out = qx { $cmd };
die "Unable to execute sg_persist ($dev).\n" if ($?>>8);
-
- close($in);
- close($out);
- close($err);
}
}
14 years