From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438180367917.6268496239811; Wed, 2 Jan 2019 06:09:40 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 638462D7E6; Wed, 2 Jan 2019 14:09:38 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 299045D961; Wed, 2 Jan 2019 14:09:38 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id C2AC43F607; Wed, 2 Jan 2019 14:09:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E8uLT000852 for ; Wed, 2 Jan 2019 09:08:56 -0500 Received: by smtp.corp.redhat.com (Postfix) id C959A608D9; Wed, 2 Jan 2019 14:08:56 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 29082608DC for ; Wed, 2 Jan 2019 14:08:56 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:33 +0100 Message-Id: <74fbe1a83d8c455b2b526f1b8fbb9ecbbc253462.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 01/19] util: introduce virbpf helpers X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 02 Jan 2019 14:09:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In order to implement devices controller with cgroup v2 we need to add support for BPF programs, cgroup v2 doesn't have devices controller. This introduces required helpers wrapping linux syscalls. Signed-off-by: Pavel Hrdina --- include/libvirt/virterror.h | 1 + src/libvirt_private.syms | 16 +++ src/util/Makefile.inc.am | 2 + src/util/virbpf.c | 263 ++++++++++++++++++++++++++++++++++++ src/util/virbpf.h | 246 +++++++++++++++++++++++++++++++++ src/util/virerror.c | 1 + 6 files changed, 529 insertions(+) create mode 100644 src/util/virbpf.c create mode 100644 src/util/virbpf.h diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index fbbe2d5624..d47bed4390 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -131,6 +131,7 @@ typedef enum { VIR_FROM_PERF =3D 65, /* Error from perf */ VIR_FROM_LIBSSH =3D 66, /* Error from libssh connection transpor= t */ VIR_FROM_RESCTRL =3D 67, /* Error from resource control */ + VIR_FROM_BPF =3D 68, /* Error from BPF code */ =20 # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c3d6306809..0cff580de2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1477,6 +1477,22 @@ virBitmapToDataBuf; virBitmapToString; =20 =20 +# util/virbpf.h +virBPFAttachProg; +virBPFCreateMap; +virBPFDeleteElem; +virBPFDetachProg; +virBPFGetMap; +virBPFGetMapInfo; +virBPFGetNextElem; +virBPFGetProg; +virBPFGetProgInfo; +virBPFLoadProg; +virBPFLookupElem; +virBPFQueryProg; +virBPFUpdateElem; + + # util/virbuffer.h virBufferAdd; virBufferAddBuffer; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index 4295babac3..1fd7ad2d43 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -17,6 +17,8 @@ UTIL_SOURCES =3D \ util/virauthconfig.h \ util/virbitmap.c \ util/virbitmap.h \ + util/virbpf.c \ + util/virbpf.h \ util/virbuffer.c \ util/virbuffer.h \ util/virperf.c \ diff --git a/src/util/virbpf.c b/src/util/virbpf.c new file mode 100644 index 0000000000..be5ebbc033 --- /dev/null +++ b/src/util/virbpf.c @@ -0,0 +1,263 @@ +/* + * virbpf.c: methods for eBPF + * + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ +#include + +#include + +#include "internal.h" + +#include "virbpf.h" +#include "virerror.h" +#include "virfile.h" +#include "virlog.h" +#include "virstring.h" + +VIR_LOG_INIT("util.bpf"); + +#define VIR_FROM_THIS VIR_FROM_BPF + +int +virBPFCreateMap(unsigned int mapType, + unsigned int keySize, + unsigned int valSize, + unsigned int maxEntries) +{ + union bpf_attr attr =3D { + .map_type =3D mapType, + .key_size =3D keySize, + .value_size =3D valSize, + .max_entries =3D maxEntries, + }; + + return syscall(SYS_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); +} + +#define LOG_BUF_SIZE (256 * 1024) + +int +virBPFLoadProg(struct bpf_insn *insns, + int progType, + unsigned int insnCnt) +{ + VIR_AUTOFREE(char *) logbuf =3D NULL; + int progfd =3D -1; + + if (VIR_ALLOC_N(logbuf, LOG_BUF_SIZE) < 0) + return -1; + + union bpf_attr attr =3D { + .prog_type =3D progType, + .insn_cnt =3D (__u32)insnCnt, + .insns =3D (__u64)insns, + .license =3D (__u64)"GPL", + .log_buf =3D (__u64)logbuf, + .log_size =3D LOG_BUF_SIZE, + .log_level =3D 1, + }; + + progfd =3D syscall(SYS_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); + + if (progfd < 0) + VIR_DEBUG("%s", logbuf); + + return progfd; +} + +int +virBPFAttachProg(int progfd, + int targetfd, + int attachType) +{ + union bpf_attr attr =3D { + .target_fd =3D targetfd, + .attach_bpf_fd =3D progfd, + .attach_type =3D attachType, + }; + + return syscall(SYS_bpf, BPF_PROG_ATTACH, &attr, sizeof(attr)); +} + +int +virBPFDetachProg(int progfd, + int targetfd, + int attachType) +{ + union bpf_attr attr =3D { + .target_fd =3D targetfd, + .attach_bpf_fd =3D progfd, + .attach_type =3D attachType, + }; + + return syscall(SYS_bpf, BPF_PROG_DETACH, &attr, sizeof(attr)); +} + +int +virBPFQueryProg(int targetfd, + unsigned int maxprogids, + int attachType, + unsigned int *progcnt, + void *progids) +{ + int rc; + + union bpf_attr attr =3D { + .query.target_fd =3D targetfd, + .query.attach_type =3D attachType, + .query.prog_cnt =3D maxprogids, + .query.prog_ids =3D (__u64)progids, + }; + + rc =3D syscall(SYS_bpf, BPF_PROG_QUERY, &attr, sizeof(attr)); + + if (rc >=3D 0) + *progcnt =3D attr.query.prog_cnt; + + return rc; +} + +int +virBPFGetProg(unsigned int id) +{ + union bpf_attr attr =3D { + .prog_id =3D id, + }; + + return syscall(SYS_bpf, BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr)); +} + +int +virBPFGetProgInfo(int progfd, + struct bpf_prog_info *info, + unsigned int **mapIDs) +{ + int rc; + + union bpf_attr attr =3D { + .info.bpf_fd =3D progfd, + .info.info_len =3D sizeof(struct bpf_prog_info), + .info.info =3D (__u64)info, + }; + + rc =3D syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr)); + if (rc < 0) + return rc; + + if (mapIDs && info->nr_map_ids > 0) { + unsigned int maplen =3D info->nr_map_ids; + VIR_AUTOFREE(unsigned int *) retmapIDs =3D NULL; + + if (VIR_ALLOC_N(retmapIDs, maplen) < 0) + return -1; + + memset(info, 0, sizeof(struct bpf_prog_info)); + info->nr_map_ids =3D maplen; + info->map_ids =3D (__u64)retmapIDs; + + memset(&attr, 0, sizeof(attr)); + attr.info.bpf_fd =3D progfd; + attr.info.info_len =3D sizeof(struct bpf_prog_info); + attr.info.info =3D (__u64)info; + + rc =3D syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr= )); + if (rc < 0) + return rc; + + VIR_STEAL_PTR(*mapIDs, retmapIDs); + } + + return rc; +} + +int +virBPFGetMap(unsigned int id) +{ + union bpf_attr attr =3D { + .map_id =3D id, + }; + + return syscall(SYS_bpf, BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr)); +} + +int +virBPFGetMapInfo(int mapfd, + struct bpf_map_info *info) +{ + union bpf_attr attr =3D { + .info.bpf_fd =3D mapfd, + .info.info_len =3D sizeof(struct bpf_map_info), + .info.info =3D (__u64)info, + }; + + return syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr)); +} + +int +virBPFLookupElem(int mapfd, + void *key, + void *val) +{ + union bpf_attr attr =3D { + .map_fd =3D mapfd, + .key =3D (__u64)key, + .value =3D (__u64)val, + }; + + return syscall(SYS_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); +} + +int +virBPFGetNextElem(int mapfd, + void *key, + void *nextKey) +{ + union bpf_attr attr =3D { + .map_fd =3D mapfd, + .key =3D (__u64)key, + .next_key =3D (__u64)nextKey, + }; + + return syscall(SYS_bpf, BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr)); +} + +int +virBPFUpdateElem(int mapfd, + void *key, + void *val) +{ + union bpf_attr attr =3D { + .map_fd =3D mapfd, + .key =3D (__u64)key, + .value =3D (__u64)val, + }; + + return syscall(SYS_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); +} + +int +virBPFDeleteElem(int mapfd, + void *key) +{ + union bpf_attr attr =3D { + .map_fd =3D mapfd, + .key =3D (__u64)key, + }; + + return syscall(SYS_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); +} diff --git a/src/util/virbpf.h b/src/util/virbpf.h new file mode 100644 index 0000000000..7085edaacc --- /dev/null +++ b/src/util/virbpf.h @@ -0,0 +1,246 @@ +/* + * virbpf.h: methods for eBPF + * + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef LIBVIRT_VIRBPF_H +# define LIBVIRT_VIRBPF_H + +# include + +/* ALU ops on registers, bpf_add|sub|...: dst_reg +=3D src_reg */ + +# define VIR_BPF_ALU64_REG(op, dst, src) \ + ((struct bpf_insn) { \ + .code =3D BPF_ALU64 | BPF_OP(op) | BPF_X, \ + .dst_reg =3D dst, \ + .src_reg =3D src, \ + .off =3D 0, \ + .imm =3D 0, \ + }) + +/* ALU ops on immediates, bpf_add|sub|...: dst_reg +=3D imm32 */ + +# define VIR_BPF_ALU64_IMM(op, dst, immval) \ + ((struct bpf_insn) { \ + .code =3D BPF_ALU64 | BPF_OP(op) | BPF_K, \ + .dst_reg =3D dst, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D immval, \ + }) + +/* Short form of mov, dst_reg =3D src_reg */ + +# define VIR_BPF_MOV64_REG(dst, src) \ + ((struct bpf_insn) { \ + .code =3D BPF_ALU64 | BPF_MOV | BPF_X, \ + .dst_reg =3D dst, \ + .src_reg =3D src, \ + .off =3D 0, \ + .imm =3D 0, \ + }) + +/* Short form of mov, dst_reg =3D imm32 */ + +# define VIR_BPF_MOV64_IMM(dst, immval) \ + ((struct bpf_insn) { \ + .code =3D BPF_ALU64 | BPF_MOV | BPF_K, \ + .dst_reg =3D dst, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D immval, \ + }) + +# define VIR_BPF_MOV32_IMM(dst, immval) \ + ((struct bpf_insn) { \ + .code =3D BPF_ALU | BPF_MOV | BPF_K, \ + .dst_reg =3D dst, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D immval, \ + }) + +/* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */ +# define VIR_BPF_LD_IMM64(dst, imm) \ + BPF_LD_IMM64_RAW(dst, 0, imm) + +# define VIR_BPF_LD_IMM64_RAW(dst, src, immval) \ + ((struct bpf_insn) { \ + .code =3D BPF_LD | BPF_DW | BPF_IMM, \ + .dst_reg =3D dst, \ + .src_reg =3D src, \ + .off =3D 0, \ + .imm =3D (__u32)immval, \ + }), \ + ((struct bpf_insn) { \ + .code =3D 0, \ + .dst_reg =3D 0, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D ((__u64)immval) >> 32, \ + }) + +# ifndef VIR_BPF_PSEUDO_MAP_FD +# define VIR_BPF_PSEUDO_MAP_FD 1 +# endif + +/* pseudo VIR_BPF_LD_IMM64 insn used to refer to process-local map_fd */ +# define VIR_BPF_LD_MAP_FD(dst, mapfd) \ + VIR_BPF_LD_IMM64_RAW(dst, VIR_BPF_PSEUDO_MAP_FD, mapfd) + +/* Memory load, dst_reg =3D *(uint *) (src_reg + off16) */ + +# define VIR_BPF_LDX_MEM(size, dst, src, offval) \ + ((struct bpf_insn) { \ + .code =3D BPF_LDX | BPF_SIZE(size) | BPF_MEM, \ + .dst_reg =3D dst, \ + .src_reg =3D src, \ + .off =3D offval, \ + .imm =3D 0, \ + }) + +/* Memory store, *(uint *) (dst_reg + off16) =3D src_reg */ + +# define VIR_BPF_STX_MEM(size, dst, src, offval) \ + ((struct bpf_insn) { \ + .code =3D BPF_STX | BPF_SIZE(size) | BPF_MEM, \ + .dst_reg =3D dst, \ + .src_reg =3D src, \ + .off =3D offval, \ + .imm =3D 0, \ + }) + +/* Memory store, *(uint *) (dst_reg + off16) =3D imm32 */ + +# define VIR_BPF_ST_MEM(size, dst, immval, offval) \ + ((struct bpf_insn) { \ + .code =3D BPF_ST | BPF_SIZE(size) | BPF_MEM, \ + .dst_reg =3D dst, \ + .src_reg =3D 0, \ + .off =3D offval, \ + .imm =3D immval, \ + }) + +/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc = + off16 */ + +# define VIR_BPF_JMP_REG(op, dst, src, offval) \ + ((struct bpf_insn) { \ + .code =3D BPF_JMP | BPF_OP(op) | BPF_X, \ + .dst_reg =3D dst, \ + .src_reg =3D src, \ + .off =3D offval, \ + .imm =3D 0, \ + }) + +/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc += off16 */ + +# define VIR_BPF_JMP_IMM(op, dst, immval, offval) \ + ((struct bpf_insn) { \ + .code =3D BPF_JMP | BPF_OP(op) | BPF_K, \ + .dst_reg =3D dst, \ + .src_reg =3D 0, \ + .off =3D offval, \ + .imm =3D immval, \ + }) + +/* Call eBPF function */ + +# define VIR_BPF_CALL_INSN(func) \ + ((struct bpf_insn) { \ + .code =3D BPF_JMP | BPF_CALL, \ + .dst_reg =3D 0, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D func, \ + }) + +/* Program exit */ + +# define VIR_BPF_EXIT_INSN() \ + ((struct bpf_insn) { \ + .code =3D BPF_JMP | BPF_EXIT, \ + .dst_reg =3D 0, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D 0, \ + }) + +int +virBPFCreateMap(unsigned int mapType, + unsigned int keySize, + unsigned int valSize, + unsigned int maxEntries); + +int +virBPFGetMapInfo(int mapfd, + struct bpf_map_info *info); + +int +virBPFLoadProg(struct bpf_insn *insns, + int progType, + unsigned int insnCnt); + +int +virBPFAttachProg(int progfd, + int targetfd, + int attachType); + +int +virBPFDetachProg(int progfd, + int targetfd, + int attachType); + +int +virBPFQueryProg(int targetfd, + unsigned int maxprogids, + int attachType, + unsigned int *progcnt, + void *progids); + +int +virBPFGetProg(unsigned int id); + +int +virBPFGetProgInfo(int progfd, + struct bpf_prog_info *info, + unsigned int **mapIDs); + +int +virBPFGetMap(unsigned int id); + +int +virBPFLookupElem(int mapfd, + void *key, + void *val); + +int +virBPFGetNextElem(int mapfd, + void *key, + void *nextKey); + +int +virBPFUpdateElem(int mapfd, + void *key, + void *val); + +int +virBPFDeleteElem(int mapfd, + void *key); + +#endif /* LIBVIRT_VIRBPF_H */ diff --git a/src/util/virerror.c b/src/util/virerror.c index 61b47d2be0..a40076f8ec 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -138,6 +138,7 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, "Perf", /* 65 */ "Libssh transport layer", "Resource control", + "BPF", ) =20 =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438143505594.1740515407031; Wed, 2 Jan 2019 06:09:03 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F182E394D3C; Wed, 2 Jan 2019 14:09:00 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 45EB8608D9; Wed, 2 Jan 2019 14:09:00 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8A9A33F602; Wed, 2 Jan 2019 14:08:58 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E8vBD000860 for ; Wed, 2 Jan 2019 09:08:57 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9BD29608DC; Wed, 2 Jan 2019 14:08:57 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 21A76608D9 for ; Wed, 2 Jan 2019 14:08:56 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:34 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 02/19] vircgroup: introduce virCgroupV2DevicesAvailable X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 02 Jan 2019 14:09:01 +0000 (UTC) Content-Type: text/plain; charset="utf-8" There is no exact way how to figure out whether BPF devices support is compiled into kernel. One way is to check kernel configure options but this is not reliable as it may not be available. Let's try to do syscall to which will list BPF cgroup device programs. Signed-off-by: Pavel Hrdina --- src/Makefile.am | 1 + src/util/vircgroupv2.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index e2b89e27e8..3de926403f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -670,6 +670,7 @@ libvirt_setuid_rpc_client_la_SOURCES =3D \ util/viratomic.c \ util/viratomic.h \ util/virbitmap.c \ + util/virbpf.c \ util/virbuffer.c \ util/vircgroup.c \ util/vircgroupbackend.c \ diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index cd58491da1..0adc0d4d23 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -20,8 +20,13 @@ #include =20 #ifdef __linux__ +# include +# include # include # include +# include +# include +# include #endif /* __linux__ */ =20 #include "internal.h" @@ -29,6 +34,7 @@ #define LIBVIRT_VIRCGROUPPRIV_H_ALLOW #include "vircgrouppriv.h" =20 +#include "virbpf.h" #include "vircgroup.h" #include "vircgroupbackend.h" #include "vircgroupv2.h" @@ -280,6 +286,31 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) } =20 =20 +static bool +virCgroupV2DevicesAvailable(virCgroupPtr group) +{ + bool ret =3D false; + int cgroupfd =3D -1; + unsigned int progCnt =3D 0; + + cgroupfd =3D open(group->unified.mountPoint, O_RDONLY); + if (cgroupfd < 0) { + VIR_DEBUG("failed to open cgroup '%s'", group->unified.mountPoint); + goto cleanup; + } + + if (virBPFQueryProg(cgroupfd, 0, BPF_CGROUP_DEVICE, &progCnt, NULL) < = 0) { + VIR_DEBUG("failed to query cgroup progs"); + goto cleanup; + } + + ret =3D true; + cleanup: + VIR_FORCE_CLOSE(cgroupfd); + return ret; +} + + static int virCgroupV2DetectControllers(virCgroupPtr group, int controllers) @@ -292,6 +323,8 @@ virCgroupV2DetectControllers(virCgroupPtr group, /* In cgroup v2 there is no cpuacct controller, the cpu.stat file alwa= ys * exists with usage stats. */ group->unified.controllers |=3D 1 << VIR_CGROUP_CONTROLLER_CPUACCT; + if (virCgroupV2DevicesAvailable(group)) + group->unified.controllers |=3D 1 << VIR_CGROUP_CONTROLLER_DEVICES; =20 for (i =3D 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) VIR_DEBUG("Controller '%s' present=3D%s", @@ -406,8 +439,10 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNU= SED, continue; =20 /* Controllers that are implicitly enabled if available. */ - if (i =3D=3D VIR_CGROUP_CONTROLLER_CPUACCT) + if (i =3D=3D VIR_CGROUP_CONTROLLER_CPUACCT || + i =3D=3D VIR_CGROUP_CONTROLLER_DEVICES) { continue; + } =20 if (virCgroupV2EnableController(parent, i) < 0) return -1; --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438182742122.77144743274403; Wed, 2 Jan 2019 06:09:42 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DBC0A2D7F0; Wed, 2 Jan 2019 14:09:40 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 99FC95C22C; Wed, 2 Jan 2019 14:09:40 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 3150B181BA17; Wed, 2 Jan 2019 14:09:40 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E8wOo000867 for ; Wed, 2 Jan 2019 09:08:58 -0500 Received: by smtp.corp.redhat.com (Postfix) id 6FD76608DC; Wed, 2 Jan 2019 14:08:58 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id E94FE608D9 for ; Wed, 2 Jan 2019 14:08:57 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:35 +0100 Message-Id: <783c28c778e0d1b65005fffbce96461a26ae1769.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 03/19] vircgroup: introduce virCgroupV2DeviceLoadProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 02 Jan 2019 14:09:41 +0000 (UTC) Content-Type: text/plain; charset="utf-8" There are two possible ways how to create BPF program: - One way is to write simple C-like code which can by compiled into BPF object file which can be loaded into kernel using elfutils. - The second way is to define macros which looks like assembler instructions and can be used directly to create BPF program that can be directly loaded into kernel. Since the program is not too complex we can use the second option. If there is no program, all devices are allowed, if there is some program it is executed and based on the exit status the access is denied for 0 and allowed for 1. Our program will follow these rules: - first it will try to look for the specific key using major and minor to see if there is any rule for that specific device - if there is no specific rule it will try to look for any rule that matches only major of the device - if there is no match with major it will try the same but with minor of the device - as the last attempt it will try to look for rule for all devices and if there is no match it will return 0 to deny that access Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 0adc0d4d23..63e3123cd9 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1595,6 +1595,82 @@ virCgroupV2GetCpuacctStat(virCgroupPtr group, } =20 =20 +static int +virCgroupV2DeviceLoadProg(int mapfd) +{ +# define VIR_CGROUP_BPF_LOOKUP \ + /* prepare key param on stack */ \ + VIR_BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8), \ + VIR_BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), \ + VIR_BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), \ + /* lookup key (major << 32) | minor in map */ \ + VIR_BPF_LD_MAP_FD(BPF_REG_1, mapfd), \ + VIR_BPF_CALL_INSN(BPF_FUNC_map_lookup_elem) + +# define VIR_CGROUP_BPF_CHECK_PERM \ + /* if no key skip perm check */ \ + VIR_BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), \ + /* get perms from map */ \ + VIR_BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), \ + /* get perms from ctx */ \ + VIR_BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6, 0), \ + /* (map perms) & (ctx perms) */ \ + VIR_BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2), \ + /* if (map perms) & (ctx perms) =3D=3D (ctx perms) exit, otherwise con= tinue */ \ + VIR_BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_2, 2), \ + /* set ret 1 and exit */ \ + VIR_BPF_MOV64_IMM(BPF_REG_0, 1), \ + VIR_BPF_EXIT_INSN() + + struct bpf_insn prog[] =3D { + /* save ctx, argument passed to BPF program */ + VIR_BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), + + /* get major from ctx and shift << 32 */ + VIR_BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6, 4), + VIR_BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32), + /* get minor from ctx and | to shifted major */ + VIR_BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_6, 8), + VIR_BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_3), + /* lookup ((major << 32) | minor) in map and check perms */ + VIR_CGROUP_BPF_LOOKUP, + VIR_CGROUP_BPF_CHECK_PERM, + + /* get major from ctx and shift << 32 */ + VIR_BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6, 4), + VIR_BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32), + /* use -1 as minor and | to shifted major */ + VIR_BPF_MOV32_IMM(BPF_REG_3, -1), + VIR_BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_3), + /* lookup ((major << 32) | -1) in map and check perms */ + VIR_CGROUP_BPF_LOOKUP, + VIR_CGROUP_BPF_CHECK_PERM, + + /* use -1 as major and shift << 32 */ + VIR_BPF_MOV32_IMM(BPF_REG_2, -1), + VIR_BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32), + /* get minor from ctx and | to shifted major */ + VIR_BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_6, 8), + VIR_BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_3), + /* lookup ((-1 << 32) | minor) in map and check perms */ + VIR_CGROUP_BPF_LOOKUP, + VIR_CGROUP_BPF_CHECK_PERM, + + /* use -1 as key which means major =3D -1 and minor =3D -1 */ + VIR_BPF_MOV64_IMM(BPF_REG_2, -1), + /* lookup -1 in map and check perms*/ + VIR_CGROUP_BPF_LOOKUP, + VIR_CGROUP_BPF_CHECK_PERM, + + /* no key was found, exit with 0 */ + VIR_BPF_MOV64_IMM(BPF_REG_0, 0), + VIR_BPF_EXIT_INSN(), + }; + + return virBPFLoadProg(prog, BPF_PROG_TYPE_CGROUP_DEVICE, ARRAY_CARDINA= LITY(prog)); +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154643820394610.30910996077148; Wed, 2 Jan 2019 06:10:03 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EFA432D7F2; Wed, 2 Jan 2019 14:10:00 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ADE13608E0; Wed, 2 Jan 2019 14:10:00 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5C84B3F606; Wed, 2 Jan 2019 14:10:00 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E8x3r000878 for ; Wed, 2 Jan 2019 09:08:59 -0500 Received: by smtp.corp.redhat.com (Postfix) id 433F6608DC; Wed, 2 Jan 2019 14:08:59 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id BD444608D9 for ; Wed, 2 Jan 2019 14:08:58 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:36 +0100 Message-Id: <4b61da0f9304d94bb97e8c0ef346caabfc6efe20.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 04/19] vircgroup: introduce virCgroupV2DeviceAttachProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 02 Jan 2019 14:10:02 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function loads the BPF prog with prepared map into kernel and attaches it into guest cgroup. It can be also used to replace existing program in the cgroup if we need to resize BPF map to store more rules for devices. The old program will be closed and removed from kernel. Signed-off-by: Pavel Hrdina --- src/util/vircgrouppriv.h | 10 ++++++++ src/util/vircgroupv2.c | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h index a6fb3bb9f8..085fea375c 100644 --- a/src/util/vircgrouppriv.h +++ b/src/util/vircgrouppriv.h @@ -42,10 +42,20 @@ struct _virCgroupV1Controller { typedef struct _virCgroupV1Controller virCgroupV1Controller; typedef virCgroupV1Controller *virCgroupV1ControllerPtr; =20 +struct _virCgroupV2Devices { + int mapfd; + int progfd; + ssize_t count; + ssize_t max; +}; +typedef struct _virCgroupV2Devices virCgroupV2Devices; +typedef virCgroupV2Devices *virCgroupV2DevicesPtr; + struct _virCgroupV2Controller { int controllers; char *mountPoint; char *placement; + virCgroupV2Devices devices; }; typedef struct _virCgroupV2Controller virCgroupV2Controller; typedef virCgroupV2Controller *virCgroupV2ControllerPtr; diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 63e3123cd9..7a8cc040eb 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1671,6 +1671,58 @@ virCgroupV2DeviceLoadProg(int mapfd) } =20 =20 +static int +virCgroupV2DeviceAttachProg(virCgroupPtr group, + int mapfd, + size_t max) +{ + int ret =3D -1; + int progfd =3D -1; + int cgroupfd =3D -1; + VIR_AUTOFREE(char *) path =3D NULL; + + if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_DEVICES, + NULL, &path) < 0) { + goto cleanup; + } + + progfd =3D virCgroupV2DeviceLoadProg(mapfd); + if (progfd < 0) { + virReportSystemError(errno, "%s", _("failed to load cgroup BPF pro= g")); + goto cleanup; + } + + cgroupfd =3D open(path, O_RDONLY); + if (cgroupfd < 0) { + virReportSystemError(errno, _("unable to open '%s'"), path); + goto cleanup; + } + + if (virBPFAttachProg(progfd, cgroupfd, BPF_CGROUP_DEVICE) < 0) { + virReportSystemError(errno, "%s", _("failed to attach cgroup BPF p= rog")); + goto cleanup; + } + + if (group->unified.devices.progfd > 0) { + VIR_DEBUG("Closing existing program that was replaced by new one."= ); + VIR_FORCE_CLOSE(group->unified.devices.progfd); + } + + group->unified.devices.progfd =3D progfd; + group->unified.devices.mapfd =3D mapfd; + group->unified.devices.max =3D max; + progfd =3D -1; + mapfd =3D -1; + + ret =3D 0; + cleanup: + VIR_FORCE_CLOSE(cgroupfd); + VIR_FORCE_CLOSE(progfd); + VIR_FORCE_CLOSE(mapfd); + return ret; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438144116373.2193393576897; Wed, 2 Jan 2019 06:09:04 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F21B9C05680E; Wed, 2 Jan 2019 14:09:01 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 24328101963D; Wed, 2 Jan 2019 14:09:01 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 75E9D3F604; Wed, 2 Jan 2019 14:09:00 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E90Xt000886 for ; Wed, 2 Jan 2019 09:09:00 -0500 Received: by smtp.corp.redhat.com (Postfix) id 154BF608DC; Wed, 2 Jan 2019 14:09:00 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8F5E1608D9 for ; Wed, 2 Jan 2019 14:08:59 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:37 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 05/19] vircgroup: introduce virCgroupV2DeviceDetectProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 02 Jan 2019 14:09:02 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function will be called if libvirtd was restarted while some domains were running. It will try to detect existing programs attached to the guest cgroup. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 7a8cc040eb..86adbc4ff9 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1723,6 +1723,111 @@ virCgroupV2DeviceAttachProg(virCgroupPtr group, } =20 =20 +static int +virCgroupV2DeviceCountMapEntries(int mapfd) +{ + int ret =3D 0; + int rc; + __u64 key =3D 0; + __u64 prevKey =3D 0; + + while ((rc =3D virBPFGetNextElem(mapfd, &prevKey, &key)) =3D=3D 0) { + ret++; + prevKey =3D key; + } + + if (rc < 0) + return -1; + + return ret; +} + + +# define MAX_PROG_IDS 10 + +static int +virCgroupV2DeviceDetectProg(virCgroupPtr group) +{ + int ret =3D -1; + int cgroupfd =3D -1; + unsigned int progcnt =3D 0; + unsigned int progids[MAX_PROG_IDS] =3D { 0 }; + VIR_AUTOFREE(char *) path =3D NULL; + + if (group->unified.devices.progfd > 0 && group->unified.devices.mapfd = > 0) + return 0; + + if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_DEVICES, + NULL, &path) < 0) { + return -1; + } + + cgroupfd =3D open(path, O_RDONLY); + if (cgroupfd < 0) { + virReportSystemError(errno, _("unable to open '%s'"), path); + goto cleanup; + } + + if (virBPFQueryProg(cgroupfd, MAX_PROG_IDS, BPF_CGROUP_DEVICE, + &progcnt, progids) < 0) { + virReportSystemError(errno, "%s", _("unable to query cgroup BPF pr= ogs")); + goto cleanup; + } + + if (progcnt > 0) { + int progfd =3D virBPFGetProg(progids[0]); + int mapfd =3D -1; + int nitems =3D -1; + struct bpf_prog_info progInfo =3D { 0 }; + struct bpf_map_info mapInfo =3D { 0 }; + VIR_AUTOFREE(unsigned int *) mapIDs =3D NULL; + + if (progfd < 0) { + virReportSystemError(errno, "%s", _("failed to get cgroup BPF = prog FD")); + goto cleanup; + } + + if (virBPFGetProgInfo(progfd, &progInfo, &mapIDs) < 0) { + virReportSystemError(errno, "%s", _("failed to get cgroup BPF = prog info")); + goto cleanup; + } + + if (progInfo.nr_map_ids =3D=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no map for cgroup BPF prog")); + goto cleanup; + } + + mapfd =3D virBPFGetMap(mapIDs[0]); + if (mapfd < 0) { + virReportSystemError(errno, "%s", _("failed to get cgroup BPF = map FD")); + goto cleanup; + } + + if (virBPFGetMapInfo(mapfd, &mapInfo) < 0) { + virReportSystemError(errno, "%s", _("failed to get cgroup BPF = map info")); + goto cleanup; + } + + nitems =3D virCgroupV2DeviceCountMapEntries(mapfd); + if (nitems < 0) { + virReportSystemError(errno, "%s", _("failed to count cgroup BP= F map items")); + goto cleanup; + } + + group->unified.devices.progfd =3D progfd; + group->unified.devices.mapfd =3D mapfd; + group->unified.devices.max =3D mapInfo.max_entries; + group->unified.devices.count =3D nitems; + } + + ret =3D 0; + cleanup: + VIR_FORCE_CLOSE(cgroupfd); + return ret; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154643822651965.96168091499499; Wed, 2 Jan 2019 06:10:26 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 20978CA396; Wed, 2 Jan 2019 14:10:24 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BDF8460139; Wed, 2 Jan 2019 14:10:23 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5C3CE3F60A; Wed, 2 Jan 2019 14:10:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E90in000893 for ; Wed, 2 Jan 2019 09:09:00 -0500 Received: by smtp.corp.redhat.com (Postfix) id D92FF608E0; Wed, 2 Jan 2019 14:09:00 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 612E3608DC for ; Wed, 2 Jan 2019 14:09:00 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:38 +0100 Message-Id: <37dff839836a207c07e08871b75dfb81b3d1dd57.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 06/19] vircgroup: introduce virCgroupV2DeviceCreateProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 02 Jan 2019 14:10:24 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function creates new BPF program with new empty BPF map with the default size and attaches it to the guest cgroup. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 86adbc4ff9..ae9aafd9a4 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1828,6 +1828,49 @@ virCgroupV2DeviceDetectProg(virCgroupPtr group) } =20 =20 +# define VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZE 64 + +static int +virCgroupV2DeviceCreateMap(size_t size) +{ + int mapfd =3D virBPFCreateMap(BPF_MAP_TYPE_HASH, sizeof(__u64), + sizeof(__u32), size); + + if (mapfd < 0) { + virReportSystemError(errno, "%s", + _("failed to initialize device BPF map")); + return -1; + } + + return mapfd; +} + + +static int +virCgroupV2DeviceCreateProg(virCgroupPtr group) +{ + int mapfd; + + if (group->unified.devices.progfd > 0 && group->unified.devices.mapfd = > 0) + return 0; + + mapfd =3D virCgroupV2DeviceCreateMap(VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZ= E); + if (mapfd < 0) + return -1; + + if (virCgroupV2DeviceAttachProg(group, mapfd, + VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZE) < = 0) { + goto error; + } + + return 0; + + error: + VIR_FORCE_CLOSE(mapfd); + return -1; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438180244344.1242605205723; Wed, 2 Jan 2019 06:09:40 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5CF267E9D8; Wed, 2 Jan 2019 14:09:38 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 25DEB60C6A; Wed, 2 Jan 2019 14:09:38 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id C0404181B9F6; Wed, 2 Jan 2019 14:09:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E91LN000908 for ; Wed, 2 Jan 2019 09:09:01 -0500 Received: by smtp.corp.redhat.com (Postfix) id ACDE4608DC; Wed, 2 Jan 2019 14:09:01 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 338DD608E0 for ; Wed, 2 Jan 2019 14:09:01 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:39 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 07/19] vircgroup: introduce virCgroupV2DeviceReallocMap X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 02 Jan 2019 14:09:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function will create a new BPF map and copy all existing rules from old BPF map. There is no way how to reallocate existing BPF map so we need to create a new copy if we run out of space in current BPF map. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index ae9aafd9a4..d70eefd92f 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1846,6 +1846,49 @@ virCgroupV2DeviceCreateMap(size_t size) } =20 =20 +static int +virCgroupV2DeviceReallocMap(int mapfd, + size_t size) +{ + __u64 key =3D 0; + __u64 prevKey =3D 0; + int rc; + int newmapfd =3D virCgroupV2DeviceCreateMap(size); + + VIR_DEBUG("realloc devices map mapfd:%d, size:%lu", mapfd, size); + + if (newmapfd < 0) + return -1; + + while ((rc =3D virBPFGetNextElem(mapfd, &prevKey, &key)) =3D=3D 0) { + __u32 val =3D 0; + + if (virBPFLookupElem(mapfd, &key, &val) < 0) { + virReportSystemError(errno, "%s", + _("failed to lookup device in old map")); + goto error; + } + + if (virBPFUpdateElem(newmapfd, &key, &val) < 0) { + virReportSystemError(errno, "%s", + _("failed to add device into new map")); + goto error; + } + + prevKey =3D key; + } + + if (rc < 0) + goto error; + + return newmapfd; + + error: + VIR_FORCE_CLOSE(newmapfd); + return -1; +} + + static int virCgroupV2DeviceCreateProg(virCgroupPtr group) { --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438247299258.42018039184404; Wed, 2 Jan 2019 06:10:47 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1F35E792B8; Wed, 2 Jan 2019 14:10:45 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CF84E6013C; Wed, 2 Jan 2019 14:10:44 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 85DF6181A968; Wed, 2 Jan 2019 14:10:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E92VD000913 for ; Wed, 2 Jan 2019 09:09:02 -0500 Received: by smtp.corp.redhat.com (Postfix) id 7E033608DC; Wed, 2 Jan 2019 14:09:02 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 04FA5608D9 for ; Wed, 2 Jan 2019 14:09:01 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:40 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 08/19] vircgroup: introduce virCgroupV2DevicePrepareProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 02 Jan 2019 14:10:46 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function will be called for every virCgroup(Allow|Deny)* API in order to prepare BPF program for guest. Since libvirtd can be restarted at any point we will first try to detect existing progam, if there is none we will create a new empty BPF program and lastly if we don't have any space left in the existing BPF map we will create a new copy of the BPF map with more space and attach a new program with that map into the guest cgroup. This solution allows us to start with reasonably small BPF map consuming only small amount of memory and if needed we can easily extend the BPF map if there is a lot of host devices used in guest or if user wants to hot-plug a lot of devices once the guest is running. This overcomes all the limitations in BPF: - map used in program has to be created before the program is loaded into kernel - once map is created you cannot change its size - you cannot replace map in existing program - you cannot use an array of maps because it can store FD to maps of one specific size so we would not be able to use it to overcome the second issue Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index d70eefd92f..aea094a328 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1914,6 +1914,33 @@ virCgroupV2DeviceCreateProg(virCgroupPtr group) } =20 =20 +static int +virCgroupV2DevicePrepareProg(virCgroupPtr group) +{ + if (virCgroupV2DeviceDetectProg(group) < 0) + return -1; + + if (virCgroupV2DeviceCreateProg(group) < 0) + return -1; + + if (group->unified.devices.count >=3D group->unified.devices.max) { + size_t max =3D group->unified.devices.max * 2; + int newmapfd =3D virCgroupV2DeviceReallocMap(group->unified.device= s.mapfd, + max); + + if (newmapfd < 0) + return -1; + + if (virCgroupV2DeviceAttachProg(group, newmapfd, max) < 0) { + VIR_FORCE_CLOSE(newmapfd); + return -1; + } + } + + return 0; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438204574979.5156407640005; Wed, 2 Jan 2019 06:10:04 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DC02080F93; Wed, 2 Jan 2019 14:10:00 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 98E9E5D9D6; Wed, 2 Jan 2019 14:10:00 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 4757318327E8; Wed, 2 Jan 2019 14:10:00 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E93wj000928 for ; Wed, 2 Jan 2019 09:09:03 -0500 Received: by smtp.corp.redhat.com (Postfix) id 58BA4608DC; Wed, 2 Jan 2019 14:09:03 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id CA9B9608D9 for ; Wed, 2 Jan 2019 14:09:02 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:41 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 09/19] vircgroup: introduce virCgroupV2DeviceRemoveProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 02 Jan 2019 14:10:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" We need to close our FD that we have for BPF program and map in order to let kernel remove all resources once the cgroup is removed as well. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index aea094a328..839f19c1f6 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -454,6 +454,10 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNU= SED, } =20 =20 +static int +virCgroupV2DeviceRemoveProg(virCgroupPtr group); + + static int virCgroupV2Remove(virCgroupPtr group) { @@ -469,6 +473,9 @@ virCgroupV2Remove(virCgroupPtr group) if (virCgroupV2PathOfController(group, controller, "", &grppath) < 0) return 0; =20 + if (virCgroupV2DeviceRemoveProg(group) < 0) + return -1; + return virCgroupRemoveRecursively(grppath); } =20 @@ -1941,6 +1948,25 @@ virCgroupV2DevicePrepareProg(virCgroupPtr group) } =20 =20 +static int +virCgroupV2DeviceRemoveProg(virCgroupPtr group) +{ + if (virCgroupV2DeviceDetectProg(group) < 0) + return -1; + + if (group->unified.devices.progfd <=3D 0 && group->unified.devices.map= fd <=3D 0) + return 0; + + if (group->unified.devices.mapfd >=3D 0) + VIR_FORCE_CLOSE(group->unified.devices.mapfd); + + if (group->unified.devices.progfd >=3D 0) + VIR_FORCE_CLOSE(group->unified.devices.progfd); + + return 0; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438272845100.62557632351536; Wed, 2 Jan 2019 06:11:12 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 879DEC7C22; Wed, 2 Jan 2019 14:11:09 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4674C608DC; Wed, 2 Jan 2019 14:11:09 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E132618434BE; Wed, 2 Jan 2019 14:11:08 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E94xY000936 for ; Wed, 2 Jan 2019 09:09:04 -0500 Received: by smtp.corp.redhat.com (Postfix) id 25C24608DC; Wed, 2 Jan 2019 14:09:04 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9ED3B608D9 for ; Wed, 2 Jan 2019 14:09:03 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:42 +0100 Message-Id: <8f95e3ce4cc46fc04aca1c96809f8a595deaeb1d.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 10/19] vircgroup: introduce virCgroupV2DeviceGetPerms X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 02 Jan 2019 14:11:10 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 839f19c1f6..30f8da22ac 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1967,6 +1967,32 @@ virCgroupV2DeviceRemoveProg(virCgroupPtr group) } =20 =20 +static __u32 +virCgroupV2DeviceGetPerms(int perms, + char type) +{ + __u32 ret =3D 0; + + if (perms & VIR_CGROUP_DEVICE_MKNOD) + ret |=3D BPF_DEVCG_ACC_MKNOD << 16; + + if (perms & VIR_CGROUP_DEVICE_READ) + ret |=3D BPF_DEVCG_ACC_READ << 16; + + if (perms & VIR_CGROUP_DEVICE_WRITE) + ret |=3D BPF_DEVCG_ACC_WRITE << 16; + + if (type =3D=3D 'b') + ret |=3D BPF_DEVCG_DEV_BLOCK; + else if (type =3D=3D 'c') + ret |=3D BPF_DEVCG_DEV_CHAR; + else + ret |=3D BPF_DEVCG_DEV_BLOCK | BPF_DEVCG_DEV_CHAR; + + return ret; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438293210724.6703243785979; Wed, 2 Jan 2019 06:11:33 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 588C18AE41; Wed, 2 Jan 2019 14:11:31 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 80A83105B200; Wed, 2 Jan 2019 14:11:30 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 278AD3F606; Wed, 2 Jan 2019 14:11:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E944T000943 for ; Wed, 2 Jan 2019 09:09:05 -0500 Received: by smtp.corp.redhat.com (Postfix) id ED697608DC; Wed, 2 Jan 2019 14:09:04 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 722B3608D9 for ; Wed, 2 Jan 2019 14:09:04 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:43 +0100 Message-Id: <1b3668c95b2eb53b20eae7bddfab8675047d724b.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 11/19] vircgroup: introduce virCgroupV2DeviceGetKey X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 02 Jan 2019 14:11:32 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Device rules are stored in BPF map that is a hash type, this function will create a key based on major and minor id of device. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 30f8da22ac..198d2ea03e 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1993,6 +1993,14 @@ virCgroupV2DeviceGetPerms(int perms, } =20 =20 +static __u64 +virCgroupV2DeviceGetKey(int major, + int minor) +{ + return (__u64)major << 32 | ((__u64)minor & 0x00000000ffffffff); +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438313817647.7559465917121; Wed, 2 Jan 2019 06:11:53 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D791CC7C0A; Wed, 2 Jan 2019 14:11:51 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A682D5D762; Wed, 2 Jan 2019 14:11:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5CC90181B9F6; Wed, 2 Jan 2019 14:11:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E95kx000961 for ; Wed, 2 Jan 2019 09:09:05 -0500 Received: by smtp.corp.redhat.com (Postfix) id C000A608DC; Wed, 2 Jan 2019 14:09:05 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 469AF608D9 for ; Wed, 2 Jan 2019 14:09:05 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:44 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 12/19] vircgroup: introduce virCgroupV2AllowDevice X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 02 Jan 2019 14:11:52 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In order to allow device we need to create key and value which will be used to update BPF map. virBPFUpdateElem() can override existing entries in BPF map so we need to check if that entry exists in order to track number of entries in our map. This can add rule for specific device but major and minor can be both -1 which follows the same behavior as in cgroup v1. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 198d2ea03e..e579464ff3 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -2001,6 +2001,35 @@ virCgroupV2DeviceGetKey(int major, } =20 =20 +static int +virCgroupV2AllowDevice(virCgroupPtr group, + char type, + int major, + int minor, + int perms) +{ + __u64 key =3D virCgroupV2DeviceGetKey(major, minor); + __u32 val =3D virCgroupV2DeviceGetPerms(perms, type); + int rc; + + if (virCgroupV2DevicePrepareProg(group) < 0) + return -1; + + rc =3D virBPFLookupElem(group->unified.devices.mapfd, &key, NULL); + + if (virBPFUpdateElem(group->unified.devices.mapfd, &key, &val) < 0) { + virReportSystemError(errno, "%s", + _("failed to update device in BPF cgroup map"= )); + return -1; + } + + if (rc < 0) + group->unified.devices.count++; + + return 0; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 @@ -2050,6 +2079,8 @@ virCgroupBackend virCgroupV2Backend =3D { .getMemSwapHardLimit =3D virCgroupV2GetMemSwapHardLimit, .getMemSwapUsage =3D virCgroupV2GetMemSwapUsage, =20 + .allowDevice =3D virCgroupV2AllowDevice, + .setCpuShares =3D virCgroupV2SetCpuShares, .getCpuShares =3D virCgroupV2GetCpuShares, .setCpuCfsPeriod =3D virCgroupV2SetCpuCfsPeriod, --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438336820470.63295066445767; Wed, 2 Jan 2019 06:12:16 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 450F2C7966; Wed, 2 Jan 2019 14:12:14 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E9F9560C6B; Wed, 2 Jan 2019 14:12:13 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 910C8181B9EA; Wed, 2 Jan 2019 14:12:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E96fJ000968 for ; Wed, 2 Jan 2019 09:09:06 -0500 Received: by smtp.corp.redhat.com (Postfix) id 92B6C608E5; Wed, 2 Jan 2019 14:09:06 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 188FD608D9 for ; Wed, 2 Jan 2019 14:09:05 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:45 +0100 Message-Id: <1a20e6f4f636171de64e94161862f29789aa7ea6.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 13/19] vircgroup: introduce virCgroupV2DenyDevice X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 02 Jan 2019 14:12:15 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In order to deny device we need to check if there is any entry in BPF map and we need to load the current value from map if there is already entry for that device. If both values are same we can remove that entry but if they are different we need to update the entry because we don't have to deny all access, but for example only write access. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index e579464ff3..aea7ba677f 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -2030,6 +2030,46 @@ virCgroupV2AllowDevice(virCgroupPtr group, } =20 =20 +static int +virCgroupV2DenyDevice(virCgroupPtr group, + char type, + int major, + int minor, + int perms) +{ + __u64 key =3D virCgroupV2DeviceGetKey(major, minor); + __u32 newval =3D virCgroupV2DeviceGetPerms(perms, type); + __u32 val =3D 0; + + if (virCgroupV2DevicePrepareProg(group) < 0) + return -1; + + if (group->unified.devices.count <=3D 0 || + virBPFLookupElem(group->unified.devices.mapfd, &key, &val) < 0) { + VIR_DEBUG("nothing to do, device is not allowed"); + return 0; + } + + if (newval =3D=3D val) { + if (virBPFDeleteElem(group->unified.devices.mapfd, &key) < 0) { + virReportSystemError(errno, "%s", + _("failed to remove device from BPF cgrou= p map")); + return -1; + } + group->unified.devices.count--; + } else { + val ^=3D val & newval; + if (virBPFUpdateElem(group->unified.devices.mapfd, &key, &val) < 0= ) { + virReportSystemError(errno, "%s", + _("failed to update device in BPF cgroup = map")); + return -1; + } + } + + return 0; +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 @@ -2080,6 +2120,7 @@ virCgroupBackend virCgroupV2Backend =3D { .getMemSwapUsage =3D virCgroupV2GetMemSwapUsage, =20 .allowDevice =3D virCgroupV2AllowDevice, + .denyDevice =3D virCgroupV2DenyDevice, =20 .setCpuShares =3D virCgroupV2SetCpuShares, .getCpuShares =3D virCgroupV2GetCpuShares, --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438210683807.1213046171716; Wed, 2 Jan 2019 06:10:10 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 94C92C034DE1; Wed, 2 Jan 2019 14:10:08 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4EA5A103BAB2; Wed, 2 Jan 2019 14:10:08 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id D33443F608; Wed, 2 Jan 2019 14:10:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E97Pn000978 for ; Wed, 2 Jan 2019 09:09:07 -0500 Received: by smtp.corp.redhat.com (Postfix) id 64C1A608DC; Wed, 2 Jan 2019 14:09:07 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id DF90D608E0 for ; Wed, 2 Jan 2019 14:09:06 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:46 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 14/19] vircgroup: introduce virCgroupV2AllowAllDevices X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 02 Jan 2019 14:10:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" If we want to allow all devices with all permissions we need to replace any existing program that has any rule configured, otherwise we just need to add new rule which will for example allow read access to all devices. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index aea7ba677f..6c3f2bf522 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -2070,6 +2070,23 @@ virCgroupV2DenyDevice(virCgroupPtr group, } =20 =20 +static int +virCgroupV2AllowAllDevices(virCgroupPtr group, + int perms) +{ + if (virCgroupV2DevicePrepareProg(group) < 0) + return -1; + + if (group->unified.devices.count > 0 && + perms =3D=3D VIR_CGROUP_DEVICE_RWM && + virCgroupV2DeviceCreateProg(group) < 0) { + return -1; + } + + return virCgroupV2AllowDevice(group, 'a', -1, -1, perms); +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 @@ -2121,6 +2138,7 @@ virCgroupBackend virCgroupV2Backend =3D { =20 .allowDevice =3D virCgroupV2AllowDevice, .denyDevice =3D virCgroupV2DenyDevice, + .allowAllDevices =3D virCgroupV2AllowAllDevices, =20 .setCpuShares =3D virCgroupV2SetCpuShares, .getCpuShares =3D virCgroupV2GetCpuShares, --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438235753707.319875102806; Wed, 2 Jan 2019 06:10:35 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D73F86147B; Wed, 2 Jan 2019 14:10:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9EF66101963D; Wed, 2 Jan 2019 14:10:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 35862181B9EB; Wed, 2 Jan 2019 14:10:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E98e5000984 for ; Wed, 2 Jan 2019 09:09:08 -0500 Received: by smtp.corp.redhat.com (Postfix) id 36E89608E0; Wed, 2 Jan 2019 14:09:08 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id B24DC608E5 for ; Wed, 2 Jan 2019 14:09:07 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:47 +0100 Message-Id: <17b5479bcec11da70dc901a043686d74a4a18672.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 15/19] vircgroup: introduce virCgroupV2DenyAllDevices X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 02 Jan 2019 14:10:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" If we want to deny all devices we just need to replace any existing program with new program with empty map. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 6c3f2bf522..4bcdd16814 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -2087,6 +2087,16 @@ virCgroupV2AllowAllDevices(virCgroupPtr group, } =20 =20 +static int +virCgroupV2DenyAllDevices(virCgroupPtr group) +{ + if (virCgroupV2DeviceDetectProg(group) < 0) + return -1; + + return virCgroupV2DeviceCreateProg(group); +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 @@ -2139,6 +2149,7 @@ virCgroupBackend virCgroupV2Backend =3D { .allowDevice =3D virCgroupV2AllowDevice, .denyDevice =3D virCgroupV2DenyDevice, .allowAllDevices =3D virCgroupV2AllowAllDevices, + .denyAllDevices =3D virCgroupV2DenyAllDevices, =20 .setCpuShares =3D virCgroupV2SetCpuShares, .getCpuShares =3D virCgroupV2GetCpuShares, --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154643825877747.61684492616553; Wed, 2 Jan 2019 06:10:58 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A2DB3C050E08; Wed, 2 Jan 2019 14:10:56 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6EC316013D; Wed, 2 Jan 2019 14:10:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 0BA213F609; Wed, 2 Jan 2019 14:10:56 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E99iJ000994 for ; Wed, 2 Jan 2019 09:09:09 -0500 Received: by smtp.corp.redhat.com (Postfix) id 0B3F3608DC; Wed, 2 Jan 2019 14:09:09 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8545B608D9 for ; Wed, 2 Jan 2019 14:09:08 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:48 +0100 Message-Id: <316571c8105e519256fe800ddbec840f7df865c0.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 16/19] vircgroup: workaround devices in hybrid mode X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 02 Jan 2019 14:10:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" So the issue here is that you can end up with configuration where you have cgroup v1 and v2 enabled at the same time and the devices controllers is enabled for cgroup v1. In cgroup v2 there is no devices controller, the device access is controlled using BPF and since it is not a cgroup controller both of them can exists at the same time and both of them are applied while resolving access to devices. In order to avoid configuring both BPF and cgroup v1 devices we will use BPF if possible and otherwise fallback to cgroup v1 devices. Signed-off-by: Pavel Hrdina --- src/util/vircgroup.c | 3 ++- src/util/vircgroupbackend.h | 3 ++- src/util/vircgroupv1.c | 9 ++++++++- src/util/vircgroupv2.c | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 3ebb3b0a0f..9d284e9bf4 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -381,7 +381,8 @@ virCgroupDetect(virCgroupPtr group, =20 for (i =3D 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { if (group->backends[i]) { - int rc =3D group->backends[i]->detectControllers(group, contro= llers); + int rc =3D group->backends[i]->detectControllers(group, contro= llers, + controllersAvai= lable); if (rc < 0) return -1; controllersAvailable |=3D rc; diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h index 24b45be9bb..9bc8e7b11d 100644 --- a/src/util/vircgroupbackend.h +++ b/src/util/vircgroupbackend.h @@ -96,7 +96,8 @@ typedef char * =20 typedef int (*virCgroupDetectControllersCB)(virCgroupPtr group, - int controllers); + int controllers, + int detected); =20 typedef bool (*virCgroupHasControllerCB)(virCgroupPtr cgroup, diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c index f6707e4894..c94fad0591 100644 --- a/src/util/vircgroupv1.c +++ b/src/util/vircgroupv1.c @@ -417,7 +417,8 @@ virCgroupV1StealPlacement(virCgroupPtr group) =20 static int virCgroupV1DetectControllers(virCgroupPtr group, - int controllers) + int controllers, + int detected) { size_t i; size_t j; @@ -427,6 +428,9 @@ virCgroupV1DetectControllers(virCgroupPtr group, /* First mark requested but non-existing controllers to be ignored= */ for (i =3D 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { if (((1 << i) & controllers)) { + int type =3D 1 << i; + if (type & detected) + VIR_FREE(group->legacy[i].mountPoint); /* Remove non-existent controllers */ if (!group->legacy[i].mountPoint) { VIR_DEBUG("Requested controller '%s' not mounted, igno= ring", @@ -466,6 +470,9 @@ virCgroupV1DetectControllers(virCgroupPtr group, VIR_DEBUG("Auto-detecting controllers"); controllers =3D 0; for (i =3D 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + int type =3D 1 << i; + if (type & detected) + VIR_FREE(group->legacy[i].mountPoint); VIR_DEBUG("Controller '%s' present=3D%s", virCgroupV1ControllerTypeToString(i), group->legacy[i].mountPoint ? "yes" : "no"); diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 4bcdd16814..e28703df89 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -313,7 +313,8 @@ virCgroupV2DevicesAvailable(virCgroupPtr group) =20 static int virCgroupV2DetectControllers(virCgroupPtr group, - int controllers) + int controllers, + int detected) { size_t i; =20 @@ -326,6 +327,8 @@ virCgroupV2DetectControllers(virCgroupPtr group, if (virCgroupV2DevicesAvailable(group)) group->unified.controllers |=3D 1 << VIR_CGROUP_CONTROLLER_DEVICES; =20 + group->unified.controllers &=3D ~detected; + for (i =3D 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) VIR_DEBUG("Controller '%s' present=3D%s", virCgroupV2ControllerTypeToString(i), --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438281423306.7217350990064; Wed, 2 Jan 2019 06:11:21 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4A7768B10C; Wed, 2 Jan 2019 14:11:19 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0795760C6D; Wed, 2 Jan 2019 14:11:19 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AE96F1832E8F; Wed, 2 Jan 2019 14:11:18 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E992S000999 for ; Wed, 2 Jan 2019 09:09:09 -0500 Received: by smtp.corp.redhat.com (Postfix) id D1580608DC; Wed, 2 Jan 2019 14:09:09 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5728F608D9 for ; Wed, 2 Jan 2019 14:09:09 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:49 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 17/19] vircgroupv2: detech BPF program before removing cgroup X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 02 Jan 2019 14:11:20 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function simply removes program from guest cgroup before we remove the cgroup. This is required step because there is a bug [1] in kernel where the program might not be properly freed if you remove cgroup with attached program. [1] Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index e28703df89..0a4aa15d0b 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1954,19 +1954,44 @@ virCgroupV2DevicePrepareProg(virCgroupPtr group) static int virCgroupV2DeviceRemoveProg(virCgroupPtr group) { + int ret =3D -1; + int cgroupfd =3D -1; + VIR_AUTOFREE(char *) path =3D NULL; + if (virCgroupV2DeviceDetectProg(group) < 0) return -1; =20 if (group->unified.devices.progfd <=3D 0 && group->unified.devices.map= fd <=3D 0) return 0; =20 + if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_DEVICES, + NULL, &path) < 0) { + return -1; + } + + cgroupfd =3D open(path, O_RDONLY); + if (cgroupfd < 0) { + virReportSystemError(errno, _("unable to open '%s'"), path); + goto cleanup; + } + + if (virBPFDetachProg(group->unified.devices.progfd, + cgroupfd, BPF_CGROUP_DEVICE) < 0) { + virReportSystemError(errno, "%s", _("failed to detach cgroup BPF p= rog")); + goto cleanup; + } + if (group->unified.devices.mapfd >=3D 0) VIR_FORCE_CLOSE(group->unified.devices.mapfd); =20 if (group->unified.devices.progfd >=3D 0) VIR_FORCE_CLOSE(group->unified.devices.progfd); =20 - return 0; + ret =3D 0; + + cleanup: + VIR_FORCE_CLOSE(cgroupfd); + return ret; } =20 =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438359015332.7560816268074; Wed, 2 Jan 2019 06:12:39 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 74C6989ADC; Wed, 2 Jan 2019 14:12:36 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 394A55D75F; Wed, 2 Jan 2019 14:12:36 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E2B313F602; Wed, 2 Jan 2019 14:12:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E9Apf001010 for ; Wed, 2 Jan 2019 09:09:10 -0500 Received: by smtp.corp.redhat.com (Postfix) id A4E33608DC; Wed, 2 Jan 2019 14:09:10 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A3D8608D9 for ; Wed, 2 Jan 2019 14:09:10 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:50 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 18/19] vircgroupv2: use dummy process to workaround kernel bug with systemd X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 02 Jan 2019 14:12:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" If some program is attached to cgroup and that cgroup is removed before detaching the program it might not be freed and will remain in the system until it's rebooted. This would not be that big deal to workaround if we wouldn't use machined to track our guests. Systemd tries to be the nice guy and if there is no process attached to TransientUnit it will destroy the unit and remove the cgroup from system which will hit the kernel bug. In order to prevent this behavior of systemd we can move another process into the guest cgroup and the cgroup will remain active even if we kill qemu process while destroying guest. We can then detach our BPF program from that cgroup and call machined terminate API to cleanup the cgroup. Signed-off-by: Pavel Hrdina --- src/libvirt_private.syms | 1 + src/lxc/lxc_cgroup.c | 1 + src/qemu/qemu_cgroup.c | 6 +++- src/util/vircgroup.c | 15 +++++++++ src/util/vircgroup.h | 1 + src/util/vircgrouppriv.h | 2 ++ src/util/vircgroupv2.c | 68 ++++++++++++++++++++++++++++++++++++++-- src/util/virsystemd.c | 2 +- src/util/virsystemd.h | 2 ++ 9 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0cff580de2..f4a81370bb 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3021,6 +3021,7 @@ virSystemdCanHybridSleep; virSystemdCanSuspend; virSystemdCreateMachine; virSystemdGetMachineNameByPID; +virSystemdHasMachined; virSystemdHasMachinedResetCachedValue; virSystemdMakeScopeName; virSystemdMakeSliceName; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index d93a19d684..a8cef74bb9 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -455,6 +455,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, nnicindexes, nicindexes, def->resource->partition, -1, + LXC_STATE_DIR, &cgroup) < 0) goto cleanup; =20 diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 4931fb6575..9374a799a1 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -946,6 +946,7 @@ qemuInitCgroup(virDomainObjPtr vm, nnicindexes, nicindexes, vm->def->resource->partition, cfg->cgroupControllers, + cfg->stateDir, &priv->cgroup) < 0) { if (virCgroupNewIgnoreError()) goto done; @@ -1256,16 +1257,19 @@ int qemuRemoveCgroup(virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv =3D vm->privateData; + int rc =3D 0; =20 if (priv->cgroup =3D=3D NULL) return 0; /* Not supported, so claim success */ =20 + rc =3D virCgroupRemove(priv->cgroup); + if (virCgroupTerminateMachine(priv->machineName) < 0) { if (!virCgroupNewIgnoreError()) VIR_DEBUG("Failed to terminate cgroup for %s", vm->def->name); } =20 - return virCgroupRemove(priv->cgroup); + return rc; } =20 =20 diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 9d284e9bf4..19d81cf050 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1105,6 +1105,7 @@ virCgroupNewMachineSystemd(const char *name, int *nicindexes, const char *partition, int controllers, + const char *stateDir, virCgroupPtr *group) { int rv; @@ -1151,6 +1152,16 @@ virCgroupNewMachineSystemd(const char *name, return -1; } =20 + if (VIR_STRDUP((*group)->stateDir, stateDir) < 0) { + virCgroupFree(group); + return -1; + } + + if (VIR_STRDUP((*group)->vmName, name) < 0) { + virCgroupFree(group); + return -1; + } + if (virCgroupAddProcess(*group, pidleader) < 0) { virErrorPtr saved =3D virSaveLastError(); virCgroupRemove(*group); @@ -1233,6 +1244,7 @@ virCgroupNewMachine(const char *name, int *nicindexes, const char *partition, int controllers, + const char *stateDir, virCgroupPtr *group) { int rv; @@ -1249,6 +1261,7 @@ virCgroupNewMachine(const char *name, nicindexes, partition, controllers, + stateDir, group)) =3D=3D 0) return 0; =20 @@ -1301,6 +1314,8 @@ virCgroupFree(virCgroupPtr *group) VIR_FREE((*group)->unified.placement); =20 VIR_FREE((*group)->path); + VIR_FREE((*group)->stateDir); + VIR_FREE((*group)->vmName); VIR_FREE(*group); } =20 diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index 372009de4a..0cd90d3651 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -98,6 +98,7 @@ int virCgroupNewMachine(const char *name, int *nicindexes, const char *partition, int controllers, + const char *stateDir, virCgroupPtr *group) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h index 085fea375c..e0ccce88a0 100644 --- a/src/util/vircgrouppriv.h +++ b/src/util/vircgrouppriv.h @@ -62,6 +62,8 @@ typedef virCgroupV2Controller *virCgroupV2ControllerPtr; =20 struct _virCgroup { char *path; + char *stateDir; + char *vmName; =20 virCgroupBackendPtr backends[VIR_CGROUP_BACKEND_TYPE_LAST]; =20 diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 0a4aa15d0b..f5c43ae4bc 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -38,9 +38,12 @@ #include "vircgroup.h" #include "vircgroupbackend.h" #include "vircgroupv2.h" +#include "vircommand.h" #include "virerror.h" #include "virfile.h" #include "virlog.h" +#include "virpidfile.h" +#include "virprocess.h" #include "virstring.h" #include "virsystemd.h" =20 @@ -479,6 +482,9 @@ virCgroupV2Remove(virCgroupPtr group) if (virCgroupV2DeviceRemoveProg(group) < 0) return -1; =20 + if (virSystemdHasMachined() =3D=3D 0) + virCgroupKillPainfully(group); + return virCgroupRemoveRecursively(grppath); } =20 @@ -1899,17 +1905,74 @@ virCgroupV2DeviceReallocMap(int mapfd, } =20 =20 +static pid_t +virCgroupV2DeviceStartDummyProc(virCgroupPtr group) +{ + pid_t ret =3D -1; + pid_t pid =3D -1; + virCommandPtr cmd =3D NULL; + VIR_AUTOFREE(char *) pidfile =3D NULL; + VIR_AUTOFREE(char *) fileName =3D NULL; + + if (virAsprintf(&fileName, "cgroup-%s", group->vmName) < 0) + return -1; + + pidfile =3D virPidFileBuildPath(group->stateDir, fileName); + if (!pidfile) + return -1; + + cmd =3D virCommandNewArgList("/usr/bin/tail", "-f", "/dev/null", + "-s", "3600", NULL); + if (!cmd) + return -1; + + virCommandDaemonize(cmd); + virCommandSetPidFile(cmd, pidfile); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + if (virPidFileReadPath(pidfile, &pid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to start dummy cgroup helper")); + goto cleanup; + } + + if (virCgroupAddMachineProcess(group, pid) < 0) + goto cleanup; + + ret =3D pid; + cleanup: + if (ret < 0) { + virCommandAbort(cmd); + if (pid > 0) + virProcessKillPainfully(pid, true); + } + if (pidfile) + unlink(pidfile); + virCommandFree(cmd); + return ret; +} + + static int virCgroupV2DeviceCreateProg(virCgroupPtr group) { - int mapfd; + int mapfd =3D -1; + pid_t pid =3D -1; =20 if (group->unified.devices.progfd > 0 && group->unified.devices.mapfd = > 0) return 0; =20 + if (virSystemdHasMachined() =3D=3D 0) { + pid =3D virCgroupV2DeviceStartDummyProc(group); + if (pid < 0) + return -1; + } + mapfd =3D virCgroupV2DeviceCreateMap(VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZ= E); if (mapfd < 0) - return -1; + goto error; =20 if (virCgroupV2DeviceAttachProg(group, mapfd, VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZE) < = 0) { @@ -1919,6 +1982,7 @@ virCgroupV2DeviceCreateProg(virCgroupPtr group) return 0; =20 error: + virProcessKillPainfully(pid, true); VIR_FORCE_CLOSE(mapfd); return -1; } diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c index f492ac1859..ca35b12a5c 100644 --- a/src/util/virsystemd.c +++ b/src/util/virsystemd.c @@ -138,7 +138,7 @@ void virSystemdHasMachinedResetCachedValue(void) * -1 =3D error * 0 =3D machine1 is available */ -static int +int virSystemdHasMachined(void) { int ret; diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h index 7d9c0ebd62..553d4196f1 100644 --- a/src/util/virsystemd.h +++ b/src/util/virsystemd.h @@ -51,4 +51,6 @@ int virSystemdCanHybridSleep(bool *result); =20 char *virSystemdGetMachineNameByPID(pid_t pid); =20 +int virSystemdHasMachined(void); + #endif /* LIBVIRT_VIRSYSTEMD_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Apr 25 14:18:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1546438302789853.7110098963145; Wed, 2 Jan 2019 06:11:42 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AED1CB083A; Wed, 2 Jan 2019 14:11:40 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 751E8101F94C; Wed, 2 Jan 2019 14:11:40 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 22228181BA1A; Wed, 2 Jan 2019 14:11:40 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x02E9BTC001024 for ; Wed, 2 Jan 2019 09:09:11 -0500 Received: by smtp.corp.redhat.com (Postfix) id 78AEC608DC; Wed, 2 Jan 2019 14:09:11 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id F25A4608D9 for ; Wed, 2 Jan 2019 14:09:10 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 2 Jan 2019 15:08:51 +0100 Message-Id: <93db414ec992a680d3d6065a5d407e06321536bf.1546437956.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 19/19] vircgroupmock: mock virBPFQueryProg X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 02 Jan 2019 14:11:41 +0000 (UTC) Content-Type: text/plain; charset="utf-8" We need to mock virBPFQueryProg() in order to prevent extra syscall which tries to detect whether we can list cgroup BPF programs. Signed-off-by: Pavel Hrdina --- src/util/virbpf.h | 5 ++++- tests/vircgroupdata/hybrid.parsed | 2 +- tests/vircgroupmock.c | 11 +++++++++++ tests/vircgrouptest.c | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/util/virbpf.h b/src/util/virbpf.h index 7085edaacc..35e89e965c 100644 --- a/src/util/virbpf.h +++ b/src/util/virbpf.h @@ -23,6 +23,8 @@ =20 # include =20 +# include "internal.h" + /* ALU ops on registers, bpf_add|sub|...: dst_reg +=3D src_reg */ =20 # define VIR_BPF_ALU64_REG(op, dst, src) \ @@ -211,7 +213,8 @@ virBPFQueryProg(int targetfd, unsigned int maxprogids, int attachType, unsigned int *progcnt, - void *progids); + void *progids) + ATTRIBUTE_NOINLINE; =20 int virBPFGetProg(unsigned int id); diff --git a/tests/vircgroupdata/hybrid.parsed b/tests/vircgroupdata/hybrid= .parsed index 7600de5f45..f755eed465 100644 --- a/tests/vircgroupdata/hybrid.parsed +++ b/tests/vircgroupdata/hybrid.parsed @@ -2,7 +2,7 @@ cpu cpuacct cpuset /not/really/sys/fs/cgroup/cpuset memory -devices /not/really/sys/fs/cgroup/devices +devices freezer /not/really/sys/fs/cgroup/freezer blkio net_cls /not/really/sys/fs/cgroup/net_cls diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c index 06bd0a5f29..0e5a7b0917 100644 --- a/tests/vircgroupmock.c +++ b/tests/vircgroupmock.c @@ -34,6 +34,7 @@ # include "testutilslxc.h" # include "virstring.h" # include "virfile.h" +# include "virbpf.h" =20 static int (*real_open)(const char *path, int flags, ...); static FILE *(*real_fopen)(const char *path, const char *mode); @@ -701,6 +702,16 @@ int open(const char *path, int flags, ...) free(newpath); return ret; } + +int +virBPFQueryProg(int targetfd ATTRIBUTE_UNUSED, + unsigned int maxprogids ATTRIBUTE_UNUSED, + int attachType ATTRIBUTE_UNUSED, + unsigned int *progcnt ATTRIBUTE_UNUSED, + void *progids ATTRIBUTE_UNUSED) +{ + return 0; +} #else /* Nothing to override on non-__linux__ platforms */ #endif diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c index 20f4c57b04..4c1f53d924 100644 --- a/tests/vircgrouptest.c +++ b/tests/vircgrouptest.c @@ -587,6 +587,7 @@ static int testCgroupNewForSelfUnified(const void *args= ATTRIBUTE_UNUSED) (1 << VIR_CGROUP_CONTROLLER_CPU) | (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | (1 << VIR_CGROUP_CONTROLLER_MEMORY) | + (1 << VIR_CGROUP_CONTROLLER_DEVICES) | (1 << VIR_CGROUP_CONTROLLER_BLKIO); =20 if (virCgroupNewSelf(&cgroup) < 0) { @@ -609,14 +610,12 @@ static int testCgroupNewForSelfHybrid(const void *arg= s ATTRIBUTE_UNUSED) const char *empty[VIR_CGROUP_CONTROLLER_LAST] =3D { 0 }; const char *mounts[VIR_CGROUP_CONTROLLER_LAST] =3D { [VIR_CGROUP_CONTROLLER_CPUSET] =3D "/not/really/sys/fs/cgroup/cpus= et", - [VIR_CGROUP_CONTROLLER_DEVICES] =3D "/not/really/sys/fs/cgroup/dev= ices", [VIR_CGROUP_CONTROLLER_FREEZER] =3D "/not/really/sys/fs/cgroup/fre= ezer", [VIR_CGROUP_CONTROLLER_NET_CLS] =3D "/not/really/sys/fs/cgroup/net= _cls", [VIR_CGROUP_CONTROLLER_PERF_EVENT] =3D "/not/really/sys/fs/cgroup/= perf_event", }; const char *placement[VIR_CGROUP_CONTROLLER_LAST] =3D { [VIR_CGROUP_CONTROLLER_CPUSET] =3D "/", - [VIR_CGROUP_CONTROLLER_DEVICES] =3D "/", [VIR_CGROUP_CONTROLLER_FREEZER] =3D "/", [VIR_CGROUP_CONTROLLER_NET_CLS] =3D "/", [VIR_CGROUP_CONTROLLER_PERF_EVENT] =3D "/", @@ -625,6 +624,7 @@ static int testCgroupNewForSelfHybrid(const void *args = ATTRIBUTE_UNUSED) (1 << VIR_CGROUP_CONTROLLER_CPU) | (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | (1 << VIR_CGROUP_CONTROLLER_MEMORY) | + (1 << VIR_CGROUP_CONTROLLER_DEVICES) | (1 << VIR_CGROUP_CONTROLLER_BLKIO); =20 if (virCgroupNewSelf(&cgroup) < 0) { --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list