Hi,
We developed shared disk monitor program, we called it "diskd".
This applied pingd mechanism to disk monitor.
We received some demands from our customers about disk monitor.
- Detection of fiber channel cable failure takes time.
Filesystem RA can not detect this failure.
- We want to monitor the shared disk on not only
Active node but also Stand-by node.
Diskd responds to these demand.
We tested this on Heartbeat 2.1.3 and RedHat 5.1.
How to configure it are described in README.
If you're interested in, please try this and let me know
your comments.
Your comments and suggestions are really appreciated.
Best regards,
--
OKADA Satoshi
NTT Open Source Software Center
diskd - DISK monitor Daemon
Diskd is program to monitor shared disk. This applied pingd mechanism to disk
monitor.
It is started on each node by respawn command, and checks the status of the
disk periodically. If disk is broken, it notifies Heartbeat of failure via
attrd.
This action updates <attributes> of <node_state> in cib.xml, and resources may
be migrated by rsc_location constraints.
1. Status information in cib.xml
A value of the <attributes> of <node_state> is changed by disk state.
* in normal running
"diskcheck_status" is set in ha.cf and value is set "normal" by diskd.
-----
<status>
<node_state id="node04-id" uname="node04" crmd="online"
crm-debug-origin="do_update_resource" shutdown="0"
in_ccm="true" ha="active" join="member" expected="member">
<transient_attributes id="node04-id">
<instance_attributes id="status-node04-id">
<attributes>
<nvpair id="status-node04-id-diskcheck_status"
name="diskcheck_status" value="normal"/>
</attributes>
</instance_attributes>
</transient_attributes>
</status>
-----
* when disk fails
A value is changed "ERROR" by diskd.
-----
<status>
<node_state id="node04-id" uname="node04" crmd="online"
crm-debug-origin="do_update_resource" shutdown="0"
in_ccm="true" ha="active" join="member" expected="member">
<transient_attributes id="node04-id">
<instance_attributes id="status-node04-id">
<attributes>
<nvpair id="status-node04-id-diskcheck_status"
name="diskcheck_status" value="ERROR"/>
</attributes>
</instance_attributes>
</transient_attributes>
</status>
-----
2. Configuration Methods
Two files are configured to start diskd.
* ha.cf
respawn root /usr/lib64/heartbeat/diskd -N /dev/sdx -a diskcheck_status
-i 10
Please refer to "diskd Usage Information" for details.
Note: How to specify disk device name by using -N option.
The device file name which does not include a partition number should be
set. (If there is "/dev/sdb1", "/dev/sdb" is set in ha.cf.)
* cib.xml
For example, to prevent resources from running on the node where disk
fails,
the following constraints is set in cib.xml .
-----
<constraints>
<rsc_location id="rul_DK_dsc" rsc="grp_DB2">
<rule id="prefered_rul_DK_dsc" score="-INFINITY" boolean_op="and">
<expression attribute="diskcheck_status" id="dkstatus1"
operation="defined"/>
<expression attribute="diskcheck_status" id="dkstatus2"
operation="eq" value="ERROR"/>
</rule>
</rsc_location>
</constraints>
3. diskd Usage Information (Options)
# /usr/lib64/heartbeat/diskd -?
usage: diskd [-V?p:a:N:Di:r:I:t:]
Basic options
--help (-?) This text
--verbose (-V) Run in verbose mode
--daemonize (-D) Run in daemon mode
--pid-file (-p) <filename> File in which to store the process'
PID
* Default=/tmp/diskd.pid
--attr-name (-a) <string> Name of the node attribute to set
* Default=diskd
--device-name (-N) <devicename> Name of the device to check status
* Mandatory option
--interval (-i) <time[s]> Disk status check interval time
* Default=30 sec.
Advanced options
--read-timeout (-t) <time[s]> Read timeout for select function
* Default=5 sec.
--retry (-r) <times> Disk status check retry
* Default=1 times
--retry-interval (-I) <time[s]> Disk status check retry interval time
* Default=5 sec.
diff -urN heartbeat-2.1.3/tools/Makefile.am
heartbeat-2.1.3_diskd100/tools/Makefile.am
--- heartbeat-2.1.3/tools/Makefile.am 2007-12-22 00:32:27.000000000 +0900
+++ heartbeat-2.1.3_diskd100/tools/Makefile.am 2008-08-04 23:55:24.000000000
+0900
@@ -37,7 +37,8 @@
sbin_SCRIPTS = ciblint hb_report ocf-tester
if CRM_BUILD
-halib_PROGRAMS = attrd pingd
+halib_PROGRAMS = attrd pingd diskd
+## halib_PROGRAMS = attrd pingd
sbin_PROGRAMS = attrd_updater
endif
@@ -59,7 +60,6 @@
$(gliblib) \
$(top_builddir)/replace/libreplace.la
-
attrd_SOURCES = attrd.c
attrd_LDADD = \
$(top_builddir)/lib/clplumbing/libplumb.la \
@@ -77,6 +77,14 @@
$(GLIBLIB) \
$(LIBRT)
+diskd_SOURCES = diskd.c
+diskd_LDADD = \
+ $(top_builddir)/lib/clplumbing/libplumb.la \
+ $(top_builddir)/lib/crm/common/libcrmcommon.la \
+ $(top_builddir)/lib/hbclient/libhbclient.la \
+ $(GLIBLIB) \
+ $(LIBRT)
+
attrd_updater_SOURCES = attrd_updater.c
attrd_updater_LDADD = \
$(top_builddir)/lib/clplumbing/libplumb.la \
diff -urN heartbeat-2.1.3/tools/Makefile.in
heartbeat-2.1.3_diskd100/tools/Makefile.in
--- heartbeat-2.1.3/tools/Makefile.in 2007-12-22 05:44:36.000000000 +0900
+++ heartbeat-2.1.3_diskd100/tools/Makefile.in 2008-08-04 23:55:31.000000000
+0900
@@ -380,7 +380,8 @@
hanoarch_DATA = utillib.sh
sbin_SCRIPTS = ciblint hb_report ocf-tester
[EMAIL PROTECTED]@halib_PROGRAMS = attrd pingd
[EMAIL PROTECTED]@halib_PROGRAMS = attrd pingd diskd
+## @[EMAIL PROTECTED] = attrd pingd
@[EMAIL PROTECTED] = attrd_updater
cl_status_SOURCES = cl_status.c
@@ -417,6 +418,13 @@
$(GLIBLIB) \
$(LIBRT)
+diskd_SOURCES = diskd.c
+diskd_LDADD = \
+ $(top_builddir)/lib/clplumbing/libplumb.la \
+ $(top_builddir)/lib/crm/common/libcrmcommon.la \
+ $(top_builddir)/lib/hbclient/libhbclient.la \
+ $(GLIBLIB) \
+ $(LIBRT)
attrd_updater_SOURCES = attrd_updater.c
attrd_updater_LDADD = \
@@ -432,7 +440,8 @@
$(top_builddir)/include/hb_config.h
CONFIG_CLEAN_FILES = ciblint haresources2cib.py hb_report ocf-tester
habin_PROGRAMS = cl_status$(EXEEXT) cl_respawn$(EXEEXT)
[EMAIL PROTECTED]@halib_PROGRAMS = attrd$(EXEEXT) pingd$(EXEEXT)
+### @[EMAIL PROTECTED] = attrd$(EXEEXT) pingd$(EXEEXT)
[EMAIL PROTECTED]@halib_PROGRAMS = attrd$(EXEEXT) pingd$(EXEEXT) diskd$(EXEEXT)
@[EMAIL PROTECTED] =
@[EMAIL PROTECTED] = attrd_updater$(EXEEXT)
@[EMAIL PROTECTED] =
@@ -459,12 +468,21 @@
am_cl_status_OBJECTS = cl_status.$(OBJEXT)
cl_status_OBJECTS = $(am_cl_status_OBJECTS)
cl_status_LDFLAGS =
+
am_pingd_OBJECTS = pingd.$(OBJEXT)
pingd_OBJECTS = $(am_pingd_OBJECTS)
pingd_DEPENDENCIES = $(top_builddir)/lib/clplumbing/libplumb.la \
$(top_builddir)/lib/crm/common/libcrmcommon.la \
$(top_builddir)/lib/hbclient/libhbclient.la
pingd_LDFLAGS =
+
+am_diskd_OBJECTS = diskd.$(OBJEXT)
+diskd_OBJECTS = $(am_diskd_OBJECTS)
+diskd_DEPENDENCIES = $(top_builddir)/lib/clplumbing/libplumb.la \
+ $(top_builddir)/lib/crm/common/libcrmcommon.la \
+ $(top_builddir)/lib/hbclient/libhbclient.la
+diskd_LDFLAGS =
+
SCRIPTS = $(halib_SCRIPTS) $(sbin_SCRIPTS)
@@ -474,7 +492,7 @@
@[EMAIL PROTECTED] = ./$(DEPDIR)/attrd.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/attrd_updater.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/cl_respawn.Po ./$(DEPDIR)/cl_status.Po \
[EMAIL PROTECTED]@ ./$(DEPDIR)/pingd.Po
[EMAIL PROTECTED]@ ./$(DEPDIR)/pingd.Po ./$(DEPDIR)/diskd.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
@@ -483,12 +501,12 @@
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(attrd_SOURCES) $(attrd_updater_SOURCES) \
- $(cl_respawn_SOURCES) $(cl_status_SOURCES) $(pingd_SOURCES)
+ $(cl_respawn_SOURCES) $(cl_status_SOURCES) $(pingd_SOURCES)
$(diskd_SOURCES)
DATA = $(hanoarch_DATA)
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am ciblint.in \
haresources2cib.py.in hb_report.in ocf-tester.in
-SOURCES = $(attrd_SOURCES) $(attrd_updater_SOURCES) $(cl_respawn_SOURCES)
$(cl_status_SOURCES) $(pingd_SOURCES)
+SOURCES = $(attrd_SOURCES) $(attrd_updater_SOURCES) $(cl_respawn_SOURCES)
$(cl_status_SOURCES) $(pingd_SOURCES) $(diskd_SOURCES)
all: all-am
@@ -609,6 +627,9 @@
pingd$(EXEEXT): $(pingd_OBJECTS) $(pingd_DEPENDENCIES)
@rm -f pingd$(EXEEXT)
$(LINK) $(pingd_LDFLAGS) $(pingd_OBJECTS) $(pingd_LDADD) $(LIBS)
+diskd$(EXEEXT): $(diskd_OBJECTS) $(diskd_DEPENDENCIES)
+ @rm -f diskd$(EXEEXT)
+ $(LINK) $(diskd_LDFLAGS) $(diskd_OBJECTS) $(diskd_LDADD) $(LIBS)
halibSCRIPT_INSTALL = $(INSTALL_SCRIPT)
install-halibSCRIPTS: $(halib_SCRIPTS)
@$(NORMAL_INSTALL)
@@ -661,6 +682,7 @@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
[EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
diff -urN heartbeat-2.1.3/tools/diskd.c heartbeat-2.1.3_diskd100/tools/diskd.c
--- heartbeat-2.1.3/tools/diskd.c 1970-01-01 09:00:00.000000000 +0900
+++ heartbeat-2.1.3_diskd100/tools/diskd.c 2008-08-04 23:55:43.000000000
+0900
@@ -0,0 +1,392 @@
+/* -------------------------------------------------------------------------
+ * diskd --- monitors shared disk.
+ * This applied pingd mechanism to disk monitor.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2008 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include <lha_internal.h>
+
+#include <sys/param.h>
+
+#include <crm/crm.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+
+#include <heartbeat.h>
+#include <hb_api.h>
+#include <clplumbing/Gmain_timeout.h>
+#include <clplumbing/lsb_exitcodes.h>
+
+#include <crm/common/ipc.h>
+#include <attrd.h>
+
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#define MIN_INTERVAL 1
+#define MAX_INTERVAL 3600
+#define MIN_TIMEOUT 1
+#define MAX_TIMEOUT 3600
+#define MIN_RETRY 0
+#define MAX_RETRY 10
+#define MIN_RETRY_INTERVAL 1
+#define MAX_RETRY_INTERVAL 3600
+#define ERROR -1
+#define normal 1
+#define BLKFLSBUF _IO(0x12,97) /* flush buffer. refer linux/hs.h */
+
+/* GMainLoop *mainloop = NULL; */
+const char *crm_system_name = "diskd";
+
+#define OPTARGS "V?p:a:N:Di:r:I:t:"
+
+IPC_Channel *attrd = NULL;
+GMainLoop* mainloop = NULL;
+const char *diskd_attr = "diskd";
+
+const char *device = NULL; /* device name for disk check */
+
+int retry = 1; /* disk check retry. default 1 times */
+int retry_interval = 5; /* disk check retry intarval time. default 5sec. */
+int interval = 30; /* disk check interval. default 30sec.*/
+int timeout = 30; /* disk check read func timeout. default 30sec.
*/
+int old_status = 0;
+const char *diskcheck_value = NULL;
+int pagesize = 0;
+void *ptr = NULL;
+void *buf;
+
+void send_update(void);
+
+static gboolean
+diskd_shutdown(int nsig, gpointer unused)
+{
+ crm_info("Exiting");
+
+ if (mainloop != NULL && g_main_is_running(mainloop)) {
+ g_main_quit(mainloop);
+ } else {
+ exit(0);
+ }
+ return FALSE;
+}
+
+static void
+usage(const char *cmd, int exit_status)
+{
+ FILE *stream;
+
+ stream = exit_status ? stderr : stdout;
+
+ fprintf(stream, "usage: %s [-%s]\n", cmd, OPTARGS);
+ fprintf(stream, " Basic options\n");
+ fprintf(stream, "\t--%s (-%c) \t\t\tThis text\n", "help", '?');
+ fprintf(stream, "\t--%s (-%c) \t\t\tRun in verbose mode\n", "verbose",
'V');
+ fprintf(stream, "\t--%s (-%c) \t\tRun in daemon mode\n", "daemonize",
'D');
+ fprintf(stream, "\t--%s (-%c) <filename>\tFile in which to store the
process' PID\n"
+ "\t\t\t\t\t* Default=/tmp/diskd.pid\n", "pid-file", 'p');
+ fprintf(stream, "\t--%s (-%c) <string>\tName of the node attribute to
set\n"
+ "\t\t\t\t\t* Default=diskd\n", "attr-name", 'a');
+ fprintf(stream, "\t--%s (-%c) <devicename>\tName of the device to check
status\n"
+ "\t\t\t\t\t* Mandatory option\n", "device-name", 'N');
+ fprintf(stream, "\t--%s (-%c) <time[s]>\tDisk status check interval
time\n"
+ "\t\t\t\t\t* Default=30 sec.\n", "interval", 'i');
+ fprintf(stream, " Advanced options\n");
+ fprintf(stream, "\t--%s (-%c) <time[s]>\tRead timeout for select
function\n"
+ "\t\t\t\t\t* Default=5 sec.\n", "read-timeout", 't');
+ fprintf(stream, "\t--%s (-%c) <times>\t\tDisk status check retry\n"
+ "\t\t\t\t\t* Default=1 times\n", "retry", 'r');
+ fprintf(stream, "\t--%s (-%c) <time[s]>\tDisk status check retry
interval time\n"
+ "\t\t\t\t\t* Default=5 sec.\n", "retry-interval", 'I');
+
+ fflush(stream);
+
+ exit(exit_status);
+}
+
+static gboolean
+check_old_status(int new_status)
+{
+
+ if (new_status != ERROR && new_status != normal) {
+ crm_warn("non-defined status, new_status = %d", new_status);
+ return FALSE;
+ }
+
+ if (old_status != new_status) {
+ if (new_status == ERROR) {
+ diskcheck_value = "ERROR";
+ } else {
+ diskcheck_value = "normal";
+ }
+ crm_warn("disk status is changed, new_status = %s",
diskcheck_value);
+ send_update();
+ old_status = new_status;
+ }
+ return TRUE;
+}
+
+
+static int diskcheck(gpointer data)
+{
+ int i;
+ int fd = -1;
+ int err;
+ int select_err;
+ struct timeval timeout_tv;
+ fd_set read_fd_set;
+
+ crm_debug_2("diskcheck start");
+
+ for (i = 0; i <= retry; i++) {
+ if ( i !=0 ) {
+ sleep(retry_interval);
+ }
+
+
+ fd = open((const char *)device, O_RDONLY | O_NONBLOCK, 0);
+ if (fd == -1) {
+ crm_err("Could not open device %s", device);
+ continue;
+ }
+
+ err = ioctl(fd, BLKFLSBUF, 0);
+ if (err != 0) {
+ crm_err("iotcl error, Could not flush baffer");
+ close(fd);
+ continue;
+ }
+
+ while( 1 ) {
+ err = read(fd, buf, pagesize);
+ if (err == pagesize) {
+ crm_debug_2("reading form data is OK");
+ close(fd);
+ check_old_status(normal);
+ return normal;
+ } else if (err != pagesize && errno == EAGAIN) {
+ crm_warn("read function return errno:EAGAIN");
+ FD_ZERO(&read_fd_set);
+ FD_SET(fd, &read_fd_set);
+ timeout_tv.tv_sec = timeout;
+ select_err = select(1, &read_fd_set, NULL,
NULL, &timeout_tv);
+ if (select_err == 1) {
+ crm_warn("select ok, read again");
+ continue;
+ } else if (select_err == -1) {
+ crm_err("select failed on device %s",
device);
+ close(fd);
+ break;
+ }
+ } else {
+ crm_err("Could not read from device %s",
device);
+ close(fd);
+ break;
+ }
+ }
+ }
+
+ crm_warn("Error(s) occurred in diskcheck function.");
+ check_old_status(ERROR);
+ return ERROR;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int lpc;
+ int argerr = 0;
+ int flag;
+ char *pid_file = NULL;
+ gboolean daemonize = FALSE;
+
+#ifdef HAVE_GETOPT_H
+ int option_index = 0;
+ static struct option long_options[] = {
+ /* Top-level Options */
+ {"verbose", 0, 0, 'V'},
+ {"help", 0, 0, '?'},
+ {"pid-file", 1, 0, 'p'},
+ {"attr-name", 1, 0, 'a'},
+ {"device-name", 1, 0, 'N'},
+ {"daemonize", 0, 0, 'D'},
+ {"interval", 1, 0, 'i'},
+ {"retry", 1, 0, 'r'},
+ {"retry-interval", 1, 0, 'I'},
+ {"read-timeout", 1, 0, 't'},
+
+ {0, 0, 0, 0}
+ };
+#endif
+ pid_file = crm_strdup("/tmp/diskd.pid");
+ crm_system_name = basename(argv[0]);
+
+ G_main_add_SignalHandler(
+ G_PRIORITY_HIGH, SIGTERM, diskd_shutdown, NULL, NULL);
+
+ crm_log_init(basename(argv[0]), LOG_INFO, TRUE, FALSE, argc, argv);
+
+ /* check user. user shuld be root.*/
+ if (strcmp("root", (const gchar *)g_get_user_name()) != 0) {
+ crm_err("permission denied. diskd should be executed by
root.\n");
+ printf ("permission denied. diskd should be executed by
root.\n");
+ exit(LSB_EXIT_GENERIC);
+ }
+
+ while (1) {
+#ifdef HAVE_GETOPT_H
+ flag = getopt_long(argc, argv, OPTARGS,
+ long_options, &option_index);
+#else
+ flag = getopt(argc, argv, OPTARGS);
+#endif
+ if (flag == -1)
+ break;
+
+ switch(flag) {
+ case 'V':
+ cl_log_enable_stderr(TRUE);
+ alter_debug(DEBUG_INC);
+ break;
+ case 'p':
+ pid_file = crm_strdup(optarg);
+ break;
+ case 'a':
+ diskd_attr = crm_strdup(optarg);
+ break;
+ case 'r':
+ retry = crm_parse_int(optarg, "1");
+ if ((retry == 0) && (strcmp(optarg, "0") != 0))
{
+ argerr++;
+ break;
+ }
+ if ((retry < MIN_RETRY) || (retry > MAX_RETRY))
+ ++argerr;
+ break;
+ case 'I':
+ retry_interval = crm_parse_int(optarg, "1");
+ if ((retry_interval < MIN_RETRY_INTERVAL) ||
(retry_interval > MAX_RETRY_INTERVAL))
+ ++argerr;
+ break;
+ case 'i':
+ interval = crm_parse_int(optarg, "1");
+ if ((interval < MIN_INTERVAL) || (interval >
MAX_INTERVAL))
+ ++argerr;
+ break;
+ case 't':
+ timeout = crm_parse_int(optarg, "1");
+ if ((timeout < MIN_TIMEOUT) || (timeout >
MAX_TIMEOUT))
+ ++argerr;
+ case 'N':
+ device = crm_strdup(optarg);
+ break;
+ case 'D':
+ daemonize = TRUE;
+ break;
+ case '?':
+ usage(crm_system_name, LSB_EXIT_GENERIC);
+ break;
+ default:
+ printf ("Argument code 0%o (%c) is not (?yet?)
supported\n", flag, flag);
+ crm_err("Argument code 0%o (%c) is not (?yet?)
supported\n", flag, flag);
+ ++argerr;
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ crm_err("non-option ARGV-elements: ");
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc) {
+ crm_err("%s ", argv[optind++]);
+ printf("%s ", argv[optind++]);
+ }
+ printf("\n");
+ argerr ++;
+ }
+ if ((argerr) || (device == NULL)){
+ usage(crm_system_name, LSB_EXIT_GENERIC);
+ }
+
+ crm_make_daemon(crm_system_name, daemonize, pid_file);
+
+ for(lpc = 0; attrd == NULL && lpc < 30; lpc++) {
+ crm_debug("attrd registration attempt: %d", lpc);
+ sleep(5);
+ attrd = init_client_ipc_comms_nodispatch(T_ATTRD);
+ }
+
+ if(attrd == NULL) {
+ printf ("attrd registration failed\n");
+ crm_err("attrd registration failed");
+ cl_flush_logs();
+ exit(LSB_EXIT_GENERIC);
+ }
+
+ pagesize = getpagesize();
+ ptr = (void *)malloc(2 * pagesize);
+ buf = (void *)(((u_long)ptr + pagesize) & ~(pagesize-1));
+ if (ptr == NULL) {
+ crm_err("Could not allocate memory");
+ check_old_status(ERROR);
+ exit(LSB_EXIT_GENERIC);
+ }
+
+ diskcheck(NULL);
+
+ Gmain_timeout_add(interval*1000, diskcheck, NULL);
+
+ crm_info("Starting %s", crm_system_name);
+ mainloop = g_main_new(FALSE);
+ g_main_run(mainloop);
+
+ free(ptr);
+ crm_info("Exiting %s", crm_system_name);
+ return 0;
+}
+
+void
+send_update()
+{
+ HA_Message *update = ha_msg_new(4);
+ ha_msg_add(update, F_TYPE, T_ATTRD);
+ ha_msg_add(update, F_ORIG, crm_system_name);
+ ha_msg_add(update, F_ATTRD_TASK, "update");
+ ha_msg_add(update, F_ATTRD_ATTRIBUTE, diskd_attr);
+
+ ha_msg_add(update, F_ATTRD_VALUE, diskcheck_value);
+
+ if(send_ipc_message(attrd, update) == FALSE) {
+ crm_err("Could not send update");
+ exit(1);
+ }
+ crm_msg_del(update);
+}
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/