Code detailed analysis of heat transfer of OpenStack virtual machine _openstack

Source: Internet
Author: User
Tags uuid

On the other hand, virtual machine migration is divided into cold transfer and heat transfer, the so-called heat transfer of the mother's words is: thermal migration (Live migration, also known as dynamic migration, real-time migration), that is, virtual machine save/Restore (Save/restore): The entire virtual machine running state intact, At the same time can be quickly restored to the original hardware platform, or even different hardware platform. After recovery, the virtual machine still runs smoothly and the user does not perceive any differences. OpenStack Virtual machine migration is based on LIBVIRT implementation, the following look at the OpenStack virtual machine thermal Migration of the specific code implementation.

First, the API entry into the nova/api/openstack/compute/contrib/admin_actions.py

@wsgi. Action (' os-migratelive ') def _migrate_live (self, req, id, body): "" "Permit Admins to (live) migrate a server
    To a new host. "" " Context = req.environ["Nova.context"] authorize (context, ' migratelive ') try:block_migration = body["Os-mig" Ratelive "] [" block_migration "] Disk_over_commit = body[" os-migratelive "] [" disk_over_commit "] host = body[" Os-mi "
          Gratelive "] [" host "] except (TypeError, keyerror): Msg = _ (" host, block_migration and Disk_over_commit must "
      "Being specified for live migration.") Raise exc.
                            Httpbadrequest (explanation=msg) try:block_migration = strutils.bool_from_string (Block_migration,
                             strict=true) Disk_over_commit = strutils.bool_from_string (Disk_over_commit, Strict=true) except ValueError as Err:raise exc.
      Httpbadrequest (Explanation=str (err)) Try:instance = Self.compute_api.get (context, ID, want_objects=true) SElf.compute_api.live_migrate (context, instance, Block_migration, Disk_over_commit, host) except ( Exception.computeserviceunavailable, exception. Invalidhypervisortype, exception. Unabletomigratetoself, exception. Destinationhypervisortooold, exception. Novalidhost, exception. Invalidlocalstorage, exception. Invalidsharedstorage, exception. Migrationprecheckerror) as Ex:raise exc. Httpbadrequest (Explanation=ex.format_message ()) except exception. Instancenotfound as E:raise exc. Httpnotfound (Explanation=e.format_message ()) except exception. Instanceinvalidstate as State_error:common.raise_http_conflict_for_instance_invalid_state (State_error, ' O S-migratelive ') except Exception:if host is none:msg = _ ("Live migration of instance%s to another hos
      T "" failed ")% id else:msg = _ (" Live Migration of instance% (ID) s to host "      "Failed")% {' id ': ID, ' Host ': host} log.exception (msg) # Return messages from scheduler raise . Httpbadrequest (explanation=msg) return webob.

 Response (status_int=202)

The first line here can be seen with the second line of the API document:

 {"
  os-migratelive": {"
    host": "0443e9a1254044d8b99f35eace132080",
    "block_migration": false,
    "disk _over_commit ': False
  }
}

Well, the source code in fact, the implementation of the migration work is the 26th, 27 lines of a statement:

Self.compute_api.live_migrate (context, instance, block_migration,
                 Disk_over_commit, host)

From this sentence into the nova/compute/api.py, the source code is as follows:

@check_instance_cell
  @check_instance_state (vm_state=[vm_states. ACTIVE])
  def live_migrate (self, context, instance, block_migration,
           Disk_over_commit, host_name): ""
    Migrate a server lively to a new host.
    "" " Log.debug (_ ("going to try to live migrate instance to%s"),
         host_name or "another host", Instance=instance)

    Instan Ce.task_state = Task_states. Migrating
    Instance.save (Expected_task_state=[none])

    self.compute_task_api.live_migrate_instance ( Context, instance,
        host_name, block_migration=block_migration,
        disk_over_commit=disk_over_commit)

Line 2nd is an adorner, used to detect the state of a virtual machine and/or a task before entering the API method, and if the instance is in an incorrect state, an exception is thrown, then the virtual machine is migrated to the new host in real time, and the virtual machine state is placed "migrating" and then entered nova/by 12 lines conductor/api.py

def live_migrate_instance (self, context, instance, host_name,
                block_migration, Disk_over_commit):
     Scheduler _hint = {' host ': host_name}
     self._manager.migrate_server (context
       , instance, Scheduler_hint, True, False, None ,
       block_migration, Disk_over_commit, None)

