Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 963d04336736b0ad7b4582b100048ea89ba48fad
Parent: 640f9211a325d1e093fd3c108a97fedae646e86e
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Wed Oct 21 13:38:42 2009 -0400
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Fri Apr 8 09:31:15 2011 -0400
rgmanager: Initial commit of central proc + migration support
This adds preliminary migration support of virtual
machines when using central processing.
Resolves: rhbz#525271
Signed-off-by: Lon Hohberger <lhh(a)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 6b0db24..2ea59f9 100644
--- a/rgmanager/src/daemons/service_op.c
+++ b/rgmanager/src/daemons/service_op.c
@@ -291,7 +291,88 @@ service_op_convalesce(char *svcName)
/*
- 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) {
+ clulog(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)) {
+ clulog(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)) {
+ clulog(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 08974ad..468706f 100644
--- a/rgmanager/src/daemons/slang_event.c
+++ b/rgmanager/src/daemons/slang_event.c
@@ -619,6 +619,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
@@ -1016,6 +1073,8 @@ SLang_Intrin_Fun_Type rgmanager_slang[] =
MAKE_INTRINSIC_S((char *)"service_convalesce", sl_convalesce_service,
SLANG_INT_TYPE),
MAKE_INTRINSIC_0("service_start", sl_start_service, SLANG_INT_TYPE),
+ MAKE_INTRINSIC_0((char *)"service_migrate", sl_migrate_service,
+ SLANG_INT_TYPE),
MAKE_INTRINSIC_S("service_status", sl_service_status,
SLANG_VOID_TYPE),
MAKE_INTRINSIC_S("service_freeze", sl_service_freeze,
diff --git a/rgmanager/src/resources/default_event_script.sl
b/rgmanager/src/resources/default_event_script.sl
index da6bc1f..db6e789 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -597,11 +597,11 @@ define default_user_event_handler()
ret = service_convalesce(service_name);
- }
+ } else if (user_request == USER_MIGRATE) {
- %
- % todo - migrate
- %
+ ret = service_migrate(service_name, user_target);
+
+ }
return ret;
}