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/

Reply via email to