Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0a8... Commit: 0a84466c0450d8c4810a5db3e6fab4ec146ff78c Parent: 4757639351be41c31c2001d64549b2b2fafb5666 Author: Lon Hohberger lhh@redhat.com AuthorDate: Wed Oct 21 13:38:42 2009 -0400 Committer: Lon Hohberger lhh@redhat.com CommitterDate: Fri Oct 23 16:06:53 2009 -0400
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; }
cluster-commits@lists.stg.fedorahosted.org