No Debian sob systemd, por padrão, as máquinas virtuais KVM sob libvirt são atribuídas à fatia "machine.slice".
Se eu adicionar um cpuset para esta fatia com cset
algum conjunto personalizado de CPUs e iniciar uma VM, a VM será adicionada ao cpuset adequado, ou seja
user@host ~ $ sudo cset set --list --recurse
cset:
Name CPUs-X MEMs-X Tasks Subs Path
------------ ---------- - ------- - ----- ---- ----------
root 0-31 y 0 y 610 1 /
machine.slice 2-15,18-31 n 0 n 0 1 /machine.slice
machine-qemu\x2d1\x2dweb1.scope 2-15,18-31 n 0 n 0 5 /ma....scope
vcpu1 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu1
vcpu2 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu2
vcpu0 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu0
emulator 2-15,18-31 n 0 n 82 0 /machine.sli...1.scope/emulator
vcpu3 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu3
O que estou tentando fazer é replicar esse comportamento com uma fatia e cpuset separados. No entanto, não parece funcionar.
Primeiro eu crio o cset:
user@host ~ $ sudo cset set -c 0-1,16-17 osd.slice
cset: --> created cpuset "osd.slice"
Depois defino o serviço que quero usar no slice:
user@host ~ $ diff -u /lib/systemd/system/[email protected] /etc/systemd/system/[email protected]
--- /lib/systemd/system/[email protected] 2021-05-27 06:04:21.000000000 -0400
+++ /etc/systemd/system/[email protected] 2022-11-08 17:20:32.515087642 -0500
@@ -6,6 +6,7 @@
Wants=network-online.target local-fs.target time-sync.target remote-fs-pre.target ceph-osd.target
[Service]
+Slice=osd.slice
LimitNOFILE=1048576
LimitNPROC=1048576
EnvironmentFile=-/etc/default/ceph
Então eu começo um dos serviços. Se eu verificar o status do serviço, vejo que está no slice/cgroup correto:
user@host ~ $ systemctl status [email protected]
● [email protected] - Ceph object storage daemon osd.0
Loaded: loaded (/etc/systemd/system/[email protected]; disabled; vendor preset: enabled)
Active: active (running) since Tue 2022-11-08 17:22:32 EST; 1s ago
Process: 251238 ExecStartPre=/usr/lib/ceph/ceph-osd-prestart.sh --cluster ${CLUSTER} --id 0 (code=exited, status=0/SUCCESS)
Main PID: 251245 (ceph-osd)
Tasks: 25
Memory: 29.5M
CPU: 611ms
CGroup: /osd.slice/[email protected]
└─251245 /usr/bin/ceph-osd -f --cluster ceph --id 0 --setuser ceph --setgroup ceph
E apenas por sanidade, se eu verificar o serviço transitório da VM, parece basicamente o mesmo:
$ systemctl status machine-qemu\\x2d1\\x2dweb1.scope
● machine-qemu\x2d1\x2dweb1.scope - Virtual Machine qemu-1-web1
Loaded: loaded (/run/systemd/transient/machine-qemu\x2d1\x2dweb1.scope; transient)
Transient: yes
Active: active (running) since Tue 2022-11-08 17:03:57 EST; 22min ago
Tasks: 87 (limit: 16384)
Memory: 1.7G
CPU: 4min 33.514s
CGroup: /machine.slice/machine-qemu\x2d1\x2dweb1.scope
└─234638 /usr/bin/kvm -name guest=web1,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-web1/master-key.aes -machine pc-i440fx-2.7,accel=kvm,usb=off,dump-guest-core=off,memory-ba>
No entanto , e é aqui que estou preso: se eu verificar cset
novamente, as "tarefas" não serão atribuídas ao slice cset como eu esperaria; eles fazem parte do root
cset, e o slice cset tem 0 tarefas e 0 subs:
user@host ~ $ sudo cset set --list --recurse
cset:
Name CPUs-X MEMs-X Tasks Subs Path
------------ ---------- - ------- - ----- ---- ----------
root 0-31 y 0 y 622 2 /
osd.slice 0-1,16-17 n 0 n 0 0 /osd.slice
Não consigo ver nada óbvio sobre como machine.slice
fazer isso, nenhuma referência a ele no arquivo da unidade real , nem nada nas unidades machine.slice
transitórias .scope
Como posso obter este novo slice/cgroup personalizado para emular o que machine.slice
está fazendo e forçar qualquer coisa abaixo dele para este cpuset?
Como um adendo para o "porquê"/X-para-meu-Y, tentei fazer algo como gerar o ceph-osd
processo no cset manualmente usando o cset proc --exec
comando, mas isso não funciona de forma confiável (às vezes simplesmente falha totalmente com "não pode move"), e mesmo que funcione, seus threads acabam presos no root cset depois, mesmo que o processo principal seja movido. Portanto, parece que preciso de uma maneira de fazer o systemd tratar toda a unidade como parte do cset, antes que o processo real comece (ao contrário do cset proc
comando que o gera, bifurca e depois altera), que se parece com o que é acabou machine.slice
aqui.