Save the host name in the dictionary scheduler_hint, and then call nova/conductor/manager.py method Migrate_server,

def migrate_server (self, context, instance, Scheduler_hint, live, rebuild, flavor, block_migration, Disk_over_commi T, Reservations=none): if instance and not Isinstance (instance, instance_obj.
      Instance): # Note (DANMS): Until v2 of the RPC APIs, we need to tolerate # old-world Instance Attrs = [' Metadata ', ' system_metadata ', ' info_cache ', ' security_groups '] instance = Instance_obj. Instance._from_db_object (context, instance_obj. Instance (), Instance, Expected_attrs=attrs) if live and not rebuild and not flavor:self._live_migrate (c  Ontext, instance, Scheduler_hint, Block_migration, Disk_over_commit) elif not live and not rebuild and Flavor:instance_uuid = instance[' uuid ' with compute_utils. Eventreporter (context, self.db, ' cold_migrate ', Instance_uuid): self._cold_migrate (Context, I Nstance, flavor, scheduler_hint[' Filter_propertIES '], reservations) else:raise Notimplementederror () 

Because the parameters passed in the nova/conductor/api.py are

Self._manager.migrate_server (context
       , instance, Scheduler_hint, True, False, None,
       block_migration, Disk_ Over_commit, None)

So Live is True,rebuild is Flase,flavor is None, execute 12th, 13 lines of code:

 If live and not rebuild and not flavor:self._live_migrate (context, instance, Scheduler_hint, Blo
           Ck_migration, Disk_over_commit) _live_migrate code is as follows: Def _live_migrate (self, context, instance, Scheduler_hint, Block_migration, disk_over_commit): Destination = Scheduler_hint.get ("host") Try:live_migrate.execute (cont Ext, instance, destination, block_migration, Disk_over_commit) except (exception. Novalidhost, Exception.computeserviceunavailable, exception. Invalidhypervisortype, exception. Invalidcpuinfo, exception. Unabletomigratetoself, exception. Destinationhypervisortooold, exception. Invalidlocalstorage, exception. Invalidsharedstorage, exception. Hypervisorunavailable, exception. Migrationprecheckerror) as Ex:with excutils.save_and_reraise_exception (): #TODO (Johngarbutt)-eventually n Eed instance actions here Request_spec = {' InStance_properties ': {' uuid ': instance[' uuid '],},} scheduler_utils.set_vm_state_and_notify (Con Text, ' Compute_task ', ' Migrate_server ', dict (vm_state=instance[' vm_state '), Task_st Ate=none, Expected_task_state=task_states. migrating,), ex, Request_spec, self.db) except Exception as Ex:LOG.error (_ (' migration of instance% (INSTANCE_ID) s to host '% (dest) s unexpectedly failed. '), {' instance_id ': instance[' uuid '], ' dest ': Destination}, Exc_info=true raise exception. Migrationerror (Reason=ex)

First, the third line will assign the host name to destination, and then perform the migration, followed by an exception capture, the implementation of the migration code is divided into two parts, first look at the first part, in the nova/conductor/tasks/live_migrate.py of the 184 line:

Def execute (context, instance, destination,
      block_migration, Disk_over_commit):
  task = Livemigrationtask ( Context, instance,
               destination,
               block_migration,
               disk_over_commit)
  #TODO (Johngarbutt) Create a Superclass that contains a Safe_execute call return
  Task.execute ()

Create a superclass that contains a security execution callback, and then return the following function, which is the second part of the code that executes the migration, at around 54 lines:

def execute (self):
    self._check_instance_is_running ()
    self._check_host_is_up (self.source)

    if not Self.destination:
      self.destination = self._find_destination ()
    else:
      self._check_requested_ Destination ()

    #TODO (Johngarbutt) need to move complexity out of compute manager return
    self.compute_rpcapi.live _migration (Self.context,
        Host=self.source,
        instance=self.instance,
        dest=self.destination,
        Block_migration=self.block_migration,
        migrate_data=self.migrate_data)
        #TODO (Johngarbutt) disk_over_ Commit?

Here are three parts:

If the current host does not exist, then the scheduling algorithm to select a target host, and related detection, to ensure that real-time migration operations;

