Hi all,
I'd like to run heartbeat on a single node.
Because heartbeat refuses to start as the it requires at least one
usable media for communication, I think it might be good idea to have
a new HBcomm plugin for this purpose.
The attached file has been tested on openSUSE 10.2 + hg version of hb2.
Comments are welcome.
Thanks.
/*
* null.c: Null communication for heartbeat v2.
*
* Copyright (C) 2007 Xinwei Hu <[EMAIL PROTECTED]>
*
* Null Communication is useful when using heartbeat to
* monitor application on one node ONLY.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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 library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*
*/
#include <lha_internal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <heartbeat.h>
#include <HBcomm.h>
#define PIL_PLUGINTYPE HB_COMM_TYPE
#define PIL_PLUGINTYPE_S HB_COMM_TYPE_S
#define PIL_PLUGIN nullc
#define PIL_PLUGIN_S "nullc"
#define PIL_PLUGINLICENSE LICENSE_LGPL
#define PIL_PLUGINLICENSEURL URL_LGPL
#include <pils/plugin.h>
static int nullc_init(void);
struct hb_media* nullc_new(const char* interface);
static int nullc_open(struct hb_media* mp);
static int nullc_close(struct hb_media* mp);
static void* nullc_read(struct hb_media* mp, int *lenp);
static int nullc_write(struct hb_media* mp, void* msg, int len);
static int nullc_descr(char** buffer);
static int nullc_mtype(char** buffer);
static int nullc_isping(void);
static struct hb_media_fns nullcOps ={
nullc_new, /* Create single object function */
NULL, /* whole-line parse function */
nullc_open,
nullc_close,
nullc_read,
nullc_write,
nullc_mtype,
nullc_descr,
nullc_isping,
};
PIL_PLUGIN_BOILERPLATE2("1.0", Debug)
static const PILPluginImports* PluginImports;
static PILPlugin* OurPlugin;
static PILInterface* OurInterface;
static struct hb_media_imports* OurImports;
static void* interfprivate;
#define LOG PluginImports->log
#define MALLOC PluginImports->alloc
#define STRDUP PluginImports->mstrdup
#define FREE PluginImports->mfree
PIL_rc
PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports);
PIL_rc
PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports)
{
/* Force the compiler to do a little type checking */
(void)(PILPluginInitFun)PIL_PLUGIN_INIT;
PluginImports = imports;
OurPlugin = us;
/* Register ourself as a plugin */
imports->register_plugin(us, &OurPIExports);
/* Register our interface implementation */
return imports->register_interface(us, PIL_PLUGINTYPE_S
, PIL_PLUGIN_S
, &nullcOps
, NULL /*close */
, &OurInterface
, (void*)&OurImports
, interfprivate);
}
#define ISNULLCOBJECT(mp) ((mp) && ((mp)->vf == (void*)&nullcOps))
#define NULLCASSERT(mp) g_assert(ISNULLCOBJECT(mp))
static int
nullc_mtype(char** buffer) {
*buffer = STRDUP(PIL_PLUGIN_S);
if (!*buffer) {
return 0;
}
return STRLEN_CONST(PIL_PLUGIN_S);
}
static int
nullc_descr(char **buffer) {
const char constret[] = "Null communication";
*buffer = STRDUP(constret);
if (!*buffer) {
return 0;
}
return STRLEN_CONST(constret);
}
static int
nullc_isping(void) {
return 0;
}
static int
nullc_init(void)
{
g_assert(OurImports != NULL);
return(HA_OK);
}
static void* msgbuf = NULL;
static sem_t* readable_lock = NULL;
static sem_t* writable_lock = NULL;
struct hb_media *
nullc_new(const char * intf)
{
struct hb_media * ret;
int shmid;
static char readlock_name[256] = "/nullc.";
static char writelock_name[256] = "/nullc.";
static char sharem_name[256] = "/nullc.";
nullc_init();
ret = (struct hb_media*) MALLOC(sizeof(struct hb_media));
if (ret != NULL) {
char * name;
memset(ret, 0, sizeof(*ret));
name = STRDUP("intf");
if (name != NULL) {
ret->name = name;
} else {
FREE(ret);
ret = NULL;
}
}
strncat(readlock_name, ret->name, 248);
strncat(writelock_name, ret->name, 248);
strncat(sharem_name, ret->name, 248);
readable_lock = sem_open(readlock_name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR, 0);
if (readable_lock == SEM_FAILED) {
PILCallLog(LOG, PIL_CRIT, "readable_lock init failed due to %s", strerror(errno));
FREE(ret);
return NULL;
}
writable_lock = sem_open(writelock_name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR, 1);
if (writable_lock == SEM_FAILED) {
PILCallLog(LOG, PIL_CRIT, "writeable_lock init failed due to %s", strerror(errno));
FREE(ret);
return NULL;
}
/*
shmid = shmget(ftok("/tmp/nullc.ASDF", 1), sizeof(char)*MAXMSG+sizeof(int), IPC_CREAT|SHM_R|SHM_W);
if (shmid == -1) {
FREE(ret);
return NULL;
}
msgbuf = shmat(shmid, NULL, 0);
*/
shmid= shm_open(sharem_name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if (shmid == -1) {
PILCallLog(LOG, PIL_CRIT, "shm_open failed due to %s", strerror(errno));
FREE(ret);
return NULL;
}
ftruncate(shmid, sizeof(char)*MAXMSG+sizeof(int));
msgbuf = mmap(NULL, sizeof(char)*MAXMSG+sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, shmid, 0);
if (msgbuf == NULL) {
PILCallLog(LOG, PIL_CRIT, "mmap failed due to %s", strerror(errno));
FREE(ret);
return NULL;
}
return(ret);
}
static int
nullc_open(struct hb_media* mp) {
return(HA_OK);
}
static int
nullc_close(struct hb_media* mp) {
PILCallLog(LOG, PIL_CRIT, "nullc_close");
return (HA_OK);
}
static void *
nullc_read(struct hb_media* mp, int * lenp) {
static char buf[MAXMSG];
int* pi = msgbuf;
int len = *pi + 1;
sem_wait(readable_lock);
memcpy(buf, (char*)msgbuf+sizeof(int), sizeof(char)*len);
*lenp = len;
*pi = 0;
sem_post(writable_lock);
// PILCallLog(LOG, PIL_CRIT, "read: %s", (char*)buf);
return buf;
}
static int
nullc_write(struct hb_media* mp, void *pkt, int len) {
int* pi = msgbuf;
char* buf = (char*)msgbuf+sizeof(int);
*pi = len;
sem_wait(writable_lock);
memcpy(buf, pkt, *pi);
sem_post(readable_lock);
// PILCallLog(LOG, PIL_CRIT, "write: %s", (char*)buf);
return(HA_OK);
}
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/