[Debian-ha-commits] [cluster-glue] 14/73: Imported Upstream version 1.0.6+hg2461
Richard Winters
devrik-guest at moszumanska.debian.org
Sat Apr 18 20:24:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
devrik-guest pushed a commit to branch master
in repository cluster-glue.
commit 75104c6a92414edbd46b763feb80cbed42f7585b
Author: Richard B Winters <rik at mmogp.com>
Date: Sat Apr 18 07:48:41 2015 -0400
Imported Upstream version 1.0.6+hg2461
---
.hg_archival.txt | 2 +-
.hgtags | 1 +
configure.ac | 24 +-
include/clplumbing/.cvsignore | 6 -
include/clplumbing/cl_random.h | 38 +-
include/clplumbing/ipc.h | 1 -
include/lha_internal.h | 9 +
include/lrm/.cvsignore | 6 -
include/pils/.cvsignore | 6 -
include/stonith/.cvsignore | 10 -
lib/clplumbing/.cvsignore | 14 -
lib/clplumbing/GSource.c | 12 +-
lib/clplumbing/cl_log.c | 44 ++-
lib/clplumbing/cl_msg.c | 4 +-
lib/clplumbing/cl_msg_types.c | 11 +-
lib/clplumbing/ipcsocket.c | 39 +-
lib/clplumbing/ipctransientclient.c | 4 +-
lib/lrm/.cvsignore | 10 -
lib/lrm/clientlib.c | 6 +-
lib/lrm/racommon.c | 8 +-
lib/pils/.cvsignore | 11 -
lib/plugins/lrm/.cvsignore | 11 -
lib/plugins/lrm/Makefile.am | 17 +
lib/plugins/lrm/dbus/Makefile.am | 16 +
.../lrm/dbus/com.ubuntu.Upstart.Instance.xml | 45 +++
lib/plugins/lrm/dbus/com.ubuntu.Upstart.Job.xml | 71 ++++
lib/plugins/lrm/dbus/com.ubuntu.Upstart.xml | 57 +++
lib/plugins/lrm/raexeclsb.c | 2 +-
lib/plugins/lrm/raexecupstart.c | 222 ++++++++++++
lib/plugins/lrm/upstart-dbus.c | 403 +++++++++++++++++++++
lib/plugins/lrm/upstart-dbus.h | 36 ++
lib/plugins/stonith/.cvsignore | 11 -
lib/plugins/stonith/cyclades.c | 17 +
lib/plugins/stonith/external.c | 26 +-
lib/plugins/stonith/external/.cvsignore | 5 -
lib/plugins/stonith/external/Makefile.am | 4 +-
lib/plugins/stonith/external/ipmi | 37 +-
lib/plugins/stonith/external/nut | 302 +++++++++++++++
lib/plugins/stonith/external/riloe | 52 ++-
lib/stonith/.cvsignore | 13 -
lib/stonith/main.c | 101 +++---
lib/stonith/sbd.c | 64 +++-
lib/stonith/sbd.h | 1 +
logd/.cvsignore | 7 -
lrm/.cvsignore | 10 -
lrm/admin/.cvsignore | 11 -
lrm/admin/lrmadmin.c | 2 +-
lrm/admin/lrmadmin.txt | 6 +-
lrm/lrmd/.cvsignore | 11 -
lrm/lrmd/lrmd.c | 35 +-
lrm/test/.cvsignore | 19 -
lrm/test/testcases/.cvsignore | 10 -
52 files changed, 1599 insertions(+), 291 deletions(-)
diff --git a/.hg_archival.txt b/.hg_archival.txt
index 8971d18..35b3691 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,2 +1,2 @@
repo: e3ffdd7ae81c596b2be7e1e110d2c1255161340e
-node: 1c87a0c58c59fc384b93ec11476cefdbb6ddc1e1
+node: e876b4cf30be589652d620b887077a9bd38f0540
diff --git a/.hgtags b/.hgtags
index 0bdbda0..160b05e 100644
--- a/.hgtags
+++ b/.hgtags
@@ -56,3 +56,4 @@ f6c2cd2593f365f984ce051db61466738ac05dcd Beta-0.4.9f
761edff8c35ea2cdf3e1bd37d600b06233e61d4f glue-1.0.4-rc1
3229873980e1028bf05de81f5bafccb3a92b9aa4 glue-1.0.4
3af80b93d9e5d5e441f3f4c3aad16775ea27d2d9 glue-1.0.5
+1c87a0c58c59fc384b93ec11476cefdbb6ddc1e1 glue-1.0.6
diff --git a/configure.ac b/configure.ac
index 8014ca0..70bbecf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,7 @@ dnl checks for system services
AC_INIT(cluster-glue, 1.0.6, linux-ha-dev at lists.linux-ha.org)
-PKG_FEATURES=""
+FEATURES=""
HB_PKG=heartbeat
AC_CONFIG_AUX_DIR(.)
@@ -129,6 +129,10 @@ AC_ARG_ENABLE([bundled-ltdl],
[ --enable-bundled-ltdl Configure, build and install the standalone ltdl library bundled with ${PACKAGE} [default=no]])
LTDL_LIBS=""
+AC_ARG_ENABLE([upstart],
+AS_HELP_STRING([--enable-upstart],
+ [Enable Upstart support in lrmd. [default=no]]))
+
INITDIR=""
AC_ARG_WITH(initdir,
[ --with-initdir=DIR directory for init (rc) scripts [${INITDIR}]],
@@ -533,7 +537,7 @@ fi
AM_CONDITIONAL(BUILD_HELP, test x"${HELP2MAN}" != x"")
if test x"${HELP2MAN}" != x""; then
- PKG_FEATURES="$PKG_FEATURES manpages"
+ FEATURES="$FEATURES manpages"
fi
dnl ===============================================
@@ -1089,6 +1093,19 @@ if test x$ac_cv_header_bzlib_h != xyes; then
fi
dnl ========================================================================
+dnl Upstart via DBus
+dnl ========================================================================
+
+if test x$enable_upstart = xyes; then
+ PKG_CHECK_MODULES(DBUS, [dbus-1, dbus-glib-1])
+ AC_SUBST(DBUS_CFLAGS)
+ AC_SUBST(DBUS_LIBS)
+ AC_PATH_PROGS(DBUS_BINDING_TOOL, dbus-binding-tool)
+fi
+AM_CONDITIONAL(UPSTART, test x$enable_upstart = xyes)
+
+
+dnl ========================================================================
dnl checks for library functions to replace them
dnl
dnl NoSuchFunctionName:
@@ -1295,6 +1312,7 @@ lib/Makefile \
lib/plugins/Makefile \
lib/plugins/InterfaceMgr/Makefile \
lib/plugins/lrm/Makefile \
+ lib/plugins/lrm/dbus/Makefile \
lib/plugins/stonith/Makefile \
lib/plugins/stonith/ribcl.py \
lib/plugins/stonith/external/Makefile \
@@ -1337,7 +1355,7 @@ dnl *****************
AC_MSG_RESULT([])
AC_MSG_RESULT([$PACKAGE configuration:])
AC_MSG_RESULT([ Version = ${VERSION} (Build: $GLUE_BUILD_VERSION)])
-AC_MSG_RESULT([ Features =${PKG_FEATURES}])
+AC_MSG_RESULT([ Features =${FEATURES}])
AC_MSG_RESULT([])
AC_MSG_RESULT([ Prefix = ${prefix}])
AC_MSG_RESULT([ Executables = ${sbindir}])
diff --git a/include/clplumbing/.cvsignore b/include/clplumbing/.cvsignore
deleted file mode 100644
index 3f213c3..0000000
--- a/include/clplumbing/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/include/clplumbing/cl_random.h b/include/clplumbing/cl_random.h
index a6721e9..a17f808 100644
--- a/include/clplumbing/cl_random.h
+++ b/include/clplumbing/cl_random.h
@@ -18,6 +18,40 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
+#include <stdlib.h>
unsigned int cl_randseed(void);
-int get_next_random(void); /* Assumes mainloop setup */
+/* Is currently rand() based.
+ * Does srand(cl_randseed()) once internally.
+ * Assumes mainloop is setup. */
+int get_next_random(void);
+
+/* generate some random number in the range [a;b];
+ * typically used to randomly delay messages. */
+#define HAVE_CL_RAND_FROM_INTERVAL 1
+static inline
+int cl_rand_from_interval(const int a, const int b)
+{
+ /*
+ * Be careful here, you don't know RAND_MAX at coding time,
+ * only at compile time. If you think
+ * (int)(a + (rand()*(b-a)+(RAND_MAX/2))/RAND_MAX);
+ * was correct, think again with RAND_MAX = INT_MAX,
+ * which is the case for many rand() implementations nowadays.
+ *
+ * Don't do modulo, either, as that will skew the distribution, and
+ * still has possible wraparounds, or an insufficient input set for too
+ * small RAND_MAX.
+ *
+ * Rather do the whole calculation in 64 bit, which should be correct
+ * as long as r, a, b, and RAND_MAX are all int.
+ * Of course, if you prefer, you can do it with floating point as well.
+ */
+#if 1 /* use long long */
+ long long r = get_next_random();
+ r = a + (r * (b-a) + RAND_MAX/2)/RAND_MAX;
+#else /* use floating point */
+ int r = get_next_random();
+ r = a + (int)(1.0 / RAND_MAX * r * (b-a) + 0.5);
+#endif
+ return r;
+}
diff --git a/include/clplumbing/ipc.h b/include/clplumbing/ipc.h
index 5afae2b..fcf7694 100644
--- a/include/clplumbing/ipc.h
+++ b/include/clplumbing/ipc.h
@@ -40,7 +40,6 @@
/* constants */
#define DEFAULT_MAX_QLEN 64
-#define MAX_MESSAGE_SIZE 4096
#define MAX_MSGPAD 128
/* channel and connection status */
#define IPC_CONNECT 1 /* Connected: can read, write */
diff --git a/include/lha_internal.h b/include/lha_internal.h
index 5df81fb..94d04bc 100644
--- a/include/lha_internal.h
+++ b/include/lha_internal.h
@@ -136,6 +136,15 @@ inet_pton(int af, const char *src, void *dst);
#define POINTER_TO_SIZE_T(p) ((size_t)(p)) /*pointer cast as size_t*/
#define POINTER_TO_SSIZE_T(p) ((ssize_t)(p)) /*pointer cast as ssize_t*/
#define POINTER_TO_ULONG(p) ((unsigned long)(p)) /*pointer cast as unsigned long*/
+ /* Sometimes we get a const g_something *, but need to pass it internally
+ * to other functions taking a non-const g_something *, which results
+ * with gcc and -Wcast-qual in a compile time warning, and with -Werror
+ * even to a compile time error.
+ * Workarounds have been to e.g. memcpy(&list, _list); or similar,
+ * the reason of which is non-obvious to the casual reader.
+ * This macro achieves the same, and annotates why it is done.
+ */
+#define UNCONST_CAST_POINTER(t, p) ((t)(unsigned long)(p))
#define HAURL(url) HA_URLBASE url
diff --git a/include/lrm/.cvsignore b/include/lrm/.cvsignore
deleted file mode 100644
index 3f213c3..0000000
--- a/include/lrm/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/include/pils/.cvsignore b/include/pils/.cvsignore
deleted file mode 100644
index bbf3142..0000000
--- a/include/pils/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-plugin.h
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/include/stonith/.cvsignore b/include/stonith/.cvsignore
deleted file mode 100644
index cab0d2e..0000000
--- a/include/stonith/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lib/clplumbing/.cvsignore b/lib/clplumbing/.cvsignore
deleted file mode 100644
index 4d36492..0000000
--- a/lib/clplumbing/.cvsignore
+++ /dev/null
@@ -1,14 +0,0 @@
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-ipctest
-ipctransientclient
-ipctransientserver
-*.beam
-parser-messages
-MISC_ERRORS
-base64_md5_test
diff --git a/lib/clplumbing/GSource.c b/lib/clplumbing/GSource.c
index d185259..7f82360 100644
--- a/lib/clplumbing/GSource.c
+++ b/lib/clplumbing/GSource.c
@@ -965,9 +965,11 @@ G_main_add_SignalHandler(int priority, int signal,
source = NULL;
sig_src = NULL;
} else {
- cl_log(LOG_INFO
- , "%s: Added signal handler for signal %d"
- , __FUNCTION__, signal);
+ if (debug_level > 1) {
+ cl_log(LOG_DEBUG
+ , "%s: Added signal handler for signal %d"
+ , __FUNCTION__, signal);
+ }
G_main_signal_list[signal] = sig_src;
CL_SIGNAL(signal, G_main_signal_handler);
/*
@@ -1309,7 +1311,9 @@ G_main_add_TriggerHandler(int priority,
source = NULL;
trig_src = NULL;
} else {
- cl_log(LOG_INFO, "G_main_add_TriggerHandler: Added signal manual handler");
+ if (debug_level > 1) {
+ cl_log(LOG_DEBUG, "G_main_add_TriggerHandler: Added signal manual handler");
+ }
}
return trig_src;
diff --git a/lib/clplumbing/cl_log.c b/lib/clplumbing/cl_log.c
index 72149c0..47e9080 100644
--- a/lib/clplumbing/cl_log.c
+++ b/lib/clplumbing/cl_log.c
@@ -478,21 +478,14 @@ prio2str(int priority)
static char * syslog_timestamp(TIME_T t);
static void
-append_log( const char * fname, const char * entity, int entity_pid
+append_log(FILE * fp, const char * entity, int entity_pid
, TIME_T timestamp, const char * pristr, const char * msg)
{
- FILE * fp = fopen(fname,"a");
static int got_uname = FALSE;
static struct utsname un;
- if (!fp) {
- syslog(LOG_ERR, "Cannot append to %s: %s", fname
- , strerror(errno));
- return;
- }
if (!syslogformatfile) {
print_logline(fp, entity, entity_pid, timestamp, pristr, msg);
- fclose(fp);
return;
}
if (!got_uname) {
@@ -507,7 +500,20 @@ append_log( const char * fname, const char * entity, int entity_pid
, (pristr ? pristr : "")
, (pristr ? ": " : "")
, msg);
- fclose(fp);
+}
+
+/*
+ * Just open the given file name
+ */
+static FILE *
+open_log_file(const char * fname)
+{
+ FILE * fp = fopen(fname ,"a");
+ if (!fp) {
+ syslog(LOG_ERR, "Failed to open log file %s: %s\n" ,
+ fname, strerror(errno));
+ }
+ return fp;
}
/*
@@ -552,11 +558,27 @@ cl_direct_log(int priority, const char* buf, gboolean use_priority_str,
}
if (debugfile_name != NULL) {
- append_log(debugfile_name,entity,entity_pid,ts,pristr,buf);
+ static FILE * debug_fp = NULL;
+ if (!debug_fp) {
+ /* As performance optimization we keep the file-handle
+ * open all the time */
+ debug_fp = open_log_file(debugfile_name);
+ }
+ if (debug_fp)
+ append_log(debug_fp ,entity, entity_pid, ts, pristr,
+ buf);
}
if (priority != LOG_DEBUG && logfile_name != NULL) {
- append_log(logfile_name,entity,entity_pid,ts,pristr,buf);
+ static FILE * log_fp = NULL;
+ if (!log_fp) {
+ /* As performance optimization we keep the file-handle
+ * open all the time */
+ log_fp = open_log_file(logfile_name);
+ }
+ if (log_fp)
+ append_log(log_fp ,entity, entity_pid, ts, pristr,
+ buf);
}
if (needprivs) {
diff --git a/lib/clplumbing/cl_msg.c b/lib/clplumbing/cl_msg.c
index f5119de..1342158 100644
--- a/lib/clplumbing/cl_msg.c
+++ b/lib/clplumbing/cl_msg.c
@@ -951,7 +951,6 @@ cl_msg_list_add_string(struct ha_msg* msg, const char* name, const char* value)
{
GList* list = NULL;
int ret;
- char buf[MAXMSG];
if(!msg || !name || !value){
cl_log(LOG_ERR, "cl_msg_list_add_string: input invalid");
@@ -959,8 +958,7 @@ cl_msg_list_add_string(struct ha_msg* msg, const char* name, const char* value)
}
- strncpy(buf, value, MAXMSG);
- list = g_list_append(list, buf);
+ list = g_list_append(list, UNCONST_CAST_POINTER(gpointer, value));
if (!list){
cl_log(LOG_ERR, "cl_msg_list_add_string: append element to"
"a glist failed");
diff --git a/lib/clplumbing/cl_msg_types.c b/lib/clplumbing/cl_msg_types.c
index 9ac8ca5..1b9537b 100644
--- a/lib/clplumbing/cl_msg_types.c
+++ b/lib/clplumbing/cl_msg_types.c
@@ -168,12 +168,9 @@ size_t
string_list_pack_length(const GList* _list)
{
size_t i;
- GList* list = NULL;
+ GList* list = UNCONST_CAST_POINTER(GList *, _list);
size_t total_length = 0;
- memcpy(&list, &_list, sizeof(GList*));
- (void)list;
-
if (list == NULL){
cl_log(LOG_WARNING, "string_list_pack_length():"
"list is NULL");
@@ -438,16 +435,14 @@ list_copy(const GList* _list)
{
size_t i;
GList* newlist = NULL;
- GList* list;
-
- memcpy(&list, &_list, sizeof(GList*));
+ GList* list = UNCONST_CAST_POINTER(GList *, _list);
for (i = 0; i < g_list_length(list); i++){
char* dup_element = NULL;
char* element = g_list_nth_data(list, i);
int len;
if (element == NULL){
- cl_log(LOG_WARNING, "list_cleanup:"
+ cl_log(LOG_WARNING, "list_copy:"
"element is NULL");
continue;
}
diff --git a/lib/clplumbing/ipcsocket.c b/lib/clplumbing/ipcsocket.c
index 3b9ac32..b712dd9 100644
--- a/lib/clplumbing/ipcsocket.c
+++ b/lib/clplumbing/ipcsocket.c
@@ -1715,6 +1715,39 @@ socket_get_send_fd(struct IPC_CHANNEL *ch)
return socket_get_recv_fd(ch);
}
+static void
+socket_adjust_buf(struct IPC_CHANNEL *ch, int optname, unsigned q_len)
+{
+ const char *direction = optname == SO_SNDBUF ? "snd" : "rcv";
+ int fd = socket_get_send_fd(ch);
+ unsigned byte;
+
+ /* Arbitrary scaling.
+ * DEFAULT_MAX_QLEN is 64, default socket buf is often 64k to 128k,
+ * at least on those linux I checked.
+ * Keep that ratio, and allow for some overhead. */
+ if (q_len == 0)
+ /* client does not want anything,
+ * reduce system buffers as well */
+ byte = 4096;
+ else if (q_len < 512)
+ byte = (32 + q_len) * 1024;
+ else
+ byte = q_len * 1024;
+
+ if (0 == setsockopt(fd, SOL_SOCKET, optname, &byte, sizeof(byte))) {
+ if (debug_level > 1) {
+ cl_log(LOG_DEBUG, "adjusted %sbuf size to %u",
+ direction, byte);
+ }
+ } else {
+ /* If this fails, you may need to adjust net.core.rmem_max,
+ * ...wmem_max, or equivalent */
+ cl_log(LOG_WARNING, "adjust %sbuf size to %u failed: %s",
+ direction, byte, strerror(errno));
+ }
+}
+
static int
socket_set_send_qlen (struct IPC_CHANNEL* ch, int q_len)
{
@@ -1722,9 +1755,9 @@ socket_set_send_qlen (struct IPC_CHANNEL* ch, int q_len)
if (ch->send_queue == NULL) {
return IPC_FAIL;
}
+ socket_adjust_buf(ch, SO_SNDBUF, q_len);
ch->send_queue->max_qlen = q_len;
- return IPC_OK;
-
+ return IPC_OK;
}
static int
@@ -1734,7 +1767,7 @@ socket_set_recv_qlen (struct IPC_CHANNEL* ch, int q_len)
if (ch->recv_queue == NULL) {
return IPC_FAIL;
}
-
+ socket_adjust_buf(ch, SO_RCVBUF, q_len);
ch->recv_queue->max_qlen = q_len;
return IPC_OK;
}
diff --git a/lib/clplumbing/ipctransientclient.c b/lib/clplumbing/ipctransientclient.c
index 398fb9c..080acf2 100644
--- a/lib/clplumbing/ipctransientclient.c
+++ b/lib/clplumbing/ipctransientclient.c
@@ -159,11 +159,11 @@ transient_client_callback(IPC_Channel* server, void* private_data)
if(lpc < MAX_MESSAGES && strcmp(messages[lpc], buffer) != 0)
{
- cl_log(LOG_ERR, "[Client] Recieved someone else's message [%s] instead of [%s]", buffer, messages[lpc]);
+ cl_log(LOG_ERR, "[Client] Received someone else's message [%s] instead of [%s]", buffer, messages[lpc]);
}
else if(lpc >= MAX_MESSAGES)
{
- cl_log(LOG_ERR, "[Client] Recieved an extra message [%s]", buffer);
+ cl_log(LOG_ERR, "[Client] Receivedan extra message [%s]", buffer);
}
lpc++;
diff --git a/lib/lrm/.cvsignore b/lib/lrm/.cvsignore
deleted file mode 100644
index cab0d2e..0000000
--- a/lib/lrm/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lib/lrm/clientlib.c b/lib/lrm/clientlib.c
index 3b00883..78dcdc8 100644
--- a/lib/lrm/clientlib.c
+++ b/lib/lrm/clientlib.c
@@ -1597,11 +1597,11 @@ execra_code2string(uniform_ret_execra_t code)
case EXECRA_FAILED_MASTER:
return "master (failed)";
case EXECRA_RA_DEAMON_DEAD1:
- return "status: deamon dead";
+ return "status: daemon dead";
case EXECRA_RA_DEAMON_DEAD2:
- return "status: deamon dead";
+ return "status: daemon dead";
case EXECRA_RA_DEAMON_STOPPED:
- return "status: deamon stopped";
+ return "status: daemon stopped";
case EXECRA_STATUS_UNKNOWN:
return "status: unknown";
default:
diff --git a/lib/lrm/racommon.c b/lib/lrm/racommon.c
index c50566a..2670f05 100644
--- a/lib/lrm/racommon.c
+++ b/lib/lrm/racommon.c
@@ -63,7 +63,13 @@ get_ra_pathname(const char* class_path, const char* type, const char* provider,
}
}else{
/*the type includes path, just copy it to pathname*/
- g_strlcpy(pathname, type, RA_MAX_NAME_LENGTH);
+ if ( *type == '/' ) {
+ g_strlcpy(pathname, type, RA_MAX_NAME_LENGTH);
+ } else {
+ *pathname = '\0';
+ cl_log(LOG_ERR, "%s: relative paths not allowed: %s",
+ __FUNCTION__, type);
+ }
}
g_free(type_dup);
diff --git a/lib/pils/.cvsignore b/lib/pils/.cvsignore
deleted file mode 100644
index 4a512a6..0000000
--- a/lib/pils/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-main
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lib/plugins/lrm/.cvsignore b/lib/plugins/lrm/.cvsignore
deleted file mode 100644
index 3f39ebd..0000000
--- a/lib/plugins/lrm/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-*.loT
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lib/plugins/lrm/Makefile.am b/lib/plugins/lrm/Makefile.am
index cee3624..fd24579 100644
--- a/lib/plugins/lrm/Makefile.am
+++ b/lib/plugins/lrm/Makefile.am
@@ -17,10 +17,17 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in
+if UPSTART
+SUBDIRS = dbus
+endif
+
LRM_DIR = lrm
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \
-I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl
+if UPSTART
+INCLUDES += $(DBUS_CFLAGS)
+endif
halibdir = $(libdir)/@HB_PKG@
havarlibdir = $(localstatedir)/lib/@HB_PKG@
@@ -31,6 +38,10 @@ COMMONLIBS = $(top_builddir)/lib/clplumbing/libplumb.la \
plugindir = $(halibdir)/plugins/RAExec
plugin_LTLIBRARIES = lsb.la ocf.la heartbeat.la
+if UPSTART
+plugin_LTLIBRARIES += upstart.la
+endif
+
lsb_la_SOURCES = raexeclsb.c
lsb_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version
@@ -39,3 +50,9 @@ ocf_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoi
heartbeat_la_SOURCES = raexechb.c
heartbeat_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version
+
+if UPSTART
+upstart_la_SOURCES = raexecupstart.c upstart-dbus.c
+upstart_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version \
+ $(DBUS_LIBS)
+endif
diff --git a/lib/plugins/lrm/dbus/Makefile.am b/lib/plugins/lrm/dbus/Makefile.am
new file mode 100644
index 0000000..ec93436
--- /dev/null
+++ b/lib/plugins/lrm/dbus/Makefile.am
@@ -0,0 +1,16 @@
+if UPSTART
+BINDINGS=Upstart_Instance.h \
+ Upstart_Job.h \
+ Upstart.h
+
+all-local:
+ for header in $(BINDINGS); do \
+ input=com.ubuntu.`echo $$header | sed 's/\.h//' | tr _ .`.xml; \
+ $(DBUS_BINDING_TOOL) --mode=glib-client $$input > $$header; \
+ done
+
+clean-local:
+ rm -f $(BINDINGS)
+
+EXTRA_DIST = *.xml
+endif
diff --git a/lib/plugins/lrm/dbus/com.ubuntu.Upstart.Instance.xml b/lib/plugins/lrm/dbus/com.ubuntu.Upstart.Instance.xml
new file mode 100644
index 0000000..d4f7ab2
--- /dev/null
+++ b/lib/plugins/lrm/dbus/com.ubuntu.Upstart.Instance.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- upstart
+
+ com.ubuntu.Upstart.Instance.xml - interface definition for interface
+ objects
+
+ Copyright © 2009 Canonical Ltd.
+ Author: Scott James Remnant <scott at netsplit.com>.
+
+ This file is free software; Canonical Ltd gives unlimited permission
+ to copy and/or distribute it, with or without modifications, as long
+ as this notice is preserved.
+
+ Communication and interaction with Upstart through this interface is
+ permitted without restriction.
+ -->
+
+<!DOCTYPE node PUBLIC
+ "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node>
+ <interface name="com.ubuntu.Upstart0_6.Instance">
+ <!-- Methods to directly control instances. Unlike the equivalent methods
+ for a Job, these are not permitted to pass or set environment. -->
+ <method name="Start">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="wait" type="b" direction="in" />
+ </method>
+ <method name="Stop">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="wait" type="b" direction="in" />
+ </method>
+ <method name="Restart">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="wait" type="b" direction="in" />
+ </method>
+
+ <!-- Basic information about an Instance -->
+ <property name="name" type="s" access="read" />
+ <property name="goal" type="s" access="read" />
+ <property name="state" type="s" access="read" />
+ <property name="processes" type="a(si)" access="read" />
+ </interface>
+</node>
diff --git a/lib/plugins/lrm/dbus/com.ubuntu.Upstart.Job.xml b/lib/plugins/lrm/dbus/com.ubuntu.Upstart.Job.xml
new file mode 100644
index 0000000..27f47a1
--- /dev/null
+++ b/lib/plugins/lrm/dbus/com.ubuntu.Upstart.Job.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- upstart
+
+ com.ubuntu.Upstart.Job.xml - interface definition for job objects
+
+ Copyright © 2009 Canonical Ltd.
+ Author: Scott James Remnant <scott at netsplit.com>.
+
+ This file is free software; Canonical Ltd gives unlimited permission
+ to copy and/or distribute it, with or without modifications, as long
+ as this notice is preserved.
+
+ Communication and interaction with Upstart through this interface is
+ permitted without restriction.
+ -->
+
+<!DOCTYPE node PUBLIC
+ "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node>
+ <interface name="com.ubuntu.Upstart0_6.Job">
+ <!-- Get object paths for instances, while you can figure these out too,
+ it's still better form to use these -->
+ <method name="GetInstance">
+ <arg name="env" type="as" direction="in" />
+ <arg name="instance" type="o" direction="out" />
+ </method>
+ <method name="GetInstanceByName">
+ <arg name="name" type="s" direction="in" />
+ <arg name="instance" type="o" direction="out" />
+ </method>
+ <method name="GetAllInstances">
+ <arg name="instances" type="ao" direction="out" />
+ </method>
+
+ <!-- Signals for changes to the instance list for a job -->
+ <signal name="InstanceAdded">
+ <arg name="instance" type="o" />
+ </signal>
+ <signal name="InstanceRemoved">
+ <arg name="instance" type="o" />
+ </signal>
+
+ <!-- Job control; the environment arguments are used for both instance
+ selection and for passing environment to the processes of the job. -->
+ <method name="Start">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="env" type="as" direction="in" />
+ <arg name="wait" type="b" direction="in" />
+ <arg name="instance" type="o" direction="out" />
+ </method>
+ <method name="Stop">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="env" type="as" direction="in" />
+ <arg name="wait" type="b" direction="in" />
+ </method>
+ <method name="Restart">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="env" type="as" direction="in" />
+ <arg name="wait" type="b" direction="in" />
+ <arg name="instance" type="o" direction="out" />
+ </method>
+
+ <!-- Basic information about a Job -->
+ <property name="name" type="s" access="read" />
+ <property name="description" type="s" access="read" />
+ <property name="author" type="s" access="read" />
+ <property name="version" type="s" access="read" />
+ </interface>
+</node>
diff --git a/lib/plugins/lrm/dbus/com.ubuntu.Upstart.xml b/lib/plugins/lrm/dbus/com.ubuntu.Upstart.xml
new file mode 100644
index 0000000..a4331cd
--- /dev/null
+++ b/lib/plugins/lrm/dbus/com.ubuntu.Upstart.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- upstart
+
+ com.ubuntu.Upstart.xml - interface definition for manager object
+
+ Copyright © 2009 Canonical Ltd.
+ Author: Scott James Remnant <scott at netsplit.com>.
+
+ This file is free software; Canonical Ltd gives unlimited permission
+ to copy and/or distribute it, with or without modifications, as long
+ as this notice is preserved.
+
+ Communication and interaction with Upstart through this interface is
+ permitted without restriction.
+ -->
+
+<!DOCTYPE node PUBLIC
+ "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node name="/com/ubuntu/Upstart">
+ <interface name="com.ubuntu.Upstart0_6">
+ <!-- Reload all configuration sources -->
+ <method name="ReloadConfiguration">
+ </method>
+
+ <!-- Get object paths for jobs, while you can figure them out, it's
+ better form to use these -->
+ <method name="GetJobByName">
+ <arg name="name" type="s" direction="in" />
+ <arg name="job" type="o" direction="out" />
+ </method>
+ <method name="GetAllJobs">
+ <arg name="jobs" type="ao" direction="out" />
+ </method>
+
+ <!-- Signals for changes to the job list -->
+ <signal name="JobAdded">
+ <arg name="job" type="o" />
+ </signal>
+ <signal name="JobRemoved">
+ <arg name="job" type="o" />
+ </signal>
+
+ <!-- Event emission -->
+ <method name="EmitEvent">
+ <annotation name="com.netsplit.Nih.Method.Async" value="true" />
+ <arg name="name" type="s" direction="in" />
+ <arg name="env" type="as" direction="in" />
+ <arg name="wait" type="b" direction="in" />
+ </method>
+
+ <!-- Basic information about Upstart -->
+ <property name="version" type="s" access="read" />
+ <property name="log_priority" type="s" access="readwrite" />
+ </interface>
+</node>
diff --git a/lib/plugins/lrm/raexeclsb.c b/lib/plugins/lrm/raexeclsb.c
index 5479709..d12b7d5 100644
--- a/lib/plugins/lrm/raexeclsb.c
+++ b/lib/plugins/lrm/raexeclsb.c
@@ -76,7 +76,7 @@
" <action name=\"status\" timeout=\"15\" />\n"\
" <action name=\"restart\" timeout=\"15\" />\n"\
" <action name=\"force-reload\" timeout=\"15\" />\n"\
-" <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n"\
+" <action name=\"monitor\" timeout=\"15\" interval=\"15\" />\n"\
" <action name=\"meta-data\" timeout=\"5\" />\n"\
" </actions>\n"\
" <special tag=\"LSB\">\n"\
diff --git a/lib/plugins/lrm/raexecupstart.c b/lib/plugins/lrm/raexecupstart.c
new file mode 100644
index 0000000..36f97c7
--- /dev/null
+++ b/lib/plugins/lrm/raexecupstart.c
@@ -0,0 +1,222 @@
+/*
+ * 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
+ *
+ * File: raexecupstart.c
+ * Copyright (C) 2010 Senko Rasic <senko.rasic at dobarkod.hr>
+ * Copyright (c) 2010 Ante Karamatic <ivoks at init.hr>
+ *
+ * Heavily based on raexeclsb.c and raexechb.c:
+ * Author: Sun Jiang Dong <sunjd at cn.ibm.com>
+ * Copyright (c) 2004 International Business Machines
+ *
+ * This code implements the Resource Agent Plugin Module for Upstart.
+ * It's a part of Local Resource Manager. Currently it's used by lrmd only.
+ */
+
+#define PIL_PLUGINTYPE RA_EXEC_TYPE
+#define PIL_PLUGIN upstart
+#define PIL_PLUGINTYPE_S "RAExec"
+#define PIL_PLUGIN_S "upstart"
+#define PIL_PLUGINLICENSE LICENSE_PUBDOM
+#define PIL_PLUGINLICENSEURL URL_PUBDOM
+
+#include <lha_internal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <dirent.h>
+#include <libgen.h> /* Add it for compiling on OSX */
+#include <glib.h>
+#include <clplumbing/cl_log.h>
+#include <pils/plugin.h>
+#include <lrm/raexec.h>
+#include <libgen.h>
+
+#include <glib-object.h>
+
+#include <libxml/entities.h>
+
+#include "upstart-dbus.h"
+
+#define meta_data_template \
+"<?xml version=\"1.0\"?>\n"\
+"<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"\
+"<resource-agent name=\"%s\" version=\"0.1\">\n"\
+" <version>1.0</version>\n"\
+" <longdesc lang=\"en\">\n"\
+" %s"\
+" </longdesc>\n"\
+" <shortdesc lang=\"en\">%s</shortdesc>\n"\
+" <parameters>\n"\
+" </parameters>\n"\
+" <actions>\n"\
+" <action name=\"start\" timeout=\"15\" />\n"\
+" <action name=\"stop\" timeout=\"15\" />\n"\
+" <action name=\"status\" timeout=\"15\" />\n"\
+" <action name=\"restart\" timeout=\"15\" />\n"\
+" <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n"\
+" <action name=\"meta-data\" timeout=\"5\" />\n"\
+" </actions>\n"\
+" <special tag=\"upstart\">\n"\
+" </special>\n"\
+"</resource-agent>\n"
+
+/* The begin of exported function list */
+static int execra(const char * rsc_id,
+ const char * rsc_type,
+ const char * provider,
+ const char * op_type,
+ const int timeout,
+ GHashTable * params);
+
+static uniform_ret_execra_t map_ra_retvalue(int ret_execra
+ , const char * op_type, const char * std_output);
+static char* get_resource_meta(const char* rsc_type, const char* provider);
+static int get_resource_list(GList ** rsc_info);
+static int get_provider_list(const char* ra_type, GList ** providers);
+
+/* The end of exported function list */
+
+/* The begin of internal used function & data list */
+#define MAX_PARAMETER_NUM 40
+
+const int MAX_LENGTH_OF_RSCNAME = 40,
+ MAX_LENGTH_OF_OPNAME = 40;
+
+typedef char * RA_ARGV[MAX_PARAMETER_NUM];
+
+/* The end of internal function & data list */
+
+/* Rource agent execution plugin operations */
+static struct RAExecOps raops =
+{ execra,
+ map_ra_retvalue,
+ get_resource_list,
+ get_provider_list,
+ get_resource_meta
+};
+
+PIL_PLUGIN_BOILERPLATE2("1.0", Debug)
+
+static const PILPluginImports* PluginImports;
+static PILPlugin* OurPlugin;
+static PILInterface* OurInterface;
+static void* OurImports;
+static void* interfprivate;
+
+PIL_rc
+PIL_PLUGIN_INIT(PILPlugin * us, const PILPluginImports* imports);
+
+PIL_rc
+PIL_PLUGIN_INIT(PILPlugin * us, const PILPluginImports* imports)
+{
+ PluginImports = imports;
+ OurPlugin = us;
+
+ imports->register_plugin(us, &OurPIExports);
+
+ g_type_init ();
+
+ return imports->register_interface(us, PIL_PLUGINTYPE_S, PIL_PLUGIN_S,
+ &raops, NULL, &OurInterface, &OurImports,
+ interfprivate);
+}
+
+static int
+execra( const char * rsc_id, const char * rsc_type, const char * provider,
+ const char * op_type, const int timeout, GHashTable * params)
+{
+ UpstartJobCommand cmd;
+
+ if (!g_strcmp0(op_type, "meta-data")) {
+ printf("%s", get_resource_meta(rsc_type, provider));
+ exit(EXECRA_OK);
+ } else if (!g_strcmp0(op_type, "monitor") || !g_strcmp0(op_type, "status")) {
+ gboolean running = upstart_job_is_running (rsc_type);
+ printf("%s", running ? "running" : "stopped");
+
+ if (running)
+ exit(EXECRA_OK);
+ else
+ exit(EXECRA_NOT_RUNNING);
+ } else if (!g_strcmp0(op_type, "start")) {
+ cmd = UPSTART_JOB_START;
+ } else if (!g_strcmp0(op_type, "stop")) {
+ cmd = UPSTART_JOB_STOP;
+ } else if (!g_strcmp0(op_type, "restart")) {
+ cmd = UPSTART_JOB_RESTART;
+ } else {
+ exit(EXECRA_UNIMPLEMENT_FEATURE);
+ }
+
+ /* It'd be better if it returned GError, so we can distinguish
+ * between failure modes (can't contact upstart, no such job,
+ * or failure to do action. */
+ if (upstart_job_do(rsc_type, cmd)) {
+ exit(EXECRA_OK);
+ } else {
+ exit(EXECRA_NO_RA);
+ }
+}
+
+static uniform_ret_execra_t
+map_ra_retvalue(int ret_execra, const char * op_type, const char * std_output)
+{
+ /* no need to map anything, execra() returns correct exit code */
+ return ret_execra;
+}
+
+static int
+get_resource_list(GList ** rsc_info)
+{
+ gchar **jobs;
+ gint i;
+ *rsc_info = NULL;
+
+ jobs = upstart_get_all_jobs();
+
+ if (!jobs)
+ return 0;
+
+ for (i = 0; jobs[i] != NULL; i++) {
+ *rsc_info = g_list_prepend(*rsc_info, jobs[i]);
+ }
+
+ /* free the array, but not the strings */
+ g_free(jobs);
+
+ *rsc_info = g_list_reverse(*rsc_info);
+ return g_list_length(*rsc_info);
+}
+
+static char *
+get_resource_meta (const gchar *rsc_type, const gchar *provider)
+{
+ return g_strdup_printf(meta_data_template, rsc_type,
+ rsc_type, rsc_type);
+}
+
+static int
+get_provider_list (const gchar *ra_type, GList **providers)
+{
+ *providers = g_list_prepend(*providers, g_strdup("upstart"));
+ return g_list_length(*providers);
+}
+
diff --git a/lib/plugins/lrm/upstart-dbus.c b/lib/plugins/lrm/upstart-dbus.c
new file mode 100644
index 0000000..d308c0e
--- /dev/null
+++ b/lib/plugins/lrm/upstart-dbus.c
@@ -0,0 +1,403 @@
+/*
+ * 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
+ *
+ * File: upstart-dbus.c
+ * Copyright (C) 2010 Senko Rasic <senko.rasic at dobarkod.hr>
+ * Copyright (c) 2010 Ante Karamatic <ivoks at init.hr>
+ *
+ *
+ * Each exported function is standalone, and creates a new connection to
+ * the upstart daemon. This is because lrmd plugins fork off for exec,
+ * and if we try and share the connection, the whole thing blocks
+ * indefinitely.
+ */
+
+#include "upstart-dbus.h"
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include <dbus/dbus.h>
+
+#include "dbus/Upstart.h"
+#include "dbus/Upstart_Job.h"
+#include "dbus/Upstart_Instance.h"
+
+#include <stdio.h>
+
+#define SYSTEM_BUS_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
+#define UPSTART_BUS_ADDRESS "unix:abstract=/com/ubuntu/upstart"
+#define UPSTART_SERVICE_NAME "com.ubuntu.Upstart"
+#define UPSTART_MANAGER_PATH "/com/ubuntu/Upstart"
+#define UPSTART_IFACE "com.ubuntu.Upstart0_6"
+#define UPSTART_JOB_IFACE UPSTART_IFACE ".Job"
+#define UPSTART_INSTANCE_IFACE UPSTART_IFACE ".Instance"
+#define UPSTART_ERROR_ALREADY_STARTED UPSTART_IFACE ".Error.AlreadyStarted"
+#define UPSTART_ERROR_UNKNOWN_INSTANCE UPSTART_IFACE ".Error.UnknownInstance"
+
+static DBusGConnection *
+get_connection(void)
+{
+ GError *error = NULL;
+ DBusGConnection *conn;
+
+ conn = dbus_g_bus_get_private(DBUS_BUS_SYSTEM, NULL, &error);
+
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+
+ conn = dbus_g_connection_open("unix:abstract=/com/ubuntu/upstart",
+ &error);
+
+ if (error)
+ {
+ g_warning("Can't connect to either system or Upstart "
+ "DBus bus.");
+ g_error_free(error);
+
+ return NULL;
+ }
+ }
+
+ return conn;
+}
+
+static DBusGProxy *
+new_proxy(DBusGConnection *conn, const gchar *object_path,
+ const gchar *iface)
+{
+ return dbus_g_proxy_new_for_name(conn,
+ UPSTART_SERVICE_NAME,
+ object_path,
+ iface);
+}
+
+static GHashTable *
+get_object_properties(DBusGProxy *obj, const gchar *iface)
+{
+ GError *error = NULL;
+ DBusGProxy *proxy;
+ GHashTable *asv;
+ GHashTable *retval;
+ GHashTableIter iter;
+ gpointer k, v;
+
+ proxy = dbus_g_proxy_new_from_proxy(obj,
+ DBUS_INTERFACE_PROPERTIES, NULL);
+
+ dbus_g_proxy_call(proxy, "GetAll", &error, G_TYPE_STRING,
+ iface, G_TYPE_INVALID,
+ dbus_g_type_get_map("GHashTable",
+ G_TYPE_STRING,
+ G_TYPE_VALUE),
+ &asv, G_TYPE_INVALID);
+
+ if (error) {
+ g_warning("Error getting %s properties: %s", iface, error->message);
+ g_error_free(error);
+ g_object_unref(proxy);
+ return NULL;
+ }
+
+ retval = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ g_hash_table_iter_init(&iter, asv);
+ while (g_hash_table_iter_next(&iter, &k, &v)) {
+ gchar *key = k;
+ GValue *val = v;
+
+ /* all known properties are strings */
+ if (G_VALUE_TYPE(val) == G_TYPE_STRING) {
+ g_hash_table_insert(retval, g_strdup(key),
+ g_value_dup_string(val));
+ }
+ }
+
+ g_hash_table_destroy(asv);
+
+ return retval;
+}
+
+gchar **
+upstart_get_all_jobs(void)
+{
+ DBusGConnection *conn;
+ DBusGProxy *manager;
+ GError *error = NULL;
+ GPtrArray *array;
+ gchar **retval = NULL;
+ gint i, j;
+
+ conn = get_connection();
+ if (!conn)
+ return NULL;
+
+ manager = new_proxy(conn, UPSTART_MANAGER_PATH, UPSTART_IFACE);
+
+ dbus_g_proxy_call(manager, "GetAllJobs", &error, G_TYPE_INVALID,
+ dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+ &array, G_TYPE_INVALID);
+
+ if (error)
+ {
+ g_warning("Can't call GetAllJobs: %s", error->message);
+ g_error_free(error);
+ g_object_unref(manager);
+ dbus_g_connection_unref(conn);
+ return NULL;
+ }
+
+ retval = g_new0(gchar *, array->len + 1);
+
+ for (i = 0, j = 0; i < array->len; i++)
+ {
+ DBusGProxy *job;
+
+ job = new_proxy(conn, g_ptr_array_index(array, i),
+ UPSTART_JOB_IFACE);
+
+ if (job) {
+ GHashTable *props = get_object_properties(job,
+ UPSTART_JOB_IFACE);
+
+ if (props) {
+ gchar *name = g_hash_table_lookup(props,
+ "name");
+
+ if (name)
+ retval[j++] = g_strdup(name);
+
+ g_hash_table_destroy(props);
+ }
+
+ g_object_unref(job);
+ }
+ }
+
+ g_ptr_array_free(array, TRUE);
+
+ g_object_unref(manager);
+ dbus_g_connection_unref(conn);
+
+ return retval;
+}
+
+static DBusGProxy *
+upstart_get_job_by_name(DBusGConnection *conn, DBusGProxy *manager,
+ const gchar *name)
+{
+ GError *error = NULL;
+ gchar *object_path;
+ DBusGProxy *retval;
+
+ dbus_g_proxy_call(manager, "GetJobByName", &error, G_TYPE_STRING,
+ name, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &object_path,
+ G_TYPE_INVALID);
+
+ if (error)
+ {
+ g_warning("Error calling GetJobByName: %s", error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ retval = new_proxy(conn, object_path, UPSTART_JOB_IFACE);
+
+ g_free(object_path);
+
+ return retval;
+}
+
+static gchar **
+get_job_instances(DBusGProxy *job)
+{
+ GError *error = NULL;
+ GPtrArray *array;
+ gchar **retval;
+ gint i;
+
+ dbus_g_proxy_call(job, "GetAllInstances", &error, G_TYPE_INVALID,
+ dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+ &array, G_TYPE_INVALID);
+
+ if (error)
+ {
+ g_warning("Can't call GetAllInstances: %s", error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ retval = g_new0(gchar *, array->len + 1);
+
+ for (i = 0; i < array->len; i++)
+ {
+ retval[i] = g_ptr_array_index(array, i);
+ }
+
+ g_ptr_array_free(array, TRUE);
+
+ return retval;
+}
+
+static DBusGProxy *
+get_first_instance(DBusGConnection *conn, DBusGProxy *job)
+{
+ gchar **instances;
+ DBusGProxy *instance = NULL;
+
+ instances = get_job_instances(job);
+
+ if (!instances)
+ return NULL;
+
+ if (*instances)
+ {
+ instance = new_proxy(conn, instances[0],
+ UPSTART_INSTANCE_IFACE);
+ }
+
+ g_strfreev(instances);
+ return instance;
+}
+
+gboolean
+upstart_job_is_running(const gchar *name)
+{
+ DBusGConnection *conn;
+ DBusGProxy *manager;
+ DBusGProxy *job;
+ gboolean retval = FALSE;
+
+ conn = get_connection();
+ if (!conn)
+ return FALSE;
+
+ manager = new_proxy(conn, UPSTART_MANAGER_PATH, UPSTART_IFACE);
+
+ job = upstart_get_job_by_name(conn, manager, name);
+ if (job) {
+ DBusGProxy *instance = get_first_instance(conn, job);
+
+ if (instance) {
+ GHashTable *props = get_object_properties(instance,
+ UPSTART_INSTANCE_IFACE);
+
+ if (props) {
+ const gchar *state = g_hash_table_lookup(props,
+ "state");
+
+ retval = !g_strcmp0(state, "running");
+
+ g_hash_table_destroy(props);
+ }
+
+ g_object_unref(instance);
+ }
+
+ g_object_unref(job);
+ }
+
+ g_object_unref(manager);
+ dbus_g_connection_unref(conn);
+
+ return retval;
+}
+
+gboolean
+upstart_job_do(const gchar *name, UpstartJobCommand cmd)
+{
+ DBusGConnection *conn;
+ DBusGProxy *manager;
+ DBusGProxy *job;
+ gboolean retval;
+
+ conn = get_connection();
+ if (!conn)
+ return FALSE;
+
+ manager = new_proxy(conn, UPSTART_MANAGER_PATH, UPSTART_IFACE);
+
+ job = upstart_get_job_by_name(conn, manager, name);
+ if (job) {
+ GError *error = NULL;
+ const gchar *cmd_name = NULL;
+ gchar *instance_path = NULL;
+ gchar *no_args[] = { NULL };
+
+ switch (cmd) {
+ case UPSTART_JOB_START:
+ cmd_name = "Start";
+ dbus_g_proxy_call (job, cmd_name, &error,
+ G_TYPE_STRV, no_args,
+ G_TYPE_BOOLEAN, TRUE,
+ G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &instance_path,
+ G_TYPE_INVALID);
+ g_free (instance_path);
+ break;
+ case UPSTART_JOB_STOP:
+ cmd_name = "Stop";
+ dbus_g_proxy_call(job, cmd_name, &error,
+ G_TYPE_STRV, no_args,
+ G_TYPE_BOOLEAN, TRUE,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ break;
+ case UPSTART_JOB_RESTART:
+ cmd_name = "Restart";
+ dbus_g_proxy_call (job, cmd_name, &error,
+ G_TYPE_STRV, no_args,
+ G_TYPE_BOOLEAN, TRUE,
+ G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &instance_path,
+ G_TYPE_INVALID);
+ g_free (instance_path);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (error) {
+ g_warning("Could not issue %s: %s", cmd_name,
+ error->message);
+
+ /* ignore "already started" or "not running" errors */
+ if (dbus_g_error_has_name(error,
+ UPSTART_ERROR_ALREADY_STARTED) ||
+ dbus_g_error_has_name(error,
+ UPSTART_ERROR_UNKNOWN_INSTANCE)) {
+ retval = TRUE;
+ } else {
+ retval = FALSE;
+ }
+ g_error_free(error);
+ } else {
+ retval = TRUE;
+ }
+
+ g_object_unref(job);
+ } else {
+ retval = FALSE;
+ }
+
+ g_object_unref(manager);
+ dbus_g_connection_unref(conn);
+ return retval;
+}
+
+
diff --git a/lib/plugins/lrm/upstart-dbus.h b/lib/plugins/lrm/upstart-dbus.h
new file mode 100644
index 0000000..d9932ec
--- /dev/null
+++ b/lib/plugins/lrm/upstart-dbus.h
@@ -0,0 +1,36 @@
+/*
+ * 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
+ *
+ * File: upstart-dbus.c
+ * Copyright (C) 2010 Senko Rasic <senko.rasic at dobarkod.hr>
+ * Copyright (c) 2010 Ante Karamatic <ivoks at init.hr>
+ */
+#ifndef _UPSTART_DBUS_H_
+#define _UPSTART_DBUS_H_
+
+#include <glib.h>
+
+typedef enum {
+ UPSTART_JOB_START,
+ UPSTART_JOB_STOP,
+ UPSTART_JOB_RESTART
+} UpstartJobCommand;
+
+G_GNUC_INTERNAL gchar **upstart_get_all_jobs(void);
+G_GNUC_INTERNAL gboolean upstart_job_do(const gchar *name, UpstartJobCommand cmd);
+G_GNUC_INTERNAL gboolean upstart_job_is_running (const gchar *name);
+
+#endif /* _UPSTART_DBUS_H_ */
+
diff --git a/lib/plugins/stonith/.cvsignore b/lib/plugins/stonith/.cvsignore
deleted file mode 100644
index 9734616..0000000
--- a/lib/plugins/stonith/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-*.beam
-parser-messages
-MISC_ERRORS
-ribcl.py
diff --git a/lib/plugins/stonith/cyclades.c b/lib/plugins/stonith/cyclades.c
index f8c0431..e765b82 100644
--- a/lib/plugins/stonith/cyclades.c
+++ b/lib/plugins/stonith/cyclades.c
@@ -155,10 +155,27 @@ static const char * NOTpluginID = "Cyclades device has been destroyed";
#include "stonith_config_xml.h"
+#define XML_SERIALPORT_SHORTDESC \
+ XML_PARM_SHORTDESC_BEGIN("en") \
+ ST_SERIALPORT \
+ XML_PARM_SHORTDESC_END
+
+#define XML_SERIALPORT_LONGDESC \
+ XML_PARM_LONGDESC_BEGIN("en") \
+ "The serial port of the IPDU which can powercycle the node" \
+ XML_PARM_LONGDESC_END
+
+#define XML_SERIALPORT_PARM \
+ XML_PARAMETER_BEGIN(ST_SERIALPORT, "string", "1") \
+ XML_SERIALPORT_SHORTDESC \
+ XML_SERIALPORT_LONGDESC \
+ XML_PARAMETER_END
+
static const char *cycladesXML =
XML_PARAMETERS_BEGIN
XML_IPADDR_PARM
XML_LOGIN_PARM
+ XML_SERIALPORT_PARM
XML_PARAMETERS_END;
static int
diff --git a/lib/plugins/stonith/external.c b/lib/plugins/stonith/external.c
index 723205f..13557c2 100644
--- a/lib/plugins/stonith/external.c
+++ b/lib/plugins/stonith/external.c
@@ -415,7 +415,7 @@ external_set_config(StonithPlugin* s, StonithNVpair *list)
for (p = sd->confignames; *p; p++) {
if (OurImports->GetValue(list, *p) == NULL) {
- LOG(PIL_INFO, "Cannot get parameter %s from "
+ LOG(PIL_DEBUG, "Cannot get parameter %s from "
"StonithNVpair", *p);
}
}
@@ -702,7 +702,7 @@ external_run_cmd(struct pluginDevice *sd, const char *op, char **output)
const int BUFF_LEN=4096;
char buff[BUFF_LEN];
int read_len = 0;
- int rc;
+ int status, rc;
char * data = NULL;
FILE * file;
char cmd[FILENAME_MAX+64];
@@ -811,9 +811,25 @@ external_run_cmd(struct pluginDevice *sd, const char *op, char **output)
goto out;
}
- rc = pclose(file);
- if (rc != 0) {
- LOG(PIL_INFO, "%s: Calling '%s' returned %d", __FUNCTION__, cmd, rc);
+ status = pclose(file);
+ if (WIFEXITED(status)) {
+ rc = WEXITSTATUS(status);
+ if (rc != 0) {
+ LOG(PIL_CRIT,
+ "%s: Calling '%s' returned %d", __FUNCTION__, cmd, rc);
+ }
+ } else {
+ if (WIFSIGNALED(status)) {
+ LOG(PIL_CRIT, "%s: '%s' got signal %d",
+ __FUNCTION__, cmd, WTERMSIG(status));
+ } else if (WIFSTOPPED(status)) {
+ LOG(PIL_INFO, "%s: '%s' stopped with signal %d",
+ __FUNCTION__, cmd, WSTOPSIG(status));
+ } else {
+ LOG(PIL_CRIT, "%s: '%s' exited abnormally (core dumped?)",
+ __FUNCTION__, cmd);
+ }
+ rc = -1;
}
if (Debug && output && data) {
LOG(PIL_DEBUG, "%s: '%s' output: %s", __FUNCTION__, cmd, data);
diff --git a/lib/plugins/stonith/external/.cvsignore b/lib/plugins/stonith/external/.cvsignore
deleted file mode 100644
index 25d4a27..0000000
--- a/lib/plugins/stonith/external/.cvsignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-Makefile.in
-ibmrsa
-riloe
-ssh
diff --git a/lib/plugins/stonith/external/Makefile.am b/lib/plugins/stonith/external/Makefile.am
index 363a860..0ca1440 100644
--- a/lib/plugins/stonith/external/Makefile.am
+++ b/lib/plugins/stonith/external/Makefile.am
@@ -20,13 +20,13 @@
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = drac5 dracmc-telnet ibmrsa-telnet ipmi rackpdu vmware xen0 \
- xen0-ha-dom0-stonith-helper sbd kdumpcheck
+ xen0-ha-dom0-stonith-helper sbd kdumpcheck nut
extdir = $(stonith_ext_plugindir)
helperdir = $(stonith_plugindir)
ext_SCRIPTS = drac5 dracmc-telnet ibmrsa ibmrsa-telnet ipmi riloe ssh vmware rackpdu xen0 hmchttp \
- xen0-ha sbd kdumpcheck ippower9258
+ xen0-ha sbd kdumpcheck ippower9258 nut
helper_SCRIPTS = xen0-ha-dom0-stonith-helper
diff --git a/lib/plugins/stonith/external/ipmi b/lib/plugins/stonith/external/ipmi
index 10cafd7..53b5a9b 100644
--- a/lib/plugins/stonith/external/ipmi
+++ b/lib/plugins/stonith/external/ipmi
@@ -60,9 +60,30 @@ run_ipmitool() {
interface="lan"
fi
+ case "${passwd_method}" in
+ param|'')
+ passwd_method=param
+ M="-P"
+ ;;
+ env)
+ M="-E"
+ ;;
+ file)
+ M="-f"
+ ;;
+ *)
+ ha_log.sh err "invalid passwd_method: \"${passwd_method}\""
+ return 1
+ esac
+
action="$*"
- ${IPMITOOL} -I ${interface} -H ${ipaddr} -U "${userid}" -P "${passwd}" ${action} 2>&1
+ if [ $passwd_method = env ]
+ then
+ IPMI_PASSWORD="${passwd}" ${IPMITOOL} -I ${interface} -H ${ipaddr} -U "${userid}" -E ${action} 2>&1
+ else
+ ${IPMITOOL} -I ${interface} -H ${ipaddr} -U "${userid}" $M "${passwd}" ${action} 2>&1
+ fi
}
# Yet another convenience wrapper that invokes run_ipmitool, captures
@@ -94,7 +115,6 @@ ipmi_is_power_on() {
esac
}
-
# Rewrite the hostname to accept "," as a delimeter for hostnames too.
case ${1} in
@@ -195,6 +215,19 @@ The password used for logging in to the STONITH device.
</longdesc>
</parameter>
+<parameter name="passwd_method" unique="1">
+<content type="string" default="param"/>
+<shortdesc lang="en">
+Method for passing passwd parameter
+</shortdesc>
+<longdesc lang="en">
+Method for passing the passwd parameter to ipmitool
+ param: pass as parameter (-P)
+ env: pass via environment (-E)
+ file: value of "passwd" is actually a file name, pass with (-f)
+</longdesc>
+</parameter>
+
<parameter name="interface" unique="1">
<content type="string" default="lan"/>
<shortdesc lang="en">
diff --git a/lib/plugins/stonith/external/nut b/lib/plugins/stonith/external/nut
new file mode 100644
index 0000000..9e51bb8
--- /dev/null
+++ b/lib/plugins/stonith/external/nut
@@ -0,0 +1,302 @@
+#!/bin/sh
+
+# External STONITH module that uses the NUT daemon to control an external UPS.
+# See the comments below, and the various NUT man pages, for how this
+# script works. It should work unchanged with most modern "smart" APC UPSes in
+# a Redhat/Fedora/RHEL-style distribution with the nut package installed.
+
+# Author: William Seligman <seligman at nevis.columbia.edu>
+# License: GPLv2
+
+# As you're designing your UPS and STONITH set-up, it may help to consider that
+# there can be potentially three computers involved:
+# 1) the machine running this STONITH module;
+# 2) the machine being controlled by this STONITH module ($hostname);
+# 3) the machine that can send commands to the UPS.
+
+# On my cluster, all the UPSes have SNMP smartcards, so every host can communicate
+# with every UPS; in other words, machines (1) and (3) are the same. If your UPSes
+# are controlled via serial or USB connections, then you might have a
+# situation in which $hostname is plugged into a UPS, which has a serial connection
+# to some master "power-control" computer, and can potentially be STONITHed
+# by any other machine in your cluster.
+
+# In general, you'll probably need the nut daemon running on both the hosts (1) and
+# (3) in the above list. The NUT daemon will also have to run on (2) if you want the
+# reset command to gracefully reboot $hostname.
+
+# The NUT command default locations. In the RHEL-type nut packages, these binaries
+# are in /usr/bin.
+RHELUPSCMD="/usr/bin/upscmd"
+RHELUPSC="/usr/bin/upsc"
+
+# Defaults for APC smart UPSes:
+
+# Reset = reboot $hostname; this will be a graceful reboot if the host
+# is running NUT and monitoring $ups.
+APCRESET="shutdown.return"
+
+# Poweroff = turn off $hostname immediately by cutting the power on $ups.
+# For a graceful shutdown, use shutdown.stayoff instead of load.off,
+# but it might take a few minutes to shutdown in this way.
+APCPOWEROFF="load.off"
+
+# Poweron = turn on the power to $ups, which will presumably turn on $hostname.
+# (Did you set $hostname's BIOS to boot up on AC power restore, as opposed to
+# "last state"?)
+APCPOWERON="load.on"
+
+# Status = returns a short string with the $ups status; OL = on-line, OFF = off-line, etc.
+APCSTATUSVAR="ups.status"
+
+
+# Stick in the defaults, if needed.
+if [ -z "${poweron}" ]; then
+ poweron=${APCPOWERON}
+fi
+if [ -z "${poweroff}" ]; then
+ poweroff=${APCPOWEROFF}
+fi
+if [ -z "${reset}" ]; then
+ reset=${APCRESET}
+fi
+if [ -z "${statusvar}" ]; then
+ statusvar=${APCSTATUSVAR}
+fi
+if [ -z "${upscmd}" ]; then
+ upscmd=${RHELUPSCMD}
+fi
+if [ -z "${upsc}" ]; then
+ upsc=${RHELUPSC}
+fi
+
+
+# Define the command to fetch the UPS status.
+STATUSCMD="${upsc} ${ups} ${statusvar}"
+
+usage() {
+ echo "Usage: $0 {on|off|reset|status|gethosts|getconfignames|getinfo-devid|getinfo-devname|getinfo-devdescr|getinfo-devurl|getinfo-xml}"
+}
+
+# Can we find the NUT binary?
+have_nut() {
+ test -x "${upscmd}"
+}
+have_upsc() {
+ test -x "${upsc}"
+}
+
+do_nut() {
+ have_nut || {
+ echo "Can't find NUT upscmd command"
+ return 1
+ }
+ if [ -z "${username}" -o -z "${password}" -o -z "${ups}" ]; then
+ echo "username, password or ups name missing; check configuration"
+ return 1
+ fi
+ # Execute the command given in argument 1.
+ ${upscmd} -u ${username} -p ${password} ${ups} ${1} || {
+ echo "error executing nut command"
+ return 1
+ }
+}
+
+case ${1} in
+gethosts)
+ echo ${hostname}
+ exit 0
+ ;;
+on)
+ result=1
+ do_nut "${poweron}"
+ result=$?
+ exit ${result}
+ ;;
+off)
+ result=1
+ do_nut "${poweroff}"
+ result=$?
+ exit ${result}
+ ;;
+reset)
+ result=1
+ do_nut "${reset}"
+ result=$?
+ exit $result
+ ;;
+status)
+ have_upsc || {
+ echo "Can't find NUT upsc command"
+ exit 1
+ }
+ ${STATUSCMD}
+ exit $?
+ ;;
+getconfignames)
+ echo "hostname ups username password poweron poweroff reset statusvar upscmd upsc"
+ exit 0
+ ;;
+getinfo-devid)
+ echo "NUT STONITH device"
+ exit 0
+ ;;
+getinfo-devname)
+ echo "NUT STONITH external device"
+ exit 0
+ ;;
+getinfo-devdescr)
+ echo "A STONITH device based on NUT (Network UPS Tools)."
+ echo " "
+ echo "For this STONITH script to work, the following conditions have"
+ echo "to be met:"
+ echo " "
+ echo "- NUT has to be installed on both the host running this script"
+ echo " and the host that controls the UPS (on RHEL systems, NUT is"
+ echo " in packages nut and nut-client) and the nut daemon services"
+ echo " (normally called the ups or upsd service) must be running"
+ echo " on both systems."
+ echo " "
+ echo "- The UPS name has to be defined in ups.conf on the host"
+ echo " that controls the UPS."
+ echo " "
+ echo "- The username/password to access the UPS must be defined in"
+ echo " upsd.users on the host that controls the UPS, with the instcmds"
+ echo " for poweron, poweroff, and reset allowed."
+ echo " "
+ echo "- The host that is running this script must be allowed access"
+ echo " via upsd.conf and upsd.users on the host the controls the UPS."
+ echo " "
+ echo "On RHEL systems, the files listed above are in /etc/ups."
+ echo " "
+ echo "The defaults will probably work with APC UPS devices. It might"
+ echo "work on others; 'upscmd -l (ups)' and 'upsc (ups)' will list"
+ echo "the commands and variables, and you can change the values"
+ echo "for poweron, poweroff, reset, and statusvar to suit your UPS."
+ echo "Change upscmd and upsc if your NUT binaries are not in /usr/bin."
+ exit 0
+ ;;
+getinfo-devurl)
+ echo "http://www.networkupstools.org/"
+ exit 0
+ ;;
+getinfo-xml)
+cat << nutXML
+<parameters>
+
+<parameter name="hostname" unique="1" required="1">
+<content type="string" default="" />
+<shortdesc lang="en">Hostname</shortdesc>
+<longdesc lang="en">
+The name of the host to be managed by this STONITH device.
+The nut daemon must be running on the host controllng the
+UPS _and_ on the host running this script; this script does
+not start/stop the daemons for you.
+</longdesc>
+</parameter>
+
+<parameter name="ups" required="1">
+<content type="string" default="" />
+<shortdesc lang="en">UPS name</shortdesc>
+<longdesc lang="en">
+The name of the UPS as defined in ups.conf on the host
+controlling the UPS. The format for this option is
+upsname[@controlhost[:port]]. The default controlhost is
+"localhost".
+</longdesc>
+</parameter>
+
+<parameter name="username" required="1">
+<content type="string" default="" />
+<shortdesc lang="en">Username</shortdesc>
+<longdesc lang="en">
+The username used for accessing the UPS. This is defined in
+upsd.conf on the host controlling the UPS.
+</longdesc>
+</parameter>
+
+<parameter name="password" required="1">
+<content type="string" default="" />
+<shortdesc lang="en">Password</shortdesc>
+<longdesc lang="en">
+The password used for logging in to the UPS for the host
+controlling the UPS, as defined in upsd.conf on that host.
+</longdesc>
+</parameter>
+
+<parameter name="poweron">
+<content type="string" default="$APCPOWERON" />
+<shortdesc lang="en">UPS Power On command</shortdesc>
+<longdesc lang="en">
+The NUT hardware command to turn on the UPS. The default
+should work for most "smart" APC UPSes. For a list of
+commands that your UPS can support, type 'upscmd -l (ups)'
+on the command line.</longdesc>
+</parameter>
+
+<parameter name="poweroff">
+<content type="string" default="$APCPOWEROFF" />
+<shortdesc lang="en">UPS Power Off command</shortdesc>
+<longdesc lang="en">
+The NUT hardware command to turn off the UPS. On most APC
+"smart" UPSes, the command shutdown.stayoff will result
+in a graceful shutdown, provided the host is running the
+nut daemon, but this might take a few minutes; load.off
+will cut the power immediately. For a list of commands that
+your UPS can support, type 'upscmd -l (ups)' on the command
+line.
+</longdesc>
+</parameter>
+
+<parameter name="reset">
+<content type="string" default="$APCRESET" />
+<shortdesc lang="en">UPS Reset command</shortdesc>
+<longdesc lang="en">
+The NUT hardware command to reset the host. On most APC
+"smart" UPSes, the command shutdown.return will result
+in a graceful shutdown, with power restored after perhaps
+a short interval. For a list of commands that your UPS can
+ support, type 'upscmd -l (ups)' on the command line.
+</longdesc>
+</parameter>
+
+<parameter name="statusvar">
+<content type="string" default="$APCSTATUSVAR" />
+<shortdesc lang="en">UPS Status variable</shortdesc>
+<longdesc lang="en">
+The NUT variable that returns the status of the UPS. On APC
+UPSes, the value of ups.status will be "OL" if the UPS is
+"on-line." For a list of variables that your UPS supports,
+type 'upsc (ups)' on the command line.
+</longdesc>
+</parameter>
+
+<parameter name="upscmd">
+<content type="string" default="$RHELUPSCMD" />
+<shortdesc lang="en">upscmd binary location</shortdesc>
+<longdesc lang="en">
+The full path to the NUT binary command 'upscmd'. On RHEL
+systems with the nut RPM installed, this location is
+/usr/bin/upscmd.
+</longdesc>
+</parameter>
+
+<parameter name="upsc">
+<content type="string" default="$RHELUPSC" />
+<shortdesc lang="en">upsc binary location</shortdesc>
+<longdesc lang="en">
+The full path to the NUT binary command 'upsc'. On RHEL
+systems with the nut RPM installed, this location is
+/usr/bin/upsc.
+</longdesc>
+</parameter>
+
+</parameters>
+nutXML
+exit 0
+;;
+*)
+ usage
+ exit 1
+ ;;
+esac
diff --git a/lib/plugins/stonith/external/riloe b/lib/plugins/stonith/external/riloe
index 9a649a9..ce98847 100644
--- a/lib/plugins/stonith/external/riloe
+++ b/lib/plugins/stonith/external/riloe
@@ -14,6 +14,9 @@
# Rewritten by Dejan Muhamedagic <dejan at suse.de>
# Now, the plugin actually reads replies from iLO.
#
+# Extended by Jochen Roeder <jochen.roeder at novell.com>
+# to enable access via proxies
+#
# 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
@@ -33,7 +36,7 @@ import os
import socket
import subprocess
import xml.dom.minidom
-from httplib import HTTPSConnection
+import httplib
import time
import re
@@ -70,6 +73,12 @@ realhost = os.environ.get('hostlist', legacy_RI_HOST)
rihost = os.environ.get('ilo_hostname', legacy_RI_HOSTRI)
ilouser = os.environ.get('ilo_user', legacy_RI_LOGIN)
ilopass = os.environ.get('ilo_password', legacy_RI_PASSWORD)
+iloproxyhost = os.environ.get('ilo_proxyhost', '')
+try:
+ iloproxyport = int(os.environ.get('ilo_proxyport', 3128))
+except ValueError:
+ my_err("ilo_proxyport is not a number")
+ sys.exit(1)
xmlinfo = '''<parameters>
<parameter name="hostlist" unique="1" required="1">
@@ -127,6 +136,22 @@ xmlinfo = '''<parameters>
about half a minute.
</longdesc>
</parameter>
+<parameter name="ilo_proxyhost" unique="0" required="0">
+ <content type="string" default=""/>
+ <shortdesc lang="en">Proxy hostname</shortdesc>
+ <longdesc lang="en">
+ proxy hostname if required to access ILO board
+ </longdesc>
+ </parameter>
+<parameter name="ilo_proxyport" unique="0" required="0">
+ <content type="string" default="3128"/>
+ <shortdesc lang="en">Proxy port</shortdesc>
+ <longdesc lang="en">
+ proxy port if required to access ILO board
+ parameter will be ignored if proxy hostname is not set
+ </longdesc>
+ </parameter>
+
</parameters>'''
info = {
@@ -143,7 +168,7 @@ if cmd in info:
sys.exit(0)
if cmd == 'getconfignames':
- for arg in [ "hostlist", "ilo_hostname", "ilo_user", "ilo_password", "ilo_can_reset", "ilo_protocol", "ilo_powerdown_method"]:
+ for arg in [ "hostlist", "ilo_hostname", "ilo_user", "ilo_password", "ilo_can_reset", "ilo_protocol", "ilo_powerdown_method", "ilo_proxyhost", "ilo_proxyport"]:
print arg
sys.exit(0)
@@ -302,13 +327,32 @@ def proc_resp(doc):
def open_ilo(host):
# open https connection
try:
- return HTTPSConnection(host)
+ if iloproxyhost != "" and iloproxyport != 0:
+ proxy=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
+ proxy.connect((iloproxyhost, iloproxyport))
+ proxy_connect='CONNECT %s:%s HTTP/1.1\r\n'%(host,443)
+ user_agent='User-Agent: python\r\n'
+ proxy_pieces=proxy_connect+user_agent+'\r\n'
+ proxy.sendall(proxy_pieces)
+ response=proxy.recv(8192)
+ status=response.split()[1]
+ if status!=str(200):
+ fatal("Error status=: %s" %(response))
+ import ssl
+ sock = ssl.wrap_socket(proxy)
+ h=httplib.HTTPConnection('localhost')
+ h.sock=sock
+ return h
+ else:
+ return httplib.HTTPSConnection(host)
except socket.gaierror, msg:
fatal("%s: %s" %(msg,host))
except socket.sslerror, msg:
fatal("%s for %s" %(msg,host))
except socket.error, msg:
fatal("%s while talking to %s" %(msg,host))
+ except ImportError, msg:
+ fatal("ssl support missing (%s)" %msg)
def send_request(req,proc_f):
'''
@@ -343,7 +387,7 @@ def send_request(req,proc_f):
t_end = time.time()
if not result:
- fatal("no response from %s"%rihost)
+ fatal("no response from %s within %0.2f s"%(rihost,(t_end-t_begin)))
for reply in result:
# work around the iLO bug, i.e. element RIBCL closed twice
if re.search("</RIBCL", reply) and re.search("<RIBCL.*/>", reply):
diff --git a/lib/stonith/.cvsignore b/lib/stonith/.cvsignore
deleted file mode 100644
index 9e662d9..0000000
--- a/lib/stonith/.cvsignore
+++ /dev/null
@@ -1,13 +0,0 @@
-meatclient
-README
-stonith
-Makefile.in
-Makefile
-.*.swp
-.deps
-.libs
-*.lo
-*.la
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lib/stonith/main.c b/lib/stonith/main.c
index 5709ced..ec10039 100644
--- a/lib/stonith/main.c
+++ b/lib/stonith/main.c
@@ -61,10 +61,12 @@ static const char META_TEMPLATE[] =
"</special>\n"
"</resource-agent>\n";
-void version();
+void version(void);
void usage(const char * cmd, int exit_status, const char * devtype);
void confhelp(const char * cmd, FILE* stream, const char * devtype);
void print_stonith_meta(Stonith * stonith_obj, const char *rsc_type);
+void print_types(void);
+void print_confignames(Stonith *s);
/*
* Note that we don't use the cl_log logging code because the STONITH
@@ -276,6 +278,39 @@ print_stonith_meta(Stonith * stonith_obj, const char *rsc_type)
#define MAXNVARG 50
+void
+print_types()
+{
+ char ** typelist;
+
+ typelist = stonith_types();
+ if (typelist == NULL) {
+ syslog(LOG_ERR, "Could not list Stonith types.");
+ }else{
+ char ** this;
+
+ for(this=typelist; *this; ++this) {
+ printf("%s\n", *this);
+ }
+ }
+}
+
+void
+print_confignames(Stonith *s)
+{
+ const char** names;
+ int i;
+
+ names = stonith_get_confignames(s);
+
+ if (names != NULL) {
+ for (i=0; names[i]; ++i) {
+ printf("%s ", names[i]);
+ }
+ }
+ printf("\n");
+}
+
int
main(int argc, char** argv)
{
@@ -283,7 +318,6 @@ main(int argc, char** argv)
int rc;
Stonith * s;
const char * SwitchType = NULL;
- const char * tmp;
const char * optfile = NULL;
const char * parameters = NULL;
int reset_type = ST_GENERIC_RESET;
@@ -417,21 +451,9 @@ main(int argc, char** argv)
if ((eqpos=strchr(argv[optind], EQUAL)) == NULL) {
break;
}
- if (parameters) {
- fprintf(stderr
- , "Cannot include both -p and name=value "
- "style arguments\n");
- usage(cmdname, 1, NULL);
- }
- if (optfile) {
- fprintf(stderr
- , "Cannot include both -F and name=value "
- "style arguments\n");
- usage(cmdname, 1, NULL);
- }
- if (params_from_env) {
+ if (parameters || optfile || params_from_env) {
fprintf(stderr
- , "Cannot use both -E and name=value "
+ , "Cannot mix name=value and -p, -F, or -E "
"style arguments\n");
usage(cmdname, 1, NULL);
}
@@ -460,18 +482,7 @@ main(int argc, char** argv)
}
if (listtypes) {
- char ** typelist;
-
- typelist = stonith_types();
- if (typelist == NULL) {
- syslog(LOG_ERR, "Could not list Stonith types.");
- }else{
- char ** this;
-
- for(this=typelist; *this; ++this) {
- printf("%s\n", *this);
- }
- }
+ print_types();
exit(0);
}
@@ -513,16 +524,7 @@ main(int argc, char** argv)
}
if (listparanames) {
- const char** names;
- int i;
- names = stonith_get_confignames(s);
-
- if (names != NULL) {
- for (i=0; names[i]; ++i) {
- printf("%s ", names[i]);
- }
- }
- printf("\n");
+ print_confignames(s);
stonith_delete(s);
s=NULL;
exit(0);
@@ -609,19 +611,19 @@ main(int argc, char** argv)
for (j=0; j < count; ++j) {
- rc = stonith_get_status(s);
+ rc = S_OK;
- if ((tmp = stonith_get_info(s, ST_DEVICEID)) == NULL) {
- SwitchType = tmp;
- }
+ if (status) {
+ rc = stonith_get_status(s);
- if (status && !silent) {
- if (rc == S_OK) {
- syslog(LOG_ERR, "%s device OK.", SwitchType);
- }else{
- /* Uh-Oh */
- syslog(LOG_ERR, "%s device not accessible."
- , SwitchType);
+ if (!silent) {
+ if (rc == S_OK) {
+ syslog(LOG_ERR, "%s device OK.", SwitchType);
+ }else{
+ /* Uh-Oh */
+ syslog(LOG_ERR, "%s device not accessible."
+ , SwitchType);
+ }
}
}
@@ -632,6 +634,7 @@ main(int argc, char** argv)
if (hostlist == NULL) {
syslog(LOG_ERR, "Could not list hosts for %s."
, SwitchType);
+ rc = -1;
}else{
char ** this;
diff --git a/lib/stonith/sbd.c b/lib/stonith/sbd.c
index b0052b0..d8fc6b0 100644
--- a/lib/stonith/sbd.c
+++ b/lib/stonith/sbd.c
@@ -19,11 +19,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <asm/unistd.h>
#include <ctype.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ptrace.h>
#include <fcntl.h>
#include <time.h>
#include <clplumbing/cl_log.h>
@@ -51,6 +53,7 @@ static int timeout_msgwait = 10;
static int watchdog_use = 0;
static int go_daemon = 0;
+static int skip_rt = 0;
static int debug = 0;
static const char *watchdogdev = "/dev/watchdog";
static char * local_uname;
@@ -74,6 +77,7 @@ usage(void)
"-h Display this help.\n"
"-n <node> Set local node name; defaults to uname -n (optional)\n"
"\n"
+"-R Do NOT enable realtime priority (debugging only)\n"
"-W Use watchdog (recommended) (watch only)\n"
"-w <dev> Specify watchdog device (optional) (watch only)\n"
"-D Run as background daemon (optional) (watch only)\n"
@@ -164,6 +168,53 @@ watchdog_close(void)
}
}
+/* This duplicates some code from linux/ioprio.h since these are not included
+ * even in linux-kernel-headers. Sucks. See also
+ * /usr/src/linux/Documentation/block/ioprio.txt and ioprio_set(2) */
+extern int sys_ioprio_set(int, int, int);
+static int ioprio_set(int which, int who, int ioprio);
+static inline int ioprio_set(int which, int who, int ioprio)
+{
+ return syscall(__NR_ioprio_set, which, who, ioprio);
+}
+
+enum {
+ IOPRIO_CLASS_NONE,
+ IOPRIO_CLASS_RT,
+ IOPRIO_CLASS_BE,
+ IOPRIO_CLASS_IDLE,
+};
+
+enum {
+ IOPRIO_WHO_PROCESS = 1,
+ IOPRIO_WHO_PGRP,
+ IOPRIO_WHO_USER,
+};
+
+#define IOPRIO_BITS (16)
+#define IOPRIO_CLASS_SHIFT (13)
+#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+
+#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
+#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
+#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+
+static void
+maximize_priority(void)
+{
+ if (skip_rt) {
+ cl_log(LOG_INFO, "Not elevating to realtime (-R specified).");
+ return;
+ }
+
+ cl_make_realtime(-1, -1, 256, 256);
+
+ if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(),
+ IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 1)) != 0) {
+ cl_perror("ioprio_set() call failed.");
+ }
+}
+
static int
open_device(const char* devname)
{
@@ -751,6 +802,9 @@ make_daemon(void)
cl_log_enable_stderr(FALSE);
+ /* This is the child; ensure privileges have not been lost. */
+ maximize_priority();
+
umask(022);
close(0);
(void)open(devnull, O_RDONLY);
@@ -759,8 +813,6 @@ make_daemon(void)
close(2);
(void)open(devnull, O_WRONLY);
cl_cdtocoredir();
- cl_make_realtime(-1, -1, 128, 128);
-
}
@@ -789,7 +841,7 @@ daemonize(void)
if (watchdog_use != 0)
watchdog_init();
-
+
while (1) {
t0 = time(NULL);
sleep(timeout_loop);
@@ -905,11 +957,14 @@ main(int argc, char** argv)
get_uname();
- while ((c = getopt (argc, argv, "DWhvw:d:n:1:2:3:4:5:")) != -1) {
+ while ((c = getopt (argc, argv, "DRWhvw:d:n:1:2:3:4:5:")) != -1) {
switch (c) {
case 'D':
go_daemon = 1;
break;
+ case 'R':
+ skip_rt = 1;
+ break;
case 'v':
debug = 1;
break;
@@ -957,6 +1012,7 @@ main(int argc, char** argv)
goto out;
}
+ maximize_priority();
if (open_device(devname) < 0) {
exit_status = -1;
goto out;
diff --git a/lib/stonith/sbd.h b/lib/stonith/sbd.h
index b671783..af2c124 100644
--- a/lib/stonith/sbd.h
+++ b/lib/stonith/sbd.h
@@ -87,5 +87,6 @@ static void do_reset(void);
static void do_off(void);
static void make_daemon(void);
static int daemonize(void);
+static void maximize_priority(void);
static void get_uname(void);
diff --git a/logd/.cvsignore b/logd/.cvsignore
deleted file mode 100644
index d43dc28..0000000
--- a/logd/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-Makefile
-Makefile.in
-ha_logd
-ha_logger
-.libs
-.deps
-logtest
diff --git a/lrm/.cvsignore b/lrm/.cvsignore
deleted file mode 100644
index f94fd1c..0000000
--- a/lrm/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-Makefile.in
-Makefile
-.deps
-.libs
-*.la
-*.lo
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lrm/admin/.cvsignore b/lrm/admin/.cvsignore
deleted file mode 100644
index a341d68..0000000
--- a/lrm/admin/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-lrmadmin
-Makefile.in
-Makefile
-.deps
-.libs
-*.la
-*.lo
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lrm/admin/lrmadmin.c b/lrm/admin/lrmadmin.c
index c2f4aff..27f37bf 100644
--- a/lrm/admin/lrmadmin.c
+++ b/lrm/admin/lrmadmin.c
@@ -140,7 +140,7 @@ static int call_id = 0;
static int TIMEOUT = -1; /* the unit is ms */
static const char *simple_help_screen =
-"lrmadmin -d,--deamon\n"
+"lrmadmin -d,--daemon\n"
" -A,--add <rscid> <raclass> <ratype> <provider|NULL> [<rsc_params_list>]\n"
" -D,--delete <rscid>\n"
" -F,--flush <rscid>\n"
diff --git a/lrm/admin/lrmadmin.txt b/lrm/admin/lrmadmin.txt
index ac651e0..739aa70 100644
--- a/lrm/admin/lrmadmin.txt
+++ b/lrm/admin/lrmadmin.txt
@@ -4,7 +4,7 @@ NAME
lrmadmin - Local Resource Manager Commander-line Daministrator Tools
SYNOPSIS
-lrmadmin {-d|--deamon}
+lrmadmin {-d|--daemon}
{-A|--add} <rscid> <rsc_class> <rsc_type> [<rsc_params_list>]
{-D|--delete} <rscid>
{-F|--flush} <rscid>
@@ -20,8 +20,8 @@ lrmadmin {-d|--deamon}
Detailed Explanation for Options
-Lrmd deamon options
- {-d|--deamon}
+Lrmd daemon options
+ {-d|--daemon}
# -s The status of lrmd: running or not running
# -r Reset lrmd (?)
diff --git a/lrm/lrmd/.cvsignore b/lrm/lrmd/.cvsignore
deleted file mode 100644
index e32199d..0000000
--- a/lrm/lrmd/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-lrmd
-Makefile.in
-Makefile
-.deps
-.libs
-*.la
-*.lo
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
diff --git a/lrm/lrmd/lrmd.c b/lrm/lrmd/lrmd.c
index 75bae81..fa819af 100644
--- a/lrm/lrmd/lrmd.c
+++ b/lrm/lrmd/lrmd.c
@@ -633,6 +633,21 @@ errout:
rsc = NULL;
return rsc;
}
+
+static void
+dump_op(gpointer key, gpointer val, gpointer data)
+{
+ lrmd_op_t* lrmd_op = (lrmd_op_t*) val;
+
+ lrmd_op_dump(lrmd_op, "rsc->last_op_table");
+}
+static void
+dump_op_table(gpointer key, gpointer val, gpointer data)
+{
+ GHashTable* table = (GHashTable*) val;
+
+ g_hash_table_foreach(table, dump_op, data);
+}
static void
lrmd_rsc_dump(char* rsc_id, const char * text)
{
@@ -652,6 +667,12 @@ lrmd_rsc_dump(char* rsc_id, const char * text)
if(!rsc) {
return;
}
+
+ /* Avoid infinite recursion loops... */
+ if (incall) {
+ return;
+ }
+ incall = TRUE;
/* TODO: Dump params and last_op_table FIXME */
lrmd_debug(LOG_DEBUG, "%s: BEGIN resource dump", text);
@@ -662,12 +683,6 @@ lrmd_rsc_dump(char* rsc_id, const char * text)
, lrm_str(rsc->class)
, lrm_str(rsc->provider));
- /* Avoid infinite recursion loops... */
- if (incall) {
- return;
- }
- incall = TRUE;
-
lrmd_debug(LOG_DEBUG, "%s: rsc->op_list...", text);
for(oplist = g_list_first(rsc->op_list); oplist;
oplist = g_list_next(oplist)) {
@@ -687,6 +702,12 @@ lrmd_rsc_dump(char* rsc_id, const char * text)
else {
lrmd_debug(LOG_DEBUG, "%s: rsc->last_op_done==NULL", text);
}
+ if (rsc->last_op_table) {
+ g_hash_table_foreach(rsc->last_op_table,dump_op_table,NULL);
+ }
+ else {
+ lrmd_debug(LOG_DEBUG, "%s: rsc->last_op_table==NULL", text);
+ }
lrmd_debug(LOG_DEBUG, "%s: END resource dump", text);
incall = FALSE;
};
@@ -2705,7 +2726,7 @@ add_op_to_runlist(lrmd_rsc_t* rsc, lrmd_op_t* op)
rsc->op_list = g_list_append(rsc->op_list, op);
if (g_list_length(rsc->op_list) >= 4) {
lrmd_log(LOG_WARNING
- , "operations list for %s is suspicously"
+ , "operations list for %s is suspiciously"
" long [%d]"
, rsc->id
, g_list_length(rsc->op_list));
diff --git a/lrm/test/.cvsignore b/lrm/test/.cvsignore
deleted file mode 100644
index b92b57e..0000000
--- a/lrm/test/.cvsignore
+++ /dev/null
@@ -1,19 +0,0 @@
-LRMBasicSanityCheck
-apitest
-plugintest
-Makefile.in
-Makefile
-.deps
-.libs
-*.la
-*.lo
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
-callbacktest
-simple_ops
-lrmregtest
-lrmregtest-heartbeat
-lrmregtest-lsb
-regression.sh
diff --git a/lrm/test/testcases/.cvsignore b/lrm/test/testcases/.cvsignore
deleted file mode 100644
index f94fd1c..0000000
--- a/lrm/test/testcases/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-Makefile.in
-Makefile
-.deps
-.libs
-*.la
-*.lo
-.*.swp
-*.beam
-parser-messages
-MISC_ERRORS
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-ha/cluster-glue.git
More information about the Debian-HA-Commits
mailing list