fence-agents: master - fence agents automatic man page generation
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=com...
Commit: 319803209f2425ca02538d22e1750b2169e10d00
Parent: 3d66266141fce66bb2fd517d14dab1333d05ea2b
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Tue Apr 20 14:26:55 2010 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Tue Apr 20 14:26:55 2010 +0200
fence agents automatic man page generation
first import from STABLE3 branch
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
configure.ac | 1 -
fence/Makefile.am | 2 +-
fence/agents/Makefile.am | 4 +-
fence/agents/alom/Makefile.am | 5 +-
fence/agents/apc/Makefile.am | 5 +-
fence/agents/apc_snmp/Makefile.am | 5 +-
fence/agents/baytech/Makefile.am | 2 +
fence/agents/baytech/fence_baytech.8 | 82 ++++++++++++++++
fence/agents/bladecenter/Makefile.am | 5 +-
fence/agents/brocade/Makefile.am | 2 +
fence/agents/brocade/fence_brocade.8 | 82 ++++++++++++++++
fence/agents/bullpap/Makefile.am | 2 +
fence/agents/bullpap/fence_bullpap.8 | 71 ++++++++++++++
fence/agents/cisco_mds/Makefile.am | 5 +-
fence/agents/cpint/Makefile.am | 2 +
fence/agents/cpint/fence_cpint.8 | 52 ++++++++++
fence/agents/drac/Makefile.am | 4 +-
fence/agents/drac/fence_drac.8 | 97 +++++++++++++++++++
fence/agents/drac5/Makefile.am | 7 +-
fence/agents/egenera/Makefile.am | 2 +
fence/agents/egenera/fence_egenera.8 | 70 ++++++++++++++
fence/agents/eps/Makefile.am | 5 +-
fence/agents/ibmblade/Makefile.am | 5 +-
fence/agents/ifmib/Makefile.am | 5 +-
fence/agents/ilo/Makefile.am | 5 +-
fence/agents/ilo_mp/Makefile.am | 5 +-
fence/agents/intelmodular/Makefile.am | 5 +-
fence/agents/ipmilan/Makefile.am | 2 +
fence/agents/ipmilan/fence_ipmilan.8 | 110 ++++++++++++++++++++++
fence/agents/ldom/Makefile.am | 5 +-
fence/agents/lib/Makefile.am | 4 +-
fence/agents/lib/fence2man.xsl | 53 +++++++++++
fence/agents/lib/ra2man.xsl | 72 --------------
fence/agents/lpar/Makefile.am | 5 +-
fence/agents/manual/Makefile.am | 4 +-
fence/agents/manual/fence_ack_manual.8 | 36 +++++++
fence/agents/mcdata/Makefile.am | 2 +
fence/agents/mcdata/fence_mcdata.8 | 82 ++++++++++++++++
fence/agents/rackswitch/Makefile.am | 6 +-
fence/agents/rackswitch/fence_rackswitch.8 | 68 +++++++++++++
fence/agents/rsa/Makefile.am | 5 +-
fence/agents/rsb/Makefile.am | 5 +-
fence/agents/sanbox2/Makefile.am | 5 +-
fence/agents/scsi/Makefile.am | 4 +-
fence/agents/scsi/fence_scsi.8 | 107 +++++++++++++++++++++
fence/agents/virsh/Makefile.am | 5 +-
fence/agents/vixel/Makefile.am | 2 +
fence/agents/vixel/fence_vixel.8 | 70 ++++++++++++++
fence/agents/vmware/Makefile.am | 9 +-
fence/agents/wti/Makefile.am | 5 +-
fence/agents/xcat/Makefile.am | 2 +
fence/agents/xcat/fence_xcat.8 | 61 ++++++++++++
fence/agents/zvm/Makefile.am | 2 +
fence/agents/zvm/fence_zvm.8 | 62 ++++++++++++
fence/man/Makefile.am | 34 -------
fence/man/fence_ack_manual.8 | 36 -------
fence/man/fence_alom.8 | 84 -----------------
fence/man/fence_apc.8 | 98 -------------------
fence/man/fence_apc_snmp.8 | 139 ---------------------------
fence/man/fence_baytech.8 | 82 ----------------
fence/man/fence_bladecenter.8 | 95 -------------------
fence/man/fence_brocade.8 | 82 ----------------
fence/man/fence_bullpap.8 | 71 --------------
fence/man/fence_cisco_mds.8 | 132 --------------------------
fence/man/fence_cpint.8 | 52 ----------
fence/man/fence_drac.8 | 97 -------------------
fence/man/fence_egenera.8 | 70 --------------
fence/man/fence_eps.8 | 106 ---------------------
fence/man/fence_ibmblade.8 | 132 --------------------------
fence/man/fence_ifmib.8 | 136 ---------------------------
fence/man/fence_ilo.8 | 94 ------------------
fence/man/fence_intelmodular.8 | 136 ---------------------------
fence/man/fence_ipmilan.8 | 110 ----------------------
fence/man/fence_ldom.8 | 114 ----------------------
fence/man/fence_mcdata.8 | 82 ----------------
fence/man/fence_rackswitch.8 | 68 -------------
fence/man/fence_rib.8 | 10 --
fence/man/fence_rsa.8 | 69 --------------
fence/man/fence_rsb.8 | 75 ---------------
fence/man/fence_sanbox2.8 | 82 ----------------
fence/man/fence_scsi.8 | 107 ---------------------
fence/man/fence_virsh.8 | 104 --------------------
fence/man/fence_vixel.8 | 70 --------------
fence/man/fence_vmware.8 | 141 ----------------------------
fence/man/fence_wti.8 | 83 ----------------
fence/man/fence_xcat.8 | 61 ------------
fence/man/fence_zvm.8 | 62 ------------
make/fenceman.mk | 8 ++
scripts/fenceparse | 4 +-
89 files changed, 1236 insertions(+), 3020 deletions(-)
diff --git a/configure.ac b/configure.ac
index 1a5d1e8..e3f20f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -261,7 +261,6 @@ AC_CONFIG_FILES([Makefile
fence/agents/wti/Makefile
fence/agents/xcat/Makefile
fence/agents/zvm/Makefile
- fence/man/Makefile
doc/Makefile])
AC_OUTPUT
diff --git a/fence/Makefile.am b/fence/Makefile.am
index 8c7caa8..43fc1a0 100644
--- a/fence/Makefile.am
+++ b/fence/Makefile.am
@@ -1,3 +1,3 @@
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS = agents man
+SUBDIRS = agents
diff --git a/fence/agents/Makefile.am b/fence/agents/Makefile.am
index c69fbc4..29e6dd7 100644
--- a/fence/agents/Makefile.am
+++ b/fence/agents/Makefile.am
@@ -1,6 +1,7 @@
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS = alom \
+SUBDIRS = lib \
+ alom \
apc \
apc_snmp \
baytech \
@@ -20,7 +21,6 @@ SUBDIRS = alom \
intelmodular \
ipmilan \
ldom \
- lib \
lpar \
manual \
mcdata \
diff --git a/fence/agents/alom/Makefile.am b/fence/agents/alom/Makefile.am
index d65f6a7..68d5fc7 100644
--- a/fence/agents/alom/Makefile.am
+++ b/fence/agents/alom/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/apc/Makefile.am
index bd120b1..2615aab 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/apc/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/apc_snmp/Makefile.am b/fence/agents/apc_snmp/Makefile.am
index 16dd01c..c64dfad 100644
--- a/fence/agents/apc_snmp/Makefile.am
+++ b/fence/agents/apc_snmp/Makefile.am
@@ -8,7 +8,10 @@ EXTRA_DIST = $(TARGET).py \
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/baytech/Makefile.am b/fence/agents/baytech/Makefile.am
index f48aa4d..afd0be6 100644
--- a/fence/agents/baytech/Makefile.am
+++ b/fence/agents/baytech/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/baytech/fence_baytech.8 b/fence/agents/baytech/fence_baytech.8
new file mode 100644
index 0000000..e60175d
--- /dev/null
+++ b/fence/agents/baytech/fence_baytech.8
@@ -0,0 +1,82 @@
+.TH fence_baytech 8
+
+.SH NAME
+fence_baytech - I/O Fencing agent for Baytech RPC switches in combination with a Cyclades Terminal Server
+
+.SH SYNOPSIS
+.B
+fence_baytech
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+
+This fencing agent is written for the Baytech RPC27-20nc in combination with
+a Cyclades terminal server. The Cyclades TS exports the RPC's serial port
+via a Telnet interface. Other interfaces, such as SSH, are possible.
+However, this script relies upon the assumption that Telnet is used. Future
+features to this agent would allow the agent to work with a multitude of
+different communication protocols such as Telnet, SSH or Kermit.
+
+The other assumption that is made is that Outlet names do not end in space.
+The name "Foo" and "Foo " are identical when the RPC prints them with
+the status command.
+
+fence_baytech accepts options on the command line as well as from stdin.
+fenced sends parameters through stdin when it execs the agent. fence_baytech
+can be run by itself with command line options which is useful for testing.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIhost\fP
+IP address or hostname to connect to.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlogin\fP
+Username name for the switch.
+.TP
+\fB-n\fP \fIport\fP
+The name of the outlet to act upon.
+.TP
+\fB-o\fP \fIaction\fP
+The action required. This can be on, off, status or reboot (default)
+.TP
+\fB-p\fP \fIpassword\fP
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-q\fP
+Quiet mode: print only error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_baytech.
+.TP
+\fIhost = < hostname | ip >\fR
+IP address or hostname to connect to.
+.TP
+\fIlogin = < param >\fR
+Login name.
+.TP
+\fIaction = < param >\fR
+The action required. This can be on, off, status or reboot (default)
+.TP
+\fIpasswd = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+\fIoutlet = < param >\fR
+The name of the outlet to act upon.
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/bladecenter/Makefile.am b/fence/agents/bladecenter/Makefile.am
index 99dcb84..0ee1ff8 100644
--- a/fence/agents/bladecenter/Makefile.am
+++ b/fence/agents/bladecenter/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/brocade/Makefile.am b/fence/agents/brocade/Makefile.am
index f3cdbd5..5ec24ef 100644
--- a/fence/agents/brocade/Makefile.am
+++ b/fence/agents/brocade/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/brocade/fence_brocade.8 b/fence/agents/brocade/fence_brocade.8
new file mode 100644
index 0000000..36fde82
--- /dev/null
+++ b/fence/agents/brocade/fence_brocade.8
@@ -0,0 +1,82 @@
+.TH fence_brocade 8
+
+.SH NAME
+fence_brocade - I/O Fencing agent for Brocade FC switches
+
+.SH SYNOPSIS
+.B
+fence_brocade
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_brocade is an I/O Fencing agent which can be used with Brocade FC
+switches. It logs into a Brocade switch via telnet and disables a specified
+port. Disabling the port which a machine is connected to effectively fences
+that machine. Lengthy telnet connections to the switch should be avoided
+while a GFS cluster is running because the connection will block any necessary
+fencing actions.
+
+fence_brocade accepts options on the command line as well as from stdin.
+fenced sends parameters through stdin when it execs the agent. fence_brocade
+can be run by itself with command line options which is useful for testing.
+
+After a fence operation has taken place the fenced machine can no longer connect
+to the Brocade FC switch. When the fenced machine is ready to be brought back
+into the GFS cluster (after reboot) the port on the Brocade FC switch needs to
+be enabled. This can be done by running fence_brocade and specifying the
+enable action.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address of the switch.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlogin\fP
+Login name for the switch.
+.TP
+\fB-n\fP \fIport\fP
+The port number to disable on the switch.
+.TP
+\fB-o\fP \fIaction\fP
+The action required. disable (default) or enable.
+.TP
+\fB-p\fP \fIpassword\fP
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-q\fP
+Quiet mode: print only error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_brocade.
+.TP
+\fIipaddr = < hostname | ip >\fR
+IP address or hostname of the switch.
+.TP
+\fIlogin = < param >\fR
+Login name.
+.TP
+\fIoption = < param >\fR
+The action required. disable (default) or enable.
+.TP
+\fIpasswd = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+\fIport = < param >\fR
+The port number to disable on the switch.
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/bullpap/Makefile.am b/fence/agents/bullpap/Makefile.am
index a93e16b..bd06cbf 100644
--- a/fence/agents/bullpap/Makefile.am
+++ b/fence/agents/bullpap/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/bullpap/fence_bullpap.8 b/fence/agents/bullpap/fence_bullpap.8
new file mode 100644
index 0000000..876b406
--- /dev/null
+++ b/fence/agents/bullpap/fence_bullpap.8
@@ -0,0 +1,71 @@
+.TH fence_bullpap 8
+
+.SH NAME
+fence_bullpap - I/O Fencing agent for Bull FAME architecture controlled by a
+PAP management console.
+
+.SH SYNOPSIS
+.B
+fence_bullpap
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_bullpap is an I/O Fencing agent which can be used with Bull's NovaScale
+machines controlled by PAP management consoles. This agent calls Bull's
+support software provided by the NSMasterHW RPM available from Bull.
+
+fence_bullpap accepts options on the command line as well as from stdin.
+fenced sends the options through stdin when it execs the agent. fence_bullpap
+can be run by itself with command line options which is useful for testing.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address or hostname of the PAP management console.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlogin\fP
+Login with administrative privileges.
+.TP
+\fB-d\fP \fIdomain\fP
+This is the domain name of the Bull machine to power-cycle.
+.TP
+\fB-o\fP \fIoption\fP
+Action to perform (on, off, reboot, status).
+.TP
+\fB-p\fP \fIpassword\fP
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-q\fP
+Quiet operation. Only print out error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIipaddr = < hostname | ip >\fR
+IP address or hostname of the PAP management console.
+.TP
+\fIlogin= < param >\fR
+Login with administrative privileges.
+.TP
+\fIdomain = < param >\fR
+This is the domain name of the Bull machine to power-cycle.
+.TP
+\fIoption = < param >\fR
+Action to perform (on, off, reboot, status).
+.TP
+\fIpasswd = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/cisco_mds/Makefile.am b/fence/agents/cisco_mds/Makefile.am
index 080cccf..04293eb 100644
--- a/fence/agents/cisco_mds/Makefile.am
+++ b/fence/agents/cisco_mds/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/cpint/Makefile.am b/fence/agents/cpint/Makefile.am
index 930639a..9e86293 100644
--- a/fence/agents/cpint/Makefile.am
+++ b/fence/agents/cpint/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/cpint/fence_cpint.8 b/fence/agents/cpint/fence_cpint.8
new file mode 100644
index 0000000..efbaa7e
--- /dev/null
+++ b/fence/agents/cpint/fence_cpint.8
@@ -0,0 +1,52 @@
+.TH fence_cpint 8
+
+.SH NAME
+fence_cpint - I/O Fencing agent for GFS on s390 and zSeries VM clusters
+
+.SH SYNOPSIS
+.B
+fence_cpint
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_cpint is an I/O Fencing agent used on a virtual machine running GFS in a
+s390 or zSeries VM cluster.
+It uses the cpint package to send a CP LOGOFF command to the specified virtual
+machine.
+For fence_cpint to execute correctly, you must have the cpint module installed,
+and hcp in your PATH.
+\fBNOTE:\fP for fence_cpint to send a command to another virtual machine, the
+machine executing it must either be a privilege class C user or it must be
+the secondary user of the virtual machine to be fenced. This means that unless
+all of you GULM server nodes are privilege class C, fence_cpint can only be
+used with SLM.
+
+fence_cpint accepts options on the command line as well as from stdin.
+fence_node sends the options through stdin when it execs the agent.
+fence_cpint can be run by itself with command line options which is useful for
+testing.
+
+.SH OPTIONS
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-u\fP \fIuserid\fP
+userid of the virtual machine to fence (required).
+.TP
+\fB-q\fP
+quiet mode, no output.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_cpint.
+.TP
+\fIuserid = < parm >\fP
+userid of the virtual machine to fence (required).
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/drac/Makefile.am b/fence/agents/drac/Makefile.am
index 24e0464..504a329 100644
--- a/fence/agents/drac/Makefile.am
+++ b/fence/agents/drac/Makefile.am
@@ -2,10 +2,12 @@ MAINTAINERCLEANFILES = Makefile.in
TARGET = fence_drac
-EXTRA_DIST = fence_drac.pl
+EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/drac/fence_drac.8 b/fence/agents/drac/fence_drac.8
new file mode 100644
index 0000000..8dda184
--- /dev/null
+++ b/fence/agents/drac/fence_drac.8
@@ -0,0 +1,97 @@
+.TH fence_drac 8
+
+.SH NAME
+fence_drac - fencing agent for Dell Remote Access Card
+
+.SH SYNOPSIS
+.B
+fence_drac
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_drac is an I/O Fencing agent which can be used with the Dell Remote
+Access Card (DRAC). This card provides remote access to controlling
+power to a server. It logs into the DRAC through the telnet interface of
+the card. By default, the telnet interface is not enabled. To enable the
+interface, you will need to use the racadm command in the racser-devel rpm
+available from Dell. To enable telnet on the DRAC:
+
+[root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1
+
+[root]# racadm racreset
+
+fence_drac accepts options on the command line as well as from stdin.
+Fenced sends parameters through stdin when it execs the agent. fence_drac
+can be run by itself with command line options. This is useful for testing
+and for turning outlets on or off from scripts.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fR
+IP address or hostname of the switch.
+.TP
+\fB-c\fP \fIcmd_prompt\fR
+Force fence_drac to use cmd_prompt as the command prompt
+.TP
+\fB-d\fP \fIdracversion\fR
+Force fence_drac to treat the device as though it was for the specified drac version
+.TP
+\fB-D\fP \fIdumpfile\fR
+Debug file of the telnet interaction
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlogin\fR
+Login name.
+.TP
+\fB-m\fP \fImodulename\fR
+The module name of the blade when using DRAC/MC firmware.
+.TP
+\fB-o\fP \fIaction\fR
+The action required. reboot (default), off, on or status.
+.TP
+\fB-p\fP \fIpassword\fR
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIaction = < param >\fR
+The action required. reboot (default), off, on or status.
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_apc.
+.TP
+\fIcmd_prompt = < param >\fr
+Force fence_drac to use cmd_prompt as the command prompt
+.TP
+\fIdrac_version = < param >\fr
+Force fence_drac to treat the device as though it was for the specified drac version.
+.TP
+\fIdebug = < dumpfile >\fR
+Debug file of the telnet interaction
+.TP
+\fIipaddr = < hostname | ip >\fR
+IP address or hostname of the switch.
+.TP
+\fIlogin = < param >\fR
+Login name.
+.TP
+\fImodulename = < param >\fr
+The module name of the blade when using DRAC/MC firmware.
+.TP
+\fIpasswd = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/drac5/Makefile.am b/fence/agents/drac5/Makefile.am
index e6b26f8..9cf2f0f 100644
--- a/fence/agents/drac5/Makefile.am
+++ b/fence/agents/drac5/Makefile.am
@@ -2,11 +2,14 @@ MAINTAINERCLEANFILES = Makefile.in
TARGET = fence_drac5
-EXTRA_DIST = fence_drac5.py
+EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/egenera/Makefile.am b/fence/agents/egenera/Makefile.am
index c31a38c..74b27a8 100644
--- a/fence/agents/egenera/Makefile.am
+++ b/fence/agents/egenera/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/egenera/fence_egenera.8 b/fence/agents/egenera/fence_egenera.8
new file mode 100644
index 0000000..cfa839e
--- /dev/null
+++ b/fence/agents/egenera/fence_egenera.8
@@ -0,0 +1,70 @@
+.TH fence_egenera 8
+
+.SH NAME
+fence_egenera - I/O Fencing agent for the Egenera BladeFrame
+
+.SH SYNOPSIS
+.B
+fence_egenera
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_egenera is an I/O Fencing agent which can be used with the Egenera
+BladeFrame. It logs into a control blade (cserver) via ssh and operates
+on a processing blade (pserver) identified by the pserver name and the
+logical process area network (LPAN) that it is in. fence_egenera requires
+that ssh keys have been setup so that the fence_egenera does not require
+a password to authenticate. Refer to ssh(8) for more information on setting
+up ssh keys.
+
+fence_egenera accepts options on the command line as well as from stdin.
+Fenced sends parameters through stdin when it execs the agent. fence_egenera
+can also be run by itself with command line options.
+
+.SH OPTIONS
+.TP
+\fB-c\fP \fIcserver\fR
+The cserver to ssh to. cserver can be in the form user@hostname to
+specify a different user to login as.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlpan\fR
+the lpan to operate on
+.TP
+\fB-o\fP \fIaction\fR
+The action required. reboot (default), off, on or status.
+.TP
+\fB-p\fP \fIpserver\fR
+the pserver to operate on
+.TP
+\fB-q\fP
+quite mode. suppress output.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIaction = < param >\fR
+The action required. reboot (default), off, on or status.
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_apc.
+.TP
+\fIcserver = < param >\fR
+The cserver to ssh to. cserver can be in the form user@hostname to
+specify a different user to login as.
+.TP
+\fIlpan = < param >\fR
+The lpan to operate on
+.TP
+\fIpserver = < param >\fR
+The pserver to operate on
+.TP
+\fIesh = < param >\fR
+The path to the esh command on the cserver (default is /opt/panmgr/bin/esh)
+
+.SH SEE ALSO
+fence(8), fence_node(8), ssh(8)
diff --git a/fence/agents/eps/Makefile.am b/fence/agents/eps/Makefile.am
index 4348755..d150254 100644
--- a/fence/agents/eps/Makefile.am
+++ b/fence/agents/eps/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/ibmblade/Makefile.am b/fence/agents/ibmblade/Makefile.am
index 53a452f..c92ed35 100644
--- a/fence/agents/ibmblade/Makefile.am
+++ b/fence/agents/ibmblade/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/ifmib/Makefile.am b/fence/agents/ifmib/Makefile.am
index 16dcc6b..21c1078 100644
--- a/fence/agents/ifmib/Makefile.am
+++ b/fence/agents/ifmib/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py README
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/ilo/Makefile.am b/fence/agents/ilo/Makefile.am
index ce7ee1c..4c218c2 100644
--- a/fence/agents/ilo/Makefile.am
+++ b/fence/agents/ilo/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/ilo_mp/Makefile.am b/fence/agents/ilo_mp/Makefile.am
index c961ba3..d322a3e 100644
--- a/fence/agents/ilo_mp/Makefile.am
+++ b/fence/agents/ilo_mp/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/intelmodular/Makefile.am b/fence/agents/intelmodular/Makefile.am
index 690cdbd..fac0d52 100644
--- a/fence/agents/intelmodular/Makefile.am
+++ b/fence/agents/intelmodular/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/ipmilan/Makefile.am b/fence/agents/ipmilan/Makefile.am
index bee7669..72437ef 100644
--- a/fence/agents/ipmilan/Makefile.am
+++ b/fence/agents/ipmilan/Makefile.am
@@ -5,3 +5,5 @@ sbin_PROGRAMS = fence_ipmilan
noinst_HEADERS = expect.h
fence_ipmilan_SOURCES = expect.c ipmilan.c
+
+dist_man_MANS = fence_ipmilan.8
diff --git a/fence/agents/ipmilan/fence_ipmilan.8 b/fence/agents/ipmilan/fence_ipmilan.8
new file mode 100644
index 0000000..98006f6
--- /dev/null
+++ b/fence/agents/ipmilan/fence_ipmilan.8
@@ -0,0 +1,110 @@
+.TH fence_ipmilan 8
+
+.SH NAME
+fence_ipmilan - I/O Fencing agent for machines controlled by IPMI over
+LAN.
+
+.SH SYNOPSIS
+.B
+fence_ipmilan
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_ipmilan is an I/O Fencing agent which can be used with
+machines controlled by IPMI. This agent calls support software
+using ipmitool (http://ipmitool.sf.net/).
+
+fence_ipmilan accepts options on the command line as well as from stdin.
+fenced sends the options through stdin when it execs the agent. fence_ipmilan
+can be run by itself with command line options which is useful for testing.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address or hostname of the IPMI controller.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlogin\fP
+Login (if required) with administrative privileges.
+.TP
+\fB-o\fP \fIoption\fP
+Action to perform (on, off, reboot).
+.TP
+\fB-p\fP \fIpassword\fP
+Password (if required) for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-P\fP
+Use the lanplus option if this is a lanplus capable interface (for example iLo2)
+.TP
+\fB-A\fP \fIAuthentication Type\fP
+Can be set to none, password, md2, or md5.
+.TP
+\fB-C\fP \fICiphersuite Type\fP
+If you are using lanplus, this option avails you to define type of ciphersuite to
+use. Standard is 3 (defined if you just use lanplus). For more information please
+refer ipmitool man page (option -C).
+.TP
+\fB-M\fP \fImethod\fP
+Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management
+card will power off with default method so there will be no chance to power machine
+on by IPMI.
+.TP
+\fB-t\fP \fItimeout\fP
+Timeout in seconds for IPMI operation. Default is 10, but in some cases it
+must be set to higher value (anything above 30 is not recommended and may
+cause strange problems).
+.TP
+\fB-q\fP
+Quiet operation. Only print out error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+.TP
+\fB-v\fP
+Verbose mode.
+
+.SH STDIN PARAMETERS
+.TP
+\fIipaddr = < hostname | ip >\fR
+IP address or hostname of the IPMI controller.
+.TP
+\fIlogin= < param >\fR
+Login (if required) with administrative privileges.
+.TP
+\fIoption = < param >\fR
+Action to perform (on, off, reboot).
+.TP
+\fIpasswd = < param >\fR
+Password (if required) for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+\fIauth = < param >\fR
+Authentication type (none, password, md2, md5).
+.TP
+\fItimeout = < param >\fR
+Timeout in seconds for IPMI operation. Default is 10, but in some cases it
+must be set to higher value (anything above 30 is not recommended and may
+cause strange problems).
+.TP
+\fIcipher = < param >\fR
+If you are using lanplus, this option avails you to define type of ciphersuite to
+use. Standard is 3 (defined if you just use lanplus). For more information please
+refer ipmitool man page (option -C).
+.TP
+\fImethod = < param >\fR
+Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management
+card will power off with default method so there will be no chance to power machine
+on by IPMI.
+.TP
+\fIlanplus\fR
+If we are using the lanplus option for ipmitool
+
+.SH SEE ALSO
+fence(8), fence_node(8), ipmitool(1)
diff --git a/fence/agents/ldom/Makefile.am b/fence/agents/ldom/Makefile.am
index 36517eb..a29346b 100644
--- a/fence/agents/ldom/Makefile.am
+++ b/fence/agents/ldom/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/lib/Makefile.am b/fence/agents/lib/Makefile.am
index 7bf9e8f..ba25f6b 100644
--- a/fence/agents/lib/Makefile.am
+++ b/fence/agents/lib/Makefile.am
@@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in
TARGET = fencing.py fencing_snmp.py
-EXTRA_DIST = fencing.py.py fencing_snmp.py.py ra2man.xsl
+EXTRA_DIST = fencing.py.py fencing_snmp.py.py fence2man.xsl
fencelibdir = ${FENCEAGENTSLIBDIR}
@@ -11,4 +11,4 @@ fencelib_DATA = $(TARGET)
include $(top_srcdir)/make/fencebuild.mk
clean-local:
- rm -f $(TARGET)
+ rm -f $(TARGET) *.pyc
diff --git a/fence/agents/lib/fence2man.xsl b/fence/agents/lib/fence2man.xsl
new file mode 100644
index 0000000..563b3a4
--- /dev/null
+++ b/fence/agents/lib/fence2man.xsl
@@ -0,0 +1,53 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" indent="no"/>
+<xsl:template match="parameter">
+<xsl:param name="show" />
+.TP
+<xsl:if test="$show = 'getopt'">.B <xsl:value-of select="getopt/@mixed" /></xsl:if>
+<xsl:if test="$show = 'stdin'">.B <xsl:value-of select="@name"/></xsl:if>
+.
+<xsl:value-of select="normalize-space(shortdesc)"/>
+<xsl:if test="not(content/@default)"><xsl:if test="@required = 1"> This parameter is always required.</xsl:if></xsl:if>
+<xsl:if test="content/@default"> (Default Value: <xsl:value-of select="content/@default"/>)</xsl:if>
+</xsl:template>
+
+<xsl:template match="action">
+.TP
+\fB<xsl:value-of select="@name"/> \fP
+<xsl:choose>
+<xsl:when test="@name = 'on'">Power on machine.</xsl:when>
+<xsl:when test="@name = 'off'">Power off machine.</xsl:when>
+<xsl:when test="@name = 'reboot'">Reboot machine.</xsl:when>
+<xsl:when test="@name = 'monitor'">Check if fencing device is running. List available plugs/virtual machines or get status of machine (if it does not support more).</xsl:when>
+<xsl:when test="@name = 'meta-data'">Display the XML metadata describing this resource.</xsl:when>
+<xsl:when test="@name = 'list'">List available plugs with aliases/virtual machines if there is support for more then one device. Returns N/A otherwise.</xsl:when>
+<xsl:when test="@name = 'status'">This returns the status of the plug/virtual machine.</xsl:when>
+<!-- Ehhh -->
+<xsl:otherwise> The operational behavior of this is not known.</xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+
+<xsl:template match="/resource-agent">
+.TH FENCE_AGENT 8 2009-10-20 "<xsl:value-of select="@name"/> (Fence Agent)"
+.SH NAME
+<xsl:value-of select="@name" /> - <xsl:value-of select="@shortdesc" />
+.SH DESCRIPTION
+.P
+<xsl:value-of select="longdesc"/>
+.P
+<xsl:value-of select="@name" /> accepts options on the command line as well
+as from stdin. Fenced sends parameters through stdin when it execs the
+agent. <xsl:value-of select="@name" /> can be run by itself with command
+line options. This is useful for testing and for turning outlets on or off
+from scripts.
+<xsl:if test="vendor-url">
+Vendor URL: <xsl:value-of select="vendor-url" />
+</xsl:if>
+.SH PARAMETERS
+<xsl:apply-templates select="parameters"><xsl:with-param name="show">getopt</xsl:with-param></xsl:apply-templates>
+.SH ACTIONS
+<xsl:apply-templates select="actions"/>
+.SH STDIN PARAMETERS
+<xsl:apply-templates select="parameters"><xsl:with-param name="show">stdin</xsl:with-param></xsl:apply-templates>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/fence/agents/lib/ra2man.xsl b/fence/agents/lib/ra2man.xsl
deleted file mode 100644
index 2169e1f..0000000
--- a/fence/agents/lib/ra2man.xsl
+++ /dev/null
@@ -1,72 +0,0 @@
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-<xsl:output method="text" indent="no"/>
-
-<xsl:template match="parameter">
-<xsl:param name="show" />
-.TP
-<xsl:if test="$show = 'getopt'">.B <xsl:value-of select="getopt/@mixed" /></xsl:if>
-<xsl:if test="$show = 'stdin'">.B <xsl:value-of select="@name"/></xsl:if>
-.
-<xsl:value-of select="normalize-space(shortdesc)"/>
-<xsl:text>
-
-</xsl:text>
-<xsl:if test="not(content/@default)"><xsl:if test="@required = 1">This parameter is always required.</xsl:if></xsl:if>
-.br
-<xsl:if test="content/@default">Default Value: <xsl:value-of select="content/@default"/></xsl:if>
-</xsl:template>
-
-<xsl:template match="action">
-.TP
-\fB<xsl:value-of select="@name"/>
-<xsl:choose>
-<xsl:when test="@name = 'on'">
-Power on machine.
-</xsl:when>
-<xsl:when test="@name = 'off'">
-Power off machine.
-</xsl:when>
-<xsl:when test="@name = 'reboot'">
-Reboot machine.
-</xsl:when>
-<xsl:when test="@name = 'monitor'">
-Check if fencing device is running. List available plugs/virtual machines or get status of machine (if it does not support more).
-</xsl:when>
-<xsl:when test="@name = 'meta-data'">
-Display the XML metadata describing this resource.
-</xsl:when>
-<xsl:when test="@name = 'list'">
-List available plugs with aliases/virtual machines if there is support for more then one device. Returns N/A otherwise.
-</xsl:when>
-<xsl:when test="@name = 'status'">
-This returns the status of the plug/virtual machine.
-</xsl:when>
-<!-- Ehhh -->
-<xsl:otherwise>
-The operational behavior of this is not known.
-</xsl:otherwise>
-</xsl:choose>
-</xsl:template>
-
-<xsl:template match="/resource-agent">
-.TH FENCE_AGENT 8 2009-01-20 "<xsl:value-of select="@name"/> (Fence Agent)"
-.SH NAME
-<xsl:value-of select="@name" /> - <xsl:value-of select="@shortdesc" />
-.SH DESCRIPTION
-<xsl:value-of select="@name" /> accepts options on the command line as well
-as from stdin. Fenced sends parameters through stdin when it execs the
-agent. <xsl:value-of select="@name" /> can be run by itself with command
-line options. This is useful for testing and for turning outlets on or off
-from scripts.
-
-<xsl:value-of select="normalize-space(longdesc)"/>
-.SH PARAMETERS
-<xsl:apply-templates select="parameters"><xsl:with-param name="show">getopt</xsl:with-param></xsl:apply-templates>
-.SH ACTIONS
-<xsl:apply-templates select="actions"/>
-.SH STDIN PARAMETERS
-<xsl:apply-templates select="parameters"><xsl:with-param name="show">stdin</xsl:with-param></xsl:apply-templates>
-
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/fence/agents/lpar/Makefile.am b/fence/agents/lpar/Makefile.am
index ca106bf..3579805 100644
--- a/fence/agents/lpar/Makefile.am
+++ b/fence/agents/lpar/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/manual/Makefile.am b/fence/agents/manual/Makefile.am
index c29b0ea..1eb2971 100644
--- a/fence/agents/manual/Makefile.am
+++ b/fence/agents/manual/Makefile.am
@@ -4,7 +4,9 @@ TARGET = fence_ack_manual
sbin_SCRIPTS = $(TARGET)
-EXTRA_DIST = $(TARGET)
+EXTRA_DIST = $(TARGET).in
+
+dist_man_MANS = $(TARGET).8
$(TARGET): $(TARGET).in
cat $^ | sed \
diff --git a/fence/agents/manual/fence_ack_manual.8 b/fence/agents/manual/fence_ack_manual.8
new file mode 100644
index 0000000..e2ba505
--- /dev/null
+++ b/fence/agents/manual/fence_ack_manual.8
@@ -0,0 +1,36 @@
+.TH fence_ack_manual 8
+
+.SH NAME
+fence_ack_manual - program run by an operator as a part of manual I/O Fencing
+
+.SH SYNOPSIS
+.B
+fence_ack_manual
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_ack_manual is run by an operator on the same node that fence_manual(8)
+was run after the operator has reset a node which required fencing. A message
+in the system log indicates to the operator that they must reset a machine and
+then run fence_ack_manual. Running fence_ack_manual allows the cluster to
+continue with recovery of the fenced machine. The victim may be disconnected
+from storage rather than resetting it.
+
+.SH OPTIONS
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-O\fP
+Run without prompting for user confirmation.
+.TP
+\fB-n\fP \fInodename\fP
+Name of node that has been reset or disconnected from storage.
+.TP
+\fB-s\fP \fIIPaddress\fP
+IP address of the machine which has been reset or disconnected from storage. (Deprecated; use -n instead.)
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/mcdata/Makefile.am b/fence/agents/mcdata/Makefile.am
index 1e5f0f6..e87f26d 100644
--- a/fence/agents/mcdata/Makefile.am
+++ b/fence/agents/mcdata/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/mcdata/fence_mcdata.8 b/fence/agents/mcdata/fence_mcdata.8
new file mode 100644
index 0000000..2230a66
--- /dev/null
+++ b/fence/agents/mcdata/fence_mcdata.8
@@ -0,0 +1,82 @@
+.TH fence_mcdata 8
+
+.SH NAME
+fence_mcdata - I/O Fencing agent for McData FC switches
+
+.SH SYNOPSIS
+.B
+fence_mcdata
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_mcdata is an I/O Fencing agent which can be used with McData FC
+switches. It logs into a McData switch via telnet and disables a specified
+port. Disabling the port which a machine is connected to effectively fences
+that machine. Lengthy telnet connections to the switch should be avoided
+while a GFS cluster is running because the connection will block any necessary
+fencing actions.
+
+fence_mcdata accepts options on the command line as well as from stdin.
+fenced sends parameters through stdin when it execs the agent. fence_mcdata
+can be run by itself with command line options which is useful for testing.
+
+After a fence operation has taken place the fenced machine can no longer connect
+to the McData FC switch. When the fenced machine is ready to be brought back
+into the GFS cluster (after reboot) the port on the McData FC switch needs to
+be enabled. This can be done by running fence_mcdata and specifying the
+enable action.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address of the switch.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-l\fP \fIlogin\fP
+Username name for the switch.
+.TP
+\fB-n\fP \fIport\fP
+The port number to disable on the switch.
+.TP
+\fB-o\fP \fIaction\fP
+The action required. disable (default) or enable.
+.TP
+\fB-p\fP \fIpassword\fP
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-q\fP
+Quiet mode: print only error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_mcdata.
+.TP
+\fIipaddr = < hostname | ip >\fR
+IP address or hostname of the switch.
+.TP
+\fIlogin = < param >\fR
+Login name.
+.TP
+\fIoption = < param >\fR
+The action required. disable (default) or enable.
+.TP
+\fIpasswd = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+\fIport = < param >\fR
+The port number to disable on the switch.
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/rackswitch/Makefile.am b/fence/agents/rackswitch/Makefile.am
index 50dbf39..29cbef8 100644
--- a/fence/agents/rackswitch/Makefile.am
+++ b/fence/agents/rackswitch/Makefile.am
@@ -1,7 +1,11 @@
MAINTAINERCLEANFILES = Makefile.in
-sbin_PROGRAMS = fence_rackswitch
+TARGET = fence_rackswitch
+
+sbin_PROGRAMS = $(TARGET)
noinst_HEADERS = do_rack.h
fence_rackswitch_SOURCES = do_rack.c
+
+dist_man_MANS = $(TARGET).8
diff --git a/fence/agents/rackswitch/fence_rackswitch.8 b/fence/agents/rackswitch/fence_rackswitch.8
new file mode 100644
index 0000000..4f662c7
--- /dev/null
+++ b/fence/agents/rackswitch/fence_rackswitch.8
@@ -0,0 +1,68 @@
+.TH fence_rackswitch 8
+
+.SH NAME
+fence_rackswitch - I/O Fencing agent for RackSaver RackSwitch
+
+.SH SYNOPSIS
+.B
+fence_rackswitch
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_rackswitch is an I/O Fencing agent which can be used with the RackSaver
+RackSwitch. It logs into the RackSwitch and boots a specified plug.
+Using the http interface to the RackSwitch should be avoided while a GFS cluster is
+running because the connection may interfere with the operation of this agent.
+
+fence_rackswitch accepts options on the command line as well as from stdin.
+fenced sends the options through stdin when it execs the agent. fence_rackswitch
+can be run by itself with command line options which is useful for testing.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address of the switch.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-n\fP \fIplug\fP
+The plug number to power cycle.
+.TP
+\fB-p\fP \fIpassword\fP
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-l\fP \fIusername\fP
+Username for login.
+.TP
+\fB-q\fP
+Quiet operation. Only print out error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_rackswitch.
+.TP
+\fIipaddr = < ip >\fR
+IP address of the switch.
+.TP
+\fIusername = < param >\fR
+Username for login.
+.TP
+\fIpassword = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+\fIport = < param >\fR
+The port (outlet) number to act upon.
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/rsa/Makefile.am b/fence/agents/rsa/Makefile.am
index 3ee9ca3..4d938be 100644
--- a/fence/agents/rsa/Makefile.am
+++ b/fence/agents/rsa/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/rsb/Makefile.am b/fence/agents/rsb/Makefile.am
index f12c9a0..640758f 100644
--- a/fence/agents/rsb/Makefile.am
+++ b/fence/agents/rsb/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/sanbox2/Makefile.am b/fence/agents/sanbox2/Makefile.am
index 540511c..896ee4c 100644
--- a/fence/agents/sanbox2/Makefile.am
+++ b/fence/agents/sanbox2/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/scsi/Makefile.am b/fence/agents/scsi/Makefile.am
index f0ba890..ca87492 100644
--- a/fence/agents/scsi/Makefile.am
+++ b/fence/agents/scsi/Makefile.am
@@ -2,10 +2,12 @@ MAINTAINERCLEANFILES = Makefile.in
TARGET = fence_scsi
-EXTRA_DIST = fence_scsi.pl
+EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/scsi/fence_scsi.8 b/fence/agents/scsi/fence_scsi.8
new file mode 100644
index 0000000..eaab222
--- /dev/null
+++ b/fence/agents/scsi/fence_scsi.8
@@ -0,0 +1,107 @@
+.TH fence_scsi 8
+
+.SH NAME
+fence_scsi - I/O fencing agent for SCSI persistent reservations
+
+.SH SYNOPSIS
+.B
+fence_scsi
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_scsi is an I/O fencing agent which can be used with the SCSI
+devices that support persistent reservations (SPC-2 or greater).
+
+SCSI persistent reservations work by having each node in the cluster
+register with the SCSI device. Registration is done using a unique key
+(based on the node's IP address). Each node that will perform I/O
+operations to the shared storage must register with the device. This
+is done at system startup with the scsi_reserve init script. This
+script will discover all clustered volumes as well as the underlying
+SCSI device(s). Device discovery is done via the lvs command (see
+lvs(8)) and is subject to any filtering rules defined in the lvm.conf
+file.
+
+After generating the node's unique key, the script will register the
+node with the SCSI device(s) that were discovered. Once the node is
+registered, the script will attempt to create a reservation. Unlike
+registrations, of which there are multiple registrants (one for each
+node in the cluster), there is only one reservation holder. If a
+reservation does not already exist for a device, the script will
+create a reservation using the node's unique key.
+
+It is important to distinguish between registrations and
+reservations. As mentioned above, each node that will perform I/O
+operations to the SCSI device must register. As a result, there will
+be multiple registrations for a given SCSI device. In contrast, there
+can only be one reservation per SCSI device. It is not important which
+node holds the reservation. The reservation simply tells the device
+how the registrants are allowed to access the device. For our
+purposes, the reservation type is "write exclusive, registrants only".
+With this reservation type, only registered nodes will be able to
+write to the device.
+
+When the cluster must fence a node, it simply revokes a node's
+registration, or "unregisters" the node. This operation also uses the
+node's unique key. By deriving the unique key based on the errant
+node's IP address, the cluster can "unregister" the key. As a
+result, the errant node will no longer be able to write to the SCSI
+device.
+
+Note that the node that holds the reservation for a device must also
+be registered with that device. When the situation arises where the
+node that is being fenced is also the reservation holder, the
+reservation must be moved. This is handled by using the
+"preempt-and-abort command" which will transfer the reservation from
+the node that is being fenced to the node that is performing the
+fencing. This operation will maintain the reservation while
+"unregistering" the node being fenced.
+
+At system shutdown, the scsi_reserve script will attempt to
+"unregister" the node from all devices. The exception is when the
+node happens to be the reservation holder. In this case, the script
+does nothing, due to the fact that there may be other nodes using the
+device and the reservation must remain intact.
+
+fence_scsi accepts options on the command line as well as from stdin.
+fenced sends parameters through stdin when it execs the agent. fence_scsi
+can be run by itself with command line options. This is useful for testing
+and for turning outlets on or off from scripts.
+
+.SH OPTIONS
+.TP
+\fB-n\fP \fInode\fR
+Name of the node to be fenced.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-v\fP
+Verbose output.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_scsi.
+.TP
+\fInodename = < hostname | ip >\fR
+Name of the node to be fenced.
+.TP
+\fIself = < nodename >\fR
+Name of the node that will perform the fencing operation.
+.TP
+\fIverbose = < param >\fR
+Verbose output.
+
+.SH LIMITATIONS
+The fence_scsi fencing agent requires a minimum of three nodes in the
+cluster to operate. For SAN devices connected via fiber channel,
+these must be physical nodes. SAN devices connected via iSCSI may use
+virtual or physical nodes. In addition, fence_scsi cannot be used in
+conjunction with qdisk.
+
+.SH SEE ALSO
+fence(8), fence_node(8), sg_persist(8), lvs(8), lvm.conf(5)
diff --git a/fence/agents/virsh/Makefile.am b/fence/agents/virsh/Makefile.am
index 0d79efd..5b97b16 100644
--- a/fence/agents/virsh/Makefile.am
+++ b/fence/agents/virsh/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/vixel/Makefile.am b/fence/agents/vixel/Makefile.am
index 7f9a623..91d7277 100644
--- a/fence/agents/vixel/Makefile.am
+++ b/fence/agents/vixel/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/vixel/fence_vixel.8 b/fence/agents/vixel/fence_vixel.8
new file mode 100644
index 0000000..dc285c5
--- /dev/null
+++ b/fence/agents/vixel/fence_vixel.8
@@ -0,0 +1,70 @@
+.TH fence_vixel 8
+
+.SH NAME
+fence_vixel - I/O Fencing agent for Vixel FC switches
+
+.SH SYNOPSIS
+.B
+fence_vixel
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_vixel is an I/O Fencing agent which can be used with Vixel FC switches.
+It logs into a Vixel switch via telnet and removes the specified port from the
+zone. Removing the zone access from the port disables the port from being able
+to access the storage.
+
+fence_vixel accepts options on the command line as well as from stdin.
+fenced sends parameters through stdin when it execs the agent. fence_vixel
+can be run by itself with command line options which is useful for testing.
+
+After a fence operation has taken place the fenced machine can no longer
+connect to the Vixel FC switch. When the fenced machine is ready to be brought
+back into the GFS cluster (after reboot) the port on the Vixel FC switch needs
+to be enabled. In order to do this, log into the Vixel FC switch. Then go to:
+
+config->zones->config <port> <comma-separated-list-of-ports-in-the-zone>
+
+Then apply
+
+Consult the Vixel manual for details
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address of the switch.
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-n\fP \fIport\fP
+The port number to remove zoning from on the switch.
+.TP
+\fB-p\fP \fIpassword\fP
+Password for login.
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password for login.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_vixel.
+.TP
+\fIipaddr = < hostname | ip >\fR
+IP address or hostname of the switch.
+.TP
+\fIpasswd = < param >\fR
+Password for login.
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password for login.
+.TP
+\fIport = < param >\fR
+The port number to remove zoning from on the switch.
+
+.SH SEE ALSO
+fence(8), fence_node(8)
diff --git a/fence/agents/vmware/Makefile.am b/fence/agents/vmware/Makefile.am
index 935735b..3eecf95 100644
--- a/fence/agents/vmware/Makefile.am
+++ b/fence/agents/vmware/Makefile.am
@@ -1,12 +1,15 @@
MAINTAINERCLEANFILES = Makefile.in
-TARGET = fence_vmware_helper fence_vmware
+TARGET = fence_vmware fence_vmware_helper
-EXTRA_DIST = fence_vmware_helper.pl fence_vmware.py
+EXTRA_DIST = fence_vmware.py fence_vmware_helper.pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = fence_vmware.8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/wti/Makefile.am b/fence/agents/wti/Makefile.am
index 3704f72..8d778c7 100644
--- a/fence/agents/wti/Makefile.am
+++ b/fence/agents/wti/Makefile.am
@@ -6,7 +6,10 @@ EXTRA_DIST = $(TARGET).py
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
-clean-local:
+clean-local: clean-man
rm -f $(TARGET)
diff --git a/fence/agents/xcat/Makefile.am b/fence/agents/xcat/Makefile.am
index 46646f7..2f7f446 100644
--- a/fence/agents/xcat/Makefile.am
+++ b/fence/agents/xcat/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/xcat/fence_xcat.8 b/fence/agents/xcat/fence_xcat.8
new file mode 100644
index 0000000..7da35d5
--- /dev/null
+++ b/fence/agents/xcat/fence_xcat.8
@@ -0,0 +1,61 @@
+.TH fence_xcat 8
+
+.SH NAME
+fence_xcat - I/O Fencing agent for xcat environments
+
+.SH SYNOPSIS
+.B
+fence_xcat
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_xcat is a wrapper to the rpower(1) command that is distributed
+with the xCAT project available at http://www.xcat.org. Use of
+fence_xcat requires that xcat has already been properly configured
+for your environment. Refer to xCAT(1) for more information on
+configuring xCAT.
+
+fence_xcat accepts options on the command line as well as from stdin.
+fenced sends parameters through stdin when it execs the agent. fence_xcat
+can be run by itself with command line options which is useful for testing.
+
+NOTE: It is recommended that fence_bladecenter(8) is used instead of fence_xcat if
+the bladecenter firmware supports telnet. This interface is much cleaner and
+easier to setup.
+
+.SH OPTIONS
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-n\fP \fInodename\fP
+The nodename as defined in nodelist.tab of the xCAT setup.
+.TP
+\fB-o\fP \fIaction\fP
+The action required. on, off, reset (default) or stat.
+.TP
+\fB-r\fP \fIrpower\fP
+The path to the rpower binary.
+.TP
+\fB-q\fP
+Quiet mode: print only error messages.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fR
+This option is used by fence_node(8) and is ignored by fence_xcat.
+.TP
+\fInodename = < param >\fR
+The nodename as defined in nodelist.tab of the xCAT setup.
+.TP
+\fIaction = < param >\fR
+The action required. on, off, reset (default) or stat.
+.TP
+\fIrpower = < param >\fR
+The path to the rpower binary.
+
+.SH SEE ALSO
+fence(8), fence_node(8), fence_bladecenter(8), nodelist.tab(8), rpower(1), xCAT(1)
diff --git a/fence/agents/zvm/Makefile.am b/fence/agents/zvm/Makefile.am
index 1e730af..dfbeb35 100644
--- a/fence/agents/zvm/Makefile.am
+++ b/fence/agents/zvm/Makefile.am
@@ -6,6 +6,8 @@ EXTRA_DIST = $(TARGET).pl
sbin_SCRIPTS = $(TARGET)
+dist_man_MANS = $(TARGET).8
+
include $(top_srcdir)/make/fencebuild.mk
clean-local:
diff --git a/fence/agents/zvm/fence_zvm.8 b/fence/agents/zvm/fence_zvm.8
new file mode 100644
index 0000000..b22f8e1
--- /dev/null
+++ b/fence/agents/zvm/fence_zvm.8
@@ -0,0 +1,62 @@
+.TH fence_zvm 8
+
+.SH NAME
+fence_zvm - I/O Fencing agent for GFS on s390 and zSeries VM clusters
+
+.SH SYNOPSIS
+.B
+fence_zvm
+[\fIOPTION\fR]...
+
+.SH DESCRIPTION
+fence_zvm is an I/O Fencing agent used on a GFS virtual machine in a s390 or zSeries VM cluster.
+It uses the s3270 program to log the specified virtual machine out of VM.
+For fence_zvm to execute correctly, you must have s3270 in your PATH.
+
+fence_zvm accepts options on the command line as well as from stdin.
+fence_node sends the options through stdin when it execs the agent.
+fence_zvm can be run by itself with command line options which is useful
+for testing.
+
+.SH OPTIONS
+.TP
+\fB-a\fP \fIIPaddress\fP
+IP address or hostname of the Physical machine (required).
+.TP
+\fB-h\fP
+Print out a help message describing available options, then exit.
+.TP
+\fB-u\fP \fIuserid\fP
+userid of the virtual machine to fence (required).
+.TP
+\fB-p\fP \fIpassword\fP
+password of the virtual machine to fence (required).
+.TP
+\fB-S\fP \fIpath\fR
+Full path to an executable to generate the password of the virtual machine to fence.
+.TP
+\fB-q\fP
+quiet mode, no output.
+.TP
+\fB-V\fP
+Print out a version message, then exit.
+
+.SH STDIN PARAMETERS
+.TP
+\fIagent = < param >\fP
+This option is used by fence_node(8) and is ignored by fence_zvm.
+.TP
+\fIipaddr = < hostname | ip >\fP
+IP address or hostname of the Physical machine (required).
+.TP
+\fIpasswd = < param >\fP
+password of the virtual machine to fence (required).
+.TP
+\fIpasswd_script = < param >\fR
+Full path to an executable to generate the password of the virtual machine to fence.
+.TP
+\fIuserid = < param >\fP
+userid of the virtual machine to fence (required).
+
+.SH SEE ALSO
+fence(8), fenced(8), fence_node(8)
diff --git a/fence/man/Makefile.am b/fence/man/Makefile.am
deleted file mode 100644
index a50ecf8..0000000
--- a/fence/man/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_man_MANS = fence_ack_manual.8 \
- fence_alom.8 \
- fence_apc.8 \
- fence_apc_snmp.8 \
- fence_baytech.8 \
- fence_bladecenter.8 \
- fence_brocade.8 \
- fence_bullpap.8 \
- fence_cisco_mds.8 \
- fence_cpint.8 \
- fence_drac.8 \
- fence_egenera.8 \
- fence_eps.8 \
- fence_ibmblade.8 \
- fence_ifmib.8 \
- fence_ilo.8 \
- fence_intelmodular.8 \
- fence_ipmilan.8 \
- fence_ldom.8 \
- fence_mcdata.8 \
- fence_rackswitch.8 \
- fence_rib.8 \
- fence_rsa.8 \
- fence_rsb.8 \
- fence_sanbox2.8 \
- fence_scsi.8 \
- fence_virsh.8 \
- fence_vixel.8 \
- fence_vmware.8 \
- fence_wti.8 \
- fence_xcat.8 \
- fence_zvm.8
diff --git a/fence/man/fence_ack_manual.8 b/fence/man/fence_ack_manual.8
deleted file mode 100644
index e2ba505..0000000
--- a/fence/man/fence_ack_manual.8
+++ /dev/null
@@ -1,36 +0,0 @@
-.TH fence_ack_manual 8
-
-.SH NAME
-fence_ack_manual - program run by an operator as a part of manual I/O Fencing
-
-.SH SYNOPSIS
-.B
-fence_ack_manual
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_ack_manual is run by an operator on the same node that fence_manual(8)
-was run after the operator has reset a node which required fencing. A message
-in the system log indicates to the operator that they must reset a machine and
-then run fence_ack_manual. Running fence_ack_manual allows the cluster to
-continue with recovery of the fenced machine. The victim may be disconnected
-from storage rather than resetting it.
-
-.SH OPTIONS
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-O\fP
-Run without prompting for user confirmation.
-.TP
-\fB-n\fP \fInodename\fP
-Name of node that has been reset or disconnected from storage.
-.TP
-\fB-s\fP \fIIPaddress\fP
-IP address of the machine which has been reset or disconnected from storage. (Deprecated; use -n instead.)
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_alom.8 b/fence/man/fence_alom.8
deleted file mode 100644
index 367bb54..0000000
--- a/fence/man/fence_alom.8
+++ /dev/null
@@ -1,84 +0,0 @@
-.TH fence_vmware 8
-
-.SH NAME
-fence_alom - I/O Fencing agent for Sun Advanced Lights Out Manager (ALOM)
-
-.SH SYNOPSIS
-.B
-fence_alom
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_alom is an I/O Fencing agent which can be used with ALOM connected machines.
-
-fence_alom accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_alom
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of ALOM.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), status, off or on.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login.
-.TP
-\fB-B\fP \fIscript\fR
-Script to run to retrieve password.
-.TP
-\fB-x\fP
-Use secure connection over ssh (this is default, and can't be disabled)
-.TP
-\fB-T\fP
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_alom.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of ALOM.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), off or on.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-.TP
-\fIsecure = < param >\fR
-Use secure connection over ssh (this is default, and can't be disabled)
-.TP
-\fItest = < param >\fR
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_apc.8 b/fence/man/fence_apc.8
deleted file mode 100644
index 42eafbe..0000000
--- a/fence/man/fence_apc.8
+++ /dev/null
@@ -1,98 +0,0 @@
-.TH fence_apc 8
-
-.SH NAME
-fence_apc - I/O Fencing agent for APC MasterSwitch
-
-.SH SYNOPSIS
-.B
-fence_apc
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_apc is an I/O Fencing agent which can be used with the APC MasterSwitch
-network power switch. It logs into a MasterSwitch via telnet and reboots
-a specified outlet. Lengthy telnet connections to the MasterSwitch should
-be avoided while a GFS cluster is running because the connection will
-block any necessary fencing actions.
-
-fence_apc accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_apc
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-n\fP \fI[<switch>:]outlet\fR
-The outlet number to act upon.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), status, off or on.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login or for passphrase.
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password.
-.TP
-\fB-x\fP
-Use secure connection over ssh (using version 1, cipher blowfish).
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-T\fP
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fB-v\fP
-Verbose.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_apc.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), off or on.
-.TP
-\fIpasswd = < param >\fR
-Password for login or for passphrase.
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-\fIsecure = < param >\fR
-Use secure connection over ssh.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The outlet number to act upon.
-.TP
-\fIswitch = < param >\fR
-The switch to operate on. Defaults to "1" if not specified.
-.TP
-\fItest = < param >\fR
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fIverbose = < param >\fR
-Verbose.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_apc_snmp.8 b/fence/man/fence_apc_snmp.8
deleted file mode 100644
index 0e4805e..0000000
--- a/fence/man/fence_apc_snmp.8
+++ /dev/null
@@ -1,139 +0,0 @@
-.TH fence_apc_snmp 8
-
-.SH NAME
-fence_apc_snmp - I/O Fencing agent for APC PDU SNMP devices
-
-.SH SYNOPSIS
-.B
-fence_apc_snmp
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_apc is an I/O Fencing agent which can be used with the APC rPDU,
-MasterSwitch and MasterSwitch+ network power switch. It logs into a device via
-SNMP and reboots a specified outlet. It supports SNMP v1 and v3 with all combinations
-of authenticity/privacy settings.
-
-fence_apc_snmp accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_apc_snmp
-can be run by itself with command line options. This is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-c\fP \fIcommunity\fR
-The read/write community string to be used in the request. Default private.
-.TP
-\fB-n\fP \fIname\fR
-Name of port to fence or port index. Port can use syntax switch:port.
-.TP
-\fB-s\fP \fInumber\fR
-The switch to operate on. Defaults to "1" if not specified.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-P\fP \fIpassword\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-R\fP \fIscript\fR
-Script to run to retrieve privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-l\fP \fIlogin\fR
-Login name for SNMP v3 (security name).
-.TP
-\fB-d\fP \fIversion\fR
-SNMP version (1,2c,3). Default 1.
-.TP
-\fB-b\fP \fIauth_protocol\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fB-E\fP \fIsec_level\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fB-B\fP \fIpriv_protocol\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fB-u\fP \fIudp_port\fR
-UDP/TCP port to use.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_apc_snmp.
-.TP
-\fIipaddr = < param >\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fIcommunity = < param >\fR
-The read/write community string to be used in the request. Default private.
-.TP
-\fIport = < param >\fR
-Name of port to fence or port index. Port can use syntax switch:port.
-.TP
-\fIswitch = < param >\fR
-The switch to operate on. Defaults to "1" if not specified.
-.TP
-\fIpasswd = < param >\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd_script = < param>\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIlogin = < param >\fR
-Login name for SNMP v3 (security name).
-.TP
-\fIsnmp_version = < param >\fR
-SNMP version (1,2c,3). Default 1.
-.TP
-\fIsnmp_auth_prot = < param >\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fIsnmp_sec_level = < param >\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fIsnmp_priv_prot = < param >\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fIudpport = < param >\fR
-UDP/TCP port to use.
-.TP
-\fIaction = < param >\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_baytech.8 b/fence/man/fence_baytech.8
deleted file mode 100644
index e60175d..0000000
--- a/fence/man/fence_baytech.8
+++ /dev/null
@@ -1,82 +0,0 @@
-.TH fence_baytech 8
-
-.SH NAME
-fence_baytech - I/O Fencing agent for Baytech RPC switches in combination with a Cyclades Terminal Server
-
-.SH SYNOPSIS
-.B
-fence_baytech
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-
-This fencing agent is written for the Baytech RPC27-20nc in combination with
-a Cyclades terminal server. The Cyclades TS exports the RPC's serial port
-via a Telnet interface. Other interfaces, such as SSH, are possible.
-However, this script relies upon the assumption that Telnet is used. Future
-features to this agent would allow the agent to work with a multitude of
-different communication protocols such as Telnet, SSH or Kermit.
-
-The other assumption that is made is that Outlet names do not end in space.
-The name "Foo" and "Foo " are identical when the RPC prints them with
-the status command.
-
-fence_baytech accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_baytech
-can be run by itself with command line options which is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIhost\fP
-IP address or hostname to connect to.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Username name for the switch.
-.TP
-\fB-n\fP \fIport\fP
-The name of the outlet to act upon.
-.TP
-\fB-o\fP \fIaction\fP
-The action required. This can be on, off, status or reboot (default)
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-q\fP
-Quiet mode: print only error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_baytech.
-.TP
-\fIhost = < hostname | ip >\fR
-IP address or hostname to connect to.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIaction = < param >\fR
-The action required. This can be on, off, status or reboot (default)
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIoutlet = < param >\fR
-The name of the outlet to act upon.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_bladecenter.8 b/fence/man/fence_bladecenter.8
deleted file mode 100644
index dabdb5d..0000000
--- a/fence/man/fence_bladecenter.8
+++ /dev/null
@@ -1,95 +0,0 @@
-.TH fence_bladecenter 8
-
-.SH NAME
-fence_bladecenter - I/O Fencing agent for IBM Bladecenter
-
-.SH SYNOPSIS
-.B
-fence_bladecenter
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_bladecenter is an I/O Fencing agent which can be used with IBM
-Bladecenters with recent enough firmware that includes telnet support. It
-logs into a Brocade chasis via telnet or ssh and uses the command line
-interface to power on and off blades. fence_bladecenter accepts options on
-the command line or from stdin.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the Bladecenter.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Login name for the Bladecenter.
-.TP
-\fB-n\fP \fIblade\fP
-The blade to operate on.
-.TP
-\fB-o\fP \fIaction\fP
-The action required. Valid actions are on, off, reboot (default) and status.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login or for passphrase.
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password.
-.TP
-\fB-k\fP \fIidentity\fR
-Identity file (private key) for ssh connection.
-.TP
-\fB-x\fP
-Use secure connection over ssh.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-q\fP
-Quiet mode: print only error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-.TP
-\fB-v\fP \fIdebuglog\fP
-Log the telnet session to \fIdebuglog\fP for debugging purposes.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_bladecenter.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. disable (default) or enable.
-.TP
-\fIpasswd = < param >\fR
-Password for login or for passphrase.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-.TP
-\fIidentity_file = < param > \fR
-Identity file (private key) for ssh.
-.TP
-\fIsecure = < param >\fR
-Use secure connection over ssh.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIblade = < param >\fR
-The blade to operate on.
-.TP
-\fIdebuglog = < param>\fR
-Optional parameter to send debug transcript of the telnet session to a log file
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_brocade.8 b/fence/man/fence_brocade.8
deleted file mode 100644
index 36fde82..0000000
--- a/fence/man/fence_brocade.8
+++ /dev/null
@@ -1,82 +0,0 @@
-.TH fence_brocade 8
-
-.SH NAME
-fence_brocade - I/O Fencing agent for Brocade FC switches
-
-.SH SYNOPSIS
-.B
-fence_brocade
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_brocade is an I/O Fencing agent which can be used with Brocade FC
-switches. It logs into a Brocade switch via telnet and disables a specified
-port. Disabling the port which a machine is connected to effectively fences
-that machine. Lengthy telnet connections to the switch should be avoided
-while a GFS cluster is running because the connection will block any necessary
-fencing actions.
-
-fence_brocade accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_brocade
-can be run by itself with command line options which is useful for testing.
-
-After a fence operation has taken place the fenced machine can no longer connect
-to the Brocade FC switch. When the fenced machine is ready to be brought back
-into the GFS cluster (after reboot) the port on the Brocade FC switch needs to
-be enabled. This can be done by running fence_brocade and specifying the
-enable action.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Login name for the switch.
-.TP
-\fB-n\fP \fIport\fP
-The port number to disable on the switch.
-.TP
-\fB-o\fP \fIaction\fP
-The action required. disable (default) or enable.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-q\fP
-Quiet mode: print only error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_brocade.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. disable (default) or enable.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The port number to disable on the switch.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_bullpap.8 b/fence/man/fence_bullpap.8
deleted file mode 100644
index 876b406..0000000
--- a/fence/man/fence_bullpap.8
+++ /dev/null
@@ -1,71 +0,0 @@
-.TH fence_bullpap 8
-
-.SH NAME
-fence_bullpap - I/O Fencing agent for Bull FAME architecture controlled by a
-PAP management console.
-
-.SH SYNOPSIS
-.B
-fence_bullpap
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_bullpap is an I/O Fencing agent which can be used with Bull's NovaScale
-machines controlled by PAP management consoles. This agent calls Bull's
-support software provided by the NSMasterHW RPM available from Bull.
-
-fence_bullpap accepts options on the command line as well as from stdin.
-fenced sends the options through stdin when it execs the agent. fence_bullpap
-can be run by itself with command line options which is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address or hostname of the PAP management console.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Login with administrative privileges.
-.TP
-\fB-d\fP \fIdomain\fP
-This is the domain name of the Bull machine to power-cycle.
-.TP
-\fB-o\fP \fIoption\fP
-Action to perform (on, off, reboot, status).
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-q\fP
-Quiet operation. Only print out error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the PAP management console.
-.TP
-\fIlogin= < param >\fR
-Login with administrative privileges.
-.TP
-\fIdomain = < param >\fR
-This is the domain name of the Bull machine to power-cycle.
-.TP
-\fIoption = < param >\fR
-Action to perform (on, off, reboot, status).
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_cisco_mds.8 b/fence/man/fence_cisco_mds.8
deleted file mode 100644
index 8c58d63..0000000
--- a/fence/man/fence_cisco_mds.8
+++ /dev/null
@@ -1,132 +0,0 @@
-.TH fence_cisco_mds 8
-
-.SH NAME
-fence_cisco_mds - I/O Fencing agent for Cisco MDS 9000 series SNMP devices
-
-.SH SYNOPSIS
-.B
-fence_cisco_mds
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_cisco_mds is an I/O Fencing agent which can be used with any Cisco MDS
-9000 series with SNMP enabled device. Agent internally uses snmpget, snmpset
-and snmpwalk command.
-
-fence_cisco_mds accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_cisco_mds
-can be run by itself with command line options. This is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the Cisco device. Can be used any syntax supported by snmpget.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-c\fP \fIcommunity\fR
-The read/write community string to be used in the request.
-.TP
-\fB-n\fP \fIname\fR
-Name of port to fence (fc1/1)
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-P\fP \fIpassword\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-R\fP \fIscript\fR
-Script to run to retrieve privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-l\fP \fIlogin\fR
-Login name for SNMP v3 (security name).
-.TP
-\fB-d\fP \fIversion\fR
-SNMP version (1,2c,3).
-.TP
-\fB-b\fP \fIauth_protocol\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fB-E\fP \fIsec_level\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fB-B\fP \fIpriv_protocol\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fB-u\fP \fIudp_port\fR
-UDP/TCP port to use.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_cisco_mds.
-.TP
-\fIipaddr = < param >\fR
-IP address or hostname of the Cisco device. Can be used any syntax supported by snmpget.
-.TP
-\fIcommunity = < param >\fR
-The read/write community string to be used in the request.
-.TP
-\fIport = < param >\fR
-Name of port to fence (fc1/1)
-.TP
-\fIpasswd = < param >\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd_script = < param>\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIlogin = < param >\fR
-Login name for SNMP v3 (security name).
-.TP
-\fIsnmp_version = < param >\fR
-SNMP version (1,2c,3).
-.TP
-\fIsnmp_auth_prot = < param >\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fIsnmp_sec_level = < param >\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fIsnmp_priv_prot = < param >\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fIudpport = < param >\fR
-UDP/TCP port to use.
-.TP
-\fIaction = < param >\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_cpint.8 b/fence/man/fence_cpint.8
deleted file mode 100644
index efbaa7e..0000000
--- a/fence/man/fence_cpint.8
+++ /dev/null
@@ -1,52 +0,0 @@
-.TH fence_cpint 8
-
-.SH NAME
-fence_cpint - I/O Fencing agent for GFS on s390 and zSeries VM clusters
-
-.SH SYNOPSIS
-.B
-fence_cpint
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_cpint is an I/O Fencing agent used on a virtual machine running GFS in a
-s390 or zSeries VM cluster.
-It uses the cpint package to send a CP LOGOFF command to the specified virtual
-machine.
-For fence_cpint to execute correctly, you must have the cpint module installed,
-and hcp in your PATH.
-\fBNOTE:\fP for fence_cpint to send a command to another virtual machine, the
-machine executing it must either be a privilege class C user or it must be
-the secondary user of the virtual machine to be fenced. This means that unless
-all of you GULM server nodes are privilege class C, fence_cpint can only be
-used with SLM.
-
-fence_cpint accepts options on the command line as well as from stdin.
-fence_node sends the options through stdin when it execs the agent.
-fence_cpint can be run by itself with command line options which is useful for
-testing.
-
-.SH OPTIONS
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-u\fP \fIuserid\fP
-userid of the virtual machine to fence (required).
-.TP
-\fB-q\fP
-quiet mode, no output.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_cpint.
-.TP
-\fIuserid = < parm >\fP
-userid of the virtual machine to fence (required).
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_drac.8 b/fence/man/fence_drac.8
deleted file mode 100644
index 8dda184..0000000
--- a/fence/man/fence_drac.8
+++ /dev/null
@@ -1,97 +0,0 @@
-.TH fence_drac 8
-
-.SH NAME
-fence_drac - fencing agent for Dell Remote Access Card
-
-.SH SYNOPSIS
-.B
-fence_drac
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_drac is an I/O Fencing agent which can be used with the Dell Remote
-Access Card (DRAC). This card provides remote access to controlling
-power to a server. It logs into the DRAC through the telnet interface of
-the card. By default, the telnet interface is not enabled. To enable the
-interface, you will need to use the racadm command in the racser-devel rpm
-available from Dell. To enable telnet on the DRAC:
-
-[root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1
-
-[root]# racadm racreset
-
-fence_drac accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_drac
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the switch.
-.TP
-\fB-c\fP \fIcmd_prompt\fR
-Force fence_drac to use cmd_prompt as the command prompt
-.TP
-\fB-d\fP \fIdracversion\fR
-Force fence_drac to treat the device as though it was for the specified drac version
-.TP
-\fB-D\fP \fIdumpfile\fR
-Debug file of the telnet interaction
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-m\fP \fImodulename\fR
-The module name of the blade when using DRAC/MC firmware.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. reboot (default), off, on or status.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIaction = < param >\fR
-The action required. reboot (default), off, on or status.
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_apc.
-.TP
-\fIcmd_prompt = < param >\fr
-Force fence_drac to use cmd_prompt as the command prompt
-.TP
-\fIdrac_version = < param >\fr
-Force fence_drac to treat the device as though it was for the specified drac version.
-.TP
-\fIdebug = < dumpfile >\fR
-Debug file of the telnet interaction
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fImodulename = < param >\fr
-The module name of the blade when using DRAC/MC firmware.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_egenera.8 b/fence/man/fence_egenera.8
deleted file mode 100644
index cfa839e..0000000
--- a/fence/man/fence_egenera.8
+++ /dev/null
@@ -1,70 +0,0 @@
-.TH fence_egenera 8
-
-.SH NAME
-fence_egenera - I/O Fencing agent for the Egenera BladeFrame
-
-.SH SYNOPSIS
-.B
-fence_egenera
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_egenera is an I/O Fencing agent which can be used with the Egenera
-BladeFrame. It logs into a control blade (cserver) via ssh and operates
-on a processing blade (pserver) identified by the pserver name and the
-logical process area network (LPAN) that it is in. fence_egenera requires
-that ssh keys have been setup so that the fence_egenera does not require
-a password to authenticate. Refer to ssh(8) for more information on setting
-up ssh keys.
-
-fence_egenera accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_egenera
-can also be run by itself with command line options.
-
-.SH OPTIONS
-.TP
-\fB-c\fP \fIcserver\fR
-The cserver to ssh to. cserver can be in the form user@hostname to
-specify a different user to login as.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlpan\fR
-the lpan to operate on
-.TP
-\fB-o\fP \fIaction\fR
-The action required. reboot (default), off, on or status.
-.TP
-\fB-p\fP \fIpserver\fR
-the pserver to operate on
-.TP
-\fB-q\fP
-quite mode. suppress output.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIaction = < param >\fR
-The action required. reboot (default), off, on or status.
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_apc.
-.TP
-\fIcserver = < param >\fR
-The cserver to ssh to. cserver can be in the form user@hostname to
-specify a different user to login as.
-.TP
-\fIlpan = < param >\fR
-The lpan to operate on
-.TP
-\fIpserver = < param >\fR
-The pserver to operate on
-.TP
-\fIesh = < param >\fR
-The path to the esh command on the cserver (default is /opt/panmgr/bin/esh)
-
-.SH SEE ALSO
-fence(8), fence_node(8), ssh(8)
diff --git a/fence/man/fence_eps.8 b/fence/man/fence_eps.8
deleted file mode 100644
index 3685837..0000000
--- a/fence/man/fence_eps.8
+++ /dev/null
@@ -1,106 +0,0 @@
-.TH fence_eps 8
-
-.SH NAME
-fence_eps - I/O Fencing agent for ePowerSwitch 8M+ power switch
-
-.SH SYNOPSIS
-.B
-fence_eps
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_eps is an I/O Fencing agent which can be used with the ePowerSwitch 8M+ power
-switch to fence connected machines. Fence agent works (in 2008/10/21) ONLY on 8M+
-device, because this is only one, which has support for hidden page feature.
-
-Agent basically works by connecting to hidden page and pass appropriate arguments
-to GET request. This means, that hidden page feature must be enabled and properly
-configured.
-
-fence_eps accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_eps
-can be run by itself with command line options. This is useful for testin
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of ePowerSwitch 8M+ device. If device is configured
-to listen on nonstandard port (other than 80), it's possible to use :port syntax
-(ex. psip:8080).
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), status, off or on.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login.
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password.
-.TP
-\fB-n\fP \fIname\fR
-Physical plug number. Entered without P and with preceding zero (where is needed).
-.TP
-\fB-c\fP \fIname\fR
-Name of hidden page. Default is (hidden.htm)
-.TP
-\fB-T\fP
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fB-q\fP
-Quiet mode.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_eps.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of ePowerSwitch 8M+ device. If device is configured
-to listen on nonstandard port (other than 80), it's possible to use :port syntax
-(ex. psip:8080).
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), status, off or on.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-.TP
-\fIport = < param >\fR
-Physical plug number. Entered without P and with preceding zero (where is needed)
-.TP
-\fIhidden_page = < param >\fR
-Name of hidden page. Default is (hidden.htm)
-.TP
-\fItest = < param >\fR
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_ibmblade.8 b/fence/man/fence_ibmblade.8
deleted file mode 100644
index fb573af..0000000
--- a/fence/man/fence_ibmblade.8
+++ /dev/null
@@ -1,132 +0,0 @@
-.TH fence_ibmblade 8
-
-.SH NAME
-fence_ibmblade - I/O Fencing agent for IBM BladeCenter
-
-.SH SYNOPSIS
-.B
-fence_ibmblade
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_ibmblade is an I/O Fencing agent which can be used with IBM BladeCenter
-chassis. It issues SNMP Set request to BladeCenter chassis, rebooting, powering
-up or down the specified Blade Server.
-
-fence_ibmblade accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_ibmblade
-can be run by itself with command line options. This is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-c\fP \fIcommunity\fR
-The read/write community string to be used in the request.
-.TP
-\fB-n\fP \fIname\fR
-Name of port to fence or ifIndex.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-P\fP \fIpassword\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-R\fP \fIscript\fR
-Script to run to retrieve privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-l\fP \fIlogin\fR
-Login name for SNMP v3 (security name).
-.TP
-\fB-d\fP \fIversion\fR
-SNMP version (1,2c,3). Default is 1.
-.TP
-\fB-b\fP \fIauth_protocol\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fB-E\fP \fIsec_level\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fB-B\fP \fIpriv_protocol\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fB-u\fP \fIudp_port\fR
-UDP/TCP port to use.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_ibmblade.
-.TP
-\fIipaddr = < param >\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fIcommunity = < param >\fR
-The read/write community string to be used in the request.
-.TP
-\fIport = < param >\fR
-Name of port to fence or ifIndex.
-.TP
-\fIpasswd = < param >\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd_script = < param>\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIlogin = < param >\fR
-Login name for SNMP v3 (security name).
-.TP
-\fIsnmp_version = < param >\fR
-SNMP version (1,2c,3). Default is 1.
-.TP
-\fIsnmp_auth_prot = < param >\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fIsnmp_sec_level = < param >\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fIsnmp_priv_prot = < param >\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fIudpport = < param >\fR
-UDP/TCP port to use.
-.TP
-\fIaction = < param >\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_ifmib.8 b/fence/man/fence_ifmib.8
deleted file mode 100644
index 38cd223..0000000
--- a/fence/man/fence_ifmib.8
+++ /dev/null
@@ -1,136 +0,0 @@
-.TH fence_ifmib 8
-
-.SH NAME
-fence_ifmib - I/O Fencing agent for IF-MIB capable SNMP devices
-
-.SH SYNOPSIS
-.B
-fence_ifmib
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_ifmib is an I/O Fencing agent which can be used with any SNMP IF-MIB capable
-device. Agent internally uses snmpget, snmpset and snmpwalk command.
-
-It was written with managed ethernet switches in mind, in order
-to fence iSCSI SAN connections. However, there are many devices that support
-the IF-MIB interface. The agent uses IF-MIB::ifAdminStatus to control the
-state of an interface.
-
-fence_ifmib accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_ifmib
-can be run by itself with command line options. This is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-c\fP \fIcommunity\fR
-The read/write community string to be used in the request.
-.TP
-\fB-n\fP \fIname\fR
-Name of port to fence (fc1/1) or ifIndex (43).
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-P\fP \fIpassword\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-R\fP \fIscript\fR
-Script to run to retrieve privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-l\fP \fIlogin\fR
-Login name for SNMP v3 (security name).
-.TP
-\fB-d\fP \fIversion\fR
-SNMP version (1,2c,3).
-.TP
-\fB-b\fP \fIauth_protocol\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fB-E\fP \fIsec_level\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fB-B\fP \fIpriv_protocol\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fB-u\fP \fIudp_port\fR
-UDP/TCP port to use.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_ifmib.
-.TP
-\fIipaddr = < param >\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fIcommunity = < param >\fR
-The read/write community string to be used in the request.
-.TP
-\fIport = < param >\fR
-Name of port to fence (fc1/1) or ifIndex (43).
-.TP
-\fIpasswd = < param >\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd_script = < param>\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIlogin = < param >\fR
-Login name for SNMP v3 (security name).
-.TP
-\fIsnmp_version = < param >\fR
-SNMP version (1,2c,3).
-.TP
-\fIsnmp_auth_prot = < param >\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fIsnmp_sec_level = < param >\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fIsnmp_priv_prot = < param >\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fIudpport = < param >\fR
-UDP/TCP port to use.
-.TP
-\fIaction = < param >\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_ilo.8 b/fence/man/fence_ilo.8
deleted file mode 100644
index 7e2d62a..0000000
--- a/fence/man/fence_ilo.8
+++ /dev/null
@@ -1,94 +0,0 @@
-.TH fence_ilo 8
-
-.SH NAME
-fence_ilo - I/O Fencing agent for HP Integrated Lights Out card
-
-.SH SYNOPSIS
-.B
-fence_ilo
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_ilo is an I/O Fencing agent used for HP servers with the Integrated Light
-Out (iLO) PCI card. The agent opens an SSL connection to the iLO card. Once the
-SSL connection is established, the agent is able to communicate with the iLO
-card through an XML stream.
-
-fence_ilo depends on the pyOpenSSL available in your distribution or
-downloadable from http://pyopenssl.sourceforge.net
-
-NOTE: fence_ilo deprecates fence_rib.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress[:port]\fR
-IP address or hostname of the iLO card. If the SSL server of the card is
-not running on the default SSL port, 443, then [:port] will also need to be
-specified.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. reboot (default), off, on or status.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login or for passphrase.
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password.
-\fB-z\fP
-Use secure connection over SSL (default).
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-r\fP \fIprotocol\fR
-RIBCL protocol to use. Default is to autodetect.
-.TP
-\fB-v\fP
-Verbose.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIaction = < param >\fR
-The action required. reboot (default), off, on or status.
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_ilo.
-.TP
-\fIhostname = < hostname | ip >\fR
-IP address or hostname of the iLO card.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIpasswd = < param >\fR
-Password for login or for passphrase.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-.TP
-\fIssl = < param >\fR
-Use secure connection over SSL.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIribcl = < param >\fR
-RIBCL protocol to use. Default is to autodetect.
-.TP
-\fIverbose = < param >\fR
-Verbose mode.
-
-.SH SEE ALSO
-fence(8), fence_node(8), fence_rib(8)
diff --git a/fence/man/fence_intelmodular.8 b/fence/man/fence_intelmodular.8
deleted file mode 100644
index 37befa5..0000000
--- a/fence/man/fence_intelmodular.8
+++ /dev/null
@@ -1,136 +0,0 @@
-.TH fence_intelmodular 8
-
-.SH NAME
-fence_intelmodular - I/O Fencing agent for Intel MFSYS SNMP devices
-
-.SH SYNOPSIS
-.B
-fence_intelmodular
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_intelmodular is an I/O Fencing agent which can be used with
-Intel Modular device (tested on Intel MFSYS25, should work with
-MFSYS35 as well). Agent internally uses snmpget, snmpset and snmpwalk command.
-
-fence_intelmodular accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_intelmodular can be run by itself with command line options. This is useful for testing.
-
-\fBNote:\fR
-Since firmware update version 2.7, SNMP v2 write support is removed, and replaced by SNMP v3 support. So
-agent now has default SNMP version 3. If you are using older firmware, please supply \fB-d\fR for command line and
-\fIsnmp_version\fR option for your cluster.conf.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-c\fP \fIcommunity\fR
-The read/write community string to be used in the request.
-.TP
-\fB-n\fP \fIname\fR
-Name of port to fence or ifIndex.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-P\fP \fIpassword\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fB-R\fP \fIscript\fR
-Script to run to retrieve privacy for SNMP v3 (privacy protocol password).
-.TP
-\fB-l\fP \fIlogin\fR
-Login name for SNMP v3 (security name).
-.TP
-\fB-d\fP \fIversion\fR
-SNMP version (1,2c,3). Default is 3.
-.TP
-\fB-b\fP \fIauth_protocol\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fB-E\fP \fIsec_level\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fB-B\fP \fIpriv_protocol\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fB-u\fP \fIudp_port\fR
-UDP/TCP port to use.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_intelmodular.
-.TP
-\fIipaddr = < param >\fR
-IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
-.TP
-\fIcommunity = < param >\fR
-The read/write community string to be used in the request.
-.TP
-\fIport = < param >\fR
-Name of port to fence or ifIndex.
-.TP
-\fIpasswd = < param >\fR
-Password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
-.TP
-\fIsnmp_priv_passwd_script = < param>\fR
-Password for privacy for SNMP v3 (privacy protocol password).
-.TP
-\fIlogin = < param >\fR
-Login name for SNMP v3 (security name).
-.TP
-\fIsnmp_version = < param >\fR
-SNMP version (1,2c,3). Default is 3.
-.TP
-\fIsnmp_auth_prot = < param >\fR
-SNMP authentication protocol (MD5|SHA).
-.TP
-\fIsnmp_sec_level = < param >\fR
-SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
-.TP
-\fIsnmp_priv_prot = < param >\fR
-SNMP privacy protocol (DES|AES).
-.TP
-\fIudpport = < param >\fR
-UDP/TCP port to use.
-.TP
-\fIaction = < param >\fR
-The action required. off (default), on, status, list or monitor. Deprecated
-options (enable -> on and disable -> off) can be used too.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_ipmilan.8 b/fence/man/fence_ipmilan.8
deleted file mode 100644
index 98006f6..0000000
--- a/fence/man/fence_ipmilan.8
+++ /dev/null
@@ -1,110 +0,0 @@
-.TH fence_ipmilan 8
-
-.SH NAME
-fence_ipmilan - I/O Fencing agent for machines controlled by IPMI over
-LAN.
-
-.SH SYNOPSIS
-.B
-fence_ipmilan
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_ipmilan is an I/O Fencing agent which can be used with
-machines controlled by IPMI. This agent calls support software
-using ipmitool (http://ipmitool.sf.net/).
-
-fence_ipmilan accepts options on the command line as well as from stdin.
-fenced sends the options through stdin when it execs the agent. fence_ipmilan
-can be run by itself with command line options which is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address or hostname of the IPMI controller.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Login (if required) with administrative privileges.
-.TP
-\fB-o\fP \fIoption\fP
-Action to perform (on, off, reboot).
-.TP
-\fB-p\fP \fIpassword\fP
-Password (if required) for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-P\fP
-Use the lanplus option if this is a lanplus capable interface (for example iLo2)
-.TP
-\fB-A\fP \fIAuthentication Type\fP
-Can be set to none, password, md2, or md5.
-.TP
-\fB-C\fP \fICiphersuite Type\fP
-If you are using lanplus, this option avails you to define type of ciphersuite to
-use. Standard is 3 (defined if you just use lanplus). For more information please
-refer ipmitool man page (option -C).
-.TP
-\fB-M\fP \fImethod\fP
-Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management
-card will power off with default method so there will be no chance to power machine
-on by IPMI.
-.TP
-\fB-t\fP \fItimeout\fP
-Timeout in seconds for IPMI operation. Default is 10, but in some cases it
-must be set to higher value (anything above 30 is not recommended and may
-cause strange problems).
-.TP
-\fB-q\fP
-Quiet operation. Only print out error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-.TP
-\fB-v\fP
-Verbose mode.
-
-.SH STDIN PARAMETERS
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the IPMI controller.
-.TP
-\fIlogin= < param >\fR
-Login (if required) with administrative privileges.
-.TP
-\fIoption = < param >\fR
-Action to perform (on, off, reboot).
-.TP
-\fIpasswd = < param >\fR
-Password (if required) for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIauth = < param >\fR
-Authentication type (none, password, md2, md5).
-.TP
-\fItimeout = < param >\fR
-Timeout in seconds for IPMI operation. Default is 10, but in some cases it
-must be set to higher value (anything above 30 is not recommended and may
-cause strange problems).
-.TP
-\fIcipher = < param >\fR
-If you are using lanplus, this option avails you to define type of ciphersuite to
-use. Standard is 3 (defined if you just use lanplus). For more information please
-refer ipmitool man page (option -C).
-.TP
-\fImethod = < param >\fR
-Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management
-card will power off with default method so there will be no chance to power machine
-on by IPMI.
-.TP
-\fIlanplus\fR
-If we are using the lanplus option for ipmitool
-
-.SH SEE ALSO
-fence(8), fence_node(8), ipmitool(1)
diff --git a/fence/man/fence_ldom.8 b/fence/man/fence_ldom.8
deleted file mode 100644
index 59167c8..0000000
--- a/fence/man/fence_ldom.8
+++ /dev/null
@@ -1,114 +0,0 @@
-.TH fence_ldom 8
-
-.SH NAME
-fence_ldom - I/O Fencing agent for Logical Domains (LDoms)
-
-.SH SYNOPSIS
-.B
-fence_ldom
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_ldom is an I/O Fencing agent which can be used with LDoms virtual
-machines. This agent works so, that run ldm command on host machine. So
-ldm must be directly runnable.
-
-Very useful parameter is -c (or cmd_prompt in stdin mode). This must be
-set to something, what is displayed after successful login to host machine.
-Default string is space on end of string (default for root in bash). But
-(for example) csh use ], so in that case you must use parameter -c with
-argument ']'. Very similar situation is, if you use bash and login to host
-machine with other user than root. Than prompt is $, so again, you must
-use parameter -c.
-
-fence_ldom accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_ldom
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of LDoms host machine.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name to LDoms host machine.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. Valid values are reboot (default), status, off or on.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login to LDoms host machine.
-.TP
-\fB-B\fP \fIscript\fR
-Script to run to retrieve password.
-.TP
-\fB-x\fP
-Use secure connection over ssh (this is default, and can't be disabled) .
-.TP
-\fB-k\fP \fIfilename\fR
-Identity file (private key) for ssh.
-.TP
-\fB-n\fP \fIname\fR
-Name of quest to fence.
-.TP
-\fB-c\fP \fIprompt\fR
-Force command prompt.
-\fB-T\fP
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_ldom.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of LDoms host machine.
-.TP
-\fIaction = < param >\fR
-The action required. Valid values are reboot (default), status, off or on.
-.TP
-\fIlogin = < param >\fR
-Login name to LDoms host machine.
-.TP
-\fIpasswd = < param >\fR
-Password for login to LDoms host machine.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-.TP
-\fIsecure = < param >\fR
-Use secure connection over ssh (this is default, and can't be disabled)
-.TP
-\fIidentity = < param >\fR
-Identity file (private key) for ssh.
-.TP
-\fIport = < param >\fR
-Name of quest to fence.
-.TP
-\fIcmd_prompt = < param >\fR
-Force command prompt.
-.TP
-\fItest = < param >\fR
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_mcdata.8 b/fence/man/fence_mcdata.8
deleted file mode 100644
index 2230a66..0000000
--- a/fence/man/fence_mcdata.8
+++ /dev/null
@@ -1,82 +0,0 @@
-.TH fence_mcdata 8
-
-.SH NAME
-fence_mcdata - I/O Fencing agent for McData FC switches
-
-.SH SYNOPSIS
-.B
-fence_mcdata
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_mcdata is an I/O Fencing agent which can be used with McData FC
-switches. It logs into a McData switch via telnet and disables a specified
-port. Disabling the port which a machine is connected to effectively fences
-that machine. Lengthy telnet connections to the switch should be avoided
-while a GFS cluster is running because the connection will block any necessary
-fencing actions.
-
-fence_mcdata accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_mcdata
-can be run by itself with command line options which is useful for testing.
-
-After a fence operation has taken place the fenced machine can no longer connect
-to the McData FC switch. When the fenced machine is ready to be brought back
-into the GFS cluster (after reboot) the port on the McData FC switch needs to
-be enabled. This can be done by running fence_mcdata and specifying the
-enable action.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Username name for the switch.
-.TP
-\fB-n\fP \fIport\fP
-The port number to disable on the switch.
-.TP
-\fB-o\fP \fIaction\fP
-The action required. disable (default) or enable.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-q\fP
-Quiet mode: print only error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_mcdata.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. disable (default) or enable.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The port number to disable on the switch.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_rackswitch.8 b/fence/man/fence_rackswitch.8
deleted file mode 100644
index 4f662c7..0000000
--- a/fence/man/fence_rackswitch.8
+++ /dev/null
@@ -1,68 +0,0 @@
-.TH fence_rackswitch 8
-
-.SH NAME
-fence_rackswitch - I/O Fencing agent for RackSaver RackSwitch
-
-.SH SYNOPSIS
-.B
-fence_rackswitch
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_rackswitch is an I/O Fencing agent which can be used with the RackSaver
-RackSwitch. It logs into the RackSwitch and boots a specified plug.
-Using the http interface to the RackSwitch should be avoided while a GFS cluster is
-running because the connection may interfere with the operation of this agent.
-
-fence_rackswitch accepts options on the command line as well as from stdin.
-fenced sends the options through stdin when it execs the agent. fence_rackswitch
-can be run by itself with command line options which is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-n\fP \fIplug\fP
-The plug number to power cycle.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-l\fP \fIusername\fP
-Username for login.
-.TP
-\fB-q\fP
-Quiet operation. Only print out error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_rackswitch.
-.TP
-\fIipaddr = < ip >\fR
-IP address of the switch.
-.TP
-\fIusername = < param >\fR
-Username for login.
-.TP
-\fIpassword = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The port (outlet) number to act upon.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_rib.8 b/fence/man/fence_rib.8
deleted file mode 100644
index 04ace3f..0000000
--- a/fence/man/fence_rib.8
+++ /dev/null
@@ -1,10 +0,0 @@
-.TH fence_rib 8
-
-.SH NAME
-fence_rib - I/O Fencing agent for Compaq Remote Insight Lights Out card
-
-.SH DESCRIPTION
-fence_rib is deprecated. fence_ilo should be used instead
-
-.SH SEE ALSO
-fence_ilo(8)
diff --git a/fence/man/fence_rsa.8 b/fence/man/fence_rsa.8
deleted file mode 100644
index ad50860..0000000
--- a/fence/man/fence_rsa.8
+++ /dev/null
@@ -1,69 +0,0 @@
-.TH fence_rsa 8
-
-.SH NAME
-fence_rsa - I/O Fencing agent for IBM RSA II
-
-.SH SYNOPSIS
-.B
-fence_rsa
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_rsa is an I/O Fencing agent which can be used with the IBM RSA II
-management interface. It logs into an RSA II device via telnet and reboots
-the associated machine. Lengthy telnet connections to the RSA II device
-should be avoided while a GFS cluster is running because the connection
-will block any necessary fencing actions.
-
-fence_rsa accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_rsa
-can be run by itself with command line options. This is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the RSA II device.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), off, on, or status.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-v\fP
-Verbose. Print informational messages to standard out.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_rsa.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the device.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), off, on, or status.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_rsb.8 b/fence/man/fence_rsb.8
deleted file mode 100644
index 2bb7bf4..0000000
--- a/fence/man/fence_rsb.8
+++ /dev/null
@@ -1,75 +0,0 @@
-.TH fence_rsb 8
-
-.SH NAME
-fence_rsb - I/O Fencing agent for Fujitsu-Siemens RSB
-
-.SH SYNOPSIS
-.B
-fence_rsb
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_rsb is an I/O Fencing agent which can be used with the Fujitsu-Siemens
-RSB management interface. It logs into an RSB device via telnet and reboots
-the associated machine. Lengthy telnet connections to the RSB device
-should be avoided while a GFS cluster is running because the connection
-will block any necessary fencing actions.
-
-fence_rsb accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_rsb
-can be run by itself with command line options. This is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of the RSB device.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name.
-.TP
-\fB-n\fP \fItelnet_port\fR
-The port number on which the telnet service listens.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), off, on, or status.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-v\fP
-Verbose. Print informational messages to standard out.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_rsb.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the device.
-.TP
-\fItelnet_port = < port number >\fR
-The port number on which the telnet service listens.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), off, on, or status.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_sanbox2.8 b/fence/man/fence_sanbox2.8
deleted file mode 100644
index 0133105..0000000
--- a/fence/man/fence_sanbox2.8
+++ /dev/null
@@ -1,82 +0,0 @@
-.TH fence_sanbox2 8
-
-.SH NAME
-fence_sanbox2 - I/O Fencing agent for QLogic SANBox2 FC switches
-
-.SH SYNOPSIS
-.B
-fence_sanbox2
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_sanbox2 is an I/O Fencing agent which can be used with QLogic SANBox2 FC
-switches. It logs into a SANBox2 switch via telnet and disables a specified
-port. Disabling the port which a machine is connected to effectively fences
-that machine. Lengthy telnet connections to the switch should be avoided
-while a GFS cluster is running because the connection will block any necessary
-fencing actions.
-
-fence_sanbox2 accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_sanbox2
-can be run by itself with command line options which is useful for testing.
-
-After a fence operation has taken place the fenced machine can no longer connect
-to the switch. When the fenced machine is ready to be brought back
-into the GFS cluster (after reboot) the port on the FC switch needs to
-be enabled. This can be done by running fence_sanbox2 and specifying the
-enable action.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fP
-Login name for the switch.
-.TP
-\fB-n\fP \fIport\fP
-The port number to disable on the switch.
-.TP
-\fB-o\fP \fIaction\fP
-The action required. disable (default) or enable.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-q\fP
-Quiet mode: print only error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_sanbox2.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIlogin = < param >\fR
-Login name.
-.TP
-\fIoption = < param >\fR
-The action required. disable (default) or enable.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The port number to disable on the switch.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_scsi.8 b/fence/man/fence_scsi.8
deleted file mode 100644
index eaab222..0000000
--- a/fence/man/fence_scsi.8
+++ /dev/null
@@ -1,107 +0,0 @@
-.TH fence_scsi 8
-
-.SH NAME
-fence_scsi - I/O fencing agent for SCSI persistent reservations
-
-.SH SYNOPSIS
-.B
-fence_scsi
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_scsi is an I/O fencing agent which can be used with the SCSI
-devices that support persistent reservations (SPC-2 or greater).
-
-SCSI persistent reservations work by having each node in the cluster
-register with the SCSI device. Registration is done using a unique key
-(based on the node's IP address). Each node that will perform I/O
-operations to the shared storage must register with the device. This
-is done at system startup with the scsi_reserve init script. This
-script will discover all clustered volumes as well as the underlying
-SCSI device(s). Device discovery is done via the lvs command (see
-lvs(8)) and is subject to any filtering rules defined in the lvm.conf
-file.
-
-After generating the node's unique key, the script will register the
-node with the SCSI device(s) that were discovered. Once the node is
-registered, the script will attempt to create a reservation. Unlike
-registrations, of which there are multiple registrants (one for each
-node in the cluster), there is only one reservation holder. If a
-reservation does not already exist for a device, the script will
-create a reservation using the node's unique key.
-
-It is important to distinguish between registrations and
-reservations. As mentioned above, each node that will perform I/O
-operations to the SCSI device must register. As a result, there will
-be multiple registrations for a given SCSI device. In contrast, there
-can only be one reservation per SCSI device. It is not important which
-node holds the reservation. The reservation simply tells the device
-how the registrants are allowed to access the device. For our
-purposes, the reservation type is "write exclusive, registrants only".
-With this reservation type, only registered nodes will be able to
-write to the device.
-
-When the cluster must fence a node, it simply revokes a node's
-registration, or "unregisters" the node. This operation also uses the
-node's unique key. By deriving the unique key based on the errant
-node's IP address, the cluster can "unregister" the key. As a
-result, the errant node will no longer be able to write to the SCSI
-device.
-
-Note that the node that holds the reservation for a device must also
-be registered with that device. When the situation arises where the
-node that is being fenced is also the reservation holder, the
-reservation must be moved. This is handled by using the
-"preempt-and-abort command" which will transfer the reservation from
-the node that is being fenced to the node that is performing the
-fencing. This operation will maintain the reservation while
-"unregistering" the node being fenced.
-
-At system shutdown, the scsi_reserve script will attempt to
-"unregister" the node from all devices. The exception is when the
-node happens to be the reservation holder. In this case, the script
-does nothing, due to the fact that there may be other nodes using the
-device and the reservation must remain intact.
-
-fence_scsi accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_scsi
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-n\fP \fInode\fR
-Name of the node to be fenced.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-v\fP
-Verbose output.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_scsi.
-.TP
-\fInodename = < hostname | ip >\fR
-Name of the node to be fenced.
-.TP
-\fIself = < nodename >\fR
-Name of the node that will perform the fencing operation.
-.TP
-\fIverbose = < param >\fR
-Verbose output.
-
-.SH LIMITATIONS
-The fence_scsi fencing agent requires a minimum of three nodes in the
-cluster to operate. For SAN devices connected via fiber channel,
-these must be physical nodes. SAN devices connected via iSCSI may use
-virtual or physical nodes. In addition, fence_scsi cannot be used in
-conjunction with qdisk.
-
-.SH SEE ALSO
-fence(8), fence_node(8), sg_persist(8), lvs(8), lvm.conf(5)
diff --git a/fence/man/fence_virsh.8 b/fence/man/fence_virsh.8
deleted file mode 100644
index 9f4f281..0000000
--- a/fence/man/fence_virsh.8
+++ /dev/null
@@ -1,104 +0,0 @@
-.TH fence_virsh 8
-
-.SH NAME
-fence_virsh - I/O Fencing agent for libvirt virtual machines using
-
-.SH SYNOPSIS
-.B
-fence_virsh
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_virsh is an I/O Fencing agent which can be used with the virtual machines
-managed by libvirt. It logs via ssh to a dom0 and there run virsh command,
-which does all work.
-
-By default, virsh needs root account to do properly work. So you must allow
-ssh login in your sshd_config.
-
-fence_virsh accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_virsh
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of dom0.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name of user root in dom0.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), status, off, on, list or monitor.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login or for passphrase for dom0 machine.
-.TP
-\fB-B\fP \fIscript\fR
-Script to run to retrieve password for dom0 machine.
-.TP
-\fB-n\fP \fIname\fR
-Name of virtual machine to fence
-.TP
-\fB-x\fP
-Use secure connection over ssh (this is default, and can't be disabled)
-.TP
-\fB-k\fP \fIfilename\fR
-Identity file (private key) for ssh
-.TP
-\fB-T\fP
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_virsh.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of dom0.
-.TP
-\fIlogin = < param >\fR
-Login name of user root in dom0.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), status, off or on.
-.TP
-\fIpasswd = < param >\fR
-Password for login or for passphrase for dom0 machine.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for dom0 machine.
-.TP
-\fIport = < param >\fR
-Name of virtual machine to fence.
-.TP
-\fIsecure = < param >\fR
-Use secure connection over ssh (this is default, and can't be disabled)
-.TP
-\fIidentity_file = < param >\fR
-Identity file (private key) for ssh
-.TP
-\fItest = < param >\fR
-Test only. Answer NO to the confirmation prompt instead of YES.
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_vixel.8 b/fence/man/fence_vixel.8
deleted file mode 100644
index dc285c5..0000000
--- a/fence/man/fence_vixel.8
+++ /dev/null
@@ -1,70 +0,0 @@
-.TH fence_vixel 8
-
-.SH NAME
-fence_vixel - I/O Fencing agent for Vixel FC switches
-
-.SH SYNOPSIS
-.B
-fence_vixel
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_vixel is an I/O Fencing agent which can be used with Vixel FC switches.
-It logs into a Vixel switch via telnet and removes the specified port from the
-zone. Removing the zone access from the port disables the port from being able
-to access the storage.
-
-fence_vixel accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_vixel
-can be run by itself with command line options which is useful for testing.
-
-After a fence operation has taken place the fenced machine can no longer
-connect to the Vixel FC switch. When the fenced machine is ready to be brought
-back into the GFS cluster (after reboot) the port on the Vixel FC switch needs
-to be enabled. In order to do this, log into the Vixel FC switch. Then go to:
-
-config->zones->config <port> <comma-separated-list-of-ports-in-the-zone>
-
-Then apply
-
-Consult the Vixel manual for details
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-n\fP \fIport\fP
-The port number to remove zoning from on the switch.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_vixel.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIpasswd = < param >\fR
-Password for login.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The port number to remove zoning from on the switch.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_vmware.8 b/fence/man/fence_vmware.8
deleted file mode 100644
index 620537b..0000000
--- a/fence/man/fence_vmware.8
+++ /dev/null
@@ -1,141 +0,0 @@
-.TH fence_vmware 8
-
-.SH NAME
-fence_vmware - I/O Fencing agent for VMware virtual machines
-
-.SH SYNOPSIS
-.B
-fence_vmware
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_vmware is an I/O Fencing agent which can be used with the VMware ESX,
-VMware ESXi or VMware Server to fence virtual machines.
-
-Before you can use this agent, it must be installed VI Perl Toolkit or vmrun
-command on every node you want to make fencing.
-
-VI Perl Toolkit is preferred for VMware ESX/ESXi and Virtual Center. Vmrun
-command is only solution for VMware Server 1/2 (this command will works against
-ESX/ESXi 3.5 up2 and VC up2 too, but not cluster aware!) and is available as part of
-VMware VIX API SDK package. VI Perl and VIX API SDK are both available from
-VMware web pages (not int RHEL repository!).
-
-You can specify type of VMware you are connecting to with \fB-d\fP switch
-(or \fIvmware_type\fR for stdin). Possible values are esx, server2 and server1.
-Default value is esx, which will use VI Perl. With server1 and server2, vmrun command
-is used.
-
-After you have successfully installed VI Perl Toolkit or VIX API, you should
-be able to run fence_vmware_helper (part of this agent) or vmrun command.
-This agent supports only vmrun from version 2.0.0 (VIX API 1.6.0).
-
-fence_vmware accepts options on the command line as well as from stdin.
-Fenced sends parameters through stdin when it execs the agent. fence_vmware
-can be run by itself with command line options. This is useful for testing
-and for turning outlets on or off from scripts.
-
-.SH HOST NAME/IP ADDRESS SPECIFICATION
-Host name can include port in standard notation host_name:port.
-Specifying port isn't mandatory, but you must use it, if you try use this agent
-against VMware server 2.0.0 with default options, where https console runs on port
-8333. In case of ESX/ESXi, you don't need to specify port, because
-default configuration runs https on standard (443) port.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fR
-IP address or hostname of ESX/ESXi host machine. See (see
-.SM
-.B "HOST NAME/IP ADDRESS SPECIFICATION"
-above).
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-l\fP \fIlogin\fR
-Login name to VMware administration console.
-.TP
-\fB-o\fP \fIaction\fR
-The action required. This can be reboot (default), status, off, on, list
-or monitor.
-.TP
-\fB-p\fP \fIpassword\fR
-Password for login for VMware administration console.
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password for VMware administration console.
-.TP
-\fB-n\fP \fIname\fR
-Name of virtual machine to fence (ie. "test" for ESX with VI Perl or
-"[datastore1] test/test.vmx" for Server 2) which is returned by list command.
-.TP
-\fB-e\fP \fIcommand\fR
-Location of fence_vmware_helper or vmrun command. Default is fence_vmware_helper or
-/usr/bin/vmrun, but if you are using nonstandard location, you may find this switch useful.
-.TP
-\fB-d\fP \fItype\fR
-Type of VMware product you are trying to connect. This can be esx, server1 or server2.
-.TP
-\fB-s\fP \fIdatacenter\fR
-VMware datacenter to use. This can be used to filter guests to operate. Without specifying,
-guests from all datacenters will be used. Parameter can be used only with VI Perl helper
-(type is esx).
-.TP
-\fB-v\fP
-Verbose. Record session to stdout, or debug file if specified (see -D).
-.TP
-\fB-D\fP
-Specifies file, where will be written debug messages from session.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_vmware.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of ESX/ESXi host machine. See (see
-.SM
-.B "HOST NAME/IP ADDRESS SPECIFICATION"
-above).
-.TP
-\fIlogin = < param >\fR
-Login name to VMware administration console.
-.TP
-\fIoption = < param >\fR
-The action required. This can be reboot (default), status, off, on, list
-or monitor.
-.TP
-\fIpasswd = < param >\fR
-Password for login for VMware administration console.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password for VMware administration console.
-.TP
-\fIport = < param >\fR
-Name of virtual machine to fence (ie. "test" for ESX with VI Perl or
-"[datastore1] test/test.vmx" for Server 2) which is returned by list command.
-.TP
-\fIexec = < param >\fR
-Location of fence_vmware_helper or vmrun command. Default is fence_vmware_helper or
-/usr/bin/vmrun, but if you are using nonstandard location, you may find this switch useful.
-.TP
-\fIvmware_type = < param >\fR
-Type of VMware product you are trying to connect. This can be esx, server1 or server2.
-.TP
-\fIvmware_datacenter = < param >\fR
-VMware datacenter to use. This can be used to filter guests to operate. Without specifying,
-guests from all datacenters will be used. Parameter can be used only with VI Perl helper
-(type is esx).
-.TP
-\fIverbose = < param >\fR
-Verbose. Record session to stdout, or debug file if specified (see debug).
-.TP
-\fIdebug = < param >\fR
-Specifies file, where will be written debug messages from session.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_wti.8 b/fence/man/fence_wti.8
deleted file mode 100644
index c2ed90d..0000000
--- a/fence/man/fence_wti.8
+++ /dev/null
@@ -1,83 +0,0 @@
-.TH fence_wti 8
-
-.SH NAME
-fence_wti - I/O Fencing agent for WTI Network Power Switch
-
-.SH SYNOPSIS
-.B
-fence_wti
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_wti is an I/O Fencing agent which can be used with the WTI Network
-Power Switch (NPS). It logs into an NPS via telnet or ssh and boots a specified plug.
-Lengthy telnet connections to the NPS should be avoided while a GFS cluster is
-running because the connection will block any necessary fencing actions.
-
-fence_wti accepts options on the command line as well as from stdin.
-fenced sends the options through stdin when it execs the agent. fence_wti
-can be run by itself with command line options which is useful for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the switch.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-n\fP \fIplug\fP
-The plug number to power cycle.
-.TP
-\fB-p\fP \fIpassword\fP
-Password for login or for passphrase.
-.TP
-\fB-S\fP \fIscript\fR
-Script to run to retrieve password.
-.TP
-\fB-x\fP
-Use secure connection over ssh.
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password for login.
-.TP
-\fB-T\fP
-Test only. Do not power cycle. Reports state of the plug.
-.TP
-\fB-q\fP
-Quiet operation. Only print out error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_wti.
-.TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
-.TP
-\fIpasswd = < param >\fR
-Password for login or for passphrase.
-.TP
-\fIpasswd_script = < param >\fR
-Script to run to retrieve password.
-.TP
-\fIidentity_file = < param > \fR
-Identity file (private key) for ssh.
-.TP
-\fIsecure = < param >\fR
-Use secure connection over ssh.
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password for login.
-.TP
-\fIport = < param >\fR
-The outlet number to act upon.
-.TP
-\fItest = < param >\fR
-Test only. Answer NO to the confirmation prompt instead of YES.
-
-.SH SEE ALSO
-fence(8), fence_node(8)
diff --git a/fence/man/fence_xcat.8 b/fence/man/fence_xcat.8
deleted file mode 100644
index 7da35d5..0000000
--- a/fence/man/fence_xcat.8
+++ /dev/null
@@ -1,61 +0,0 @@
-.TH fence_xcat 8
-
-.SH NAME
-fence_xcat - I/O Fencing agent for xcat environments
-
-.SH SYNOPSIS
-.B
-fence_xcat
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_xcat is a wrapper to the rpower(1) command that is distributed
-with the xCAT project available at http://www.xcat.org. Use of
-fence_xcat requires that xcat has already been properly configured
-for your environment. Refer to xCAT(1) for more information on
-configuring xCAT.
-
-fence_xcat accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent. fence_xcat
-can be run by itself with command line options which is useful for testing.
-
-NOTE: It is recommended that fence_bladecenter(8) is used instead of fence_xcat if
-the bladecenter firmware supports telnet. This interface is much cleaner and
-easier to setup.
-
-.SH OPTIONS
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-n\fP \fInodename\fP
-The nodename as defined in nodelist.tab of the xCAT setup.
-.TP
-\fB-o\fP \fIaction\fP
-The action required. on, off, reset (default) or stat.
-.TP
-\fB-r\fP \fIrpower\fP
-The path to the rpower binary.
-.TP
-\fB-q\fP
-Quiet mode: print only error messages.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fR
-This option is used by fence_node(8) and is ignored by fence_xcat.
-.TP
-\fInodename = < param >\fR
-The nodename as defined in nodelist.tab of the xCAT setup.
-.TP
-\fIaction = < param >\fR
-The action required. on, off, reset (default) or stat.
-.TP
-\fIrpower = < param >\fR
-The path to the rpower binary.
-
-.SH SEE ALSO
-fence(8), fence_node(8), fence_bladecenter(8), nodelist.tab(8), rpower(1), xCAT(1)
diff --git a/fence/man/fence_zvm.8 b/fence/man/fence_zvm.8
deleted file mode 100644
index b22f8e1..0000000
--- a/fence/man/fence_zvm.8
+++ /dev/null
@@ -1,62 +0,0 @@
-.TH fence_zvm 8
-
-.SH NAME
-fence_zvm - I/O Fencing agent for GFS on s390 and zSeries VM clusters
-
-.SH SYNOPSIS
-.B
-fence_zvm
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_zvm is an I/O Fencing agent used on a GFS virtual machine in a s390 or zSeries VM cluster.
-It uses the s3270 program to log the specified virtual machine out of VM.
-For fence_zvm to execute correctly, you must have s3270 in your PATH.
-
-fence_zvm accepts options on the command line as well as from stdin.
-fence_node sends the options through stdin when it execs the agent.
-fence_zvm can be run by itself with command line options which is useful
-for testing.
-
-.SH OPTIONS
-.TP
-\fB-a\fP \fIIPaddress\fP
-IP address or hostname of the Physical machine (required).
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-u\fP \fIuserid\fP
-userid of the virtual machine to fence (required).
-.TP
-\fB-p\fP \fIpassword\fP
-password of the virtual machine to fence (required).
-.TP
-\fB-S\fP \fIpath\fR
-Full path to an executable to generate the password of the virtual machine to fence.
-.TP
-\fB-q\fP
-quiet mode, no output.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fP
-This option is used by fence_node(8) and is ignored by fence_zvm.
-.TP
-\fIipaddr = < hostname | ip >\fP
-IP address or hostname of the Physical machine (required).
-.TP
-\fIpasswd = < param >\fP
-password of the virtual machine to fence (required).
-.TP
-\fIpasswd_script = < param >\fR
-Full path to an executable to generate the password of the virtual machine to fence.
-.TP
-\fIuserid = < param >\fP
-userid of the virtual machine to fence (required).
-
-.SH SEE ALSO
-fence(8), fenced(8), fence_node(8)
diff --git a/make/fenceman.mk b/make/fenceman.mk
new file mode 100644
index 0000000..410d6cb
--- /dev/null
+++ b/make/fenceman.mk
@@ -0,0 +1,8 @@
+%.8: $(TARGET) $(top_srcdir)/fence/agents/lib/fence2man.xsl
+ set -e && \
+ PYTHONPATH=$(top_srcdir)/fence/agents/lib \
+ python $^ -o metadata > .$@.tmp && \
+ xsltproc $(top_srcdir)/fence/agents/lib/fence2man.xsl .$@.tmp > $@
+
+clean-man:
+ rm -f *.8 .*.8.tmp
diff --git a/scripts/fenceparse b/scripts/fenceparse
index 0a12fc8..b6ed431 100644
--- a/scripts/fenceparse
+++ b/scripts/fenceparse
@@ -12,7 +12,9 @@ infile="$5"
definedata="$(cat $definefile | grep "^\#define $define" | sed -e 's/.*'$define' //')"
-realinfile="$(ls $srcdir/$infile.*)"
+realinfile="$(ls $srcdir/$infile.*{py,pl,sh} 2>/dev/null || true)"
+
+[ -z "$realinfile" ] && exit 1
interpreter="$(cat $realinfile | head -n 1 | awk -F "/" '{print $NF}')"
interpreter="$(echo $interpreter)"
14 years, 1 month
fence-agents: master - fence-agents: fix build with locales other than C
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=com...
Commit: 3d66266141fce66bb2fd517d14dab1333d05ea2b
Parent: 3be82d287b4212bfca3db679983b8687746417ef
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Tue Apr 20 12:36:30 2010 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Tue Apr 20 12:40:14 2010 +0200
fence-agents: fix build with locales other than C
Resolves rhbz#583948
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
scripts/fenceparse | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/scripts/fenceparse b/scripts/fenceparse
index c34cb82..0a12fc8 100644
--- a/scripts/fenceparse
+++ b/scripts/fenceparse
@@ -2,6 +2,8 @@
set -e
+export LC_ALL=C
+
definefile="$1"
define="$2"
release="$3"
14 years, 1 month
cluster: STABLE3 - fence-agents: fix build with locales other than C
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: dd798057688f05adcda65ba1bcc929987f1600b8
Parent: 2db59f61a6ffd024c780e1dfb59a6dfb9ca19104
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Tue Apr 20 12:36:30 2010 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Tue Apr 20 12:36:30 2010 +0200
fence-agents: fix build with locales other than C
Resolves rhbz#583948
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
scripts/fenceparse | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/scripts/fenceparse b/scripts/fenceparse
index 49457a6..b6ed431 100644
--- a/scripts/fenceparse
+++ b/scripts/fenceparse
@@ -2,6 +2,8 @@
set -e
+export LC_ALL=C
+
definefile="$1"
define="$2"
release="$3"
14 years, 1 month
cluster: STABLE3 - fencing: Creating manual pages fails when default value is a list
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 2db59f61a6ffd024c780e1dfb59a6dfb9ca19104
Parent: 18175f51f101ff9a62e46c86a920c53a5f4c6ade
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Tue Apr 20 12:27:47 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Tue Apr 20 12:27:47 2010 +0200
fencing: Creating manual pages fails when default value is a list
Problem was concatenating string + list in python. Lists can't be
entered using command line or stdin.
Resolves: rhbz#583019
---
fence/agents/lib/fencing.py.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 831cdb1..6646eb9 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -430,7 +430,7 @@ def metadata(avail_opt, options, docs):
default = ""
if all_opt[option].has_key("default"):
- default = "default=\""+all_opt[option]["default"]+"\""
+ default = "default=\""+str(all_opt[option]["default"])+"\""
elif options.has_key("-" + all_opt[option]["getopt"][:-1]):
if options["-" + all_opt[option]["getopt"][:-1]]:
try:
@@ -438,7 +438,7 @@ def metadata(avail_opt, options, docs):
except TypeError:
## @todo/@note: Currently there is no clean way how to handle lists
## we can create a string from it but we can't set it on command line
- default = "default=\"list of values\""
+ default = "default=\"" + str(options["-" + all_opt[option]["getopt"][:-1]]) +"\""
elif options.has_key("-" + all_opt[option]["getopt"]):
default = "default=\"true\" "
14 years, 1 month
cluster: STABLE3 - fence_ilo_mp: Proper error message instead of python traceback
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 18175f51f101ff9a62e46c86a920c53a5f4c6ade
Parent: 147e0ea97d1e721e1d2a2ecc497e04afb322d4d7
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Tue Apr 20 12:15:55 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Tue Apr 20 12:15:55 2010 +0200
fence_ilo_mp: Proper error message instead of python traceback
Fencing agent for iLO MP did not have proper exception handling.
Resolves: rhbz#583017
---
fence/agents/ilo_mp/fence_ilo_mp.py | 48 +++++++++++++++++++++++-----------
1 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/fence/agents/ilo_mp/fence_ilo_mp.py b/fence/agents/ilo_mp/fence_ilo_mp.py
index 1f9363b..e2f26fa 100644
--- a/fence/agents/ilo_mp/fence_ilo_mp.py
+++ b/fence/agents/ilo_mp/fence_ilo_mp.py
@@ -11,22 +11,37 @@ BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
- conn.send("show /system1\n")
- conn.log_expect(options, "EnabledState=(.*)", int(options["-Y"]))
+ try:
+ conn.send("show /system1\r\n")
+
+ re_state = re.compile('EnabledState=(.*)', re.IGNORECASE)
+ conn.log_expect(options, re_state, int(options["-Y"]))
- status = conn.match.group(1)
+ status = conn.match.group(1).lower()
- if status.startswith("Enabled"):
- return "on"
- else:
- return "off"
+ if status.startswith("enabled"):
+ return "on"
+ else:
+ return "off"
+ except pexpect.EOF:
+ fail(EC_CONNECTION_LOST)
+ except pexpect.TIMEOUT:
+ fail(EC_TIMED_OUT)
def set_power_status(conn, options):
- if options["-o"] == "on":
- conn.send("start /system1\n")
- else:
- conn.send("stop -f /system1\n")
- return
+ try:
+ if options["-o"] == "on":
+ conn.send("start /system1\r\n")
+ else:
+ conn.send("stop -f /system1\r\n")
+
+ conn.log_expect(options, options["-c"], int(options["-g"]))
+
+ return
+ except pexpect.EOF:
+ fail(EC_CONNECTION_LOST)
+ except pexpect.TIMEOUT:
+ fail(EC_TIMED_OUT)
def main():
device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
@@ -37,9 +52,10 @@ def main():
atexit.register(atexit_handler)
+ all_opt["cmd_prompt"]["default"] = [ "MP>", "hpiLO->" ]
+ all_opt["power_wait"]["default"] = 5
+
options = check_input(device_opt, process_input(device_opt))
- if 0 == options.has_key("-c"):
- options["-c"] = "MP>"
docs = { }
docs["shortdesc"] = "Fence agent for HP iLO MP"
@@ -48,7 +64,7 @@ def main():
show_docs(options, docs)
conn = fence_login(options)
- conn.send("SMCLP\n")
+ conn.send("SMCLP\r\n")
##
## Fence operations
@@ -56,7 +72,7 @@ def main():
result = fence_action(conn, options, set_power_status, get_power_status)
try:
- conn.send("exit\n")
+ conn.send("exit\r\n")
except exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
14 years, 1 month
cluster: STABLE3 - fence_egenera: log file path should be absolute not relative
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 147e0ea97d1e721e1d2a2ecc497e04afb322d4d7
Parent: cf40ea82f348e6a178f51bbc0b4334d98313c63e
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Tue Apr 20 12:14:40 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Tue Apr 20 12:14:40 2010 +0200
fence_egenera: log file path should be absolute not relative
---
fence/agents/egenera/fence_egenera.pl | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fence/agents/egenera/fence_egenera.pl b/fence/agents/egenera/fence_egenera.pl
index 8df0029..8e6aa1b 100644
--- a/fence/agents/egenera/fence_egenera.pl
+++ b/fence/agents/egenera/fence_egenera.pl
@@ -292,9 +292,9 @@ sub pserver_boot
sub pserver_shutdown
{
my $rtrn=1;
- local *egen_log;
- open(egen_log,">>@LOGDIR(a)/fence_egenera.log");
- print egen_log "Attempting shutdown at ".`date`."\n";
+ local *egen_log;
+ open(egen_log,">>/@LOGDIR(a)/fence_egenera.log");
+ print egen_log "Attempting shutdown at ".`date`."\n";
for (my $trys=0; $trys<20; $trys++)
{
last if (pserver_status != 0);
14 years, 1 month
cluster: STABLE3 - gfs2_fsck segfault when statfs system file is missing
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: cf40ea82f348e6a178f51bbc0b4334d98313c63e
Parent: 3714f6f1b47cf0a9cec46fb14843221c35431a79
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Apr 19 18:14:09 2010 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Apr 19 18:14:09 2010 -0500
gfs2_fsck segfault when statfs system file is missing
This patch repairs badly damaged gfs2 file systems. It can
rebuild destroyed superblock, master directory, root dinode and
all of the system dinodes.
rhbz#576330
---
gfs2/edit/hexedit.c | 4 +-
gfs2/edit/savemeta.c | 4 +-
gfs2/fsck/fs_recovery.c | 2 -
gfs2/fsck/fsck.h | 9 +-
gfs2/fsck/initialize.c | 661 ++++++++++++++++++++++++++++++++++++++++++---
gfs2/fsck/main.c | 114 --------
gfs2/fsck/metawalk.c | 3 +-
gfs2/fsck/metawalk.h | 2 +
gfs2/fsck/pass1.c | 410 ++++++++++++++++++++++-------
gfs2/fsck/rgrepair.c | 59 ++++-
gfs2/libgfs2/fs_ops.c | 2 +-
gfs2/libgfs2/libgfs2.h | 9 +-
gfs2/libgfs2/misc.c | 45 +++
gfs2/libgfs2/rgrp.c | 4 +-
gfs2/libgfs2/structures.c | 26 ++-
gfs2/libgfs2/super.c | 27 ++-
gfs2/mkfs/main_grow.c | 4 +-
gfs2/mkfs/main_mkfs.c | 44 ---
18 files changed, 1109 insertions(+), 320 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 109f9c0..408b763 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1743,6 +1743,8 @@ static void read_superblock(int fd)
sbd.fssize = sbd.device.length;
gfs1_rindex_read(&sbd, 0, &count);
} else {
+ int sane;
+
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
@@ -1751,7 +1753,7 @@ static void read_superblock(int fd)
sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
sbd.fssize = sbd.device.length;
- rindex_read(&sbd, 0, &count);
+ rindex_read(&sbd, 0, &count, &sane);
}
}
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index f6d136f..4f5b3c4 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -587,12 +587,14 @@ void savemeta(char *out_fn, int saveoption)
brelse(lbh);
}
if (!slow) {
+ int sane;
+
printf("Reading resource groups...");
fflush(stdout);
if (gfs1)
slow = gfs1_ri_update(&sbd, 0, &rgcount, 0);
else
- slow = ri_update(&sbd, 0, &rgcount);
+ slow = ri_update(&sbd, 0, &rgcount, &sane);
printf("Done.\n\n");
fflush(stdout);
}
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 05f41e4..d908873 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -570,7 +570,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
/* Get master dinode */
- sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
/* read in the journal index data */
@@ -596,7 +595,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
inode_put(&sdp->md.journal[i]);
}
- inode_put(&sdp->master_dir);
inode_put(&sdp->md.jiinode);
/* Sync the buffers to disk so we get a fresh start. */
fsync(sdp->device_fd);
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 022b61e..b0e1efc 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -79,10 +79,12 @@ struct inode_with_dups {
enum rgindex_trust_level { /* how far can we trust our RG index? */
blind_faith = 0, /* We'd like to trust the rgindex. We always used to
before bz 179069. This should cover most cases. */
- open_minded = 1, /* At least 1 RG is corrupt. Try to calculate what it
+ ye_of_little_faith = 1, /* The rindex seems trustworthy but there's
+ rg damage that need to be fixed. */
+ open_minded = 2, /* At least 1 RG is corrupt. Try to calculate what it
should be, in a perfect world where our RGs are all
on even boundaries. Blue sky. Chirping birds. */
- distrust = 2 /* The world isn't perfect, our RGs are not on nice neat
+ distrust = 3 /* The world isn't perfect, our RGs are not on nice neat
boundaries. The fs must have been messed with by
gfs2_grow or something. Count the RGs by hand. */
};
@@ -102,7 +104,8 @@ extern int pass2(struct gfs2_sbd *sbp);
extern int pass3(struct gfs2_sbd *sbp);
extern int pass4(struct gfs2_sbd *sbp);
extern int pass5(struct gfs2_sbd *sbp);
-extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count);
+extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
+ int *sane);
extern void gfs2_dup_free(void);
extern int fsck_query(const char *format, ...)
__attribute__((format(printf,1,2)));
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 2910326..14cc9f6 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -24,8 +24,11 @@
free(x); \
x = NULL; \
}
+#define HIGHEST_BLOCK 0xffffffffffffffff
static int was_mounted_ro = 0;
+static uint64_t possible_root = HIGHEST_BLOCK;
+static struct master_dir fix_md;
/**
* block_mounters
@@ -306,6 +309,87 @@ static int check_rgrps_integrity(struct gfs2_sbd *sdp)
}
/**
+ * rebuild_master - rebuild a destroyed master directory
+ */
+static int rebuild_master(struct gfs2_sbd *sdp)
+{
+ struct gfs2_inum inum;
+ struct gfs2_buffer_head *bh;
+
+ log_err(_("The system master directory seems to be destroyed.\n"));
+ if (!query(_("Okay to rebuild it? (y/n)"))) {
+ log_err(_("System master not rebuilt; aborting.\n"));
+ return -1;
+ }
+ log_err(_("Trying to rebuild the master directory.\n"));
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = sdp->sd_sb.sb_master_dir.no_addr;
+ bh = init_dinode(sdp, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
+ sdp->master_dir = inode_get(sdp, bh);
+ sdp->master_dir->bh_owned = 1;
+
+ if (fix_md.jiinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.jiinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "jindex", 6, &inum,
+ IF2DT(S_IFDIR | 0700));
+ sdp->master_dir->i_di.di_nlink++;
+ } else {
+ build_jindex(sdp);
+ }
+
+ if (fix_md.pinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.pinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "per_node", 8, &inum,
+ IF2DT(S_IFDIR | 0700));
+ sdp->master_dir->i_di.di_nlink++;
+ } else {
+ build_per_node(sdp);
+ }
+
+ if (fix_md.inum) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.inum->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "inum", 4, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_inum(sdp);
+ }
+
+ if (fix_md.statfs) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.statfs->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "statfs", 6, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_statfs(sdp);
+ }
+
+ if (fix_md.riinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.riinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "rindex", 6, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_rindex(sdp);
+ }
+
+ if (fix_md.qinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.qinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "quota", 5, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_quota(sdp);
+ }
+
+ log_err(_("Master directory rebuilt.\n"));
+ inode_put(&sdp->master_dir);
+ return 0;
+}
+
+/**
* init_system_inodes
*
* Returns: 0 on success, -1 on failure
@@ -315,7 +399,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
uint64_t inumbuf;
char *buf;
struct gfs2_statfs_change sc;
- int rgcount;
+ int rgcount, sane = 1;
enum rgindex_trust_level trust_lvl;
uint64_t addl_mem_needed;
@@ -325,52 +409,43 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_info( _("Initializing special inodes...\n"));
- /* Get master dinode */
- sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
/* Get root dinode */
sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
- /* Look for "inum" entry in master dinode */
- gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
- /* Read inum entry into buffer */
- gfs2_readi(sdp->md.inum, &inumbuf, 0, sdp->md.inum->i_di.di_size);
- /* call gfs2_inum_range_in() to retrieve range */
- sdp->md.next_inum = be64_to_cpu(inumbuf);
-
- gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
- buf = malloc(sdp->md.statfs->i_di.di_size);
- // FIXME: handle failed malloc
- gfs2_readi(sdp->md.statfs, buf, 0, sdp->md.statfs->i_di.di_size);
- /* call gfs2_inum_range_in() to retrieve range */
- gfs2_statfs_change_in(&sc, buf);
- free(buf);
-
-
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-
gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
-
- gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
-
- gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode);
-
- /* FIXME fill in per_node structure */
+ if (!sdp->md.riinode) {
+ if (query( _("The gfs2 system rindex inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_rindex(sdp);
+ }
/*******************************************************************
- ******* Fill in rgrp and journal indexes and related fields *****
+ ****************** Fill in journal information ******************
*******************************************************************/
+ /* rgrepair requires the journals be read in in order to distinguish
+ "real" rgrps from rgrps that are just copies left in journals. */
+ gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+ if (!sdp->md.jiinode) {
+ if (query( _("The gfs2 system jindex inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_jindex(sdp);
+ }
+
/* read in the ji data */
if (ji_update(sdp)){
- log_err( _("Unable to read in ji inode.\n"));
+ log_err( _("Unable to read in jindex inode.\n"));
return -1;
}
+ /*******************************************************************
+ ******** Validate and read in resource group information ********
+ *******************************************************************/
log_warn( _("Validating Resource Group index.\n"));
for (trust_lvl = blind_faith; trust_lvl <= distrust; trust_lvl++) {
log_warn( _("Level %d RG check.\n"), trust_lvl + 1);
- if ((rg_repair(sdp, trust_lvl, &rgcount) == 0) &&
- (ri_update(sdp, 0, &rgcount) == 0)) {
+ if ((rg_repair(sdp, trust_lvl, &rgcount, &sane) == 0) &&
+ (ri_update(sdp, 0, &rgcount, &sane) == 0)) {
log_warn( _("(level %d passed)\n"), trust_lvl + 1);
break;
}
@@ -386,6 +461,54 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
check_rgrps_integrity(sdp);
/*******************************************************************
+ ***************** Initialize more system inodes *****************
+ *******************************************************************/
+ /* Look for "inum" entry in master dinode */
+ gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
+ if (!sdp->md.inum) {
+ if (query( _("The gfs2 system inum inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_inum(sdp);
+ }
+ /* Read inum entry into buffer */
+ gfs2_readi(sdp->md.inum, &inumbuf, 0, sdp->md.inum->i_di.di_size);
+ /* call gfs2_inum_range_in() to retrieve range */
+ sdp->md.next_inum = be64_to_cpu(inumbuf);
+
+ gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
+ if (!sdp->md.statfs) {
+ if (query( _("The gfs2 system statfs inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_statfs(sdp);
+ else {
+ log_err( _("fsck.gfs2 cannot continue without a "
+ "valid statfs file; aborting.\n"));
+ return FSCK_ERROR;
+ }
+ }
+ buf = malloc(sdp->md.statfs->i_di.di_size);
+ // FIXME: handle failed malloc
+ gfs2_readi(sdp->md.statfs, buf, 0, sdp->md.statfs->i_di.di_size);
+ /* call gfs2_inum_range_in() to retrieve range */
+ gfs2_statfs_change_in(&sc, buf);
+ free(buf);
+
+ gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
+ if (!sdp->md.qinode) {
+ if (query( _("The gfs2 system quota inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_quota(sdp);
+ }
+
+ gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode);
+ if (!sdp->md.pinode) {
+ if (query( _("The gfs2 system per_node directory inode is "
+ "missing. Okay to rebuild it? (y/n) ")))
+ build_per_node(sdp);
+ }
+
+ /* FIXME fill in per_node structure */
+ /*******************************************************************
******* Now, set boundary fields in the super block *************
*******************************************************************/
if(set_block_ranges(sdp)){
@@ -409,6 +532,454 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
return -1;
}
+static int get_lockproto_table(struct gfs2_sbd *sdp)
+{
+ FILE *fp;
+ char line[PATH_MAX], *p, *p2;
+ char fsname[PATH_MAX];
+
+ memset(sdp->lockproto, 0, sizeof(sdp->lockproto));
+ memset(sdp->locktable, 0, sizeof(sdp->locktable));
+ fp = fopen("/etc/cluster/cluster.conf", "rt");
+ if (!fp) {
+ /* no cluster.conf; must be a stand-alone file system */
+ strcpy(sdp->lockproto, "lock_nolock");
+ log_warn(_("Lock protocol determined to be: lock_nolock\n"));
+ log_warn(_("Stand-alone file system: No need for a lock "
+ "table.\n"));
+ return 0;
+ }
+ /* We found a cluster.conf so assume it's a clustered file system */
+ log_warn(_("Lock protocol assumed to be: " GFS2_DEFAULT_LOCKPROTO
+ "\n"));
+ strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
+ while (fgets(line, sizeof(line) - 1, fp)) {
+ p = strstr(line,"<cluster name=");
+ if (p) {
+ p += 15;
+ p2 = strchr(p,'"');
+ strncpy(sdp->locktable, p, p2 - p);
+ break;
+ }
+ }
+ if (sdp->locktable[0] == '\0') {
+ log_err(_("Error: Unable to determine cluster name from "
+ "/etc/cluster.conf\n"));
+ } else {
+ memset(fsname, 0, sizeof(fsname));
+ p = strrchr(opts.device, '/');
+ if (p) {
+ p++;
+ strncpy(fsname, p, sizeof(fsname));
+ } else
+ strcpy(fsname, "repaired");
+ strcat(sdp->locktable, ":");
+ strcat(sdp->locktable, fsname);
+ log_warn(_("Lock table determined to be: %s\n"),
+ sdp->locktable);
+ }
+ fclose(fp);
+ return 0;
+}
+
+/**
+ * is_journal_copy - Is this a "real" dinode or a copy inside a journal?
+ * A real dinode will be located at the block number in its no_addr.
+ * A journal-copy will be at a different block (inside the journal).
+ */
+static int is_journal_copy(struct gfs2_inode *ip, struct gfs2_buffer_head *bh)
+{
+ if (ip->i_di.di_num.no_addr == bh->b_blocknr)
+ return 0;
+ return 1; /* journal copy */
+}
+
+/**
+ * peruse_system_dinode - process a system dinode
+ *
+ * This function looks at a system dinode and tries to figure out which
+ * dinode it is: statfs, inum, per_node, master, etc. Some of them we
+ * can deduce from the contents. For example, di_size will be a multiple
+ * of 96 for the rindex. di_size will be 8 for inum, 24 for statfs, etc.
+ * the per_node directory will have a ".." entry that will lead us to
+ * the master dinode if it's been destroyed.
+ */
+static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
+ struct gfs2_buffer_head *bh)
+{
+ struct gfs2_inode *ip, *child_ip;
+ struct gfs2_inum inum;
+ int error;
+
+ if (di->di_num.no_formal_ino == 2) {
+ if (sdp->sd_sb.sb_master_dir.no_addr)
+ return;
+ log_warn(_("Found system master directory at: 0x%llx.\n"),
+ di->di_num.no_addr);
+ sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr;
+ return;
+ }
+ ip = inode_read(sdp, di->di_num.no_addr);
+ if (di->di_num.no_formal_ino == 3) {
+ if (fix_md.jiinode || is_journal_copy(ip, bh))
+ return;
+ log_warn(_("Found system jindex file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ fix_md.jiinode = ip;
+ } else if (S_ISDIR(di->di_mode)) {
+ /* Check for a jindex dir entry. Only one system dir has a
+ jindex: master */
+ gfs2_lookupi(ip, "jindex", 6, &child_ip);
+ if (child_ip) {
+ if (fix_md.jiinode || is_journal_copy(ip, bh))
+ return;
+ fix_md.jiinode = child_ip;
+ sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr;
+ log_warn(_("Found system master directory at: "
+ "0x%llx\n"), di->di_num.no_addr);
+ return;
+ }
+
+ /* Check for a statfs_change0 dir entry. Only one system dir
+ has a statfs_change: per_node, and its .. will be master. */
+ gfs2_lookupi(ip, "statfs_change0", 14, &child_ip);
+ if (child_ip) {
+ if (fix_md.pinode || is_journal_copy(ip, bh))
+ return;
+ log_warn(_("Found system per_node directory at: "
+ "0x%llx\n"), ip->i_di.di_num.no_addr);
+ fix_md.pinode = ip;
+ error = dir_search(ip, "..", 2, NULL, &inum);
+ if (!error && inum.no_addr) {
+ sdp->sd_sb.sb_master_dir.no_addr =
+ inum.no_addr;
+ log_warn(_("From per_node\'s \'..\' I "
+ "backtracked the master directory "
+ "to: 0x%llx\n"), inum.no_addr);
+ }
+ return;
+ }
+ log_debug(_("Unknown system directory at block 0x%llx\n"),
+ di->di_num.no_addr);
+ inode_put(&ip);
+ } else if (di->di_size == 8) {
+ if (fix_md.inum || is_journal_copy(ip, bh))
+ return;
+ fix_md.inum = ip;
+ log_warn(_("Found system inum file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ } else if (di->di_size == 24) {
+ if (fix_md.statfs || is_journal_copy(ip, bh))
+ return;
+ fix_md.statfs = ip;
+ log_warn(_("Found system statfs file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ } else if ((di->di_size % 96) == 0) {
+ if (fix_md.riinode || is_journal_copy(ip, bh))
+ return;
+ fix_md.riinode = ip;
+ log_warn(_("Found system rindex file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ } else if (!fix_md.qinode && di->di_size >= 176 &&
+ di->di_num.no_formal_ino >= 12 &&
+ di->di_num.no_formal_ino <= 100) {
+ if (is_journal_copy(ip, bh))
+ return;
+ fix_md.qinode = ip;
+ log_warn(_("Found system quota file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ }
+}
+
+/**
+ * peruse_user_dinode - process a user dinode trying to find the root directory
+ *
+ */
+static void peruse_user_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
+ struct gfs2_buffer_head *bh)
+{
+ struct gfs2_inode *ip, *parent_ip;
+ struct gfs2_inum inum;
+ int error;
+
+ if (sdp->sd_sb.sb_root_dir.no_addr) /* if we know the root dinode */
+ return; /* we don't need to find the root */
+ if (!S_ISDIR(di->di_mode)) /* if this isn't a directory */
+ return; /* it can't lead us to the root anyway */
+
+ if (di->di_num.no_formal_ino == 1) {
+ struct gfs2_buffer_head *root_bh;
+
+ if (di->di_num.no_addr == bh->b_blocknr) {
+ log_warn(_("Found the root directory at: 0x%llx.\n"),
+ di->di_num.no_addr);
+ sdp->sd_sb.sb_root_dir.no_addr = di->di_num.no_addr;
+ return;
+ }
+ log_warn(_("The root dinode should be at block 0x%llx but it "
+ "seems to be destroyed.\n"),
+ (unsigned long long)di->di_num.no_addr);
+ log_warn(_("Found a copy of the root directory in a journal "
+ "at block: 0x%llx.\n"),
+ (unsigned long long)bh->b_blocknr);
+ if (!query(_("Do you want to replace the root dinode from the "
+ "copy? (y/n)"))) {
+ log_err(_("Damaged root dinode not fixed.\n"));
+ return;
+ }
+ root_bh = bread(sdp, di->di_num.no_addr);
+ memcpy(root_bh->b_data, bh->b_data, sdp->bsize);
+ bmodified(root_bh);
+ brelse(root_bh);
+ log_warn(_("Root directory copied from the journal.\n"));
+ return;
+ }
+ ip = inode_read(sdp, di->di_num.no_addr);
+ while (ip) {
+ gfs2_lookupi(ip, "..", 2, &parent_ip);
+ if (parent_ip && parent_ip->i_di.di_num.no_addr ==
+ ip->i_di.di_num.no_addr) {
+ log_warn(_("fsck found the root inode at: 0x%llx\n"),
+ ip->i_di.di_num.no_addr);
+ sdp->sd_sb.sb_root_dir.no_addr =
+ ip->i_di.di_num.no_addr;
+ inode_put(&parent_ip);
+ inode_put(&ip);
+ return;
+ }
+ if (!parent_ip)
+ break;
+ inode_put(&ip);
+ ip = parent_ip;
+ }
+ error = dir_search(ip, "..", 2, NULL, &inum);
+ if (!error && inum.no_addr && inum.no_addr < possible_root) {
+ possible_root = inum.no_addr;
+ log_debug(_("Found a possible root at: 0x%llx\n"),
+ (unsigned long long)possible_root);
+ }
+ inode_put(&ip);
+}
+
+/**
+ * find_rgs_for_bsize - check a range of blocks for rgrps to determine bsize.
+ * Assumes: device is open.
+ */
+static int find_rgs_for_bsize(struct gfs2_sbd *sdp, uint64_t startblock,
+ uint32_t *known_bsize)
+{
+ uint64_t blk, max_rg_size, rb_addr;
+ struct gfs2_buffer_head *bh, *rb_bh;
+ uint32_t bsize, bsize2;
+ uint32_t chk;
+ char *p;
+ int found_rg;
+ struct gfs2_meta_header mh;
+
+ sdp->bsize = GFS2_DEFAULT_BSIZE;
+ max_rg_size = 524288;
+ /* Max RG size is 2GB. Max block size is 4K. 2G / 4K blks = 524288,
+ So this is traversing 2GB in 4K block increments. */
+ for (blk = startblock; blk < startblock + max_rg_size; blk++) {
+ bh = bread(sdp, blk);
+ found_rg = 0;
+ for (bsize = 0; bsize < GFS2_DEFAULT_BSIZE;
+ bsize += GFS2_BASIC_BLOCK) {
+ p = bh->b_data + bsize;
+ chk = ((struct gfs2_meta_header *)p)->mh_magic;
+ if (be32_to_cpu(chk) != GFS2_MAGIC)
+ continue;
+ chk = ((struct gfs2_meta_header *)p)->mh_type;
+ if (be32_to_cpu(chk) == GFS2_METATYPE_RG) {
+ found_rg = 1;
+ break;
+ }
+ }
+ if (!found_rg)
+ continue;
+ /* Try all the block sizes in 512 byte multiples */
+ for (bsize2 = GFS2_BASIC_BLOCK; bsize2 <= GFS2_DEFAULT_BSIZE;
+ bsize2 += GFS2_BASIC_BLOCK) {
+ rb_addr = (bh->b_blocknr *
+ (GFS2_DEFAULT_BSIZE / bsize2)) +
+ (bsize / bsize2) + 1;
+ sdp->bsize = bsize2; /* temporarily */
+ rb_bh = bread(sdp, rb_addr);
+ gfs2_meta_header_in(&mh, rb_bh);
+ brelse(rb_bh);
+ if (mh.mh_magic == GFS2_MAGIC &&
+ mh.mh_type == GFS2_METATYPE_RB) {
+ log_debug(_("boff:%d bsize2:%d rg:0x%llx, "
+ "rb:0x%llx\n"), bsize, bsize2,
+ (unsigned long long)blk,
+ (unsigned long long)rb_addr);
+ *known_bsize = bsize2;
+ break;
+ }
+ }
+ brelse(bh);
+ if (!(*known_bsize)) {
+ sdp->bsize = GFS2_DEFAULT_BSIZE;
+ continue;
+ }
+
+ sdp->bsize = *known_bsize;
+ log_warn(_("Block size determined to be: %d\n"), *known_bsize);
+ return 0;
+ }
+ return 0;
+}
+
+/**
+ * peruse_metadata - check a range of blocks for metadata
+ * Assumes: device is open.
+ */
+static int peruse_metadata(struct gfs2_sbd *sdp, uint64_t startblock)
+{
+ uint64_t blk, max_rg_size;
+ struct gfs2_buffer_head *bh;
+ struct gfs2_dinode di;
+ int found_gfs2_dinodes = 0, possible_gfs1_dinodes = 0;
+
+ max_rg_size = 2147483648ull / sdp->bsize;
+ /* Max RG size is 2GB. 2G / bsize. */
+ for (blk = startblock; blk < startblock + max_rg_size; blk++) {
+ bh = bread(sdp, blk);
+ if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+ brelse(bh);
+ continue;
+ }
+ gfs2_dinode_in(&di, bh);
+ if (!found_gfs2_dinodes &&
+ di.di_num.no_addr == di.di_num.no_formal_ino) {
+ possible_gfs1_dinodes++;
+ if (possible_gfs1_dinodes > 5) {
+ log_err(_("Found several gfs (version 1) "
+ "dinodes; aborting.\n"));
+ brelse(bh);
+ return -1;
+ }
+ } else {
+ found_gfs2_dinodes++;
+ }
+ if (di.di_flags & GFS2_DIF_SYSTEM)
+ peruse_system_dinode(sdp, &di, bh);
+ else
+ peruse_user_dinode(sdp, &di, bh);
+ brelse(bh);
+ }
+ return 0;
+}
+
+/**
+ * sb_repair - repair a damaged superblock
+ * Assumes: device is open.
+ * The biggest RG size is 2GB
+ */
+static int sb_repair(struct gfs2_sbd *sdp)
+{
+ uint64_t real_device_size, half;
+ uint32_t known_bsize = 0;
+ unsigned char uuid[16];
+ int error = 0;
+
+ memset(&fix_md, 0, sizeof(fix_md));
+ /* Step 1 - First we need to determine the correct block size. */
+ sdp->bsize = GFS2_DEFAULT_BSIZE;
+ log_warn(_("Gathering information to repair the gfs2 superblock. "
+ "This may take some time.\n"));
+ error = find_rgs_for_bsize(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) /
+ GFS2_DEFAULT_BSIZE, &known_bsize);
+ if (error)
+ return error;
+ if (!known_bsize) {
+ log_warn(_("Block size not apparent; checking elsewhere.\n"));
+ /* First, figure out the device size. We need that so we can
+ find a suitable start point to determine what's what. */
+ device_size(sdp->device_fd, &real_device_size);
+ half = real_device_size / 2; /* in bytes */
+ half /= sdp->bsize;
+ /* Start looking halfway through the device for gfs2
+ structures. If there aren't any at all, forget it. */
+ error = find_rgs_for_bsize(sdp, half, &known_bsize);
+ if (error)
+ return error;
+ }
+ if (!known_bsize) {
+ log_err(_("Unable to determine the block size; this "
+ "does not look like a gfs2 file system.\n"));
+ return -1;
+ }
+ /* Step 2 - look for the sytem dinodes */
+ error = peruse_metadata(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) /
+ GFS2_DEFAULT_BSIZE);
+ if (error)
+ return error;
+ if (!sdp->sd_sb.sb_master_dir.no_addr) {
+ log_err(_("Unable to locate the system master directory.\n"));
+ return -1;
+ }
+ if (!sdp->sd_sb.sb_root_dir.no_addr) {
+ struct gfs2_inum inum;
+
+ log_err(_("Unable to locate the root directory.\n"));
+ if (possible_root == HIGHEST_BLOCK) {
+ /* Take advantage of the fact that mkfs.gfs2
+ creates master immediately after root. */
+ log_err(_("Can't find any dinodes that might "
+ "be the root; using master - 1.\n"));
+ possible_root = sdp->sd_sb.sb_master_dir.no_addr - 1;
+ }
+ log_err(_("Found a root directory candidate at 0x%llx\n"),
+ (unsigned long long)possible_root);
+ sdp->sd_sb.sb_root_dir.no_addr = possible_root;
+ sdp->md.rooti = inode_read(sdp, possible_root);
+ if (!sdp->md.rooti ||
+ sdp->md.rooti->i_di.di_header.mh_magic != GFS2_MAGIC) {
+ struct gfs2_buffer_head *bh;
+
+ log_err(_("The root dinode block is destroyed.\n"));
+ log_err(_("At this point I recommend "
+ "reinitializing it.\n"
+ "Hopefully everything will later "
+ "be put into lost+found.\n"));
+ if (!query(_("Okay to reinitialize the root "
+ "dinode? (y/n)"))) {
+ log_err(_("The root dinode was not "
+ "reinitialized; aborting.\n"));
+ return -1;
+ }
+ inum.no_formal_ino = 1;
+ inum.no_addr = possible_root;
+ bh = init_dinode(sdp, &inum, S_IFDIR | 0755, 0, &inum);
+ brelse(bh);
+ }
+ }
+ /* Step 3 - Rebuild the lock protocol and file system table name */
+ get_lockproto_table(sdp);
+ if (query(_("Okay to fix the GFS2 superblock? (y/n)"))) {
+ log_info(_("Master system directory found at: 0x%llx\n"),
+ sdp->sd_sb.sb_master_dir.no_addr);
+ sdp->master_dir = inode_read(sdp,
+ sdp->sd_sb.sb_master_dir.no_addr);
+ sdp->master_dir->i_di.di_num.no_addr =
+ sdp->sd_sb.sb_master_dir.no_addr;
+ log_info(_("Root directory found at: 0x%llx\n"),
+ sdp->sd_sb.sb_root_dir.no_addr);
+ sdp->md.rooti = inode_read(sdp,
+ sdp->sd_sb.sb_root_dir.no_addr);
+ get_random_bytes(uuid, sizeof(uuid));
+ build_sb(sdp, uuid);
+ inode_put(&sdp->md.rooti);
+ inode_put(&sdp->master_dir);
+ } else {
+ log_crit(_("GFS2 superblock not fixed; fsck cannot proceed "
+ "without a valid superblock.\n"));
+ return -1;
+ }
+ return 0;
+}
+
/**
* fill_super_block
* @sdp:
@@ -441,8 +1012,17 @@ static int fill_super_block(struct gfs2_sbd *sdp)
log_crit(_("Bad constants (1)\n"));
exit(-1);
}
- if(read_sb(sdp) < 0){
- return -1;
+ if (read_sb(sdp) < 0) {
+ /* First, check for a gfs1 (not gfs2) file system */
+ if (sdp->sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
+ sdp->sd_sb.sb_header.mh_type == GFS2_METATYPE_SB)
+ return -1; /* This is gfs1, don't try to repair */
+ /* It's not a "sane" gfs1 fs so try to repair it */
+ if (sb_repair(sdp) != 0)
+ return -1; /* unrepairable, so exit */
+ /* Now that we've tried to repair it, re-read it. */
+ if (read_sb(sdp) < 0)
+ return -1;
}
return 0;
@@ -504,10 +1084,8 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
}
/* read in sb from disk */
- if (fill_super_block(sbp)) {
- stack;
+ if (fill_super_block(sbp))
return FSCK_ERROR;
- }
/* Change lock protocol to be fsck_* instead of lock_* */
if(!opts.no && preen_is_safe(sbp, preen, force_check)) {
@@ -517,6 +1095,17 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
}
}
+ /* Get master dinode */
+ sbp->master_dir = inode_read(sbp, sbp->sd_sb.sb_master_dir.no_addr);
+ if (sbp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC ||
+ sbp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI ||
+ !sbp->master_dir->i_di.di_size) {
+ inode_put(&sbp->master_dir);
+ rebuild_master(sbp);
+ sbp->master_dir = inode_read(sbp,
+ sbp->sd_sb.sb_master_dir.no_addr);
+ }
+
/* verify various things */
if(replay_journals(sbp, preen, force_check, &clean_journals)) {
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 6bddeea..222219f 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -144,117 +144,6 @@ static void interrupt(int sig)
}
}
-/* Check system inode and verify it's marked "in use" in the bitmap: */
-/* Should work for all system inodes: root, master, jindex, per_node, etc. */
-static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
- int builder(struct gfs2_sbd *sbp),
- enum gfs2_mark_block mark)
-{
- uint64_t iblock = 0;
- struct dir_status ds = {0};
-
- log_info( _("Checking system inode '%s'\n"), filename);
- if (sysinode) {
- /* Read in the system inode, look at its dentries, and start
- * reading through them */
- iblock = sysinode->i_di.di_num.no_addr;
- log_info( _("System inode for '%s' is located at block %"
- PRIu64 " (0x%" PRIx64 ")\n"), filename,
- iblock, iblock);
-
- /* FIXME: check this block's validity */
-
- ds.q = block_type(iblock);
- /* If the inode exists but the block is marked */
- /* free, we might be recovering from a corrupt */
- /* bitmap. In that case, don't rebuild the inode. */
- /* Just reuse the inode and fix the bitmap. */
- if (ds.q == gfs2_block_free) {
- log_info( _("The inode exists but the block is not "
- "marked 'in use'; fixing it.\n"));
- fsck_blockmap_set(sysinode,
- sysinode->i_di.di_num.no_addr,
- filename, mark);
- ds.q = mark;
- if (mark == gfs2_inode_dir)
- dirtree_insert(sysinode->i_di.di_num.no_addr);
- }
- }
- else
- log_info( _("System inode for '%s' is missing.\n"), filename);
- /* If there are errors with the inode here, we need to
- * create a new inode and get it all setup - of course,
- * everything will be in lost+found then, but we *need* our
- * system inodes before we can do any of that. */
- if(!sysinode || ds.q != mark) {
- log_err( _("Invalid or missing %s system inode.\n"), filename);
- if (query(_("Create new %s system inode? (y/n) "), filename)) {
- builder(sysinode->i_sbd);
- fsck_blockmap_set(sysinode,
- sysinode->i_di.di_num.no_addr,
- filename, mark);
- ds.q = mark;
- if (mark == gfs2_inode_dir)
- dirtree_insert(sysinode->i_di.di_num.no_addr);
- }
- else {
- log_err( _("Cannot continue without valid %s inode\n"),
- filename);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int check_system_inodes(struct gfs2_sbd *sdp)
-{
- /*******************************************************************
- ******* Check the system inode integrity *************
- *******************************************************************/
- if (check_system_inode(sdp->master_dir, "master", build_master,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.rooti, "root", build_root,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.inum, "inum", build_inum,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.statfs, "statfs", build_statfs,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.jiinode, "jindex", build_jindex,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.riinode, "rindex", build_rindex,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.qinode, "quota", build_quota,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.pinode, "per_node", build_per_node,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- return 0;
-}
-
static void check_statfs(struct gfs2_sbd *sdp)
{
osi_list_t *tmp;
@@ -363,9 +252,6 @@ int main(int argc, char **argv)
else
log_notice( _("Pass1 complete \n"));
- /* Make sure the system inodes are okay & represented in the bitmap. */
- check_system_inodes(sbp);
-
if (!fsck_abort) {
last_reported_block = 0;
pass = "pass 1b";
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 0f18733..0ab8d7e 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -172,8 +172,7 @@ struct duptree *dupfind(uint64_t block)
return NULL;
}
-static struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
- uint64_t block)
+struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp, uint64_t block)
{
if (lf_dip && lf_dip->i_di.di_num.no_addr == block)
return lf_dip;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 9eb2372..c602492 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -34,6 +34,8 @@ extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
enum gfs2_mark_block new_blockmap_state);
extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
extern struct duptree *dupfind(uint64_t block);
+extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
+ uint64_t block);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index a3cd7f7..6c4762d 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -72,6 +72,7 @@ static int invalidate_eattr_indir(struct gfs2_inode *ip, uint64_t block,
static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private);
+static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
struct metawalk_fxns pass1_fxns = {
.private = NULL,
@@ -101,6 +102,98 @@ struct metawalk_fxns invalidate_fxns = {
.check_eattr_leaf = invalidate_eattr_leaf,
};
+/*
+ * resuscitate_metalist - make sure a system directory entry's metadata blocks
+ * are marked "in use" in the bitmap.
+ *
+ * This function makes sure metadata blocks for system and root directories are
+ * marked "in use" by the bitmap. You don't want root's indirect blocks
+ * deleted, do you? Or worse, reused for lost+found.
+ */
+static int resuscitate_metalist(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, void *private)
+{
+ struct block_count *bc = (struct block_count *)private;
+
+ *bh = NULL;
+ if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
+ fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
+ _("itself"), gfs2_bad_block);
+ log_err( _("Bad indirect block pointer (out of range) "
+ "found in system inode %lld (0x%llx).\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ return 1;
+ }
+ if (fsck_system_inode(ip->i_sbd, block))
+ fsck_blockmap_set(ip, block, _("system file"), gfs2_indir_blk);
+ else
+ check_n_fix_bitmap(ip->i_sbd, block, gfs2_indir_blk);
+ bc->indir_count++;
+ return 0;
+}
+
+/*
+ * resuscitate_dentry - make sure a system directory entry is alive
+ *
+ * This function makes sure directory entries in system directories are
+ * kept alive. You don't want journal0 deleted from jindex, do you?
+ */
+static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
+ struct gfs2_dirent *prev_de,
+ struct gfs2_buffer_head *bh, char *filename,
+ uint16_t *count, void *priv)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_dirent dentry, *de;
+ char tmp_name[PATH_MAX];
+ uint64_t block;
+ enum gfs2_mark_block dinode_type;
+
+ memset(&dentry, 0, sizeof(struct gfs2_dirent));
+ gfs2_dirent_in(&dentry, (char *)dent);
+ de = &dentry;
+ block = de->de_inum.no_addr;
+ /* Start of checks */
+ memset(tmp_name, 0, sizeof(tmp_name));
+ if(de->de_name_len < sizeof(tmp_name))
+ strncpy(tmp_name, filename, de->de_name_len);
+ else
+ strncpy(tmp_name, filename, sizeof(tmp_name) - 1);
+ if(gfs2_check_range(sdp, block)) {
+ log_err( _("Block # referenced by system directory entry %s "
+ "in inode %lld (0x%llx) is out of range; "
+ "ignored.\n"),
+ tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ return 0;
+ }
+ if (block == sdp->md.jiinode->i_di.di_num.no_addr ||
+ block == sdp->md.pinode->i_di.di_num.no_addr ||
+ block == sdp->master_dir->i_di.di_num.no_addr)
+ dinode_type = gfs2_inode_dir;
+ else
+ dinode_type = gfs2_inode_file;
+ /* If this is a system dinode, we'll handle it later in
+ check_system_inodes. If not, it'll be handled by pass1 but
+ since it's in a system directory we need to make sure it's
+ represented in the rgrp bitmap. */
+ if (fsck_system_inode(sdp, block))
+ fsck_blockmap_set(ip, block, _("system file"), dinode_type);
+ else
+ check_n_fix_bitmap(sdp, block, dinode_type);
+ /* Return the number of leaf entries so metawalk doesn't flag this
+ leaf as having none. */
+ *count = be16_to_cpu(((struct gfs2_leaf *)bh->b_data)->lf_entries);
+ return 0;
+}
+
+struct metawalk_fxns sysdir_fxns = {
+ .private = NULL,
+ .check_metalist = resuscitate_metalist,
+ .check_dentry = resuscitate_dentry,
+};
+
static int leaf(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *bh, void *private)
{
@@ -865,40 +958,15 @@ struct metawalk_fxns rangecheck_fxns = {
.check_eattr_leaf = rangecheck_eattr_leaf,
};
-static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
+/*
+ * handle_ip - process an incore structure representing a dinode.
+ */
+static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
{
- uint8_t q;
- struct gfs2_inode *ip;
int error;
struct block_count bc = {0};
- uint64_t block = bh->b_blocknr;
long bad_pointers;
-
- q = block_type(block);
- if(q != gfs2_block_free) {
- log_err( _("Found a duplicate inode block at #%" PRIu64
- " (0x%" PRIx64 ") previously marked as a %s\n"),
- block, block, block_type_string(q));
- add_duplicate_ref(ip, block, ref_as_meta, 0, INODE_VALID);
- return 0;
- }
-
- ip = fsck_inode_get(sdp, bh);
- if (ip->i_di.di_num.no_addr != block) {
- log_err( _("Inode #%llu (0x%llx): Bad inode address found: %llu "
- "(0x%llx)\n"), (unsigned long long)block,
- (unsigned long long)block,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- if(query( _("Fix address in inode at block #%"
- PRIu64 " (0x%" PRIx64 ")? (y/n) "),
- block, block)) {
- ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
- bmodified(ip->i_bh);
- } else
- log_err( _("Address in inode at block #%" PRIu64
- " (0x%" PRIx64 ") not fixed\n"), block, block);
- }
+ uint64_t block = ip->i_bh->b_blocknr;
bad_pointers = 0L;
@@ -916,7 +984,6 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
BAD_POINTER_TOLERANCE);
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("badly corrupt"), gfs2_block_free);
- fsck_inode_put(&ip);
return 0;
}
@@ -924,64 +991,40 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
case S_IFDIR:
if (fsck_blockmap_set(ip, block, _("directory"),
- gfs2_inode_dir)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- if(!dirtree_insert(block)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_dir))
+ goto bad_dinode;
+ if(!dirtree_insert(block))
+ goto bad_dinode;
break;
case S_IFREG:
if (fsck_blockmap_set(ip, block, _("file"),
- gfs2_inode_file)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_file))
+ goto bad_dinode;
break;
case S_IFLNK:
if (fsck_blockmap_set(ip, block, _("symlink"),
- gfs2_inode_lnk)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_lnk))
+ goto bad_dinode;
break;
case S_IFBLK:
if (fsck_blockmap_set(ip, block, _("block device"),
- gfs2_inode_blk)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_blk))
+ goto bad_dinode;
break;
case S_IFCHR:
if (fsck_blockmap_set(ip, block, _("character device"),
- gfs2_inode_chr)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_chr))
+ goto bad_dinode;
break;
case S_IFIFO:
if (fsck_blockmap_set(ip, block, _("fifo"),
- gfs2_inode_fifo)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_fifo))
+ goto bad_dinode;
break;
case S_IFSOCK:
if (fsck_blockmap_set(ip, block, _("socket"),
- gfs2_inode_sock)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_sock))
+ goto bad_dinode;
break;
default:
/* We found a dinode that has an invalid mode, so we can't
@@ -997,19 +1040,12 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
skip parts that we can't be sure of based on dinode type. */
check_metatree(ip, &invalidate_fxns);
if (fsck_blockmap_set(ip, block, _("invalid mode"),
- gfs2_inode_invalid)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- fsck_inode_put(&ip);
+ gfs2_inode_invalid))
+ goto bad_dinode;
return 0;
}
- if(set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ if(set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink))
+ goto bad_dinode;
if (S_ISDIR(ip->i_di.di_mode) &&
(ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
@@ -1021,22 +1057,16 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
ip->i_di.di_depth,
(1 >> (ip->i_di.di_size/sizeof(uint64_t))));
if(fsck_blockmap_set(ip, block, _("bad depth"),
- gfs2_block_free)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- fsck_inode_put(&ip);
+ gfs2_block_free))
+ goto bad_dinode;
return 0;
}
}
pass1_fxns.private = &bc;
error = check_metatree(ip, &pass1_fxns);
- if (fsck_abort || error < 0) {
- fsck_inode_put(&ip);
+ if (fsck_abort || error < 0)
return 0;
- }
if (error > 0) {
log_err( _("Error: inode %llu (0x%llx) has unrecoverable "
"errors; invalidating.\n"),
@@ -1050,7 +1080,6 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
Therefore we mark the inode as free space. */
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("corrupt"), gfs2_block_free);
- fsck_inode_put(&ip);
return 0;
}
@@ -1089,7 +1118,196 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
(unsigned long long)ip->i_di.di_num.no_addr);
}
+ return 0;
+bad_dinode:
+ stack;
+ return -1;
+}
+
+/*
+ * handle_di - This is now a wrapper function that takes a gfs2_buffer_head
+ * and calls handle_ip, which takes an in-code dinode structure.
+ */
+static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
+{
+ uint8_t q;
+ int error = 0;
+ uint64_t block = bh->b_blocknr;
+ struct gfs2_inode *ip;
+
+ ip = fsck_inode_get(sdp, bh);
+ q = block_type(block);
+ if(q != gfs2_block_free) {
+ log_err( _("Found a duplicate inode block at #%" PRIu64
+ " (0x%" PRIx64 ") previously marked as a %s\n"),
+ block, block, block_type_string(q));
+ add_duplicate_ref(ip, block, ref_as_meta, 0, INODE_VALID);
+ fsck_inode_put(&ip);
+ return 0;
+ }
+
+ if (ip->i_di.di_num.no_addr != block) {
+ log_err( _("Inode #%llu (0x%llx): Bad inode address found: %llu "
+ "(0x%llx)\n"), (unsigned long long)block,
+ (unsigned long long)block,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ if(query( _("Fix address in inode at block #%"
+ PRIu64 " (0x%" PRIx64 ")? (y/n) "),
+ block, block)) {
+ ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
+ bmodified(ip->i_bh);
+ } else
+ log_err( _("Address in inode at block #%" PRIu64
+ " (0x%" PRIx64 ") not fixed\n"), block, block);
+ }
+ error = handle_ip(sdp, ip);
fsck_inode_put(&ip);
+ return error;
+}
+
+/* Check system inode and verify it's marked "in use" in the bitmap: */
+/* Should work for all system inodes: root, master, jindex, per_node, etc. */
+static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
+ int builder(struct gfs2_sbd *sbp),
+ enum gfs2_mark_block mark)
+{
+ uint64_t iblock = 0;
+ struct dir_status ds = {0};
+ int error;
+
+ log_info( _("Checking system inode '%s'\n"), filename);
+ if (sysinode) {
+ /* Read in the system inode, look at its dentries, and start
+ * reading through them */
+ iblock = sysinode->i_di.di_num.no_addr;
+ log_info( _("System inode for '%s' is located at block %"
+ PRIu64 " (0x%" PRIx64 ")\n"), filename,
+ iblock, iblock);
+
+ /* FIXME: check this block's validity */
+
+ ds.q = block_type(iblock);
+ /* If the inode exists but the block is marked free, we might
+ be recovering from a corrupt bitmap. In that case, don't
+ rebuild the inode. Just reuse the inode and fix the
+ bitmap. */
+ if (ds.q == gfs2_block_free) {
+ log_info( _("The inode exists but the block is not "
+ "marked 'in use'; fixing it.\n"));
+ fsck_blockmap_set(sysinode,
+ sysinode->i_di.di_num.no_addr,
+ filename, mark);
+ ds.q = mark;
+ if (mark == gfs2_inode_dir)
+ dirtree_insert(sysinode->i_di.di_num.no_addr);
+ }
+ } else
+ log_info( _("System inode for '%s' is missing.\n"), filename);
+ /* If there are errors with the inode here, we need to create a new
+ inode and get it all setup - of course, everything will be in
+ lost+found then, but we *need* our system inodes before we can
+ do any of that. */
+ if(!sysinode || ds.q != mark) {
+ log_err( _("Invalid or missing %s system inode (should be %d, "
+ "is %d).\n"), filename, mark, ds.q);
+ if (query(_("Create new %s system inode? (y/n) "), filename)) {
+ builder(sysinode->i_sbd);
+ fsck_blockmap_set(sysinode,
+ sysinode->i_di.di_num.no_addr,
+ filename, mark);
+ ds.q = mark;
+ if (mark == gfs2_inode_dir)
+ dirtree_insert(sysinode->i_di.di_num.no_addr);
+ } else {
+ log_err( _("Cannot continue without valid %s inode\n"),
+ filename);
+ return -1;
+ }
+ }
+ if (S_ISDIR(sysinode->i_di.di_mode)) {
+ struct block_count bc = {0};
+
+ sysdir_fxns.private = &bc;
+ if (sysinode->i_di.di_flags & GFS2_DIF_EXHASH)
+ check_metatree(sysinode, &sysdir_fxns);
+ else
+ check_linear_dir(sysinode, sysinode->i_bh,
+ &sysdir_fxns);
+ }
+ error = handle_ip(sysinode->i_sbd, sysinode);
+ return error;
+}
+
+static int build_a_journal(struct gfs2_sbd *sdp)
+{
+ build_journal(sdp, sdp->md.journals, sdp->md.jiinode);
+ return 0;
+}
+
+static int check_system_inodes(struct gfs2_sbd *sdp)
+{
+ int journal_count;
+
+ /*******************************************************************
+ ******* Check the system inode integrity *************
+ *******************************************************************/
+ if (check_system_inode(sdp->master_dir, "master", build_master,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.rooti, "root", build_root,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.inum, "inum", build_inum,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.statfs, "statfs", build_statfs,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.jiinode, "jindex", build_jindex,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.riinode, "rindex", build_rindex,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.qinode, "quota", build_quota,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.pinode, "per_node", build_per_node,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ /* We have to play a trick on build_journal: We swap md.journals
+ in order to keep a count of which journal we need to build. */
+ journal_count = sdp->md.journals;
+ for (sdp->md.journals = 0; sdp->md.journals < journal_count;
+ sdp->md.journals++) {
+ char jname[16];
+
+ sprintf(jname, "journal%d", sdp->md.journals);
+ if (check_system_inode(sdp->md.journal[sdp->md.journals],
+ jname, build_a_journal,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ }
+
return 0;
}
@@ -1124,6 +1342,9 @@ int pass1(struct gfs2_sbd *sbp)
* sweep - is there any metadata we need to mark here before
* the sweeps start that we won't find otherwise? */
+ /* Make sure the system inodes are okay & represented in the bitmap. */
+ check_system_inodes(sbp);
+
/* So, do we do a depth first search starting at the root
* inode, or use the rg bitmaps, or just read every fs block
* to find the inodes? If we use the depth first search, why
@@ -1190,6 +1411,11 @@ int pass1(struct gfs2_sbd *sbp)
}
check_n_fix_bitmap(sbp, block,
gfs2_block_free);
+ } else if (fsck_system_inode(sbp, block)) {
+ log_debug(_("Already processed system inode "
+ "%lld (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
} else if (handle_di(sbp, bh) < 0) {
stack;
brelse(bh);
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 0b5c576..705ba86 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -378,10 +378,11 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
{
int x = errblock - rg->ri.ri_addr;
- log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither"
+ log_err( _("Block #%lld (0x%llx) (%d of %d) is neither"
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
- rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
- (int)x+1, (int)rg->ri.ri_length);
+ (unsigned long long)rg->ri.ri_addr + x,
+ (unsigned long long)rg->ri.ri_addr + x,
+ (int)x+1, (int)rg->ri.ri_length);
if (query( _("Fix the Resource Group? (y/n)"))) {
log_err( _("Attempting to repair the RG.\n"));
rg->bh[x] = bread(sdp, rg->ri.ri_addr + x);
@@ -401,12 +402,46 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
gfs2_rgrp_out(&rg->rg, rg->bh[x]);
}
brelse(rg->bh[x]);
+ rg->bh[x] = NULL;
return 0;
}
return 1;
}
/*
+ * expect_rindex_sanity - the rindex file seems trustworthy, so use those
+ * values as our expected values and assume the
+ * damage is only to the rgrps themselves.
+ */
+static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
+ int *num_rgs)
+{
+ osi_list_t *tmp;
+ struct rgrp_list *exp, *rgd; /* expected, actual */
+
+ *num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
+ osi_list_init(ret_list);
+ for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+ rgd = osi_list_entry(tmp, struct rgrp_list, list);
+
+ exp = calloc(1, sizeof(struct rgrp_list));
+ if (exp == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
+ exp->start = rgd->start;
+ exp->length = rgd->length;
+ memcpy(&exp->ri, &rgd->ri, sizeof(exp->ri));
+ memcpy(&exp->rg, &rgd->rg, sizeof(exp->rg));
+ exp->bits = NULL;
+ gfs2_compute_bitstructs(sdp, exp);
+ osi_list_add_prev(&exp->list, ret_list);
+ }
+ sdp->rgrps = *num_rgs;
+ return 0;
+}
+
+/*
* rg_repair - try to repair a damaged rg index (rindex)
* trust_lvl - This is how much we trust the rindex file.
* blind_faith means we take the rindex at face value.
@@ -414,7 +449,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
* distrust means it's not to be trusted, so we should go to
* greater lengths to build it from scratch.
*/
-int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
+int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
{
int error, discrepancies;
osi_list_t expected_rglist;
@@ -424,10 +459,20 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
if (trust_lvl == blind_faith)
return 0;
- else if (trust_lvl == open_minded) { /* If we can't trust RG index */
+ else if (trust_lvl == ye_of_little_faith) { /* if rindex seems sane */
+ if (!(*sane)) {
+ log_err(_("The rindex file does not meet our "
+ "expectations.\n"));
+ return -1;
+ }
+ error = expect_rindex_sanity(sdp, &expected_rglist,
+ &calc_rg_count);
+ if (error)
+ return error;
+ } else if (trust_lvl == open_minded) { /* If we can't trust RG index */
/* Calculate our own RG index for comparison */
error = gfs2_rindex_calculate(sdp, &expected_rglist,
- &calc_rg_count);
+ &calc_rg_count);
if (error) { /* If calculated RGs don't match the fs */
gfs2_rgrp_free(&expected_rglist);
return -1;
@@ -445,7 +490,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
}
/* Read in the rindex */
osi_list_init(&sdp->rglist); /* Just to be safe */
- rindex_read(sdp, 0, &rgcount_from_index);
+ rindex_read(sdp, 0, &rgcount_from_index, sane);
if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) {
log_warn( _("WARNING: rindex file is corrupt.\n"));
gfs2_rgrp_free(&expected_rglist);
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index ed773b4..e0a1681 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1521,7 +1521,7 @@ static int dir_l_search(struct gfs2_inode *dip, const char *filename,
*
* Returns: 0 if found, -1 on failure, -ENOENT if not found.
*/
-static int dir_search(struct gfs2_inode *dip, const char *filename, int len,
+int dir_search(struct gfs2_inode *dip, const char *filename, int len,
unsigned int *type, struct gfs2_inum *inum)
{
int error;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index f98f845..0c4bc8a 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -446,6 +446,8 @@ extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
unsigned int mode, uint32_t flags);
extern void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
struct gfs2_dirent *prev, struct gfs2_dirent *cur);
+extern int dir_search(struct gfs2_inode *dip, const char *filename, int len,
+ unsigned int *type, struct gfs2_inum *inum);
extern int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
struct gfs2_inode **ipp);
extern void dir_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -621,6 +623,7 @@ extern char *get_sysfs(const char *fsname, const char *filename);
extern int get_sysfs_uint(const char *fsname, const char *filename, unsigned int *val);
extern int set_sysfs(const char *fsname, const char *filename, const char *val);
extern int is_fsname(char *name);
+extern void get_random_bytes(void *buf, int nbytes);
/* recovery.c */
extern void gfs2_replay_incr_blk(struct gfs2_inode *ip, unsigned int *blk);
@@ -648,6 +651,8 @@ extern void gfs2_rgrp_free(osi_list_t *rglist);
/* structures.c */
extern int build_master(struct gfs2_sbd *sdp);
extern void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
+extern int build_journal(struct gfs2_sbd *sdp, int j,
+ struct gfs2_inode *jindex);
extern int build_jindex(struct gfs2_sbd *sdp);
extern int build_per_node(struct gfs2_sbd *sdp);
extern int build_inum(struct gfs2_sbd *sdp);
@@ -666,8 +671,8 @@ extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
extern int check_sb(struct gfs2_sb *sb);
extern int read_sb(struct gfs2_sbd *sdp);
extern int ji_update(struct gfs2_sbd *sdp);
-extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
-extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
+extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane);
+extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane);
extern int write_sb(struct gfs2_sbd *sdp);
/* ondisk.c */
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index ffa0dba..8981114 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -16,6 +16,7 @@
#include <linux/kdev_t.h>
#include <sys/sysmacros.h>
#include <mntent.h>
+#include <sys/time.h>
#include "libgfs2.h"
@@ -409,3 +410,47 @@ char *mp2fsname(char *mp)
return fsname;
}
+
+/*
+ * get_random_bytes - Generate a series of random bytes using /dev/urandom.
+ *
+ * Modified from original code in gen_uuid.c in e2fsprogs/lib
+ */
+void get_random_bytes(void *buf, int nbytes)
+{
+ int i, n = nbytes, fd;
+ int lose_counter = 0;
+ unsigned char *cp = (unsigned char *) buf;
+ struct timeval tv;
+
+ gettimeofday(&tv, 0);
+ fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
+ srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+ /* Crank the random number generator a few times */
+ gettimeofday(&tv, 0);
+ for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
+ rand();
+ if (fd >= 0) {
+ while (n > 0) {
+ i = read(fd, cp, n);
+ if (i <= 0) {
+ if (lose_counter++ > 16)
+ break;
+ continue;
+ }
+ n -= i;
+ cp += i;
+ lose_counter = 0;
+ }
+ close(fd);
+ }
+
+ /*
+ * We do this all the time, but this is the only source of
+ * randomness if /dev/random/urandom is out to lunch.
+ */
+ for (cp = buf, i = 0; i < nbytes; i++)
+ *cp++ ^= (rand() >> 7) & 0xFF;
+
+ return;
+}
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index f42fdaa..8d2d405 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -133,8 +133,10 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
uint64_t error;
error = rgd->ri.ri_addr + x;
- for (; x >= 0; x--)
+ for (; x >= 0; x--) {
brelse(rgd->bh[x]);
+ rgd->bh[x] = NULL;
+ }
return error;
}
}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 37ed8e6..c288abd 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -126,6 +126,22 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
return 0;
}
+int build_journal(struct gfs2_sbd *sdp, int j, struct gfs2_inode *jindex)
+{
+ char name[256];
+ struct gfs2_inode *ip;
+ int ret;
+
+ sprintf(name, "journal%u", j);
+ ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
+ ret = write_journal(sdp, ip, j,
+ sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
+ if (ret)
+ return ret;
+ inode_put(&ip);
+ return 0;
+}
+
int build_jindex(struct gfs2_sbd *sdp)
{
struct gfs2_inode *jindex;
@@ -136,18 +152,10 @@ int build_jindex(struct gfs2_sbd *sdp)
GFS2_DIF_SYSTEM);
for (j = 0; j < sdp->md.journals; j++) {
- char name[256];
- struct gfs2_inode *ip;
-
- sprintf(name, "journal%u", j);
- ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
- ret = write_journal(sdp, ip, j,
- sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
+ ret = build_journal(sdp, j, jindex);
if (ret)
return ret;
- inode_put(&ip);
}
-
if (sdp->debug) {
printf("\nJindex:\n");
gfs2_dinode_print(&jindex->i_di);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 1fa18ce..c5b5800 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -159,10 +159,11 @@ int ji_update(struct gfs2_sbd *sdp)
* fd: optional file handle for rindex file (if meta_fs file system is mounted)
* (if fd is <= zero, it will read from raw device)
* @count1: return count of the rgs.
+ * @sane: return whether rindex is consistent
*
* Returns: 0 on success, -1 on failure
*/
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
{
unsigned int rg;
int error;
@@ -170,8 +171,11 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
struct rgrp_list *rgd, *prev_rgd;
uint64_t prev_length = 0;
+ *sane = 1;
*count1 = 0;
prev_rgd = NULL;
+ if (!fd && sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex))
+ *sane = 0; /* rindex file size must be a multiple of 96 */
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -196,12 +200,27 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
+ /* If rg addresses go backwards, it's not sane
+ (or it's converted from gfs1). */
+ if (prev_rgd->start >= rgd->start)
+ *sane = 0;
+ /* If rg lengths are not consistent, it's not sane
+ (or it's converted from gfs1). The first RG will
+ be a different length due to space allocated for
+ the superblock, so we can't detect this until
+ we check rgrp 3, when we can compare the distance
+ between rgrp 1 and rgrp 2. */
+ if (rg > 2 && prev_length &&
+ prev_length != rgd->start - prev_rgd->start)
+ *sane = 0;
prev_length = rgd->start - prev_rgd->start;
prev_rgd->length = prev_length;
}
- if(gfs2_compute_bitstructs(sdp, rgd))
+ if(gfs2_compute_bitstructs(sdp, rgd)) {
+ *sane = 0;
return -1;
+ }
(*count1)++;
prev_rgd = rgd;
@@ -222,7 +241,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
*
* Returns: 0 on success, -1 on failure.
*/
-int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
+int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
{
struct rgrp_list *rgd;
struct gfs2_rindex *ri;
@@ -231,7 +250,7 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
uint64_t errblock = 0;
uint64_t rmax = 0;
- if (rindex_read(sdp, fd, &count1))
+ if (rindex_read(sdp, fd, &count1, sane))
goto fail;
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index e622b3b..34f5291 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -259,6 +259,8 @@ main_grow(int argc, char *argv[])
decode_arguments(argc, argv, sdp);
while ((argc - optind) > 0) {
+ int sane;
+
sdp->path_name = argv[optind++];
sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC);
if (sdp->path_fd < 0)
@@ -322,7 +324,7 @@ main_grow(int argc, char *argv[])
/* and therefore out of date. It shouldn't matter because */
/* we're only going to write out new RG information after */
/* the existing RGs, and only write to the index at EOF. */
- ri_update(sdp, rindex_fd, &rgcount);
+ ri_update(sdp, rindex_fd, &rgcount, &sane);
fssize = filesystem_size(sdp);
figure_out_rgsize(sdp, &rgsize);
fsgrowth = ((sdp->device.length - fssize) * sdp->bsize);
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index eff2c9a..6af8c3a 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -478,50 +478,6 @@ static void check_mount(char *device)
return;
}
-/*
- * get_random_bytes - Generate a series of random bytes using /dev/urandom.
- *
- * Modified from original code in gen_uuid.c in e2fsprogs/lib
- */
-static void get_random_bytes(void *buf, int nbytes)
-{
- int i, n = nbytes, fd;
- int lose_counter = 0;
- unsigned char *cp = (unsigned char *) buf;
- struct timeval tv;
-
- gettimeofday(&tv, 0);
- fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
- srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
- /* Crank the random number generator a few times */
- gettimeofday(&tv, 0);
- for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
- rand();
- if (fd >= 0) {
- while (n > 0) {
- i = read(fd, cp, n);
- if (i <= 0) {
- if (lose_counter++ > 16)
- break;
- continue;
- }
- n -= i;
- cp += i;
- lose_counter = 0;
- }
- close(fd);
- }
-
- /*
- * We do this all the time, but this is the only source of
- * randomness if /dev/random/urandom is out to lunch.
- */
- for (cp = buf, i = 0; i < nbytes; i++)
- *cp++ ^= (rand() >> 7) & 0xFF;
-
- return;
-}
-
/**
* print_results - print out summary information
* @sdp: the command line
14 years, 1 month
gfs2-utils: master - gfs2_fsck segfault when statfs system file is missing
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 8eea6115a16de81ba457ae16b28b3ac49bfad08e
Parent: 470299f2fcf2ac8c1ac4954112b1235b64c3b1dd
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Apr 19 18:14:09 2010 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Apr 19 18:22:09 2010 -0500
gfs2_fsck segfault when statfs system file is missing
This patch repairs badly damaged gfs2 file systems. It can
rebuild destroyed superblock, master directory, root dinode and
all of the system dinodes.
rhbz#576330
---
gfs2/edit/hexedit.c | 4 +-
gfs2/edit/savemeta.c | 4 +-
gfs2/fsck/fs_recovery.c | 2 -
gfs2/fsck/fsck.h | 9 +-
gfs2/fsck/initialize.c | 661 ++++++++++++++++++++++++++++++++++++++++++---
gfs2/fsck/main.c | 114 --------
gfs2/fsck/metawalk.c | 3 +-
gfs2/fsck/metawalk.h | 2 +
gfs2/fsck/pass1.c | 410 ++++++++++++++++++++++-------
gfs2/fsck/rgrepair.c | 59 ++++-
gfs2/libgfs2/fs_ops.c | 2 +-
gfs2/libgfs2/libgfs2.h | 9 +-
gfs2/libgfs2/misc.c | 45 +++
gfs2/libgfs2/rgrp.c | 4 +-
gfs2/libgfs2/structures.c | 26 ++-
gfs2/libgfs2/super.c | 27 ++-
gfs2/mkfs/main_grow.c | 4 +-
gfs2/mkfs/main_mkfs.c | 44 ---
18 files changed, 1109 insertions(+), 320 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index d89b137..8d2561f 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1745,6 +1745,8 @@ static void read_superblock(int fd)
sbd.fssize = sbd.device.length;
gfs1_rindex_read(&sbd, 0, &count);
} else {
+ int sane;
+
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
@@ -1753,7 +1755,7 @@ static void read_superblock(int fd)
sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
sbd.fssize = sbd.device.length;
- rindex_read(&sbd, 0, &count);
+ rindex_read(&sbd, 0, &count, &sane);
}
}
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index bc1976c..7af9e48 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -589,12 +589,14 @@ void savemeta(char *out_fn, int saveoption)
brelse(lbh);
}
if (!slow) {
+ int sane;
+
printf("Reading resource groups...");
fflush(stdout);
if (gfs1)
slow = gfs1_ri_update(&sbd, 0, &rgcount, 0);
else
- slow = ri_update(&sbd, 0, &rgcount);
+ slow = ri_update(&sbd, 0, &rgcount, &sane);
printf("Done.\n\n");
fflush(stdout);
}
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 89e43be..da03ac4 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -572,7 +572,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
/* Get master dinode */
- sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
/* read in the journal index data */
@@ -598,7 +597,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
inode_put(&sdp->md.journal[i]);
}
- inode_put(&sdp->master_dir);
inode_put(&sdp->md.jiinode);
/* Sync the buffers to disk so we get a fresh start. */
fsync(sdp->device_fd);
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 022b61e..b0e1efc 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -79,10 +79,12 @@ struct inode_with_dups {
enum rgindex_trust_level { /* how far can we trust our RG index? */
blind_faith = 0, /* We'd like to trust the rgindex. We always used to
before bz 179069. This should cover most cases. */
- open_minded = 1, /* At least 1 RG is corrupt. Try to calculate what it
+ ye_of_little_faith = 1, /* The rindex seems trustworthy but there's
+ rg damage that need to be fixed. */
+ open_minded = 2, /* At least 1 RG is corrupt. Try to calculate what it
should be, in a perfect world where our RGs are all
on even boundaries. Blue sky. Chirping birds. */
- distrust = 2 /* The world isn't perfect, our RGs are not on nice neat
+ distrust = 3 /* The world isn't perfect, our RGs are not on nice neat
boundaries. The fs must have been messed with by
gfs2_grow or something. Count the RGs by hand. */
};
@@ -102,7 +104,8 @@ extern int pass2(struct gfs2_sbd *sbp);
extern int pass3(struct gfs2_sbd *sbp);
extern int pass4(struct gfs2_sbd *sbp);
extern int pass5(struct gfs2_sbd *sbp);
-extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count);
+extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
+ int *sane);
extern void gfs2_dup_free(void);
extern int fsck_query(const char *format, ...)
__attribute__((format(printf,1,2)));
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 622a8f1..e04198a 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -26,8 +26,11 @@
free(x); \
x = NULL; \
}
+#define HIGHEST_BLOCK 0xffffffffffffffff
static int was_mounted_ro = 0;
+static uint64_t possible_root = HIGHEST_BLOCK;
+static struct master_dir fix_md;
/**
* block_mounters
@@ -308,6 +311,87 @@ static int check_rgrps_integrity(struct gfs2_sbd *sdp)
}
/**
+ * rebuild_master - rebuild a destroyed master directory
+ */
+static int rebuild_master(struct gfs2_sbd *sdp)
+{
+ struct gfs2_inum inum;
+ struct gfs2_buffer_head *bh;
+
+ log_err(_("The system master directory seems to be destroyed.\n"));
+ if (!query(_("Okay to rebuild it? (y/n)"))) {
+ log_err(_("System master not rebuilt; aborting.\n"));
+ return -1;
+ }
+ log_err(_("Trying to rebuild the master directory.\n"));
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = sdp->sd_sb.sb_master_dir.no_addr;
+ bh = init_dinode(sdp, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
+ sdp->master_dir = inode_get(sdp, bh);
+ sdp->master_dir->bh_owned = 1;
+
+ if (fix_md.jiinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.jiinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "jindex", 6, &inum,
+ IF2DT(S_IFDIR | 0700));
+ sdp->master_dir->i_di.di_nlink++;
+ } else {
+ build_jindex(sdp);
+ }
+
+ if (fix_md.pinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.pinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "per_node", 8, &inum,
+ IF2DT(S_IFDIR | 0700));
+ sdp->master_dir->i_di.di_nlink++;
+ } else {
+ build_per_node(sdp);
+ }
+
+ if (fix_md.inum) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.inum->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "inum", 4, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_inum(sdp);
+ }
+
+ if (fix_md.statfs) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.statfs->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "statfs", 6, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_statfs(sdp);
+ }
+
+ if (fix_md.riinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.riinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "rindex", 6, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_rindex(sdp);
+ }
+
+ if (fix_md.qinode) {
+ inum.no_formal_ino = sdp->md.next_inum++;
+ inum.no_addr = fix_md.qinode->i_di.di_num.no_addr;
+ dir_add(sdp->master_dir, "quota", 5, &inum,
+ IF2DT(S_IFREG | 0600));
+ } else {
+ build_quota(sdp);
+ }
+
+ log_err(_("Master directory rebuilt.\n"));
+ inode_put(&sdp->master_dir);
+ return 0;
+}
+
+/**
* init_system_inodes
*
* Returns: 0 on success, -1 on failure
@@ -317,7 +401,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
uint64_t inumbuf;
char *buf;
struct gfs2_statfs_change sc;
- int rgcount;
+ int rgcount, sane = 1;
enum rgindex_trust_level trust_lvl;
uint64_t addl_mem_needed;
@@ -327,52 +411,43 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_info( _("Initializing special inodes...\n"));
- /* Get master dinode */
- sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
/* Get root dinode */
sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
- /* Look for "inum" entry in master dinode */
- gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
- /* Read inum entry into buffer */
- gfs2_readi(sdp->md.inum, &inumbuf, 0, sdp->md.inum->i_di.di_size);
- /* call gfs2_inum_range_in() to retrieve range */
- sdp->md.next_inum = be64_to_cpu(inumbuf);
-
- gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
- buf = malloc(sdp->md.statfs->i_di.di_size);
- // FIXME: handle failed malloc
- gfs2_readi(sdp->md.statfs, buf, 0, sdp->md.statfs->i_di.di_size);
- /* call gfs2_inum_range_in() to retrieve range */
- gfs2_statfs_change_in(&sc, buf);
- free(buf);
-
-
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-
gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
-
- gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
-
- gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode);
-
- /* FIXME fill in per_node structure */
+ if (!sdp->md.riinode) {
+ if (query( _("The gfs2 system rindex inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_rindex(sdp);
+ }
/*******************************************************************
- ******* Fill in rgrp and journal indexes and related fields *****
+ ****************** Fill in journal information ******************
*******************************************************************/
+ /* rgrepair requires the journals be read in in order to distinguish
+ "real" rgrps from rgrps that are just copies left in journals. */
+ gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+ if (!sdp->md.jiinode) {
+ if (query( _("The gfs2 system jindex inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_jindex(sdp);
+ }
+
/* read in the ji data */
if (ji_update(sdp)){
- log_err( _("Unable to read in ji inode.\n"));
+ log_err( _("Unable to read in jindex inode.\n"));
return -1;
}
+ /*******************************************************************
+ ******** Validate and read in resource group information ********
+ *******************************************************************/
log_warn( _("Validating Resource Group index.\n"));
for (trust_lvl = blind_faith; trust_lvl <= distrust; trust_lvl++) {
log_warn( _("Level %d RG check.\n"), trust_lvl + 1);
- if ((rg_repair(sdp, trust_lvl, &rgcount) == 0) &&
- (ri_update(sdp, 0, &rgcount) == 0)) {
+ if ((rg_repair(sdp, trust_lvl, &rgcount, &sane) == 0) &&
+ (ri_update(sdp, 0, &rgcount, &sane) == 0)) {
log_warn( _("(level %d passed)\n"), trust_lvl + 1);
break;
}
@@ -388,6 +463,54 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
check_rgrps_integrity(sdp);
/*******************************************************************
+ ***************** Initialize more system inodes *****************
+ *******************************************************************/
+ /* Look for "inum" entry in master dinode */
+ gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
+ if (!sdp->md.inum) {
+ if (query( _("The gfs2 system inum inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_inum(sdp);
+ }
+ /* Read inum entry into buffer */
+ gfs2_readi(sdp->md.inum, &inumbuf, 0, sdp->md.inum->i_di.di_size);
+ /* call gfs2_inum_range_in() to retrieve range */
+ sdp->md.next_inum = be64_to_cpu(inumbuf);
+
+ gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
+ if (!sdp->md.statfs) {
+ if (query( _("The gfs2 system statfs inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_statfs(sdp);
+ else {
+ log_err( _("fsck.gfs2 cannot continue without a "
+ "valid statfs file; aborting.\n"));
+ return FSCK_ERROR;
+ }
+ }
+ buf = malloc(sdp->md.statfs->i_di.di_size);
+ // FIXME: handle failed malloc
+ gfs2_readi(sdp->md.statfs, buf, 0, sdp->md.statfs->i_di.di_size);
+ /* call gfs2_inum_range_in() to retrieve range */
+ gfs2_statfs_change_in(&sc, buf);
+ free(buf);
+
+ gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
+ if (!sdp->md.qinode) {
+ if (query( _("The gfs2 system quota inode is missing. "
+ "Okay to rebuild it? (y/n) ")))
+ build_quota(sdp);
+ }
+
+ gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode);
+ if (!sdp->md.pinode) {
+ if (query( _("The gfs2 system per_node directory inode is "
+ "missing. Okay to rebuild it? (y/n) ")))
+ build_per_node(sdp);
+ }
+
+ /* FIXME fill in per_node structure */
+ /*******************************************************************
******* Now, set boundary fields in the super block *************
*******************************************************************/
if(set_block_ranges(sdp)){
@@ -411,6 +534,454 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
return -1;
}
+static int get_lockproto_table(struct gfs2_sbd *sdp)
+{
+ FILE *fp;
+ char line[PATH_MAX], *p, *p2;
+ char fsname[PATH_MAX];
+
+ memset(sdp->lockproto, 0, sizeof(sdp->lockproto));
+ memset(sdp->locktable, 0, sizeof(sdp->locktable));
+ fp = fopen("/etc/cluster/cluster.conf", "rt");
+ if (!fp) {
+ /* no cluster.conf; must be a stand-alone file system */
+ strcpy(sdp->lockproto, "lock_nolock");
+ log_warn(_("Lock protocol determined to be: lock_nolock\n"));
+ log_warn(_("Stand-alone file system: No need for a lock "
+ "table.\n"));
+ return 0;
+ }
+ /* We found a cluster.conf so assume it's a clustered file system */
+ log_warn(_("Lock protocol assumed to be: " GFS2_DEFAULT_LOCKPROTO
+ "\n"));
+ strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
+ while (fgets(line, sizeof(line) - 1, fp)) {
+ p = strstr(line,"<cluster name=");
+ if (p) {
+ p += 15;
+ p2 = strchr(p,'"');
+ strncpy(sdp->locktable, p, p2 - p);
+ break;
+ }
+ }
+ if (sdp->locktable[0] == '\0') {
+ log_err(_("Error: Unable to determine cluster name from "
+ "/etc/cluster.conf\n"));
+ } else {
+ memset(fsname, 0, sizeof(fsname));
+ p = strrchr(opts.device, '/');
+ if (p) {
+ p++;
+ strncpy(fsname, p, sizeof(fsname));
+ } else
+ strcpy(fsname, "repaired");
+ strcat(sdp->locktable, ":");
+ strcat(sdp->locktable, fsname);
+ log_warn(_("Lock table determined to be: %s\n"),
+ sdp->locktable);
+ }
+ fclose(fp);
+ return 0;
+}
+
+/**
+ * is_journal_copy - Is this a "real" dinode or a copy inside a journal?
+ * A real dinode will be located at the block number in its no_addr.
+ * A journal-copy will be at a different block (inside the journal).
+ */
+static int is_journal_copy(struct gfs2_inode *ip, struct gfs2_buffer_head *bh)
+{
+ if (ip->i_di.di_num.no_addr == bh->b_blocknr)
+ return 0;
+ return 1; /* journal copy */
+}
+
+/**
+ * peruse_system_dinode - process a system dinode
+ *
+ * This function looks at a system dinode and tries to figure out which
+ * dinode it is: statfs, inum, per_node, master, etc. Some of them we
+ * can deduce from the contents. For example, di_size will be a multiple
+ * of 96 for the rindex. di_size will be 8 for inum, 24 for statfs, etc.
+ * the per_node directory will have a ".." entry that will lead us to
+ * the master dinode if it's been destroyed.
+ */
+static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
+ struct gfs2_buffer_head *bh)
+{
+ struct gfs2_inode *ip, *child_ip;
+ struct gfs2_inum inum;
+ int error;
+
+ if (di->di_num.no_formal_ino == 2) {
+ if (sdp->sd_sb.sb_master_dir.no_addr)
+ return;
+ log_warn(_("Found system master directory at: 0x%llx.\n"),
+ di->di_num.no_addr);
+ sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr;
+ return;
+ }
+ ip = inode_read(sdp, di->di_num.no_addr);
+ if (di->di_num.no_formal_ino == 3) {
+ if (fix_md.jiinode || is_journal_copy(ip, bh))
+ return;
+ log_warn(_("Found system jindex file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ fix_md.jiinode = ip;
+ } else if (S_ISDIR(di->di_mode)) {
+ /* Check for a jindex dir entry. Only one system dir has a
+ jindex: master */
+ gfs2_lookupi(ip, "jindex", 6, &child_ip);
+ if (child_ip) {
+ if (fix_md.jiinode || is_journal_copy(ip, bh))
+ return;
+ fix_md.jiinode = child_ip;
+ sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr;
+ log_warn(_("Found system master directory at: "
+ "0x%llx\n"), di->di_num.no_addr);
+ return;
+ }
+
+ /* Check for a statfs_change0 dir entry. Only one system dir
+ has a statfs_change: per_node, and its .. will be master. */
+ gfs2_lookupi(ip, "statfs_change0", 14, &child_ip);
+ if (child_ip) {
+ if (fix_md.pinode || is_journal_copy(ip, bh))
+ return;
+ log_warn(_("Found system per_node directory at: "
+ "0x%llx\n"), ip->i_di.di_num.no_addr);
+ fix_md.pinode = ip;
+ error = dir_search(ip, "..", 2, NULL, &inum);
+ if (!error && inum.no_addr) {
+ sdp->sd_sb.sb_master_dir.no_addr =
+ inum.no_addr;
+ log_warn(_("From per_node\'s \'..\' I "
+ "backtracked the master directory "
+ "to: 0x%llx\n"), inum.no_addr);
+ }
+ return;
+ }
+ log_debug(_("Unknown system directory at block 0x%llx\n"),
+ di->di_num.no_addr);
+ inode_put(&ip);
+ } else if (di->di_size == 8) {
+ if (fix_md.inum || is_journal_copy(ip, bh))
+ return;
+ fix_md.inum = ip;
+ log_warn(_("Found system inum file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ } else if (di->di_size == 24) {
+ if (fix_md.statfs || is_journal_copy(ip, bh))
+ return;
+ fix_md.statfs = ip;
+ log_warn(_("Found system statfs file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ } else if ((di->di_size % 96) == 0) {
+ if (fix_md.riinode || is_journal_copy(ip, bh))
+ return;
+ fix_md.riinode = ip;
+ log_warn(_("Found system rindex file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ } else if (!fix_md.qinode && di->di_size >= 176 &&
+ di->di_num.no_formal_ino >= 12 &&
+ di->di_num.no_formal_ino <= 100) {
+ if (is_journal_copy(ip, bh))
+ return;
+ fix_md.qinode = ip;
+ log_warn(_("Found system quota file at: 0x%llx\n"),
+ di->di_num.no_addr);
+ }
+}
+
+/**
+ * peruse_user_dinode - process a user dinode trying to find the root directory
+ *
+ */
+static void peruse_user_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
+ struct gfs2_buffer_head *bh)
+{
+ struct gfs2_inode *ip, *parent_ip;
+ struct gfs2_inum inum;
+ int error;
+
+ if (sdp->sd_sb.sb_root_dir.no_addr) /* if we know the root dinode */
+ return; /* we don't need to find the root */
+ if (!S_ISDIR(di->di_mode)) /* if this isn't a directory */
+ return; /* it can't lead us to the root anyway */
+
+ if (di->di_num.no_formal_ino == 1) {
+ struct gfs2_buffer_head *root_bh;
+
+ if (di->di_num.no_addr == bh->b_blocknr) {
+ log_warn(_("Found the root directory at: 0x%llx.\n"),
+ di->di_num.no_addr);
+ sdp->sd_sb.sb_root_dir.no_addr = di->di_num.no_addr;
+ return;
+ }
+ log_warn(_("The root dinode should be at block 0x%llx but it "
+ "seems to be destroyed.\n"),
+ (unsigned long long)di->di_num.no_addr);
+ log_warn(_("Found a copy of the root directory in a journal "
+ "at block: 0x%llx.\n"),
+ (unsigned long long)bh->b_blocknr);
+ if (!query(_("Do you want to replace the root dinode from the "
+ "copy? (y/n)"))) {
+ log_err(_("Damaged root dinode not fixed.\n"));
+ return;
+ }
+ root_bh = bread(sdp, di->di_num.no_addr);
+ memcpy(root_bh->b_data, bh->b_data, sdp->bsize);
+ bmodified(root_bh);
+ brelse(root_bh);
+ log_warn(_("Root directory copied from the journal.\n"));
+ return;
+ }
+ ip = inode_read(sdp, di->di_num.no_addr);
+ while (ip) {
+ gfs2_lookupi(ip, "..", 2, &parent_ip);
+ if (parent_ip && parent_ip->i_di.di_num.no_addr ==
+ ip->i_di.di_num.no_addr) {
+ log_warn(_("fsck found the root inode at: 0x%llx\n"),
+ ip->i_di.di_num.no_addr);
+ sdp->sd_sb.sb_root_dir.no_addr =
+ ip->i_di.di_num.no_addr;
+ inode_put(&parent_ip);
+ inode_put(&ip);
+ return;
+ }
+ if (!parent_ip)
+ break;
+ inode_put(&ip);
+ ip = parent_ip;
+ }
+ error = dir_search(ip, "..", 2, NULL, &inum);
+ if (!error && inum.no_addr && inum.no_addr < possible_root) {
+ possible_root = inum.no_addr;
+ log_debug(_("Found a possible root at: 0x%llx\n"),
+ (unsigned long long)possible_root);
+ }
+ inode_put(&ip);
+}
+
+/**
+ * find_rgs_for_bsize - check a range of blocks for rgrps to determine bsize.
+ * Assumes: device is open.
+ */
+static int find_rgs_for_bsize(struct gfs2_sbd *sdp, uint64_t startblock,
+ uint32_t *known_bsize)
+{
+ uint64_t blk, max_rg_size, rb_addr;
+ struct gfs2_buffer_head *bh, *rb_bh;
+ uint32_t bsize, bsize2;
+ uint32_t chk;
+ char *p;
+ int found_rg;
+ struct gfs2_meta_header mh;
+
+ sdp->bsize = GFS2_DEFAULT_BSIZE;
+ max_rg_size = 524288;
+ /* Max RG size is 2GB. Max block size is 4K. 2G / 4K blks = 524288,
+ So this is traversing 2GB in 4K block increments. */
+ for (blk = startblock; blk < startblock + max_rg_size; blk++) {
+ bh = bread(sdp, blk);
+ found_rg = 0;
+ for (bsize = 0; bsize < GFS2_DEFAULT_BSIZE;
+ bsize += GFS2_BASIC_BLOCK) {
+ p = bh->b_data + bsize;
+ chk = ((struct gfs2_meta_header *)p)->mh_magic;
+ if (be32_to_cpu(chk) != GFS2_MAGIC)
+ continue;
+ chk = ((struct gfs2_meta_header *)p)->mh_type;
+ if (be32_to_cpu(chk) == GFS2_METATYPE_RG) {
+ found_rg = 1;
+ break;
+ }
+ }
+ if (!found_rg)
+ continue;
+ /* Try all the block sizes in 512 byte multiples */
+ for (bsize2 = GFS2_BASIC_BLOCK; bsize2 <= GFS2_DEFAULT_BSIZE;
+ bsize2 += GFS2_BASIC_BLOCK) {
+ rb_addr = (bh->b_blocknr *
+ (GFS2_DEFAULT_BSIZE / bsize2)) +
+ (bsize / bsize2) + 1;
+ sdp->bsize = bsize2; /* temporarily */
+ rb_bh = bread(sdp, rb_addr);
+ gfs2_meta_header_in(&mh, rb_bh);
+ brelse(rb_bh);
+ if (mh.mh_magic == GFS2_MAGIC &&
+ mh.mh_type == GFS2_METATYPE_RB) {
+ log_debug(_("boff:%d bsize2:%d rg:0x%llx, "
+ "rb:0x%llx\n"), bsize, bsize2,
+ (unsigned long long)blk,
+ (unsigned long long)rb_addr);
+ *known_bsize = bsize2;
+ break;
+ }
+ }
+ brelse(bh);
+ if (!(*known_bsize)) {
+ sdp->bsize = GFS2_DEFAULT_BSIZE;
+ continue;
+ }
+
+ sdp->bsize = *known_bsize;
+ log_warn(_("Block size determined to be: %d\n"), *known_bsize);
+ return 0;
+ }
+ return 0;
+}
+
+/**
+ * peruse_metadata - check a range of blocks for metadata
+ * Assumes: device is open.
+ */
+static int peruse_metadata(struct gfs2_sbd *sdp, uint64_t startblock)
+{
+ uint64_t blk, max_rg_size;
+ struct gfs2_buffer_head *bh;
+ struct gfs2_dinode di;
+ int found_gfs2_dinodes = 0, possible_gfs1_dinodes = 0;
+
+ max_rg_size = 2147483648ull / sdp->bsize;
+ /* Max RG size is 2GB. 2G / bsize. */
+ for (blk = startblock; blk < startblock + max_rg_size; blk++) {
+ bh = bread(sdp, blk);
+ if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+ brelse(bh);
+ continue;
+ }
+ gfs2_dinode_in(&di, bh);
+ if (!found_gfs2_dinodes &&
+ di.di_num.no_addr == di.di_num.no_formal_ino) {
+ possible_gfs1_dinodes++;
+ if (possible_gfs1_dinodes > 5) {
+ log_err(_("Found several gfs (version 1) "
+ "dinodes; aborting.\n"));
+ brelse(bh);
+ return -1;
+ }
+ } else {
+ found_gfs2_dinodes++;
+ }
+ if (di.di_flags & GFS2_DIF_SYSTEM)
+ peruse_system_dinode(sdp, &di, bh);
+ else
+ peruse_user_dinode(sdp, &di, bh);
+ brelse(bh);
+ }
+ return 0;
+}
+
+/**
+ * sb_repair - repair a damaged superblock
+ * Assumes: device is open.
+ * The biggest RG size is 2GB
+ */
+static int sb_repair(struct gfs2_sbd *sdp)
+{
+ uint64_t real_device_size, half;
+ uint32_t known_bsize = 0;
+ unsigned char uuid[16];
+ int error = 0;
+
+ memset(&fix_md, 0, sizeof(fix_md));
+ /* Step 1 - First we need to determine the correct block size. */
+ sdp->bsize = GFS2_DEFAULT_BSIZE;
+ log_warn(_("Gathering information to repair the gfs2 superblock. "
+ "This may take some time.\n"));
+ error = find_rgs_for_bsize(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) /
+ GFS2_DEFAULT_BSIZE, &known_bsize);
+ if (error)
+ return error;
+ if (!known_bsize) {
+ log_warn(_("Block size not apparent; checking elsewhere.\n"));
+ /* First, figure out the device size. We need that so we can
+ find a suitable start point to determine what's what. */
+ device_size(sdp->device_fd, &real_device_size);
+ half = real_device_size / 2; /* in bytes */
+ half /= sdp->bsize;
+ /* Start looking halfway through the device for gfs2
+ structures. If there aren't any at all, forget it. */
+ error = find_rgs_for_bsize(sdp, half, &known_bsize);
+ if (error)
+ return error;
+ }
+ if (!known_bsize) {
+ log_err(_("Unable to determine the block size; this "
+ "does not look like a gfs2 file system.\n"));
+ return -1;
+ }
+ /* Step 2 - look for the sytem dinodes */
+ error = peruse_metadata(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) /
+ GFS2_DEFAULT_BSIZE);
+ if (error)
+ return error;
+ if (!sdp->sd_sb.sb_master_dir.no_addr) {
+ log_err(_("Unable to locate the system master directory.\n"));
+ return -1;
+ }
+ if (!sdp->sd_sb.sb_root_dir.no_addr) {
+ struct gfs2_inum inum;
+
+ log_err(_("Unable to locate the root directory.\n"));
+ if (possible_root == HIGHEST_BLOCK) {
+ /* Take advantage of the fact that mkfs.gfs2
+ creates master immediately after root. */
+ log_err(_("Can't find any dinodes that might "
+ "be the root; using master - 1.\n"));
+ possible_root = sdp->sd_sb.sb_master_dir.no_addr - 1;
+ }
+ log_err(_("Found a root directory candidate at 0x%llx\n"),
+ (unsigned long long)possible_root);
+ sdp->sd_sb.sb_root_dir.no_addr = possible_root;
+ sdp->md.rooti = inode_read(sdp, possible_root);
+ if (!sdp->md.rooti ||
+ sdp->md.rooti->i_di.di_header.mh_magic != GFS2_MAGIC) {
+ struct gfs2_buffer_head *bh;
+
+ log_err(_("The root dinode block is destroyed.\n"));
+ log_err(_("At this point I recommend "
+ "reinitializing it.\n"
+ "Hopefully everything will later "
+ "be put into lost+found.\n"));
+ if (!query(_("Okay to reinitialize the root "
+ "dinode? (y/n)"))) {
+ log_err(_("The root dinode was not "
+ "reinitialized; aborting.\n"));
+ return -1;
+ }
+ inum.no_formal_ino = 1;
+ inum.no_addr = possible_root;
+ bh = init_dinode(sdp, &inum, S_IFDIR | 0755, 0, &inum);
+ brelse(bh);
+ }
+ }
+ /* Step 3 - Rebuild the lock protocol and file system table name */
+ get_lockproto_table(sdp);
+ if (query(_("Okay to fix the GFS2 superblock? (y/n)"))) {
+ log_info(_("Master system directory found at: 0x%llx\n"),
+ sdp->sd_sb.sb_master_dir.no_addr);
+ sdp->master_dir = inode_read(sdp,
+ sdp->sd_sb.sb_master_dir.no_addr);
+ sdp->master_dir->i_di.di_num.no_addr =
+ sdp->sd_sb.sb_master_dir.no_addr;
+ log_info(_("Root directory found at: 0x%llx\n"),
+ sdp->sd_sb.sb_root_dir.no_addr);
+ sdp->md.rooti = inode_read(sdp,
+ sdp->sd_sb.sb_root_dir.no_addr);
+ get_random_bytes(uuid, sizeof(uuid));
+ build_sb(sdp, uuid);
+ inode_put(&sdp->md.rooti);
+ inode_put(&sdp->master_dir);
+ } else {
+ log_crit(_("GFS2 superblock not fixed; fsck cannot proceed "
+ "without a valid superblock.\n"));
+ return -1;
+ }
+ return 0;
+}
+
/**
* fill_super_block
* @sdp:
@@ -443,8 +1014,17 @@ static int fill_super_block(struct gfs2_sbd *sdp)
log_crit(_("Bad constants (1)\n"));
exit(-1);
}
- if(read_sb(sdp) < 0){
- return -1;
+ if (read_sb(sdp) < 0) {
+ /* First, check for a gfs1 (not gfs2) file system */
+ if (sdp->sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
+ sdp->sd_sb.sb_header.mh_type == GFS2_METATYPE_SB)
+ return -1; /* This is gfs1, don't try to repair */
+ /* It's not a "sane" gfs1 fs so try to repair it */
+ if (sb_repair(sdp) != 0)
+ return -1; /* unrepairable, so exit */
+ /* Now that we've tried to repair it, re-read it. */
+ if (read_sb(sdp) < 0)
+ return -1;
}
return 0;
@@ -506,10 +1086,8 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
}
/* read in sb from disk */
- if (fill_super_block(sbp)) {
- stack;
+ if (fill_super_block(sbp))
return FSCK_ERROR;
- }
/* Change lock protocol to be fsck_* instead of lock_* */
if(!opts.no && preen_is_safe(sbp, preen, force_check)) {
@@ -519,6 +1097,17 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
}
}
+ /* Get master dinode */
+ sbp->master_dir = inode_read(sbp, sbp->sd_sb.sb_master_dir.no_addr);
+ if (sbp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC ||
+ sbp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI ||
+ !sbp->master_dir->i_di.di_size) {
+ inode_put(&sbp->master_dir);
+ rebuild_master(sbp);
+ sbp->master_dir = inode_read(sbp,
+ sbp->sd_sb.sb_master_dir.no_addr);
+ }
+
/* verify various things */
if(replay_journals(sbp, preen, force_check, &clean_journals)) {
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index af09ecb..a5763b4 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -146,117 +146,6 @@ static void interrupt(int sig)
}
}
-/* Check system inode and verify it's marked "in use" in the bitmap: */
-/* Should work for all system inodes: root, master, jindex, per_node, etc. */
-static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
- int builder(struct gfs2_sbd *sbp),
- enum gfs2_mark_block mark)
-{
- uint64_t iblock = 0;
- struct dir_status ds = {0};
-
- log_info( _("Checking system inode '%s'\n"), filename);
- if (sysinode) {
- /* Read in the system inode, look at its dentries, and start
- * reading through them */
- iblock = sysinode->i_di.di_num.no_addr;
- log_info( _("System inode for '%s' is located at block %"
- PRIu64 " (0x%" PRIx64 ")\n"), filename,
- iblock, iblock);
-
- /* FIXME: check this block's validity */
-
- ds.q = block_type(iblock);
- /* If the inode exists but the block is marked */
- /* free, we might be recovering from a corrupt */
- /* bitmap. In that case, don't rebuild the inode. */
- /* Just reuse the inode and fix the bitmap. */
- if (ds.q == gfs2_block_free) {
- log_info( _("The inode exists but the block is not "
- "marked 'in use'; fixing it.\n"));
- fsck_blockmap_set(sysinode,
- sysinode->i_di.di_num.no_addr,
- filename, mark);
- ds.q = mark;
- if (mark == gfs2_inode_dir)
- dirtree_insert(sysinode->i_di.di_num.no_addr);
- }
- }
- else
- log_info( _("System inode for '%s' is missing.\n"), filename);
- /* If there are errors with the inode here, we need to
- * create a new inode and get it all setup - of course,
- * everything will be in lost+found then, but we *need* our
- * system inodes before we can do any of that. */
- if(!sysinode || ds.q != mark) {
- log_err( _("Invalid or missing %s system inode.\n"), filename);
- if (query(_("Create new %s system inode? (y/n) "), filename)) {
- builder(sysinode->i_sbd);
- fsck_blockmap_set(sysinode,
- sysinode->i_di.di_num.no_addr,
- filename, mark);
- ds.q = mark;
- if (mark == gfs2_inode_dir)
- dirtree_insert(sysinode->i_di.di_num.no_addr);
- }
- else {
- log_err( _("Cannot continue without valid %s inode\n"),
- filename);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int check_system_inodes(struct gfs2_sbd *sdp)
-{
- /*******************************************************************
- ******* Check the system inode integrity *************
- *******************************************************************/
- if (check_system_inode(sdp->master_dir, "master", build_master,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.rooti, "root", build_root,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.inum, "inum", build_inum,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.statfs, "statfs", build_statfs,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.jiinode, "jindex", build_jindex,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.riinode, "rindex", build_rindex,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.qinode, "quota", build_quota,
- gfs2_inode_file)) {
- stack;
- return -1;
- }
- if (check_system_inode(sdp->md.pinode, "per_node", build_per_node,
- gfs2_inode_dir)) {
- stack;
- return -1;
- }
- return 0;
-}
-
static void check_statfs(struct gfs2_sbd *sdp)
{
osi_list_t *tmp;
@@ -365,9 +254,6 @@ int main(int argc, char **argv)
else
log_notice( _("Pass1 complete \n"));
- /* Make sure the system inodes are okay & represented in the bitmap. */
- check_system_inodes(sbp);
-
if (!fsck_abort) {
last_reported_block = 0;
pass = "pass 1b";
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index d6ec4c5..7ea4b59 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -174,8 +174,7 @@ struct duptree *dupfind(uint64_t block)
return NULL;
}
-static struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
- uint64_t block)
+struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp, uint64_t block)
{
if (lf_dip && lf_dip->i_di.di_num.no_addr == block)
return lf_dip;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 9eb2372..c602492 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -34,6 +34,8 @@ extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
enum gfs2_mark_block new_blockmap_state);
extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
extern struct duptree *dupfind(uint64_t block);
+extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
+ uint64_t block);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index a2a2188..a335d28 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -74,6 +74,7 @@ static int invalidate_eattr_indir(struct gfs2_inode *ip, uint64_t block,
static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private);
+static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
struct metawalk_fxns pass1_fxns = {
.private = NULL,
@@ -103,6 +104,98 @@ struct metawalk_fxns invalidate_fxns = {
.check_eattr_leaf = invalidate_eattr_leaf,
};
+/*
+ * resuscitate_metalist - make sure a system directory entry's metadata blocks
+ * are marked "in use" in the bitmap.
+ *
+ * This function makes sure metadata blocks for system and root directories are
+ * marked "in use" by the bitmap. You don't want root's indirect blocks
+ * deleted, do you? Or worse, reused for lost+found.
+ */
+static int resuscitate_metalist(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, void *private)
+{
+ struct block_count *bc = (struct block_count *)private;
+
+ *bh = NULL;
+ if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
+ fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
+ _("itself"), gfs2_bad_block);
+ log_err( _("Bad indirect block pointer (out of range) "
+ "found in system inode %lld (0x%llx).\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ return 1;
+ }
+ if (fsck_system_inode(ip->i_sbd, block))
+ fsck_blockmap_set(ip, block, _("system file"), gfs2_indir_blk);
+ else
+ check_n_fix_bitmap(ip->i_sbd, block, gfs2_indir_blk);
+ bc->indir_count++;
+ return 0;
+}
+
+/*
+ * resuscitate_dentry - make sure a system directory entry is alive
+ *
+ * This function makes sure directory entries in system directories are
+ * kept alive. You don't want journal0 deleted from jindex, do you?
+ */
+static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
+ struct gfs2_dirent *prev_de,
+ struct gfs2_buffer_head *bh, char *filename,
+ uint16_t *count, void *priv)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_dirent dentry, *de;
+ char tmp_name[PATH_MAX];
+ uint64_t block;
+ enum gfs2_mark_block dinode_type;
+
+ memset(&dentry, 0, sizeof(struct gfs2_dirent));
+ gfs2_dirent_in(&dentry, (char *)dent);
+ de = &dentry;
+ block = de->de_inum.no_addr;
+ /* Start of checks */
+ memset(tmp_name, 0, sizeof(tmp_name));
+ if(de->de_name_len < sizeof(tmp_name))
+ strncpy(tmp_name, filename, de->de_name_len);
+ else
+ strncpy(tmp_name, filename, sizeof(tmp_name) - 1);
+ if(gfs2_check_range(sdp, block)) {
+ log_err( _("Block # referenced by system directory entry %s "
+ "in inode %lld (0x%llx) is out of range; "
+ "ignored.\n"),
+ tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ return 0;
+ }
+ if (block == sdp->md.jiinode->i_di.di_num.no_addr ||
+ block == sdp->md.pinode->i_di.di_num.no_addr ||
+ block == sdp->master_dir->i_di.di_num.no_addr)
+ dinode_type = gfs2_inode_dir;
+ else
+ dinode_type = gfs2_inode_file;
+ /* If this is a system dinode, we'll handle it later in
+ check_system_inodes. If not, it'll be handled by pass1 but
+ since it's in a system directory we need to make sure it's
+ represented in the rgrp bitmap. */
+ if (fsck_system_inode(sdp, block))
+ fsck_blockmap_set(ip, block, _("system file"), dinode_type);
+ else
+ check_n_fix_bitmap(sdp, block, dinode_type);
+ /* Return the number of leaf entries so metawalk doesn't flag this
+ leaf as having none. */
+ *count = be16_to_cpu(((struct gfs2_leaf *)bh->b_data)->lf_entries);
+ return 0;
+}
+
+struct metawalk_fxns sysdir_fxns = {
+ .private = NULL,
+ .check_metalist = resuscitate_metalist,
+ .check_dentry = resuscitate_dentry,
+};
+
static int leaf(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *bh, void *private)
{
@@ -867,40 +960,15 @@ struct metawalk_fxns rangecheck_fxns = {
.check_eattr_leaf = rangecheck_eattr_leaf,
};
-static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
+/*
+ * handle_ip - process an incore structure representing a dinode.
+ */
+static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
{
- uint8_t q;
- struct gfs2_inode *ip;
int error;
struct block_count bc = {0};
- uint64_t block = bh->b_blocknr;
long bad_pointers;
-
- q = block_type(block);
- if(q != gfs2_block_free) {
- log_err( _("Found a duplicate inode block at #%" PRIu64
- " (0x%" PRIx64 ") previously marked as a %s\n"),
- block, block, block_type_string(q));
- add_duplicate_ref(ip, block, ref_as_meta, 0, INODE_VALID);
- return 0;
- }
-
- ip = fsck_inode_get(sdp, bh);
- if (ip->i_di.di_num.no_addr != block) {
- log_err( _("Inode #%llu (0x%llx): Bad inode address found: %llu "
- "(0x%llx)\n"), (unsigned long long)block,
- (unsigned long long)block,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- if(query( _("Fix address in inode at block #%"
- PRIu64 " (0x%" PRIx64 ")? (y/n) "),
- block, block)) {
- ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
- bmodified(ip->i_bh);
- } else
- log_err( _("Address in inode at block #%" PRIu64
- " (0x%" PRIx64 ") not fixed\n"), block, block);
- }
+ uint64_t block = ip->i_bh->b_blocknr;
bad_pointers = 0L;
@@ -918,7 +986,6 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
BAD_POINTER_TOLERANCE);
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("badly corrupt"), gfs2_block_free);
- fsck_inode_put(&ip);
return 0;
}
@@ -926,64 +993,40 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
case S_IFDIR:
if (fsck_blockmap_set(ip, block, _("directory"),
- gfs2_inode_dir)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- if(!dirtree_insert(block)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_dir))
+ goto bad_dinode;
+ if(!dirtree_insert(block))
+ goto bad_dinode;
break;
case S_IFREG:
if (fsck_blockmap_set(ip, block, _("file"),
- gfs2_inode_file)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_file))
+ goto bad_dinode;
break;
case S_IFLNK:
if (fsck_blockmap_set(ip, block, _("symlink"),
- gfs2_inode_lnk)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_lnk))
+ goto bad_dinode;
break;
case S_IFBLK:
if (fsck_blockmap_set(ip, block, _("block device"),
- gfs2_inode_blk)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_blk))
+ goto bad_dinode;
break;
case S_IFCHR:
if (fsck_blockmap_set(ip, block, _("character device"),
- gfs2_inode_chr)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_chr))
+ goto bad_dinode;
break;
case S_IFIFO:
if (fsck_blockmap_set(ip, block, _("fifo"),
- gfs2_inode_fifo)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_fifo))
+ goto bad_dinode;
break;
case S_IFSOCK:
if (fsck_blockmap_set(ip, block, _("socket"),
- gfs2_inode_sock)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_inode_sock))
+ goto bad_dinode;
break;
default:
/* We found a dinode that has an invalid mode, so we can't
@@ -999,19 +1042,12 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
skip parts that we can't be sure of based on dinode type. */
check_metatree(ip, &invalidate_fxns);
if (fsck_blockmap_set(ip, block, _("invalid mode"),
- gfs2_inode_invalid)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- fsck_inode_put(&ip);
+ gfs2_inode_invalid))
+ goto bad_dinode;
return 0;
}
- if(set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ if(set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink))
+ goto bad_dinode;
if (S_ISDIR(ip->i_di.di_mode) &&
(ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
@@ -1023,22 +1059,16 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
ip->i_di.di_depth,
(1 >> (ip->i_di.di_size/sizeof(uint64_t))));
if(fsck_blockmap_set(ip, block, _("bad depth"),
- gfs2_block_free)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- fsck_inode_put(&ip);
+ gfs2_block_free))
+ goto bad_dinode;
return 0;
}
}
pass1_fxns.private = &bc;
error = check_metatree(ip, &pass1_fxns);
- if (fsck_abort || error < 0) {
- fsck_inode_put(&ip);
+ if (fsck_abort || error < 0)
return 0;
- }
if (error > 0) {
log_err( _("Error: inode %llu (0x%llx) has unrecoverable "
"errors; invalidating.\n"),
@@ -1052,7 +1082,6 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
Therefore we mark the inode as free space. */
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("corrupt"), gfs2_block_free);
- fsck_inode_put(&ip);
return 0;
}
@@ -1091,7 +1120,196 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
(unsigned long long)ip->i_di.di_num.no_addr);
}
+ return 0;
+bad_dinode:
+ stack;
+ return -1;
+}
+
+/*
+ * handle_di - This is now a wrapper function that takes a gfs2_buffer_head
+ * and calls handle_ip, which takes an in-code dinode structure.
+ */
+static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
+{
+ uint8_t q;
+ int error = 0;
+ uint64_t block = bh->b_blocknr;
+ struct gfs2_inode *ip;
+
+ ip = fsck_inode_get(sdp, bh);
+ q = block_type(block);
+ if(q != gfs2_block_free) {
+ log_err( _("Found a duplicate inode block at #%" PRIu64
+ " (0x%" PRIx64 ") previously marked as a %s\n"),
+ block, block, block_type_string(q));
+ add_duplicate_ref(ip, block, ref_as_meta, 0, INODE_VALID);
+ fsck_inode_put(&ip);
+ return 0;
+ }
+
+ if (ip->i_di.di_num.no_addr != block) {
+ log_err( _("Inode #%llu (0x%llx): Bad inode address found: %llu "
+ "(0x%llx)\n"), (unsigned long long)block,
+ (unsigned long long)block,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ if(query( _("Fix address in inode at block #%"
+ PRIu64 " (0x%" PRIx64 ")? (y/n) "),
+ block, block)) {
+ ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
+ bmodified(ip->i_bh);
+ } else
+ log_err( _("Address in inode at block #%" PRIu64
+ " (0x%" PRIx64 ") not fixed\n"), block, block);
+ }
+ error = handle_ip(sdp, ip);
fsck_inode_put(&ip);
+ return error;
+}
+
+/* Check system inode and verify it's marked "in use" in the bitmap: */
+/* Should work for all system inodes: root, master, jindex, per_node, etc. */
+static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
+ int builder(struct gfs2_sbd *sbp),
+ enum gfs2_mark_block mark)
+{
+ uint64_t iblock = 0;
+ struct dir_status ds = {0};
+ int error;
+
+ log_info( _("Checking system inode '%s'\n"), filename);
+ if (sysinode) {
+ /* Read in the system inode, look at its dentries, and start
+ * reading through them */
+ iblock = sysinode->i_di.di_num.no_addr;
+ log_info( _("System inode for '%s' is located at block %"
+ PRIu64 " (0x%" PRIx64 ")\n"), filename,
+ iblock, iblock);
+
+ /* FIXME: check this block's validity */
+
+ ds.q = block_type(iblock);
+ /* If the inode exists but the block is marked free, we might
+ be recovering from a corrupt bitmap. In that case, don't
+ rebuild the inode. Just reuse the inode and fix the
+ bitmap. */
+ if (ds.q == gfs2_block_free) {
+ log_info( _("The inode exists but the block is not "
+ "marked 'in use'; fixing it.\n"));
+ fsck_blockmap_set(sysinode,
+ sysinode->i_di.di_num.no_addr,
+ filename, mark);
+ ds.q = mark;
+ if (mark == gfs2_inode_dir)
+ dirtree_insert(sysinode->i_di.di_num.no_addr);
+ }
+ } else
+ log_info( _("System inode for '%s' is missing.\n"), filename);
+ /* If there are errors with the inode here, we need to create a new
+ inode and get it all setup - of course, everything will be in
+ lost+found then, but we *need* our system inodes before we can
+ do any of that. */
+ if(!sysinode || ds.q != mark) {
+ log_err( _("Invalid or missing %s system inode (should be %d, "
+ "is %d).\n"), filename, mark, ds.q);
+ if (query(_("Create new %s system inode? (y/n) "), filename)) {
+ builder(sysinode->i_sbd);
+ fsck_blockmap_set(sysinode,
+ sysinode->i_di.di_num.no_addr,
+ filename, mark);
+ ds.q = mark;
+ if (mark == gfs2_inode_dir)
+ dirtree_insert(sysinode->i_di.di_num.no_addr);
+ } else {
+ log_err( _("Cannot continue without valid %s inode\n"),
+ filename);
+ return -1;
+ }
+ }
+ if (S_ISDIR(sysinode->i_di.di_mode)) {
+ struct block_count bc = {0};
+
+ sysdir_fxns.private = &bc;
+ if (sysinode->i_di.di_flags & GFS2_DIF_EXHASH)
+ check_metatree(sysinode, &sysdir_fxns);
+ else
+ check_linear_dir(sysinode, sysinode->i_bh,
+ &sysdir_fxns);
+ }
+ error = handle_ip(sysinode->i_sbd, sysinode);
+ return error;
+}
+
+static int build_a_journal(struct gfs2_sbd *sdp)
+{
+ build_journal(sdp, sdp->md.journals, sdp->md.jiinode);
+ return 0;
+}
+
+static int check_system_inodes(struct gfs2_sbd *sdp)
+{
+ int journal_count;
+
+ /*******************************************************************
+ ******* Check the system inode integrity *************
+ *******************************************************************/
+ if (check_system_inode(sdp->master_dir, "master", build_master,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.rooti, "root", build_root,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.inum, "inum", build_inum,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.statfs, "statfs", build_statfs,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.jiinode, "jindex", build_jindex,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.riinode, "rindex", build_rindex,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.qinode, "quota", build_quota,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ if (check_system_inode(sdp->md.pinode, "per_node", build_per_node,
+ gfs2_inode_dir)) {
+ stack;
+ return -1;
+ }
+ /* We have to play a trick on build_journal: We swap md.journals
+ in order to keep a count of which journal we need to build. */
+ journal_count = sdp->md.journals;
+ for (sdp->md.journals = 0; sdp->md.journals < journal_count;
+ sdp->md.journals++) {
+ char jname[16];
+
+ sprintf(jname, "journal%d", sdp->md.journals);
+ if (check_system_inode(sdp->md.journal[sdp->md.journals],
+ jname, build_a_journal,
+ gfs2_inode_file)) {
+ stack;
+ return -1;
+ }
+ }
+
return 0;
}
@@ -1126,6 +1344,9 @@ int pass1(struct gfs2_sbd *sbp)
* sweep - is there any metadata we need to mark here before
* the sweeps start that we won't find otherwise? */
+ /* Make sure the system inodes are okay & represented in the bitmap. */
+ check_system_inodes(sbp);
+
/* So, do we do a depth first search starting at the root
* inode, or use the rg bitmaps, or just read every fs block
* to find the inodes? If we use the depth first search, why
@@ -1192,6 +1413,11 @@ int pass1(struct gfs2_sbd *sbp)
}
check_n_fix_bitmap(sbp, block,
gfs2_block_free);
+ } else if (fsck_system_inode(sbp, block)) {
+ log_debug(_("Already processed system inode "
+ "%lld (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
} else if (handle_di(sbp, bh) < 0) {
stack;
brelse(bh);
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 957b1d9..5c82ebc 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -380,10 +380,11 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
{
int x = errblock - rg->ri.ri_addr;
- log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither"
+ log_err( _("Block #%lld (0x%llx) (%d of %d) is neither"
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
- rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
- (int)x+1, (int)rg->ri.ri_length);
+ (unsigned long long)rg->ri.ri_addr + x,
+ (unsigned long long)rg->ri.ri_addr + x,
+ (int)x+1, (int)rg->ri.ri_length);
if (query( _("Fix the Resource Group? (y/n)"))) {
log_err( _("Attempting to repair the RG.\n"));
rg->bh[x] = bread(sdp, rg->ri.ri_addr + x);
@@ -403,12 +404,46 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
gfs2_rgrp_out(&rg->rg, rg->bh[x]);
}
brelse(rg->bh[x]);
+ rg->bh[x] = NULL;
return 0;
}
return 1;
}
/*
+ * expect_rindex_sanity - the rindex file seems trustworthy, so use those
+ * values as our expected values and assume the
+ * damage is only to the rgrps themselves.
+ */
+static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
+ int *num_rgs)
+{
+ osi_list_t *tmp;
+ struct rgrp_list *exp, *rgd; /* expected, actual */
+
+ *num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
+ osi_list_init(ret_list);
+ for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+ rgd = osi_list_entry(tmp, struct rgrp_list, list);
+
+ exp = calloc(1, sizeof(struct rgrp_list));
+ if (exp == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
+ exp->start = rgd->start;
+ exp->length = rgd->length;
+ memcpy(&exp->ri, &rgd->ri, sizeof(exp->ri));
+ memcpy(&exp->rg, &rgd->rg, sizeof(exp->rg));
+ exp->bits = NULL;
+ gfs2_compute_bitstructs(sdp, exp);
+ osi_list_add_prev(&exp->list, ret_list);
+ }
+ sdp->rgrps = *num_rgs;
+ return 0;
+}
+
+/*
* rg_repair - try to repair a damaged rg index (rindex)
* trust_lvl - This is how much we trust the rindex file.
* blind_faith means we take the rindex at face value.
@@ -416,7 +451,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
* distrust means it's not to be trusted, so we should go to
* greater lengths to build it from scratch.
*/
-int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
+int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
{
int error, discrepancies;
osi_list_t expected_rglist;
@@ -426,10 +461,20 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
if (trust_lvl == blind_faith)
return 0;
- else if (trust_lvl == open_minded) { /* If we can't trust RG index */
+ else if (trust_lvl == ye_of_little_faith) { /* if rindex seems sane */
+ if (!(*sane)) {
+ log_err(_("The rindex file does not meet our "
+ "expectations.\n"));
+ return -1;
+ }
+ error = expect_rindex_sanity(sdp, &expected_rglist,
+ &calc_rg_count);
+ if (error)
+ return error;
+ } else if (trust_lvl == open_minded) { /* If we can't trust RG index */
/* Calculate our own RG index for comparison */
error = gfs2_rindex_calculate(sdp, &expected_rglist,
- &calc_rg_count);
+ &calc_rg_count);
if (error) { /* If calculated RGs don't match the fs */
gfs2_rgrp_free(&expected_rglist);
return -1;
@@ -447,7 +492,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
}
/* Read in the rindex */
osi_list_init(&sdp->rglist); /* Just to be safe */
- rindex_read(sdp, 0, &rgcount_from_index);
+ rindex_read(sdp, 0, &rgcount_from_index, sane);
if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) {
log_warn( _("WARNING: rindex file is corrupt.\n"));
gfs2_rgrp_free(&expected_rglist);
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 4590409..4c67983 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1522,7 +1522,7 @@ static int dir_l_search(struct gfs2_inode *dip, const char *filename,
*
* Returns: 0 if found, -1 on failure, -ENOENT if not found.
*/
-static int dir_search(struct gfs2_inode *dip, const char *filename, int len,
+int dir_search(struct gfs2_inode *dip, const char *filename, int len,
unsigned int *type, struct gfs2_inum *inum)
{
int error;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index f98f845..0c4bc8a 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -446,6 +446,8 @@ extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
unsigned int mode, uint32_t flags);
extern void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
struct gfs2_dirent *prev, struct gfs2_dirent *cur);
+extern int dir_search(struct gfs2_inode *dip, const char *filename, int len,
+ unsigned int *type, struct gfs2_inum *inum);
extern int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
struct gfs2_inode **ipp);
extern void dir_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -621,6 +623,7 @@ extern char *get_sysfs(const char *fsname, const char *filename);
extern int get_sysfs_uint(const char *fsname, const char *filename, unsigned int *val);
extern int set_sysfs(const char *fsname, const char *filename, const char *val);
extern int is_fsname(char *name);
+extern void get_random_bytes(void *buf, int nbytes);
/* recovery.c */
extern void gfs2_replay_incr_blk(struct gfs2_inode *ip, unsigned int *blk);
@@ -648,6 +651,8 @@ extern void gfs2_rgrp_free(osi_list_t *rglist);
/* structures.c */
extern int build_master(struct gfs2_sbd *sdp);
extern void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
+extern int build_journal(struct gfs2_sbd *sdp, int j,
+ struct gfs2_inode *jindex);
extern int build_jindex(struct gfs2_sbd *sdp);
extern int build_per_node(struct gfs2_sbd *sdp);
extern int build_inum(struct gfs2_sbd *sdp);
@@ -666,8 +671,8 @@ extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
extern int check_sb(struct gfs2_sb *sb);
extern int read_sb(struct gfs2_sbd *sdp);
extern int ji_update(struct gfs2_sbd *sdp);
-extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
-extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
+extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane);
+extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane);
extern int write_sb(struct gfs2_sbd *sdp);
/* ondisk.c */
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index aac91ff..487a488 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -18,6 +18,7 @@
#include <linux/kdev_t.h>
#include <sys/sysmacros.h>
#include <mntent.h>
+#include <sys/time.h>
#include "libgfs2.h"
@@ -411,3 +412,47 @@ char *mp2fsname(char *mp)
return fsname;
}
+
+/*
+ * get_random_bytes - Generate a series of random bytes using /dev/urandom.
+ *
+ * Modified from original code in gen_uuid.c in e2fsprogs/lib
+ */
+void get_random_bytes(void *buf, int nbytes)
+{
+ int i, n = nbytes, fd;
+ int lose_counter = 0;
+ unsigned char *cp = (unsigned char *) buf;
+ struct timeval tv;
+
+ gettimeofday(&tv, 0);
+ fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
+ srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+ /* Crank the random number generator a few times */
+ gettimeofday(&tv, 0);
+ for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
+ rand();
+ if (fd >= 0) {
+ while (n > 0) {
+ i = read(fd, cp, n);
+ if (i <= 0) {
+ if (lose_counter++ > 16)
+ break;
+ continue;
+ }
+ n -= i;
+ cp += i;
+ lose_counter = 0;
+ }
+ close(fd);
+ }
+
+ /*
+ * We do this all the time, but this is the only source of
+ * randomness if /dev/random/urandom is out to lunch.
+ */
+ for (cp = buf, i = 0; i < nbytes; i++)
+ *cp++ ^= (rand() >> 7) & 0xFF;
+
+ return;
+}
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 4a7717a..e3e230e 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -135,8 +135,10 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
uint64_t error;
error = rgd->ri.ri_addr + x;
- for (; x >= 0; x--)
+ for (; x >= 0; x--) {
brelse(rgd->bh[x]);
+ rgd->bh[x] = NULL;
+ }
return error;
}
}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index c0a9832..e798868 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -128,6 +128,22 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
return 0;
}
+int build_journal(struct gfs2_sbd *sdp, int j, struct gfs2_inode *jindex)
+{
+ char name[256];
+ struct gfs2_inode *ip;
+ int ret;
+
+ sprintf(name, "journal%u", j);
+ ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
+ ret = write_journal(sdp, ip, j,
+ sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
+ if (ret)
+ return ret;
+ inode_put(&ip);
+ return 0;
+}
+
int build_jindex(struct gfs2_sbd *sdp)
{
struct gfs2_inode *jindex;
@@ -138,18 +154,10 @@ int build_jindex(struct gfs2_sbd *sdp)
GFS2_DIF_SYSTEM);
for (j = 0; j < sdp->md.journals; j++) {
- char name[256];
- struct gfs2_inode *ip;
-
- sprintf(name, "journal%u", j);
- ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
- ret = write_journal(sdp, ip, j,
- sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
+ ret = build_journal(sdp, j, jindex);
if (ret)
return ret;
- inode_put(&ip);
}
-
if (sdp->debug) {
printf("\nJindex:\n");
gfs2_dinode_print(&jindex->i_di);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index e4c6bdb..961f72d 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -161,10 +161,11 @@ int ji_update(struct gfs2_sbd *sdp)
* fd: optional file handle for rindex file (if meta_fs file system is mounted)
* (if fd is <= zero, it will read from raw device)
* @count1: return count of the rgs.
+ * @sane: return whether rindex is consistent
*
* Returns: 0 on success, -1 on failure
*/
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
{
unsigned int rg;
int error;
@@ -172,8 +173,11 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
struct rgrp_list *rgd, *prev_rgd;
uint64_t prev_length = 0;
+ *sane = 1;
*count1 = 0;
prev_rgd = NULL;
+ if (!fd && sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex))
+ *sane = 0; /* rindex file size must be a multiple of 96 */
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -198,12 +202,27 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
+ /* If rg addresses go backwards, it's not sane
+ (or it's converted from gfs1). */
+ if (prev_rgd->start >= rgd->start)
+ *sane = 0;
+ /* If rg lengths are not consistent, it's not sane
+ (or it's converted from gfs1). The first RG will
+ be a different length due to space allocated for
+ the superblock, so we can't detect this until
+ we check rgrp 3, when we can compare the distance
+ between rgrp 1 and rgrp 2. */
+ if (rg > 2 && prev_length &&
+ prev_length != rgd->start - prev_rgd->start)
+ *sane = 0;
prev_length = rgd->start - prev_rgd->start;
prev_rgd->length = prev_length;
}
- if(gfs2_compute_bitstructs(sdp, rgd))
+ if(gfs2_compute_bitstructs(sdp, rgd)) {
+ *sane = 0;
return -1;
+ }
(*count1)++;
prev_rgd = rgd;
@@ -224,7 +243,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
*
* Returns: 0 on success, -1 on failure.
*/
-int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
+int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
{
struct rgrp_list *rgd;
struct gfs2_rindex *ri;
@@ -233,7 +252,7 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
uint64_t errblock = 0;
uint64_t rmax = 0;
- if (rindex_read(sdp, fd, &count1))
+ if (rindex_read(sdp, fd, &count1, sane))
goto fail;
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index ed3d07c..6e4d549 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -261,6 +261,8 @@ main_grow(int argc, char *argv[])
decode_arguments(argc, argv, sdp);
while ((argc - optind) > 0) {
+ int sane;
+
sdp->path_name = argv[optind++];
sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC);
if (sdp->path_fd < 0)
@@ -324,7 +326,7 @@ main_grow(int argc, char *argv[])
/* and therefore out of date. It shouldn't matter because */
/* we're only going to write out new RG information after */
/* the existing RGs, and only write to the index at EOF. */
- ri_update(sdp, rindex_fd, &rgcount);
+ ri_update(sdp, rindex_fd, &rgcount, &sane);
fssize = filesystem_size(sdp);
figure_out_rgsize(sdp, &rgsize);
fsgrowth = ((sdp->device.length - fssize) * sdp->bsize);
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 9250663..42c931f 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -480,50 +480,6 @@ static void check_mount(char *device)
return;
}
-/*
- * get_random_bytes - Generate a series of random bytes using /dev/urandom.
- *
- * Modified from original code in gen_uuid.c in e2fsprogs/lib
- */
-static void get_random_bytes(void *buf, int nbytes)
-{
- int i, n = nbytes, fd;
- int lose_counter = 0;
- unsigned char *cp = (unsigned char *) buf;
- struct timeval tv;
-
- gettimeofday(&tv, 0);
- fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
- srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
- /* Crank the random number generator a few times */
- gettimeofday(&tv, 0);
- for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
- rand();
- if (fd >= 0) {
- while (n > 0) {
- i = read(fd, cp, n);
- if (i <= 0) {
- if (lose_counter++ > 16)
- break;
- continue;
- }
- n -= i;
- cp += i;
- lose_counter = 0;
- }
- close(fd);
- }
-
- /*
- * We do this all the time, but this is the only source of
- * randomness if /dev/random/urandom is out to lunch.
- */
- for (cp = buf, i = 0; i < nbytes; i++)
- *cp++ ^= (rand() >> 7) & 0xFF;
-
- return;
-}
-
/**
* print_results - print out summary information
* @sdp: the command line
14 years, 1 month
cluster: STABLE3 - gfs2_convert: Does not convert full gfs1 filesystems
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 3714f6f1b47cf0a9cec46fb14843221c35431a79
Parent: 4f604bd22ed4b319dc64692c6d7f8596a68825e0
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Mon Apr 19 16:32:08 2010 -0500
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Mon Apr 19 16:32:08 2010 -0500
gfs2_convert: Does not convert full gfs1 filesystems
We now check to see if the number of blocks we intend
to allocate while creating GFS2 file system structures
are less than the available free blocks. If not enough
blocks are available, we reduce the journal size (1MB
at a time) until we can fit everything in.
Resolves: rhbz#581047
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 106 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 6543903..9621a09 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -60,6 +60,8 @@
#define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */
#define GFS_FORMAT_MULTI (1401) /* Multi-Host */
+#define DIV_RU(x, y) (((x) + (y) - 1) / (y))
+
struct gfs1_rgrp {
struct gfs2_meta_header rg_header; /* hasn't changed from gfs1 to 2 */
uint32_t rg_flags;
@@ -2009,6 +2011,100 @@ static void conv_build_jindex(struct gfs2_sbd *sdp)
inode_put(&sdp->md.jiinode);
}
+static unsigned int total_file_blocks(struct gfs2_sbd *sdp,
+ uint64_t filesize, int journaled)
+{
+ unsigned int data_blks = 0, meta_blks = 0, total_blks;
+ unsigned int max, height, bsize;
+ uint64_t *arr;
+
+ /* Now find the total meta blocks required for data_blks */
+ if (filesize <= sdp->bsize - sizeof(struct gfs2_dinode)) {
+ total_blks = 1; /* stuffed inode */
+ goto out;
+ }
+
+ if (journaled) {
+ arr = sdp->sd_jheightsize;
+ max = sdp->sd_max_jheight;
+ bsize = sdp->sd_jbsize;
+ } else {
+ arr = sdp->sd_heightsize;
+ max = sdp->sd_max_height;
+ bsize = sdp->bsize;
+ }
+ data_blks = DIV_RU(filesize, bsize); /* total data blocks reqd */
+
+ for (height = 0; height < max; height++)
+ if (arr[height] >= filesize)
+ break;
+ if (height == 1) {
+ total_blks = data_blks + 1; /* dinode has direct ptrs to data blocks */
+ goto out;
+ }
+
+ meta_blks = DIV_RU(data_blks, sdp->sd_inptrs);
+ total_blks = data_blks + meta_blks;
+out:
+ return data_blks + meta_blks;
+}
+
+/* We check if the GFS2 filesystem files/structures created after the call to
+ * check_fit() in main() will fit in the currently available free blocks
+ */
+static int check_fit(struct gfs2_sbd *sdp)
+{
+ unsigned int blks_need = 0, blks_avail = sdp->blks_total - sdp->blks_alloced;
+
+ /* build_master() */
+ blks_need++; /*creation of master dir inode - 1 block */
+
+ /* conv_build_jindex() */
+ {
+ blks_need++; /* creation of 'jindex' disk inode */
+ /* creation of journals */
+ blks_need += sdp->md.journals *
+ total_file_blocks(sdp, sdp->jsize << 20, 1);
+ }
+ /* build_per_node() */
+ {
+ blks_need++; /* creation of 'per_node' dir inode */
+ /* njourn x (inum_range + statfs_change + quota_change inodes) */
+ blks_need += sdp->md.journals * 3;
+ /* quota change inodes are prealloced */
+ blks_need += sdp->md.journals *
+ total_file_blocks(sdp, sdp->qcsize << 20, 1);
+ }
+ /* build_inum() */
+ blks_need++; /* creation of 'inum' disk inode */
+
+ /* build_statfs() */
+ blks_need++; /* creation of 'statfs' disk inode */
+
+ /* build_rindex() */
+ {
+ osi_list_t *tmp, *head;
+ unsigned int rg_count = 0;
+
+ blks_need++; /* creationg of 'rindex' disk inode */
+ /* find the total # of rindex entries, gives size of rindex inode */
+ for (head = &sdp->rglist, tmp = head->next; tmp != head;
+ tmp = tmp->next)
+ rg_count++;
+ blks_need +=
+ total_file_blocks(sdp, rg_count * sizeof(struct gfs2_rindex), 1);
+ }
+ /* build_quota() */
+ blks_need++; /* quota inode block and uid=gid=0 quota - total 1 block */
+
+ /* Up until this point we require blks_need blocks. We don't
+ * include the blocks freed by the next step (remove_obsolete_gfs1)
+ * because it's possible for us to exceed the available blocks
+ * before this step */
+
+ return blks_avail > blks_need;
+}
+
/* ------------------------------------------------------------------------- */
/* main - mainline code */
/* ------------------------------------------------------------------------- */
@@ -2096,12 +2192,22 @@ int main(int argc, char **argv)
/* Create our system files and directories. */
/* ---------------------------------------------- */
if (!error) {
+ int jreduce = 0;
/* Now we've got to treat it as a gfs2 file system */
if (compute_constants(&sb2)) {
log_crit("Error: Bad constants (1)\n");
exit(-1);
}
+ /* Check if all the files we're about to create will
+ * fit into the space remaining on the device */
+ while (!check_fit(&sb2)) {
+ sb2.jsize--; /* reduce jsize by 1MB each time */
+ jreduce = 1;
+ }
+ if (jreduce)
+ log_notice("Reduced journal size to %u MB to accommodate "
+ "GFS2 file system structures.\n", sb2.jsize);
/* Build the master subdirectory. */
build_master(&sb2); /* Does not do inode_put */
sb2.sd_sb.sb_master_dir = sb2.master_dir->i_di.di_num;
14 years, 1 month
cluster: STABLE3 - cman: make libcman /dev/zero fd close-on-exec
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 4f604bd22ed4b319dc64692c6d7f8596a68825e0
Parent: dd9f2f2c9e524bf9eedadceb0714f1b04a26dd5b
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Mon Apr 19 10:28:35 2010 +0100
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Mon Apr 19 10:28:35 2010 +0100
cman: make libcman /dev/zero fd close-on-exec
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
cman/lib/libcman.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/cman/lib/libcman.c b/cman/lib/libcman.c
index 93c5df1..daaad07 100644
--- a/cman/lib/libcman.c
+++ b/cman/lib/libcman.c
@@ -319,6 +319,7 @@ static cman_handle_t open_socket(const char *name, int namelen, void *privdata)
h = NULL;
errno = saved_errno;
}
+ fcntl(h->zero_fd, F_SETFD, 1); /* Set close-on-exec */
return (cman_handle_t)h;
}
14 years, 1 month