When host is created we create a record for each of the host's cpus. A number of cpus is set aside for SPDK, and the rest are marked as available. Each VmHostSlide can get a set of cpus assigned to it and effectively reserved for that slice. That functionality is not fully used yet but will be expanded upon in subsequent commits.
72 lines
2.9 KiB
Ruby
72 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "../model"
|
|
|
|
class VmHostSlice < Sequel::Model
|
|
one_to_one :strand, key: :id
|
|
many_to_one :vm_host
|
|
one_to_many :vms
|
|
one_to_many :cpus, class: :VmHostCpu, key: :vm_host_slice_id
|
|
|
|
include ResourceMethods
|
|
include SemaphoreMethods
|
|
semaphore :destroy, :start_after_host_reboot, :checkup
|
|
|
|
plugin :association_dependencies, cpus: :nullify
|
|
|
|
# We use cgroup format here, which looks like:
|
|
# 2-3,6-10
|
|
# (comma-separated ranges of cpus)
|
|
def allowed_cpus_cgroup
|
|
@allowed_cpus_cgroup ||= cpus.map(&:cpu_number).sort.slice_when { |a, b| b != a + 1 }.map do |group|
|
|
(group.size > 1) ? "#{group.first}-#{group.last}" : group.first.to_s
|
|
end.join(",")
|
|
end
|
|
|
|
# It allocates the CPUs to the slice and updates the slice's cores and total_cpu_percent
|
|
# Input (allowed_cpus) should be a list of cpu numbers.
|
|
def set_allowed_cpus(allowed_cpus)
|
|
allocated_cpus = vm_host.cpus_dataset.where(
|
|
Sequel[:vm_host_cpu][:spdk] => false,
|
|
Sequel[:vm_host_cpu][:vm_host_slice_id] => nil,
|
|
Sequel[:vm_host_cpu][:cpu_number] => allowed_cpus
|
|
).update(vm_host_slice_id: id)
|
|
|
|
# A concurrent xact might take some of the CPUs, so check if we got them all
|
|
fail "Not enough CPUs available." if allocated_cpus != allowed_cpus.size
|
|
|
|
# Get the proportion of cores to cpus from the host
|
|
threads_per_core = vm_host.total_cpus / vm_host.total_cores
|
|
|
|
update(cores: allocated_cpus / threads_per_core, total_cpu_percent: allocated_cpus * 100)
|
|
end
|
|
end
|
|
|
|
# Table: vm_host_slice
|
|
# Columns:
|
|
# id | uuid | PRIMARY KEY
|
|
# name | text | NOT NULL
|
|
# enabled | boolean | NOT NULL DEFAULT false
|
|
# is_shared | boolean | NOT NULL DEFAULT false
|
|
# cores | integer | NOT NULL
|
|
# total_cpu_percent | integer | NOT NULL
|
|
# used_cpu_percent | integer | NOT NULL
|
|
# total_memory_gib | integer | NOT NULL
|
|
# used_memory_gib | integer | NOT NULL
|
|
# family | text | NOT NULL
|
|
# created_at | timestamp with time zone | NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
# vm_host_id | uuid | NOT NULL
|
|
# Indexes:
|
|
# vm_host_slice_pkey | PRIMARY KEY btree (id)
|
|
# Check constraints:
|
|
# cores_not_negative | (cores >= 0)
|
|
# cpu_allocation_limit | (used_cpu_percent <= total_cpu_percent)
|
|
# memory_allocation_limit | (used_memory_gib <= total_memory_gib)
|
|
# used_cpu_not_negative | (used_cpu_percent >= 0)
|
|
# used_memory_not_negative | (used_memory_gib >= 0)
|
|
# Foreign key constraints:
|
|
# vm_host_slice_vm_host_id_fkey | (vm_host_id) REFERENCES vm_host(id)
|
|
# Referenced By:
|
|
# vm | vm_vm_host_slice_id_fkey | (vm_host_slice_id) REFERENCES vm_host_slice(id)
|
|
# vm_host_cpu | vm_host_cpu_vm_host_slice_id_fkey | (vm_host_slice_id) REFERENCES vm_host_slice(id)
|