[DRBD-cvs] svn commit by rasto - r2201 - in trunk: . tools - added
files
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Thu May 18 16:14:24 CEST 2006
Author: rasto
Date: 2006-05-18 16:14:23 +0200 (Thu, 18 May 2006)
New Revision: 2201
Added:
trunk/tools/
trunk/tools/README
trunk/tools/dopd.c
trunk/tools/dopd.h
trunk/tools/drbd-peer-outdater.c
Log:
added files
Added: trunk/tools/README
===================================================================
--- trunk/tools/README 2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/README 2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,20 @@
+1) compile
+
+copy this directory into heartbeat tools directory and compile it
+with heartbeat.
+
+2) prepare drbdmeta
+
+cd /sbin
+chown .haclient drbdmeta
+chmod o-x drbdmeta
+chmod u+s drbdmeta
+
+3) Configure Heartbeat to run the DRBD outdate peer daemon
+
+Add these lines to /etc/ha.d/ha.cf
+---
+respawn hacluster /usr/lib/heartbeat/dopd
+apiauth dopd gid=haclient uid=hacluster
+---
+
Added: trunk/tools/dopd.c
===================================================================
--- trunk/tools/dopd.c 2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/dopd.c 2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,557 @@
+/* $Id$ */
+/* drbd outdate peer daemon
+ * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
+ * Written by Rasto Levrinc <rasto at linbit.at>
+ *
+ * based on ipfail.c and attrd.c
+ *
+ * This library 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
+ */
+
+#include <portability.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <heartbeat.h>
+#include <ha_msg.h>
+#include <hb_api.h>
+#include <clplumbing/cl_signal.h>
+#include <clplumbing/GSource.h>
+#include <clplumbing/Gmain_timeout.h>
+#include <clplumbing/coredumps.h>
+#include <dopd.h>
+#include <clplumbing/cl_misc.h>
+
+#include <crm/crm.h>
+#include <crm/common/ipc.h>
+
+
+const char *node_name; /* The node we are connected to */
+char other_node[SYS_NMLN]; /* The remote node in the pair */
+int node_stable; /* Other node stable? */
+int need_standby; /* Are we waiting for stability? */
+int quitnow = 0; /* Allows a signal to break us out of loop */
+GMainLoop *mainloop; /* Reference to the mainloop for events */
+ll_cluster_t *dopd_cluster_conn;
+
+/* only one client can be connected at a time */
+
+typedef struct dopd_client_s
+{
+ char *id;
+
+ IPC_Channel *channel;
+ GCHSource *source;
+} dopd_client_t;
+
+IPC_Channel *CURR_CLIENT_CHANNEL = NULL;
+
+/* send_message_to_other_node()
+ * send message with drbd resource to other node.
+ */
+static gboolean
+send_message_to_other_node(const char *drbd_resource)
+{
+ ll_cluster_t *hb = dopd_cluster_conn;
+ HA_Message *msg = NULL;
+
+ crm_info("sending start_outdate message to the other node %s -> %s",
+ node_name, other_node);
+
+ msg = ha_msg_new(3);
+ ha_msg_add(msg, F_TYPE, "start_outdate");
+ ha_msg_add(msg, F_ORIG, node_name);
+ ha_msg_add(msg, F_DOPD_RES, drbd_resource);
+
+ crm_debug("sending [start_outdate res: %s] to other node",
+ drbd_resource);
+ hb->llc_ops->sendnodemsg(hb, msg, other_node);
+ ha_msg_del(msg);
+
+ return TRUE;
+}
+
+/* msg_start_outdate()
+ * got start_outdate message with resource from other node. Execute drbd
+ * outdate command, convert return code and send message to other node
+ * with return code.
+ *
+ * Conversion of return codes:
+ * 0 => 4
+ * 5 => 3
+ * 17 => 6
+ * other => 5
+ */
+void
+msg_start_outdate(struct ha_msg *msg, void *private)
+{
+ ll_cluster_t *hb = (ll_cluster_t *)private;
+ int rc = 5;
+ int command_ret;
+
+ char rc_string[4];
+ HA_Message *msg2 = NULL;
+ const char *drbd_resource = ha_msg_value(msg, F_DOPD_RES);
+ char *command;
+
+ /* execute outdate command */
+ crm_malloc0(command, strlen(OUTDATE_COMMAND) + 1 + strlen(drbd_resource) + 1);
+ strcpy(command, OUTDATE_COMMAND);
+ strcat(command, " ");
+ strcat(command, drbd_resource);
+ crm_debug("command: %s", command);
+ command_ret = system(command) >> 8;
+
+ /* convert return code */
+ crm_free(command);
+ if (command_ret == 0)
+ rc = 4;
+ else if (command_ret == 5)
+ rc = 3;
+ else if (command_ret == 17)
+ rc = 6;
+ else
+ crm_info("unknown exit code from "OUTDATE_COMMAND": %i",
+ command_ret);
+
+ crm_debug("msg_start_outdate: %s, command rc: %i, rc: %i",
+ ha_msg_value(msg, F_ORIG), command_ret, rc);
+ sprintf(rc_string, "%i", rc);
+
+ /* send return code to oder node */
+ msg2 = ha_msg_new(3);
+ ha_msg_add(msg2, F_TYPE, "outdate_rc");
+ ha_msg_add(msg2, F_DOPD_VALUE, rc_string);
+ ha_msg_add(msg2, F_ORIG, node_name);
+
+ hb->llc_ops->sendnodemsg(hb, msg2, other_node);
+ ha_msg_del(msg2);
+}
+
+/* msg_outdate_rc()
+ * got outdate_rc message with return code from other node. Send the
+ * return code to the outdater client.
+ */
+void
+msg_outdate_rc(struct ha_msg *msg_in, void *private)
+{
+ HA_Message *msg_out = NULL;
+ const char *rc_string = ha_msg_value(msg_in, F_DOPD_VALUE);
+
+ if (CURR_CLIENT_CHANNEL == NULL)
+ return;
+ crm_debug("msg_outdate_rc: %s", rc_string);
+ msg_out = ha_msg_new(3);
+ ha_msg_add(msg_out, F_TYPE, "outdater_rc");
+ ha_msg_add(msg_out, F_ORIG, node_name);
+ ha_msg_add(msg_out, F_DOPD_VALUE, rc_string);
+
+ if (send_ipc_message(CURR_CLIENT_CHANNEL, msg_out) == FALSE) {
+ crm_err("Could not send message to the client");
+ }
+ CURR_CLIENT_CHANNEL = NULL;
+}
+
+/* outdater_callback()
+ * got message from outdater client with drbd resource, it will be sent
+ * to the other node.
+ */
+static gboolean
+outdater_callback(IPC_Channel *client, gpointer user_data)
+{
+ int lpc = 0;
+ HA_Message *msg = NULL;
+ const char *drbd_resource = NULL;
+ dopd_client_t *curr_client = (dopd_client_t*)user_data;
+ gboolean stay_connected = TRUE;
+
+ crm_debug("invoked: %s", curr_client->id);
+
+ /* allow one connection from outdater at a time */
+ if (CURR_CLIENT_CHANNEL != NULL &&
+ CURR_CLIENT_CHANNEL != curr_client->channel) {
+ crm_debug("one client already connected");
+ return FALSE;
+ }
+ CURR_CLIENT_CHANNEL = curr_client->channel;
+
+ while (IPC_ISRCONN(client)) {
+ if(client->ops->is_message_pending(client) == 0) {
+ break;
+ }
+
+ msg = msgfromIPC_noauth(client);
+ if (msg == NULL) {
+ crm_debug("%s: no message this time",
+ curr_client->id);
+ continue;
+ }
+
+ lpc++;
+
+ crm_debug("Processing msg from %s", curr_client->id);
+ crm_debug("Got message from (%s). (%s)",
+ ha_msg_value(msg, F_ORIG),
+ ha_msg_value(msg, F_OUTDATER_RES));
+
+ drbd_resource = ha_msg_value(msg, F_OUTDATER_RES);
+ send_message_to_other_node(drbd_resource);
+
+ crm_msg_del(msg);
+ msg = NULL;
+
+ if(client->ch_status != IPC_CONNECT) {
+ break;
+ }
+ }
+ crm_debug("Processed %d messages", lpc);
+ if (client->ch_status != IPC_CONNECT) {
+ stay_connected = FALSE;
+ }
+ return stay_connected;
+}
+
+
+/* outdater_ipc_connection_destroy()
+ * clean client struct
+ */
+static void
+outdater_ipc_connection_destroy(gpointer user_data)
+{
+ dopd_client_t *client = (dopd_client_t*)user_data;
+
+ if (client == NULL)
+ return;
+
+ if (client->source != NULL) {
+ crm_debug("Deleting %s (%p) from mainloop",
+ client->id, client->source);
+ G_main_del_IPC_Channel(client->source);
+ client->source = NULL;
+ }
+ crm_free(client->id);
+ if (client->channel == CURR_CLIENT_CHANNEL) {
+ crm_debug("connection from client closed");
+ CURR_CLIENT_CHANNEL = NULL;
+ }
+ crm_free(client);
+ return;
+}
+
+/* outdater_client_connect()
+ * outdater is connected set outdater_callback.
+ */
+static gboolean
+outdater_client_connect(IPC_Channel *channel, gpointer user_data)
+{
+ dopd_client_t *new_client = NULL;
+ crm_debug("Connecting channel");
+ if(channel == NULL) {
+ crm_err("Channel was NULL");
+ return FALSE;
+
+ } else if(channel->ch_status != IPC_CONNECT) {
+ crm_err("Channel was disconnected");
+ return FALSE;
+ }
+
+ crm_malloc0(new_client, sizeof(dopd_client_t));
+ new_client->channel = channel;
+ crm_malloc0(new_client->id, 10);
+ strcpy(new_client->id, "outdater");
+
+ new_client->source = G_main_add_IPC_Channel(
+ G_PRIORITY_DEFAULT, channel, FALSE, outdater_callback,
+ new_client, outdater_ipc_connection_destroy);
+
+ crm_debug("Client %s (%p) connected",
+ new_client->id,
+ new_client->source);
+
+ return TRUE;
+}
+
+static void
+outdater_client_destroy(gpointer user_data)
+{
+ crm_info("ipc server destroy");
+}
+
+int
+is_stable(ll_cluster_t *hb)
+{
+ const char *resources = hb->llc_ops->get_resources(hb);
+ if (!resources)
+ /* Heartbeat is not providing resource management */
+ return -1;
+
+ if (!strcmp(resources, "transition"))
+ return 0;
+
+ return 1;
+}
+
+/* node_walk()
+ * get name of other node and set other_node string
+ */
+void
+node_walk(ll_cluster_t *hb)
+{
+ const char *node;
+
+ crm_debug("Starting node walk");
+ if (hb->llc_ops->init_nodewalk(hb) != HA_OK) {
+ crm_err("Cannot start node walk");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(9);
+ }
+ while((node = hb->llc_ops->nextnode(hb)) != NULL) {
+ crm_debug("Cluster node: %s: status: %s", node,
+ hb->llc_ops->node_status(hb, node));
+
+ /* Look for our partner */
+ if (!strcmp("normal", hb->llc_ops->node_type(hb, node))
+ && strcmp(node, node_name)) {
+ strcpy(other_node, node);
+ crm_debug("[They are %s]", other_node);
+ }
+ }
+ if (hb->llc_ops->end_nodewalk(hb) != HA_OK) {
+ crm_err("Cannot end node walk");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(12);
+ }
+}
+
+/* set_callbacks()
+ * set callbacks for communication between two nodes
+ */
+void
+set_callbacks(ll_cluster_t *hb)
+{
+ /* Add each of the callbacks we use with the API */
+ if (hb->llc_ops->set_msg_callback(hb, "start_outdate",
+ msg_start_outdate, hb) != HA_OK) {
+ crm_err("Cannot set msg_start_outdate callback");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(2);
+ }
+
+ if (hb->llc_ops->set_msg_callback(hb, "outdate_rc",
+ msg_outdate_rc, hb) != HA_OK) {
+ crm_err("Cannot set msg_outdate_rc callback");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(2);
+ }
+}
+
+void
+set_signals(ll_cluster_t *hb)
+{
+ /* Setup the various signals */
+
+ CL_SIGINTERRUPT(SIGINT, 1);
+ CL_SIGNAL(SIGINT, gotsig);
+ CL_SIGINTERRUPT(SIGTERM, 1);
+ CL_SIGNAL(SIGTERM, gotsig);
+
+ crm_debug("Setting message signal");
+ if (hb->llc_ops->setmsgsignal(hb, 0) != HA_OK) {
+ crm_err("Cannot set message signal");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(13);
+ }
+}
+
+void
+gotsig(int nsig)
+{
+ (void)nsig;
+ quitnow = 1;
+}
+
+/* Used to handle the API in the gmainloop */
+gboolean
+dopd_dispatch(IPC_Channel* ipc, gpointer user_data)
+{
+ struct ha_msg *reply;
+ ll_cluster_t *hb = user_data;
+
+ reply = hb->llc_ops->readmsg(hb, 0);
+
+ if (reply != NULL) {
+ ha_msg_del(reply); reply=NULL;
+ return TRUE;
+ }
+ return TRUE;
+}
+
+void
+dopd_dispatch_destroy(gpointer user_data)
+{
+ return;
+}
+
+gboolean
+dopd_timeout_dispatch(gpointer user_data)
+{
+ ll_cluster_t *hb = user_data;
+
+ if (quitnow) {
+ g_main_quit(mainloop);
+ return FALSE;
+ }
+
+ if (hb->llc_ops->msgready(hb)) {
+ return dopd_dispatch(NULL, user_data);
+ }
+ return TRUE;
+}
+
+/* Sign in to the API */
+void
+open_api(ll_cluster_t *hb)
+{
+ crm_debug("Signing in with heartbeat");
+ if (hb->llc_ops->signon(hb, "dopd")!= HA_OK) {
+ crm_err("Cannot sign on with heartbeat");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(1);
+ }
+}
+
+/* Log off of the API and clean up */
+void
+close_api(ll_cluster_t *hb)
+{
+ if (hb->llc_ops->signoff(hb, FALSE) != HA_OK) {
+ crm_err("Cannot sign off from heartbeat.");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(14);
+ }
+ if (hb->llc_ops->delete(hb) != HA_OK) {
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ crm_err("Cannot delete API object.");
+ exit(15);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ unsigned fmask;
+ ll_cluster_t *hb;
+ char pid[10];
+ char *bname, *parameter;
+ IPC_Channel *apiIPC;
+
+ /* Get the name of the binary for logging purposes */
+ bname = ha_strdup(argv[0]);
+ crm_log_init(bname);
+
+ hb = ll_cluster_new("heartbeat");
+ dopd_cluster_conn = hb;
+
+ memset(other_node, 0, sizeof(other_node));
+ need_standby = 0;
+
+ memset(pid, 0, sizeof(pid));
+ snprintf(pid, sizeof(pid), "%ld", (long)getpid());
+ crm_debug("PID=%s", pid);
+
+ open_api(hb);
+
+ node_stable = is_stable(hb);
+ if (node_stable == -1) {
+ crm_err("No managed resources");
+ exit(100);
+ }
+
+ /* Obtain our local node name */
+ node_name = hb->llc_ops->get_mynodeid(hb);
+ if (node_name == NULL) {
+ crm_err("Cannot get my nodeid");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(19);
+ }
+ crm_debug("[We are %s]", node_name);
+
+ /* See if we should drop cores somewhere odd... */
+ parameter = hb->llc_ops->get_parameter(hb, KEY_COREROOTDIR);
+ if (parameter) {
+ cl_set_corerootdir(parameter);
+ cl_cdtocoredir();
+ }
+ cl_cdtocoredir();
+
+
+ set_callbacks(hb);
+
+ fmask = LLC_FILTER_DEFAULT;
+
+ crm_debug("Setting message filter mode");
+ if (hb->llc_ops->setfmode(hb, fmask) != HA_OK) {
+ crm_err("Cannot set filter mode");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ exit(8);
+ }
+
+ node_walk(hb);
+
+ set_signals(hb);
+
+ crm_debug("Waiting for messages...");
+ errno = 0;
+
+ mainloop = g_main_new(TRUE);
+
+ apiIPC = hb->llc_ops->ipcchan(hb);
+
+ /* Watch the API IPC for input */
+ G_main_add_IPC_Channel(G_PRIORITY_HIGH, apiIPC, FALSE,
+ dopd_dispatch, (gpointer)hb,
+ dopd_dispatch_destroy);
+
+ Gmain_timeout_add_full(G_PRIORITY_DEFAULT, 1000,
+ dopd_timeout_dispatch, (gpointer)hb,
+ dopd_dispatch_destroy);
+ int rc = init_server_ipc_comms(
+ ha_strdup(T_OUTDATER),
+ outdater_client_connect,
+ outdater_client_destroy);
+ if (rc != 0)
+ crm_err("Could not start IPC server");
+
+ g_main_run(mainloop);
+ g_main_destroy(mainloop);
+
+ if (!quitnow && errno != EAGAIN && errno != EINTR) {
+ crm_err("read_hb_msg returned NULL");
+ crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+ }
+
+ close_api(hb);
+
+ return 0;
+}
Added: trunk/tools/dopd.h
===================================================================
--- trunk/tools/dopd.h 2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/dopd.h 2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/* drbd outdate peer daemon
+ * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
+ *
+ * Written by Rasto Levrinc <rasto at linbit.at>
+ *
+ * This library 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
+ */
+
+
+#define T_OUTDATER "outdater"
+#define F_OUTDATER_RES "outdater_res"
+#define F_DOPD_VALUE "dop_value"
+#define F_DOPD_RES "dop_res"
+
+#define OUTDATE_COMMAND "/sbin/drbdadm outdate"
+
+
+/* Prototypes */
+void node_walk(ll_cluster_t *);
+void set_signals(ll_cluster_t *);
+void gotsig(int);
+void set_callbacks(ll_cluster_t *);
+void open_api(ll_cluster_t *);
+void close_api(ll_cluster_t *);
+gboolean dopd_dispatch(IPC_Channel *, gpointer);
+void dopd_dispatch_destroy(gpointer);
+gboolean dopd_timeout_dispatch(gpointer);
+int is_stable(ll_cluster_t *);
+void msg_start_outdate(struct ha_msg *, void *);
+void msg_outdate_rc(struct ha_msg *, void *);
Added: trunk/tools/drbd-peer-outdater.c
===================================================================
--- trunk/tools/drbd-peer-outdater.c 2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/drbd-peer-outdater.c 2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,230 @@
+/* $Id$ */
+/* drbd-peer-outdater
+ * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
+ *
+ * Written by Rasto Levrinc <rasto at linbit.at>
+ *
+ * based on attrd
+ *
+ * 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
+ */
+
+#include <portability.h>
+
+#include <sys/param.h>
+
+#include <crm/crm.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+#include <crm/common/ipc.h>
+#include <clplumbing/lsb_exitcodes.h>
+#include <clplumbing/Gmain_timeout.h>
+#include <dopd.h>
+
+#define OPTARGS "hVt:r:"
+
+typedef struct dop_client_s
+{
+ int timeout;
+ GMainLoop *mainloop;
+ int rc;
+} dop_client_t;
+
+const char *crm_system_name = "drbd-peer-outdater";
+
+static void usage(const char* cmd, int exit_status);
+
+static void
+dop_exit(dop_client_t *client)
+{
+ int rc;
+
+ if (client == NULL)
+ exit(5);
+ rc = client->rc;
+
+ crm_free(client);
+ exit(rc);
+}
+
+static gboolean
+outdate_callback(IPC_Channel * server, gpointer user_data)
+{
+ dop_client_t *client = (dop_client_t *)user_data;
+ HA_Message *msg = NULL;
+ const char *rc_string;
+ char *ep;
+ int rc;
+
+ msg = msgfromIPC_noauth(server);
+ if (!msg) {
+ fprintf(stderr, "no message from server or other "
+ "instance is running\n");
+ if (client->mainloop != NULL &&
+ g_main_is_running(client->mainloop))
+ g_main_quit(client->mainloop);
+ return FALSE;
+ }
+ crm_debug_2("message: %s, %s\n",
+ ha_msg_value(msg, F_TYPE),
+ ha_msg_value(msg, F_ORIG)
+ );
+ rc_string = ha_msg_value(msg, F_DOPD_VALUE);
+
+ errno = 0;
+ rc = strtol(rc_string, &ep, 10);
+ if (errno != 0 || *ep != EOS) {
+ fprintf(stderr, "unknown message: %s from server", rc_string);
+ ha_msg_del(msg);
+ if (client->mainloop != NULL &&
+ g_main_is_running(client->mainloop))
+ g_main_quit(client->mainloop);
+ return FALSE;
+ }
+
+ ha_msg_del(msg);
+
+ if (client->mainloop != NULL && g_main_is_running(client->mainloop)) {
+ client->rc = rc;
+ g_main_quit(client->mainloop);
+ } else
+ dop_exit(client);
+
+ return TRUE;
+}
+
+static void
+outdater_dispatch_destroy(gpointer user_data)
+{
+ return;
+}
+
+static gboolean
+outdater_timeout_dispatch(gpointer user_data)
+{
+ dop_client_t *client = (dop_client_t *)user_data;
+ fprintf(stderr, "error: could not connect to dopd after %i seconds"
+ ": timeout reached\n", client->timeout);
+ if (client->mainloop != NULL && g_main_is_running(client->mainloop))
+ g_main_quit(client->mainloop);
+ return FALSE;
+}
+
+int
+main(int argc, char ** argv)
+{
+ HA_Message *update = NULL;
+ IPC_Channel *ipc_server = NULL;
+ int argerr = 0;
+ int flag;
+ char *drbd_resource = NULL;
+ char drbd_resource_default[] = "r0";
+ int timeout = 60; // timeout in seconds
+
+ dop_client_t *new_client = NULL;
+ GCHSource *src = NULL;
+
+ crm_log_init(crm_system_name);
+
+ crm_debug_3("Begining option processing");
+ while ((flag = getopt(argc, argv, OPTARGS)) != EOF) {
+ switch(flag) {
+ case 'V':
+ alter_debug(DEBUG_INC);
+ break;
+ case 'h': /* Help message */
+ usage(crm_system_name, LSB_EXIT_OK);
+ break;
+ case 't': /* Help message */
+ timeout = atoi(optarg);
+ break;
+ case 'r': /* Help message */
+ drbd_resource = crm_strdup(optarg);
+ break;
+ default:
+ ++argerr;
+ break;
+ }
+ }
+
+ crm_debug_3("Option processing complete");
+
+ /* the caller drbdadm sets DRBD_RESOURCE env variable, use it if
+ * -r option was not specified, or use default value */
+ if ((drbd_resource == NULL) && !(drbd_resource = getenv("DRBD_RESOURCE"))) {
+ drbd_resource = drbd_resource_default;
+ }
+
+ if (optind > argc) {
+ ++argerr;
+ }
+
+ if (argerr) {
+ usage(crm_system_name, LSB_EXIT_GENERIC);
+ }
+
+ crm_debug_2("drbd resource: %s\n", drbd_resource);
+
+ crm_malloc0(new_client, sizeof(dop_client_t));
+ new_client->timeout = timeout;
+ new_client->mainloop = g_main_new(FALSE);
+ new_client->rc = 5;
+
+ /* Connect to the IPC server */
+ src = init_client_ipc_comms(T_OUTDATER, outdate_callback,
+ (gpointer)new_client, &ipc_server);
+
+ if (ipc_server == NULL) {
+ fprintf(stderr, "Could not connect to "T_OUTDATER" channel\n");
+ dop_exit(new_client); // unreachable
+ }
+
+ /* send message with drbd resource to dopd */
+ update = ha_msg_new(3);
+ ha_msg_add(update, F_TYPE, T_OUTDATER);
+ ha_msg_add(update, F_ORIG, crm_system_name);
+ ha_msg_add(update, F_OUTDATER_RES, drbd_resource);
+
+ if (send_ipc_message(ipc_server, update) == FALSE) {
+ fprintf(stderr, "Could not send message\n");
+ dop_exit(new_client);
+ }
+
+ Gmain_timeout_add_full(G_PRIORITY_DEFAULT, new_client->timeout * 1000,
+ outdater_timeout_dispatch, (gpointer)new_client,
+ outdater_dispatch_destroy);
+
+ g_main_run(new_client->mainloop);
+ dop_exit(new_client);
+ return 5;
+}
+
+static void
+usage(const char* cmd, int exit_status)
+{
+ FILE* stream;
+
+ stream = exit_status ? stderr : stdout;
+ fprintf(stream, "usage: %s [-tr]\n", cmd);
+ fprintf(stream, "\t-t <int>\ttimeout in seconds\n");
+ fprintf(stream, "\t-r <string>\tdrbd resource, default is r0\n");
+ fflush(stream);
+
+ exit(exit_status);
+}
+
More information about the drbd-cvs
mailing list