From nobody Tue May 7 02:38:39 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 15474808824151001.7080109766179; Mon, 14 Jan 2019 07:48:02 -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 BA0AD7F3E7; Mon, 14 Jan 2019 15:47:56 +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 5A2244DC44; Mon, 14 Jan 2019 15:47: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 E3E24181BA1A; Mon, 14 Jan 2019 15:47:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlrrh012755 for ; Mon, 14 Jan 2019 10:47:53 -0500 Received: by smtp.corp.redhat.com (Postfix) id AFDDD5C225; Mon, 14 Jan 2019 15:47:53 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E66C5C276 for ; Mon, 14 Jan 2019 15:47:52 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:35 +0100 Message-Id: <95e240a69f9ecc07780a4af911b9a8232ddebfa1.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 01/17] 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.25]); Mon, 14 Jan 2019 15:47:59 +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 --- configure.ac | 5 + include/libvirt/virterror.h | 1 + src/libvirt_private.syms | 16 ++ src/util/Makefile.inc.am | 2 + src/util/virbpf.c | 437 ++++++++++++++++++++++++++++++++++++ src/util/virbpf.h | 271 ++++++++++++++++++++++ src/util/virerror.c | 1 + 7 files changed, 733 insertions(+) create mode 100644 src/util/virbpf.c create mode 100644 src/util/virbpf.h diff --git a/configure.ac b/configure.ac index ac52189dff..0b7afece25 100644 --- a/configure.ac +++ b/configure.ac @@ -885,6 +885,11 @@ AC_CHECK_DECLS([clock_serv_t, host_get_clock_service, = clock_get_time], #include ]) =20 +# Check if we have new enough kernel to support BPF devices for cgroups v2 +if test "$with_linux" =3D "yes"; then + AC_CHECK_DECLS([BPF_PROG_QUERY], [], [], [#include ]) +fi + # Check if we need to look for ifconfig if test "$want_ifconfig" =3D "yes"; then AC_PATH_PROG([IFCONFIG_PATH], [ifconfig]) 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..ea4b8c0a4a --- /dev/null +++ b/src/util/virbpf.c @@ -0,0 +1,437 @@ +/* + * virbpf.c: methods for eBPF + * + * 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 + +#if HAVE_DECL_BPF_PROG_QUERY +int +virBPFCreateMap(unsigned int mapType, + unsigned int keySize, + unsigned int valSize, + unsigned int maxEntries) +{ + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + + attr.map_type =3D mapType; + attr.key_size =3D keySize; + attr.value_size =3D valSize; + attr.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; + union bpf_attr attr; + + if (VIR_ALLOC_N(logbuf, LOG_BUF_SIZE) < 0) + return -1; + + memset(&attr, 0, sizeof(attr)); + + attr.prog_type =3D progType; + attr.insn_cnt =3D (uint32_t)insnCnt; + attr.insns =3D (uint64_t)insns; + attr.license =3D (uint64_t)"GPL"; + attr.log_buf =3D (uint64_t)logbuf; + attr.log_size =3D LOG_BUF_SIZE; + attr.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; + + memset(&attr, 0, sizeof(attr)); + + attr.target_fd =3D targetfd; + attr.attach_bpf_fd =3D progfd; + attr.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; + + memset(&attr, 0, sizeof(attr)); + + attr.target_fd =3D targetfd; + attr.attach_bpf_fd =3D progfd; + attr.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) +{ + union bpf_attr attr; + int rc; + + memset(&attr, 0, sizeof(attr)); + + attr.query.target_fd =3D targetfd; + attr.query.attach_type =3D attachType; + attr.query.prog_cnt =3D maxprogids; + attr.query.prog_ids =3D (uint64_t)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; + + memset(&attr, 0, sizeof(attr)); + + attr.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) +{ + union bpf_attr attr; + int rc; + + 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 (uint64_t)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 (uint64_t)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 (uint64_t)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; + + memset(&attr, 0, sizeof(attr)); + + attr.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; + + memset(&attr, 0, sizeof(attr)); + + attr.info.bpf_fd =3D mapfd; + attr.info.info_len =3D sizeof(struct bpf_map_info); + attr.info.info =3D (uint64_t)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; + + memset(&attr, 0, sizeof(attr)); + + attr.map_fd =3D mapfd; + attr.key =3D (uint64_t)key; + attr.value =3D (uint64_t)val; + + return syscall(SYS_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); +} + + +int +virBPFGetNextElem(int mapfd, + void *key, + void *nextKey) +{ + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + + attr.map_fd =3D mapfd; + attr.key =3D (uint64_t)key; + attr.next_key =3D (uint64_t)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; + + memset(&attr, 0, sizeof(attr)); + + attr.map_fd =3D mapfd; + attr.key =3D (uint64_t)key; + attr.value =3D (uint64_t)val; + + return syscall(SYS_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); +} + + +int +virBPFDeleteElem(int mapfd, + void *key) +{ + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + + attr.map_fd =3D mapfd; + attr.key =3D (uint64_t)key; + + return syscall(SYS_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); +} +#else /* HAVE_DECL_BPF_PROG_QUERY */ +int +virBPFCreateMap(unsigned int mapType ATTRIBUTE_UNUSED, + unsigned int keySize ATTRIBUTE_UNUSED, + unsigned int valSize ATTRIBUTE_UNUSED, + unsigned int maxEntries ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFLoadProg(struct bpf_insn *insns ATTRIBUTE_UNUSED, + int progType ATTRIBUTE_UNUSED, + unsigned int insnCnt ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFAttachProg(int progfd ATTRIBUTE_UNUSED, + int targetfd ATTRIBUTE_UNUSED, + int attachType ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFDetachProg(int progfd ATTRIBUTE_UNUSED, + int targetfd ATTRIBUTE_UNUSED, + int attachType ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFQueryProg(int targetfd ATTRIBUTE_UNUSED, + unsigned int maxprogids ATTRIBUTE_UNUSED, + int attachType ATTRIBUTE_UNUSED, + unsigned int *progcnt ATTRIBUTE_UNUSED, + void *progids ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFGetProg(unsigned int id ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFGetProgInfo(int progfd ATTRIBUTE_UNUSED, + struct bpf_prog_info *info ATTRIBUTE_UNUSED, + unsigned int **mapIDs ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFGetMap(unsigned int id ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFGetMapInfo(int mapfd ATTRIBUTE_UNUSED, + struct bpf_map_info *info ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFLookupElem(int mapfd ATTRIBUTE_UNUSED, + void *key ATTRIBUTE_UNUSED, + void *val ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFGetNextElem(int mapfd ATTRIBUTE_UNUSED, + void *key ATTRIBUTE_UNUSED, + void *nextKey ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFUpdateElem(int mapfd ATTRIBUTE_UNUSED, + void *key ATTRIBUTE_UNUSED, + void *val ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} + + +int +virBPFDeleteElem(int mapfd ATTRIBUTE_UNUSED, + void *key ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("BPF not supported with this kernel")); + return -1; +} +#endif /* HAVE_DECL_BPF_PROG_QUERY */ diff --git a/src/util/virbpf.h b/src/util/virbpf.h new file mode 100644 index 0000000000..0fd6a05388 --- /dev/null +++ b/src/util/virbpf.h @@ -0,0 +1,271 @@ +/* + * virbpf.h: methods for eBPF + * + * 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 + +# if HAVE_DECL_BPF_PROG_QUERY + +# 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 (uint32_t)immval, \ + }), \ + ((struct bpf_insn) { \ + .code =3D 0, \ + .dst_reg =3D 0, \ + .src_reg =3D 0, \ + .off =3D 0, \ + .imm =3D ((uint64_t)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, \ + }) + +# else /* HAVE_DECL_BPF_PROG_QUERY */ + +struct bpf_prog_info; +struct bpf_map_info; +struct bpf_insn; + +# define VIR_BPF_ALU64_REG(op, dst, src) +# define VIR_BPF_ALU64_IMM(op, dst, immval) +# define VIR_BPF_MOV64_REG(dst, src) +# define VIR_BPF_MOV64_IMM(dst, immval) +# define VIR_BPF_MOV32_IMM(dst, immval) +# define VIR_BPF_LD_IMM64(dst, imm) +# define VIR_BPF_LD_IMM64_RAW(dst, src, immval) +# define VIR_BPF_PSEUDO_MAP_FD +# define VIR_BPF_LD_MAP_FD(dst, mapfd) +# define VIR_BPF_LDX_MEM(size, dst, src, offval) +# define VIR_BPF_STX_MEM(size, dst, src, offval) +# define VIR_BPF_ST_MEM(size, dst, immval, offval) +# define VIR_BPF_JMP_REG(op, dst, src, offval) +# define VIR_BPF_JMP_IMM(op, dst, immval, offval) +# define VIR_BPF_CALL_INSN(func) +# define VIR_BPF_EXIT_INSN() + +# endif /* HAVE_DECL_BPF_PROG_QUERY */ + +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 Tue May 7 02:38:39 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 1547480888001895.5135889876034; Mon, 14 Jan 2019 07:48:08 -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 A2C1551EF3; Mon, 14 Jan 2019 15:48:03 +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 13DF918661; Mon, 14 Jan 2019 15:48:03 +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 A34553F603; Mon, 14 Jan 2019 15:48:02 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlsn5012764 for ; Mon, 14 Jan 2019 10:47:54 -0500 Received: by smtp.corp.redhat.com (Postfix) id 863F35C71A; Mon, 14 Jan 2019 15:47:54 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0C8DC5C225 for ; Mon, 14 Jan 2019 15:47:53 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:36 +0100 Message-Id: <3a42bd5dfda060235258594c9f9e85d38a24adc1.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 02/17] 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 14 Jan 2019 15:48:05 +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 --- configure.ac | 3 +- src/Makefile.am | 2 + src/libvirt_private.syms | 3 ++ src/util/Makefile.inc.am | 2 + src/util/vircgroupv2.c | 7 +++- src/util/vircgroupv2devices.c | 73 +++++++++++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 27 +++++++++++++ 7 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/util/vircgroupv2devices.c create mode 100644 src/util/vircgroupv2devices.h diff --git a/configure.ac b/configure.ac index 0b7afece25..acc0e888ea 100644 --- a/configure.ac +++ b/configure.ac @@ -887,7 +887,8 @@ AC_CHECK_DECLS([clock_serv_t, host_get_clock_service, c= lock_get_time], =20 # Check if we have new enough kernel to support BPF devices for cgroups v2 if test "$with_linux" =3D "yes"; then - AC_CHECK_DECLS([BPF_PROG_QUERY], [], [], [#include ]) + AC_CHECK_DECLS([BPF_PROG_QUERY, BPF_CGROUP_DEVICE], + [], [], [#include ]) fi =20 # Check if we need to look for ifconfig diff --git a/src/Makefile.am b/src/Makefile.am index cd386297ed..9d9e50d527 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -672,11 +672,13 @@ 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 \ util/vircgroupv1.c \ util/vircgroupv2.c \ + util/vircgroupv2devices.c \ util/vircommand.c \ util/virconf.c \ util/virdbus.c \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0cff580de2..6a822f7d90 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1611,6 +1611,9 @@ virCgroupV1Register; # util/vircgroupv2.h virCgroupV2Register; =20 +# util/vircgroupv2devices.h +virCgroupV2DevicesAvailable; + # util/virclosecallbacks.h virCloseCallbacksGet; virCloseCallbacksGetConn; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index 1fd7ad2d43..6eb9e1b889 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -31,6 +31,8 @@ UTIL_SOURCES =3D \ util/vircgroupv1.h \ util/vircgroupv2.c \ util/vircgroupv2.h \ + util/vircgroupv2devices.c \ + util/vircgroupv2devices.h \ util/virclosecallbacks.c \ util/virclosecallbacks.h \ util/vircommand.c \ diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index cd58491da1..a56f3443e3 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -32,6 +32,7 @@ #include "vircgroup.h" #include "vircgroupbackend.h" #include "vircgroupv2.h" +#include "vircgroupv2devices.h" #include "virerror.h" #include "virfile.h" #include "virlog.h" @@ -292,6 +293,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 +409,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; diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c new file mode 100644 index 0000000000..10080d4fff --- /dev/null +++ b/src/util/vircgroupv2devices.c @@ -0,0 +1,73 @@ +/* + * vircgroupv2devices.c: methods for cgroups v2 BPF devices + * + * 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 + +#if HAVE_DECL_BPF_CGROUP_DEVICE +# include +# include +# include +# include +# include +#endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ + +#include "internal.h" + +#define LIBVIRT_VIRCGROUPPRIV_H_ALLOW +#include "vircgrouppriv.h" + +#include "virbpf.h" +#include "vircgroup.h" +#include "vircgroupv2devices.h" +#include "virfile.h" +#include "virlog.h" + +VIR_LOG_INIT("util.cgroup"); + +#define VIR_FROM_THIS VIR_FROM_CGROUP + +#if HAVE_DECL_BPF_CGROUP_DEVICE +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; +} +#else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ +bool +virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) +{ + return false; +} +#endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h new file mode 100644 index 0000000000..2ab35681db --- /dev/null +++ b/src/util/vircgroupv2devices.h @@ -0,0 +1,27 @@ +/* + * vircgroupv2devices.h: methods for cgroups v2 BPF devices + * + * 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_VIRCGROUPV2DEVICES_H +# define LIBVIRT_VIRCGROUPV2DEVICES_H + +# include "vircgroup.h" + +bool +virCgroupV2DevicesAvailable(virCgroupPtr group); + +#endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480895871869.1254202456573; Mon, 14 Jan 2019 07:48:15 -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 121FD8E3EA; Mon, 14 Jan 2019 15:48:10 +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 75CAD5D776; Mon, 14 Jan 2019 15:48: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 047201843669; Mon, 14 Jan 2019 15:48:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFltgo012771 for ; Mon, 14 Jan 2019 10:47:55 -0500 Received: by smtp.corp.redhat.com (Postfix) id 5A48B5C1B4; Mon, 14 Jan 2019 15:47:55 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id D4F585C225 for ; Mon, 14 Jan 2019 15:47:54 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:37 +0100 Message-Id: <06afea8ed2075af1e64fd3bd0c72512ea4153aad.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 03/17] vircgroup: introduce virCgroupV2DevicesAttachProg 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.25]); Mon, 14 Jan 2019 15:48:14 +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. 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/libvirt_private.syms | 1 + src/util/vircgrouppriv.h | 10 +++ src/util/vircgroupv2devices.c | 140 ++++++++++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 5 ++ 4 files changed, 156 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a822f7d90..3fc91ce207 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1612,6 +1612,7 @@ virCgroupV1Register; virCgroupV2Register; =20 # util/vircgroupv2devices.h +virCgroupV2DevicesAttachProg; virCgroupV2DevicesAvailable; =20 # util/virclosecallbacks.h 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/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index 10080d4fff..0b721a0aad 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -64,10 +64,150 @@ virCgroupV2DevicesAvailable(virCgroupPtr group) VIR_FORCE_CLOSE(cgroupfd); return ret; } + + +static int +virCgroupV2DevicesLoadProg(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)); +} + + +int +virCgroupV2DevicesAttachProg(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 (virCgroupPathOfController(group, VIR_CGROUP_CONTROLLER_DEVICES, + NULL, &path) < 0) { + goto cleanup; + } + + progfd =3D virCgroupV2DevicesLoadProg(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; +} #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ bool virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) { return false; } + + +int +virCgroupV2DevicesAttachProg(virCgroupPtr group ATTRIBUTE_UNUSED, + int mapfd ATTRIBUTE_UNUSED, + size_t max ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("cgroups v2 BPF devices not supported " + "with this kernel")); + return -1; +} #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index 2ab35681db..1ba87acb00 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -24,4 +24,9 @@ bool virCgroupV2DevicesAvailable(virCgroupPtr group); =20 +int +virCgroupV2DevicesAttachProg(virCgroupPtr group, + int mapfd, + size_t max); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480881821490.57604248546136; Mon, 14 Jan 2019 07:48:01 -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 F372CC0CB57A; Mon, 14 Jan 2019 15:47:58 +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 B2BD25D744; Mon, 14 Jan 2019 15:47:58 +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 6574918434BE; Mon, 14 Jan 2019 15:47:58 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlu8N012784 for ; Mon, 14 Jan 2019 10:47:56 -0500 Received: by smtp.corp.redhat.com (Postfix) id 3114B5C25D; Mon, 14 Jan 2019 15:47:56 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id A82A85C1B4 for ; Mon, 14 Jan 2019 15:47:55 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:38 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 04/17] vircgroup: introduce virCgroupV2DevicesDetectProg 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.31]); Mon, 14 Jan 2019 15:48:00 +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/libvirt_private.syms | 1 + src/util/vircgroupv2devices.c | 117 ++++++++++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 3 + 3 files changed, 121 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3fc91ce207..7f1050ef5a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1614,6 +1614,7 @@ virCgroupV2Register; # util/vircgroupv2devices.h virCgroupV2DevicesAttachProg; virCgroupV2DevicesAvailable; +virCgroupV2DevicesDetectProg; =20 # util/virclosecallbacks.h virCloseCallbacksGet; diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index 0b721a0aad..e609faa210 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -192,6 +192,113 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group, VIR_FORCE_CLOSE(mapfd); return ret; } + + +static int +virCgroupV2DevicesCountMapEntries(int mapfd) +{ + int ret =3D 0; + int rc; + uint64_t key =3D 0; + uint64_t 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 + +int +virCgroupV2DevicesDetectProg(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 (virCgroupPathOfController(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) { + /* No need to have alternate code, this function will not be called + * if compiled with old kernel. */ + 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 virCgroupV2DevicesCountMapEntries(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; +} #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ bool virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) @@ -210,4 +317,14 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group ATTRIB= UTE_UNUSED, "with this kernel")); return -1; } + + +int +virCgroupV2DevicesDetectProg(virCgroupPtr group ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("cgroups v2 BPF devices not supported " + "with this kernel")); + return -1; +} #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index 1ba87acb00..a8e50dcca5 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -29,4 +29,7 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group, int mapfd, size_t max); =20 +int +virCgroupV2DevicesDetectProg(virCgroupPtr group); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480890160901.1760286181359; Mon, 14 Jan 2019 07:48:10 -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 00289C3A8C; Mon, 14 Jan 2019 15:48:05 +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 8CE9B5D77B; Mon, 14 Jan 2019 15:48:05 +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 1E14B18434BE; Mon, 14 Jan 2019 15:48:05 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlviG012791 for ; Mon, 14 Jan 2019 10:47:57 -0500 Received: by smtp.corp.redhat.com (Postfix) id 058B5617B6; Mon, 14 Jan 2019 15:47:57 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D8295C25D for ; Mon, 14 Jan 2019 15:47:56 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:39 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 05/17] vircgroup: introduce virCgroupV2DevicesCreateProg 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.30]); Mon, 14 Jan 2019 15:48:07 +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/libvirt_private.syms | 1 + src/util/vircgroupv2devices.c | 53 +++++++++++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 3 ++ 3 files changed, 57 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7f1050ef5a..8ec188e9cd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1614,6 +1614,7 @@ virCgroupV2Register; # util/vircgroupv2devices.h virCgroupV2DevicesAttachProg; virCgroupV2DevicesAvailable; +virCgroupV2DevicesCreateProg; virCgroupV2DevicesDetectProg; =20 # util/virclosecallbacks.h diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index e609faa210..cd369ef6ab 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -299,6 +299,49 @@ virCgroupV2DevicesDetectProg(virCgroupPtr group) VIR_FORCE_CLOSE(cgroupfd); return ret; } + + +# define VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZE 64 + +static int +virCgroupV2DevicesCreateMap(size_t size) +{ + int mapfd =3D virBPFCreateMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t), + sizeof(uint32_t), size); + + if (mapfd < 0) { + virReportSystemError(errno, "%s", + _("failed to initialize device BPF map")); + return -1; + } + + return mapfd; +} + + +int +virCgroupV2DevicesCreateProg(virCgroupPtr group) +{ + int mapfd; + + if (group->unified.devices.progfd > 0 && group->unified.devices.mapfd = > 0) + return 0; + + mapfd =3D virCgroupV2DevicesCreateMap(VIR_CGROUP_V2_INITIAL_BPF_MAP_SI= ZE); + if (mapfd < 0) + return -1; + + if (virCgroupV2DevicesAttachProg(group, mapfd, + VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZE) <= 0) { + goto error; + } + + return 0; + + error: + VIR_FORCE_CLOSE(mapfd); + return -1; +} #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ bool virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) @@ -327,4 +370,14 @@ virCgroupV2DevicesDetectProg(virCgroupPtr group ATTRIB= UTE_UNUSED) "with this kernel")); return -1; } + + +int +virCgroupV2DevicesCreateProg(virCgroupPtr group ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("cgroups v2 BPF devices not supported " + "with this kernel")); + return -1; +} #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index a8e50dcca5..bcbd761537 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -32,4 +32,7 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group, int virCgroupV2DevicesDetectProg(virCgroupPtr group); =20 +int +virCgroupV2DevicesCreateProg(virCgroupPtr group); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480888424832.6033436838735; Mon, 14 Jan 2019 07:48:08 -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 A373BC0D4721; Mon, 14 Jan 2019 15:48:04 +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 D1F8A5DEE1; Mon, 14 Jan 2019 15:48:03 +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 6EFCD3F605; Mon, 14 Jan 2019 15:48:03 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlv0j012796 for ; Mon, 14 Jan 2019 10:47:57 -0500 Received: by smtp.corp.redhat.com (Postfix) id CD32D17572; Mon, 14 Jan 2019 15:47:57 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 51F6D177F1 for ; Mon, 14 Jan 2019 15:47:57 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:40 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 06/17] vircgroup: introduce virCgroupV2DevicesPrepareProg 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.31]); Mon, 14 Jan 2019 15:48:06 +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. Since there is no way how to reallocate existing BPF map we need to create a new copy if we run out of space in current BPF map. 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/libvirt_private.syms | 1 + src/util/vircgroupv2devices.c | 83 +++++++++++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 3 ++ 3 files changed, 87 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8ec188e9cd..1d1f8bf478 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1616,6 +1616,7 @@ virCgroupV2DevicesAttachProg; virCgroupV2DevicesAvailable; virCgroupV2DevicesCreateProg; virCgroupV2DevicesDetectProg; +virCgroupV2DevicesPrepareProg; =20 # util/virclosecallbacks.h virCloseCallbacksGet; diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index cd369ef6ab..e3a415d615 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -319,6 +319,52 @@ virCgroupV2DevicesCreateMap(size_t size) } =20 =20 +static int +virCgroupV2DevicesReallocMap(int mapfd, + size_t size) +{ + uint64_t key =3D 0; + uint64_t prevKey =3D 0; + int rc; + int newmapfd =3D virCgroupV2DevicesCreateMap(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) { + uint32_t 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 && errno !=3D ENOENT) { + virReportSystemError(errno, "%s", + _("failed to copy all device rules")); + goto error; + } + + return newmapfd; + + error: + VIR_FORCE_CLOSE(newmapfd); + return -1; +} + + int virCgroupV2DevicesCreateProg(virCgroupPtr group) { @@ -342,6 +388,33 @@ virCgroupV2DevicesCreateProg(virCgroupPtr group) VIR_FORCE_CLOSE(mapfd); return -1; } + + +int +virCgroupV2DevicesPrepareProg(virCgroupPtr group) +{ + if (virCgroupV2DevicesDetectProg(group) < 0) + return -1; + + if (virCgroupV2DevicesCreateProg(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 virCgroupV2DevicesReallocMap(group->unified.devic= es.mapfd, + max); + + if (newmapfd < 0) + return -1; + + if (virCgroupV2DevicesAttachProg(group, newmapfd, max) < 0) { + VIR_FORCE_CLOSE(newmapfd); + return -1; + } + } + + return 0; +} #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ bool virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) @@ -380,4 +453,14 @@ virCgroupV2DevicesCreateProg(virCgroupPtr group ATTRIB= UTE_UNUSED) "with this kernel")); return -1; } + + +int +virCgroupV2DevicesPrepareProg(virCgroupPtr group ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("cgroups v2 BPF devices not supported " + "with this kernel")); + return -1; +} #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index bcbd761537..10c80c8ae4 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -35,4 +35,7 @@ virCgroupV2DevicesDetectProg(virCgroupPtr group); int virCgroupV2DevicesCreateProg(virCgroupPtr group); =20 +int +virCgroupV2DevicesPrepareProg(virCgroupPtr group); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480893895234.15314145851232; Mon, 14 Jan 2019 07:48:13 -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 96645C3A74; Mon, 14 Jan 2019 15:48:10 +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 498645E7A4; Mon, 14 Jan 2019 15:48:10 +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 D4B21184B54A; Mon, 14 Jan 2019 15:48:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlwKJ012804 for ; Mon, 14 Jan 2019 10:47:58 -0500 Received: by smtp.corp.redhat.com (Postfix) id A16C517572; Mon, 14 Jan 2019 15:47:58 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 261E15C1B4 for ; Mon, 14 Jan 2019 15:47:57 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:41 +0100 Message-Id: <90fdef0098b834577060dface99c13537fb94cd8.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 07/17] vircgroup: introduce virCgroupV2DevicesRemoveProg 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]); Mon, 14 Jan 2019 15:48:12 +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/libvirt_private.syms | 1 + src/util/vircgroupv2.c | 3 +++ src/util/vircgroupv2devices.c | 26 ++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 3 +++ 4 files changed, 33 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1d1f8bf478..c4f5cdea46 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1617,6 +1617,7 @@ virCgroupV2DevicesAvailable; virCgroupV2DevicesCreateProg; virCgroupV2DevicesDetectProg; virCgroupV2DevicesPrepareProg; +virCgroupV2DevicesRemoveProg; =20 # util/virclosecallbacks.h virCloseCallbacksGet; diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index a56f3443e3..b5d4776d14 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -439,6 +439,9 @@ virCgroupV2Remove(virCgroupPtr group) if (virCgroupV2PathOfController(group, controller, "", &grppath) < 0) return 0; =20 + if (virCgroupV2DevicesRemoveProg(group) < 0) + return -1; + return virCgroupRemoveRecursively(grppath); } =20 diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index e3a415d615..e7f8c048fc 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -415,6 +415,25 @@ virCgroupV2DevicesPrepareProg(virCgroupPtr group) =20 return 0; } + + +int +virCgroupV2DevicesRemoveProg(virCgroupPtr group) +{ + if (virCgroupV2DevicesDetectProg(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; +} #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ bool virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) @@ -463,4 +482,11 @@ virCgroupV2DevicesPrepareProg(virCgroupPtr group ATTRI= BUTE_UNUSED) "with this kernel")); return -1; } + + +int +virCgroupV2DevicesRemoveProg(virCgroupPtr group ATTRIBUTE_UNUSED) +{ + return 0; +} #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index 10c80c8ae4..ae02f9c334 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -38,4 +38,7 @@ virCgroupV2DevicesCreateProg(virCgroupPtr group); int virCgroupV2DevicesPrepareProg(virCgroupPtr group); =20 +int +virCgroupV2DevicesRemoveProg(virCgroupPtr group); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480894565267.4146154343929; Mon, 14 Jan 2019 07:48:14 -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 BCC1E30EF76; Mon, 14 Jan 2019 15:48:11 +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 7A7005DEE1; Mon, 14 Jan 2019 15:48:11 +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 059A83F604; Mon, 14 Jan 2019 15:48:11 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFlxY2012820 for ; Mon, 14 Jan 2019 10:47:59 -0500 Received: by smtp.corp.redhat.com (Postfix) id 774C45C225; Mon, 14 Jan 2019 15:47:59 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id EED485C1B4 for ; Mon, 14 Jan 2019 15:47:58 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:42 +0100 Message-Id: <3f1640e1cfa0acf4ae4e3b907418cc3c4be080c1.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 08/17] 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 14 Jan 2019 15:48:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Pavel Hrdina --- src/libvirt_private.syms | 1 + src/util/vircgroupv2devices.c | 34 ++++++++++++++++++++++++++++++++++ src/util/vircgroupv2devices.h | 6 ++++++ 3 files changed, 41 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c4f5cdea46..0d25911bc1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1616,6 +1616,7 @@ virCgroupV2DevicesAttachProg; virCgroupV2DevicesAvailable; virCgroupV2DevicesCreateProg; virCgroupV2DevicesDetectProg; +virCgroupV2DevicesGetPerms; virCgroupV2DevicesPrepareProg; virCgroupV2DevicesRemoveProg; =20 diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index e7f8c048fc..9cf9edee3a 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -434,6 +434,32 @@ virCgroupV2DevicesRemoveProg(virCgroupPtr group) =20 return 0; } + + +uint32_t +virCgroupV2DevicesGetPerms(int perms, + char type) +{ + uint32_t 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; +} #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ bool virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) @@ -489,4 +515,12 @@ virCgroupV2DevicesRemoveProg(virCgroupPtr group ATTRIB= UTE_UNUSED) { return 0; } + + +uint32_t +virCgroupV2DevicesGetPerms(int perms ATTRIBUTE_UNUSED, + char type ATTRIBUTE_UNUSED) +{ + return 0; +} #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index ae02f9c334..cbfd9ae119 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -19,6 +19,8 @@ #ifndef LIBVIRT_VIRCGROUPV2DEVICES_H # define LIBVIRT_VIRCGROUPV2DEVICES_H =20 +# include + # include "vircgroup.h" =20 bool @@ -41,4 +43,8 @@ virCgroupV2DevicesPrepareProg(virCgroupPtr group); int virCgroupV2DevicesRemoveProg(virCgroupPtr group); =20 +uint32_t +virCgroupV2DevicesGetPerms(int perms, + char type); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480900921511.5743067494092; Mon, 14 Jan 2019 07:48:20 -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 145B52DD77C; Mon, 14 Jan 2019 15:48:16 +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 58BC217B10; Mon, 14 Jan 2019 15:48:15 +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 05BE13F606; Mon, 14 Jan 2019 15:48:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm0pg012827 for ; Mon, 14 Jan 2019 10:48:00 -0500 Received: by smtp.corp.redhat.com (Postfix) id 4D14C5C276; Mon, 14 Jan 2019 15:48:00 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id C4F7E5C25D for ; Mon, 14 Jan 2019 15:47:59 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:43 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 09/17] vircgroup: introduce virCgroupV2DevicesGetKey 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.29]); Mon, 14 Jan 2019 15:48:17 +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/libvirt_private.syms | 1 + src/util/vircgroupv2devices.c | 8 ++++++++ src/util/vircgroupv2devices.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0d25911bc1..f1da5ede71 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1616,6 +1616,7 @@ virCgroupV2DevicesAttachProg; virCgroupV2DevicesAvailable; virCgroupV2DevicesCreateProg; virCgroupV2DevicesDetectProg; +virCgroupV2DevicesGetKey; virCgroupV2DevicesGetPerms; virCgroupV2DevicesPrepareProg; virCgroupV2DevicesRemoveProg; diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index 9cf9edee3a..8bf5100724 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -524,3 +524,11 @@ virCgroupV2DevicesGetPerms(int perms ATTRIBUTE_UNUSED, return 0; } #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ + + +uint64_t +virCgroupV2DevicesGetKey(int major, + int minor) +{ + return (uint64_t)major << 32 | ((uint64_t)minor & 0x00000000ffffffff); +} diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index cbfd9ae119..d717c9755f 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -47,4 +47,8 @@ uint32_t virCgroupV2DevicesGetPerms(int perms, char type); =20 +uint64_t +virCgroupV2DevicesGetKey(int major, + int minor); + #endif /* LIBVIRT_VIRCGROUPV2DEVICES_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 02:38:39 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 1547480899143275.0032450578666; Mon, 14 Jan 2019 07:48:19 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EB94EC0C274E; Mon, 14 Jan 2019 15:48:14 +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 A8FD416BF7; Mon, 14 Jan 2019 15:48:14 +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 31F2E3F605; Mon, 14 Jan 2019 15:48:14 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm1WR012840 for ; Mon, 14 Jan 2019 10:48:01 -0500 Received: by smtp.corp.redhat.com (Postfix) id 23D7C5C276; Mon, 14 Jan 2019 15:48:01 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A30F5C25D for ; Mon, 14 Jan 2019 15:48:00 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:44 +0100 Message-Id: <0223e6e00b506130a8b7b58fa76bd2c067920ae4.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 10/17] 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.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 14 Jan 2019 15:48:17 +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 | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index b5d4776d14..962d41ba0a 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -29,6 +29,7 @@ #define LIBVIRT_VIRCGROUPPRIV_H_ALLOW #include "vircgrouppriv.h" =20 +#include "virbpf.h" #include "vircgroup.h" #include "vircgroupbackend.h" #include "vircgroupv2.h" @@ -1568,6 +1569,35 @@ virCgroupV2GetCpuacctStat(virCgroupPtr group, } =20 =20 +static int +virCgroupV2AllowDevice(virCgroupPtr group, + char type, + int major, + int minor, + int perms) +{ + uint64_t key =3D virCgroupV2DevicesGetKey(major, minor); + uint32_t val =3D virCgroupV2DevicesGetPerms(perms, type); + int rc; + + if (virCgroupV2DevicesPrepareProg(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 @@ -1617,6 +1647,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 Tue May 7 02:38:39 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 1547480905426725.6520592271705; Mon, 14 Jan 2019 07:48:25 -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 91439A0B42; Mon, 14 Jan 2019 15:48:21 +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 1E4885D780; Mon, 14 Jan 2019 15:48:21 +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 B4E5A1800540; Mon, 14 Jan 2019 15:48:20 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm2GH012855 for ; Mon, 14 Jan 2019 10:48:02 -0500 Received: by smtp.corp.redhat.com (Postfix) id 08061177F7; Mon, 14 Jan 2019 15:48:02 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 79E7B61D03 for ; Mon, 14 Jan 2019 15:48:01 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:45 +0100 Message-Id: <368c20c10ce648acf74a37f57168a1de3d7bc46f.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 11/17] 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Mon, 14 Jan 2019 15:48:24 +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 962d41ba0a..b6c09baadc 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1598,6 +1598,46 @@ virCgroupV2AllowDevice(virCgroupPtr group, } =20 =20 +static int +virCgroupV2DenyDevice(virCgroupPtr group, + char type, + int major, + int minor, + int perms) +{ + uint64_t key =3D virCgroupV2DevicesGetKey(major, minor); + uint32_t newval =3D virCgroupV2DevicesGetPerms(perms, type); + uint32_t val =3D 0; + + if (virCgroupV2DevicesPrepareProg(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 @@ -1648,6 +1688,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 Tue May 7 02:38:39 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 1547480912314420.6441714111943; Mon, 14 Jan 2019 07:48:32 -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 3AA12C0C6C30; Mon, 14 Jan 2019 15:48:27 +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 D7FA536FA; Mon, 14 Jan 2019 15:48:26 +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 802923F603; Mon, 14 Jan 2019 15:48:26 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm2pw012862 for ; Mon, 14 Jan 2019 10:48:02 -0500 Received: by smtp.corp.redhat.com (Postfix) id D02ED17572; Mon, 14 Jan 2019 15:48:02 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5417F5C1B4 for ; Mon, 14 Jan 2019 15:48:02 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:46 +0100 Message-Id: <0f9316c0d1c492744dc9582f5594b7e75e071c5e.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 12/17] 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.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.32]); Mon, 14 Jan 2019 15:48:30 +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 b6c09baadc..8ad4de986f 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1638,6 +1638,23 @@ virCgroupV2DenyDevice(virCgroupPtr group, } =20 =20 +static int +virCgroupV2AllowAllDevices(virCgroupPtr group, + int perms) +{ + if (virCgroupV2DevicesPrepareProg(group) < 0) + return -1; + + if (group->unified.devices.count > 0 && + perms =3D=3D VIR_CGROUP_DEVICE_RWM && + virCgroupV2DevicesCreateProg(group) < 0) { + return -1; + } + + return virCgroupV2AllowDevice(group, 'a', -1, -1, perms); +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 @@ -1689,6 +1706,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 Tue May 7 02:38:39 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 1547480901850323.91753301486244; Mon, 14 Jan 2019 07:48:21 -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 B27892EED0B; Mon, 14 Jan 2019 15:48:17 +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 F268661B63; Mon, 14 Jan 2019 15:48:16 +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 817483F608; Mon, 14 Jan 2019 15:48:16 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm3wx012878 for ; Mon, 14 Jan 2019 10:48:03 -0500 Received: by smtp.corp.redhat.com (Postfix) id C95F417B15; Mon, 14 Jan 2019 15:48:03 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 28D755C1B4 for ; Mon, 14 Jan 2019 15:48:02 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:47 +0100 Message-Id: <7b864698f6c9b1f191792d3d67c4f0f28876f966.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 13/17] 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.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.29]); Mon, 14 Jan 2019 15:48:19 +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 8ad4de986f..f2ea1eb7df 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1655,6 +1655,16 @@ virCgroupV2AllowAllDevices(virCgroupPtr group, } =20 =20 +static int +virCgroupV2DenyAllDevices(virCgroupPtr group) +{ + if (virCgroupV2DevicesDetectProg(group) < 0) + return -1; + + return virCgroupV2DevicesCreateProg(group); +} + + virCgroupBackend virCgroupV2Backend =3D { .type =3D VIR_CGROUP_BACKEND_TYPE_V2, =20 @@ -1707,6 +1717,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 Tue May 7 02:38:39 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 1547480905439795.7144860703683; Mon, 14 Jan 2019 07:48:25 -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 2459EC0D263A; Mon, 14 Jan 2019 15:48:20 +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 9BCB06149A; Mon, 14 Jan 2019 15:48: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 422CD18436BF; Mon, 14 Jan 2019 15:48:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm49A012889 for ; Mon, 14 Jan 2019 10:48:04 -0500 Received: by smtp.corp.redhat.com (Postfix) id 960CF6531A; Mon, 14 Jan 2019 15:48:04 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 035E517AFC for ; Mon, 14 Jan 2019 15:48:03 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:48 +0100 Message-Id: <9b50d68fc016844af2dcbafaed7bbfb704e8d74f.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 14/17] 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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 14 Jan 2019 15:48:23 +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 f2ea1eb7df..44c4c7fc90 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -284,7 +284,8 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) =20 static int virCgroupV2DetectControllers(virCgroupPtr group, - int controllers) + int controllers, + int detected) { size_t i; =20 @@ -297,6 +298,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 Tue May 7 02:38:39 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 1547480907158173.6628036949312; Mon, 14 Jan 2019 07:48:27 -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 2F08EC0E6758; Mon, 14 Jan 2019 15:48:22 +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 CA33F4F9A1; Mon, 14 Jan 2019 15:48:21 +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 65CB11888B46; Mon, 14 Jan 2019 15:48:21 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm5oJ012894 for ; Mon, 14 Jan 2019 10:48:05 -0500 Received: by smtp.corp.redhat.com (Postfix) id 6B44D1757E; Mon, 14 Jan 2019 15:48:05 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id DB8446148F for ; Mon, 14 Jan 2019 15:48:04 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:49 +0100 Message-Id: <9609d780a38cf279201d67d18f9c0f8be81915e4.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 15/17] 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 14 Jan 2019 15:48:25 +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/vircgroupv2devices.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index 8bf5100724..a481ba89b7 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -420,19 +420,44 @@ virCgroupV2DevicesPrepareProg(virCgroupPtr group) int virCgroupV2DevicesRemoveProg(virCgroupPtr group) { + int ret =3D -1; + int cgroupfd =3D -1; + VIR_AUTOFREE(char *) path =3D NULL; + if (virCgroupV2DevicesDetectProg(group) < 0) return -1; =20 if (group->unified.devices.progfd <=3D 0 && group->unified.devices.map= fd <=3D 0) return 0; =20 + if (virCgroupPathOfController(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 Tue May 7 02:38:39 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 1547480917447679.2637755686613; Mon, 14 Jan 2019 07:48:37 -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 0C5AD2E605C; Mon, 14 Jan 2019 15:48:32 +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 87A1F18AD2; Mon, 14 Jan 2019 15:48:31 +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 3709D184B54C; Mon, 14 Jan 2019 15:48:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm6Ne012899 for ; Mon, 14 Jan 2019 10:48:06 -0500 Received: by smtp.corp.redhat.com (Postfix) id 44E3F5C25D; Mon, 14 Jan 2019 15:48:06 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id B9FA5177CE for ; Mon, 14 Jan 2019 15:48:05 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:50 +0100 Message-Id: <7f70aa6e9b644fac5a1f09535722372d8a579b11.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 16/17] 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 14 Jan 2019 15:48:34 +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 | 16 ++++++++ src/util/vircgroup.h | 1 + src/util/vircgrouppriv.h | 2 + src/util/vircgroupv2.c | 2 + src/util/vircgroupv2devices.c | 70 ++++++++++++++++++++++++++++++++++- src/util/virsystemd.c | 2 +- src/util/virsystemd.h | 2 + 10 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f1da5ede71..c22c81cebe 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3031,6 +3031,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..506cc49b9a 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 @@ -2897,6 +2912,7 @@ virCgroupNewMachine(const char *name ATTRIBUTE_UNUSED, int *nicindexes ATTRIBUTE_UNUSED, const char *partition ATTRIBUTE_UNUSED, int controllers ATTRIBUTE_UNUSED, + const char *stateDir ATTRIBUTE_UNUSED, virCgroupPtr *group ATTRIBUTE_UNUSED) { virReportSystemError(ENXIO, "%s", 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 44c4c7fc90..03efabe198 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -37,6 +37,8 @@ #include "virerror.h" #include "virfile.h" #include "virlog.h" +#include "virpidfile.h" +#include "virprocess.h" #include "virstring.h" #include "virsystemd.h" =20 diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c index a481ba89b7..9d8fc5557e 100644 --- a/src/util/vircgroupv2devices.c +++ b/src/util/vircgroupv2devices.c @@ -31,10 +31,15 @@ #include "vircgrouppriv.h" =20 #include "virbpf.h" +#include "vircommand.h" #include "vircgroup.h" #include "vircgroupv2devices.h" #include "virfile.h" #include "virlog.h" +#include "virpidfile.h" +#include "virprocess.h" +#include "virstring.h" +#include "virsystemd.h" =20 VIR_LOG_INIT("util.cgroup"); =20 @@ -365,17 +370,74 @@ virCgroupV2DevicesReallocMap(int mapfd, } =20 =20 +static pid_t +virCgroupV2DevicesStartDummyProc(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; +} + + int virCgroupV2DevicesCreateProg(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 virCgroupV2DevicesStartDummyProc(group); + if (pid < 0) + return -1; + } + mapfd =3D virCgroupV2DevicesCreateMap(VIR_CGROUP_V2_INITIAL_BPF_MAP_SI= ZE); if (mapfd < 0) - return -1; + goto error; =20 if (virCgroupV2DevicesAttachProg(group, mapfd, VIR_CGROUP_V2_INITIAL_BPF_MAP_SIZE) <= 0) { @@ -385,6 +447,7 @@ virCgroupV2DevicesCreateProg(virCgroupPtr group) return 0; =20 error: + virProcessKillPainfully(pid, true); VIR_FORCE_CLOSE(mapfd); return -1; } @@ -453,6 +516,9 @@ virCgroupV2DevicesRemoveProg(virCgroupPtr group) if (group->unified.devices.progfd >=3D 0) VIR_FORCE_CLOSE(group->unified.devices.progfd); =20 + if (virSystemdHasMachined() =3D=3D 0) + virCgroupKillPainfully(group); + ret =3D 0; =20 cleanup: 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 Tue May 7 02:38:39 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 1547480910052971.0881526543067; Mon, 14 Jan 2019 07:48:30 -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 EB7FD13BF52; Mon, 14 Jan 2019 15:48:26 +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 971225D969; Mon, 14 Jan 2019 15:48:26 +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 10B883F602; Mon, 14 Jan 2019 15:48:26 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0EFm7EP012912 for ; Mon, 14 Jan 2019 10:48:07 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1C980177CE; Mon, 14 Jan 2019 15:48:07 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 94BF261B8F for ; Mon, 14 Jan 2019 15:48:06 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 14 Jan 2019 16:47:51 +0100 Message-Id: <2a66f1cffa14e642f816c55820df622e5e293414.1547480099.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 17/17] vircgroupmock: mock 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 14 Jan 2019 15:48:28 +0000 (UTC) Content-Type: text/plain; charset="utf-8" We need to mock virCgroupV2DevicesAvailable() in order to remove any dependency on kernel as BPF devices might not be available. Signed-off-by: Pavel Hrdina --- src/util/vircgroupv2devices.h | 5 ++++- tests/vircgroupdata/hybrid.parsed | 2 +- tests/vircgroupmock.c | 7 +++++++ tests/vircgrouptest.c | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index d717c9755f..5fc35942ef 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -21,10 +21,13 @@ =20 # include =20 +# include "internal.h" + # include "vircgroup.h" =20 bool -virCgroupV2DevicesAvailable(virCgroupPtr group); +virCgroupV2DevicesAvailable(virCgroupPtr group) + ATTRIBUTE_NOINLINE; =20 int virCgroupV2DevicesAttachProg(virCgroupPtr group, 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..97f98e91ee 100644 --- a/tests/vircgroupmock.c +++ b/tests/vircgroupmock.c @@ -34,6 +34,7 @@ # include "testutilslxc.h" # include "virstring.h" # include "virfile.h" +# include "vircgroupv2devices.h" =20 static int (*real_open)(const char *path, int flags, ...); static FILE *(*real_fopen)(const char *path, const char *mode); @@ -701,6 +702,12 @@ int open(const char *path, int flags, ...) free(newpath); return ret; } + +bool +virCgroupV2DevicesAvailable(virCgroupPtr group ATTRIBUTE_UNUSED) +{ + return true; +} #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