If the target host is present, the relevant detection operation is carried out directly to ensure the real-time migration operation;

Perform the migration operation.

The first two parts no longer repeat, see the third part of the code directly, in the nova/compute/rpcapi.py:

def live_migration (self, ctxt, instance, dest, Block_migration, host,
            Migrate_data=none):
    # Note (RUSSELLB) Havana compat
    Version = Self._get_compat_version (' 3.0 ', ' 2.0 ')
    instance_p = jsonutils.to_primitive (instance)
    cctxt = Self.client.prepare (Server=host, version=version)
    cctxt.cast (ctxt, ' live_migration ', instance= Instance_p,
          dest=dest, block_migration=block_migration,
          migrate_data=migrate_data)

Hot Migration starts:

 def live_migration (self, context, instance, dest, Post_method, Recover_method, Block_migration=false, Migrate_data=none): "" "spawning live_migration operation for distributing High-loa D.:p Aram Context:security Context:p Aram Instance:nova.db.sqlalchemy.models.Instance Object Instan
    Ce object is migrated.
      :p Aram Dest:destination host:p Aram Post_method:post operation method.
    Expected nova.compute.manager.post_live_migration.
      :p Aram Recover_method:recovery Method If any exception occurs.
    Expected nova.compute.manager.recover_live_migration.
    :p Aram Block_migration:if True, do block migration. :p Aram Migrate_data:implementation specific params "" Greenthread.spawn (self._live_migration, Context, Instanc E, dest, Post_method, Recover_method, Block_migration, migrate_data) 

This method establishes a green thread running method _live_migration to perform the real-time migration; The main is to invoke the Libvirt Python interface method Virdomainmigratetouri, To implement migrating domain objects from the current host to a given target host;

Spawn: Create a green thread to run the method "func (*args, **kwargs)", here is to run the method _live_migration;

_live_migration: Perform real-time migration, mainly call Libvirt Python interface method Virdomainmigratetouri, to migrate domain objects from the current host to a given target host;

Then call the _live_migration method in the green thread:

def _live_migration (self, context, instance, dest, Post_method, Recover_method, Block_migration=false,

    Migrate_data=none): "" "Do Live migration. :p Aram Context:security Context:p Aram Instance:nova.db.sqlalchemy.models.Instance object Instance Objec
    T is migrated.
      :p Aram Dest:destination host:p Aram Post_method:post operation method.
    Expected nova.compute.manager.post_live_migration.
      :p Aram Recover_method:recovery Method If any exception occurs.
    Expected nova.compute.manager.recover_live_migration.
    :p Aram Block_migration:if True, do block migration.
    :p Aram Migrate_data:implementation specific Params "" "# Do Live migration. Try:if block_migration:flaglist = CONF.libvirt.block_migration_flag.split (', ') else:flaglis t = CONF.libvirt.live_migration_flag.split (', ') flagvals = [GetAttr (Libvirt, X.strip ()) for x in flaglist] Log Ical_sum = reduce (lambda x, y:x | y, flagvals) dom = Self._lookup_by_name (instance["name"]) Dom.migratetouri (CON F.libvirt.live_migration_uri% dest, logical_sum, None, CONF.libvirt.live_mig Ration_bandwidth) except Exception as E:with excutils.save_and_reraise_exception (): Log.error (_ ("Live Migration failure:%s "), E, instance=instance) Recover_method (context, instance, dest, Block_migratio
    N) # Waiting for completion of live_migration. Timer = Loopingcall.
 Fixedintervalloopingcall (F=none)
If block_migration:
         flaglist = CONF.libvirt.block_migration_flag.split (', ')

This gets the block Migration flags list, Block_migration_flag: This parameter defines the migration flags for block migrations.

else:
         flaglist = CONF.libvirt.live_migration_flag.split (', ')
       flagvals = [GetAttr (Libvirt, X.strip ()) for X in Flaglist]
      logical_sum = reduce (lambda x, y:x | y, Flagvals)

This section gets a list of real-time migration flags, Live_migration_flag This parameter defines the migration flags for live migrations.

 Dom = Self._lookup_by_name (instance["name")

Retrieves the Libvirt domain object based on the given instance name.

 Timer = Loopingcall. Fixedintervalloopingcall (F=none)

Gets the time that the live migration waits to complete.

The Heat migration Code section ends here.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.