From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lon Hohberger Date: Wed, 21 Oct 2009 16:16:57 -0400 Subject: [Cluster-devel] [PATCH] rgmanager: Initial commit of central proc + migration support Message-ID: <1256156217-24948-1-git-send-email-lhh@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit This adds preliminary migration support of virtual machines when using central processing. Signed-off-by: Lon Hohberger --- 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