<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 31, 2018 at 8:26 PM, Eric Fried <span dir="ltr"><<a href="mailto:openstack@fried.cc" target="_blank">openstack@fried.cc</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">> 1. Make everything perform the pivot on compute node start (which can be<br>
>    re-used by a CLI tool for the offline case)<br>
> 2. Make everything default to non-nested inventory at first, and provide<br>
>    a way to migrate a compute node and its instances one at a time (in<br>
>    place) to roll through.<br>
<br>
</span>I agree that it sure would be nice to do ^ rather than requiring the<br>
"slide puzzle" thing.<br>
<br>
But how would this be accomplished, in light of the current "separation<br>
of responsibilities" drawn at the virt driver interface, whereby the<br>
virt driver isn't supposed to talk to placement directly, or know<br>
anything about allocations?  Here's a first pass:<br>
<br></blockquote><div><br><br></div><div>What we usually do is to implement either at the compute service level or at the virt driver level some init_host() method that will reconcile what you want.<br></div><div>For example, we could just imagine a non-virt specific method (and I like that because it's non-virt specific) - ie. called by compute's init_host() that would lookup the compute root RP inventories, see whether one ore more inventories tied to specific resource classes have to be moved from the root RP and be attached to a child RP.<br></div><div>The only subtility that would require a virt-specific update would be the name of the child RP (as both Xen and libvirt plan to use the child RP name as the vGPU type identifier) but that's an implementation detail that a possible virt driver update by the resource tracker would reconcile that.<br><br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The virt driver, via the return value from update_provider_tree, tells<br>
the resource tracker that "inventory of resource class A on provider B<br>
have moved to provider C" for all applicable AxBxC.  E.g.<br>
<br>
[ { 'from_resource_provider': <cn_rp_uuid>,<br>
    'moved_resources': [VGPU: 4],<br>
    'to_resource_provider': <gpu_rp1_uuid><br>
  },<br>
  { 'from_resource_provider': <cn_rp_uuid>,<br>
    'moved_resources': [VGPU: 4],<br>
    'to_resource_provider': <gpu_rp2_uuid><br>
  },<br>
  { 'from_resource_provider': <cn_rp_uuid>,<br>
    'moved_resources': [<br>
        SRIOV_NET_VF: 2,<br>
        NET_BANDWIDTH_EGRESS_KILOBITS_<wbr>PER_SECOND: 1000,<br>
        NET_BANDWIDTH_INGRESS_<wbr>KILOBITS_PER_SECOND: 1000,<br>
    ],<br>
    'to_resource_provider': <gpu_rp2_uuid><br>
  }<br>
]<br>
<br>
As today, the resource tracker takes the updated provider tree and<br>
invokes [1] the report client method update_from_provider_tree [2] to<br>
flush the changes to placement.  But now update_from_provider_tree also<br>
accepts the return value from update_provider_tree and, for each "move":<br>
<br>
- Creates provider C (as described in the provider_tree) if it doesn't<br>
already exist.<br>
- Creates/updates provider C's inventory as described in the<br>
provider_tree (without yet updating provider B's inventory).  This ought<br>
to create the inventory of resource class A on provider C.<br>
- Discovers allocations of rc A on rp B and POSTs to move them to rp C*.<br>
- Updates provider B's inventory.<br>
<br>
(*There's a hole here: if we're splitting a glommed-together inventory<br>
across multiple new child providers, as the VGPUs in the example, we<br>
don't know which allocations to put where.  The virt driver should know<br>
which instances own which specific inventory units, and would be able to<br>
report that info within the data structure.  That's getting kinda close<br>
to the virt driver mucking with allocations, but maybe it fits well<br>
enough into this model to be acceptable?)<br>
<br>
Note that the return value from update_provider_tree is optional, and<br>
only used when the virt driver is indicating a "move" of this ilk.  If<br>
it's None/[] then the RT/update_from_provider_tree flow is the same as<br>
it is today.<br>
<br>
If we can do it this way, we don't need a migration tool.  In fact, we<br>
don't even need to restrict provider tree "reshaping" to release<br>
boundaries.  As long as the virt driver understands its own data model<br>
migrations and reports them properly via update_provider_tree, it can<br>
shuffle its tree around whenever it wants.<br>
<br>
Thoughts?<br>
<br>
-efried<br>
<br>
[1]<br>
<a href="https://github.com/openstack/nova/blob/8753c9a38667f984d385b4783c3c2fc34d7e8e1b/nova/compute/resource_tracker.py#L890" rel="noreferrer" target="_blank">https://github.com/openstack/<wbr>nova/blob/<wbr>8753c9a38667f984d385b4783c3c2f<wbr>c34d7e8e1b/nova/compute/<wbr>resource_tracker.py#L890</a><br>
[2]<br>
<a href="https://github.com/openstack/nova/blob/8753c9a38667f984d385b4783c3c2fc34d7e8e1b/nova/scheduler/client/report.py#L1341" rel="noreferrer" target="_blank">https://github.com/openstack/<wbr>nova/blob/<wbr>8753c9a38667f984d385b4783c3c2f<wbr>c34d7e8e1b/nova/scheduler/<wbr>client/report.py#L1341</a><br>
<div class="HOEnZb"><div class="h5"><br>
______________________________<wbr>______________________________<wbr>______________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">OpenStack-dev-request@lists.<wbr>openstack.org?subject:<wbr>unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/<wbr>cgi-bin/mailman/listinfo/<wbr>openstack-dev</a><br>
</div></div></blockquote></div><br></div></div>