[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [PATCH] rgmanager: Initial commit of central proc + migration support



This adds preliminary migration support of virtual
machines when using central processing.

Signed-off-by: Lon Hohberger <lhh redhat com>
---
 rgmanager/src/daemons/service_op.c              |   85 ++++++++++++++++++++++-
 rgmanager/src/daemons/slang_event.c             |   59 ++++++++++++++++
 rgmanager/src/resources/default_event_script.sl |    8 +-
 3 files changed, 146 insertions(+), 6 deletions(-)

diff --git a/rgmanager/src/daemons/service_op.c b/rgmanager/src/daemons/service_op.c
index aa36f41..a508f1e 100644
--- a/rgmanager/src/daemons/service_op.c
+++ b/rgmanager/src/daemons/service_op.c
@@ -187,7 +187,88 @@ service_op_stop(char *svcName, int do_disable, int event_type)
 
 
 /*
-   TODO
-   service_op_migrate()
+   service_op_migrate() - send a virtual machine to another host
+   in the cluster
  */
+int
+service_op_migrate(char *svcName,
+		   int target_node)
+{
+	SmMessageSt msg;
+	int msg_ret;
+	msgctx_t ctx;
+	rg_state_t svcStatus;
+	int msgtarget = my_id();
+
+	/* Build the message header */
+	msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
+	msg.sm_hdr.gh_command = RG_ACTION_REQUEST;
+	msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER; 
+	msg.sm_hdr.gh_length = sizeof (SmMessageSt);
+
+	msg.sm_data.d_action = RG_MIGRATE;
+
+	strncpy(msg.sm_data.d_svcName, svcName,
+		sizeof(msg.sm_data.d_svcName));
+
+	msg.sm_data.d_ret = 0;
+	msg.sm_data.d_svcOwner = target_node;
+
+	/* Open a connection to the local node - it will decide what to
+	   do in this case. XXX inefficient; should queue requests
+	   locally and immediately forward requests otherwise */
+
+	if (get_service_state_internal(svcName, &svcStatus) < 0)
+		return RG_EFAIL;
+	if (svcStatus.rs_owner > 0) {
+		if (member_online(svcStatus.rs_owner)) {
+			msgtarget = svcStatus.rs_owner;
+		}
+
+		if (msgtarget <= 0) {
+			return RG_EFAIL;
+		}
+	}
+
+	if (msg_open(MSG_CLUSTER, msgtarget, RG_PORT, &ctx, 2)< 0) {
+		logt_print(LOG_ERR,
+		       "#58: Failed opening connection to member #%d\n",
+		       my_id());
+		return -1;
+	}
+
+	/* Encode */
+	swab_SmMessageSt(&msg);
+
+	/* Send stop message to the other node */
+	if (msg_send(&ctx, &msg, sizeof (SmMessageSt)) < 
+	    (int)sizeof (SmMessageSt)) {
+		logt_print(LOG_ERR, "Failed to send complete message\n");
+		msg_close(&ctx);
+		return -1;
+	}
+
+	/* Check the response */
+	do {
+		msg_ret = msg_receive(&ctx, &msg,
+				      sizeof (SmMessageSt), 10);
+		if ((msg_ret == -1 && errno != ETIMEDOUT) ||
+		    (msg_ret > 0)) {
+			break;
+		}
+	} while(1);
 
+	if (msg_ret != sizeof (SmMessageSt)) {
+		logt_print(LOG_WARNING, "Strange response size: %d vs %d\n",
+		       msg_ret, (int)sizeof(SmMessageSt));
+		return 0;	/* XXX really UNKNOWN */
+	}
+
+	/* Got a valid response from other node. */
+	msg_close(&ctx);
+
+	/* Decode */
+	swab_SmMessageSt(&msg);
+
+	return msg.sm_data.d_ret;
+}
diff --git a/rgmanager/src/daemons/slang_event.c b/rgmanager/src/daemons/slang_event.c
index de8aa61..29ae9f2 100644
--- a/rgmanager/src/daemons/slang_event.c
+++ b/rgmanager/src/daemons/slang_event.c
@@ -580,6 +580,63 @@ out:
 }
 
 
+static int
+sl_migrate_service(void)
+{
+	char *svcname = NULL;
+	int target_node = 0;
+	int nargs, t, newowner = 0, ret = -1;
+
+	nargs = SLang_Num_Function_Args;
+
+	/* Takes one, two, or three */
+	if (nargs != 2) {
+		SLang_verror(SL_Syntax_Error,
+		     (char *)"%s: Wrong # of args (%d), must be 2: service_name target_node\n",
+		     __FUNCTION__, nargs);
+		return -1;
+	}
+
+	t = SLang_peek_at_stack();
+	if (t != SLANG_INT_TYPE) {
+		SLang_verror(SL_Syntax_Error,
+			     (char *)"%s: expected type %d got %d\n",
+			     __FUNCTION__, SLANG_INT_TYPE, t);
+		goto out;
+	}
+
+	if (SLang_pop_integer(&target_node) < 0) {
+		SLang_verror(SL_Syntax_Error,
+		    (char *)"%s: Failed to pop integer from stack!\n",
+		    __FUNCTION__);
+		goto out;
+	}
+
+	t = SLang_peek_at_stack();
+	if (t != SLANG_STRING_TYPE) {
+		SLang_verror(SL_Syntax_Error,
+			     (char *)"%s: expected type %d got %d\n",
+			     __FUNCTION__,
+			     SLANG_STRING_TYPE, t);
+		goto out;
+	}
+
+	if (SLpop_string(&svcname) < 0) {
+		goto out;
+	}
+
+	ret = service_op_migrate(svcname, target_node);
+
+	if (ret == 0)
+		ret = target_node;
+out:
+	if (svcname)
+		free(svcname);
+	_user_return = ret;
+	return ret;
+}
+
+
 /* Take an array of integers given its length and
    push it on to the S/Lang stack */
 void
@@ -979,6 +1036,8 @@ static SLang_Intrin_Fun_Type rgmanager_slang[] =
 			 SLANG_INT_TYPE),
 	MAKE_INTRINSIC_0((char *)"service_start", sl_start_service,
 			 SLANG_INT_TYPE),
+	MAKE_INTRINSIC_0((char *)"service_migrate", sl_migrate_service,
+			 SLANG_INT_TYPE),
 	MAKE_INTRINSIC_S((char *)"service_status", sl_service_status,
 			 SLANG_VOID_TYPE),
 	MAKE_INTRINSIC_S((char *)"service_freeze", sl_service_freeze,
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index 7809b20..84e6d72 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -585,11 +585,11 @@ define default_user_event_handler()
 
 		ret = service_unfreeze(service_name);
 
-	}
+	} else if (user_request == USER_MIGRATE) {
 
-	%
-	% todo - migrate
-	%
+		ret = service_migrate(service_name, user_target);
+
+	}
 
 	return ret;
 }
-- 
1.6.2.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]