From nobody Fri Apr 26 13:50:37 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1637660939; cv=none; d=zohomail.com; s=zohoarc; b=MVIbH2t3qvKUUeyckwOJR5rsV4ZxrEW1sZBNJrZEN8LHaQwmchik7m8I2ksdb8lnAXdoVBL8LMrCUH0l+o+j2kA8NwGqjgFCO3ZgCQftzwB5yhQtOxZM/yG07Z6N/SP3gwwHLKgSugGSNYTOWp2Yqqd+65KoGH+jXyCkNz/H9YA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1637660939; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Gy+yvZVRCHqVg2tUwSsVfANVxS5OQKEwwDTTbjpf4vc=; b=BVrK0fCIxsNRBrghr2/7kS8/44kujL6B4JGRRfXeJ2cZ145CkwDKqVe5zdGmtlLgBM7fPytXvmNbPqOmCAeiaVMgdspPJR/L80yMcDjnkxnKYTQ/qGHyTjjPaMGjbzyv+Fkf0k3mnmxd7lU5fjtR88gnuKn3cvo9ZdHk2fvHhwA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1637660939843310.70029625344296; Tue, 23 Nov 2021 01:48:59 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-586-4YNYS2M-P52oY-bfeJ0iMA-1; Tue, 23 Nov 2021 04:48:55 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5893F87D544; Tue, 23 Nov 2021 09:48:50 +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 3DFC060862; Tue, 23 Nov 2021 09:48:50 +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 1323E1832E85; Tue, 23 Nov 2021 09:48:50 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 1AN9mkdx007118 for ; Tue, 23 Nov 2021 04:48:46 -0500 Received: by smtp.corp.redhat.com (Postfix) id 58C9251E3; Tue, 23 Nov 2021 09:48:46 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 535D051E2 for ; Tue, 23 Nov 2021 09:48:43 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 62C75811E78 for ; Tue, 23 Nov 2021 09:48:43 +0000 (UTC) Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-546-y7whOOz-MEmHgczgsfJIIQ-1; Tue, 23 Nov 2021 04:48:41 -0500 Received: by mail-ed1-f69.google.com with SMTP id l15-20020a056402124f00b003e57269ab87so17339831edw.6 for ; Tue, 23 Nov 2021 01:48:41 -0800 (PST) Received: from wheatley.localdomain (nat-pool-brq-t.redhat.com. [213.175.37.10]) by smtp.gmail.com with ESMTPSA id hc16sm5065383ejc.12.2021.11.23.01.48.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Nov 2021 01:48:40 -0800 (PST) Received: from wheatley.redhat.com (wheatley.k8r.cz [127.0.0.1]) by wheatley.localdomain (Postfix) with ESMTP id 126F920BC4F7 for ; Tue, 23 Nov 2021 10:48:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637660938; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=Gy+yvZVRCHqVg2tUwSsVfANVxS5OQKEwwDTTbjpf4vc=; b=gd901wmn5OfLlSZdzvXWEtfLrnD2awGnS8BfdkSILAYQ/sRAK+5eb4oZZTwTw81RVqkPFW 6jR3yriyFNrByFvNIXCWUlcFBckkH9zPCEkrxgvRwEHH+2YXg2PL/1AxQB+qppuFfnkX9P WsM2vDACjKFFKOLLKCdUHP5RFsJQUtY= X-MC-Unique: 4YNYS2M-P52oY-bfeJ0iMA-1 X-MC-Unique: y7whOOz-MEmHgczgsfJIIQ-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Gy+yvZVRCHqVg2tUwSsVfANVxS5OQKEwwDTTbjpf4vc=; b=1blM4I7Hx7okoXQ7op0MGfbslE3D7chHq6u7RlgnWhhvEymVCwIFs76vouGs21ae8o IrhRi6LnLGLcsMOk/XiC0wr3fhBxxph2L5TyZl9X8RQiLj5xqR4KxWagpdJ+HcqvwnSK Fb/iDuoxisqC1Sf33rHmg37alNXDWowaTkTIr/tDDMOmZR6j5I6i1c/KTH7e7YddLX+I rohbf+XnNczEpQpX1eB3b0NK+7X2m0Z2xKZwwWHw8Qt3G9FRug/yR6YPPPKCziCOtv25 MdFkC6OFiiQUyIOhKvVb3f07r54Fq/vHeCNb2TuLtBgReyD3ZjavuAjzu0xshbbG0Z/w RYBw== X-Gm-Message-State: AOAM531KUDMtLVbdJ8OtAW9ZJL5XMvAo0SLn1TXC0mfVtUapEcJLVHK5 8QaArYFz1iBPY/0P/DP3llBOySdZQyg9++POX9M4fxK6tg9PvdX8R8FNIW8x+GoBRfohFnIGJ+s 2wGEsk2k17e/pxWteIxZU/6TMscINsz4Q0VhA9FA4DeT2cT4BdISBx/V8v3UejG6DRt5+ShU= X-Received: by 2002:a05:6402:2d9:: with SMTP id b25mr7156681edx.383.1637660920694; Tue, 23 Nov 2021 01:48:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJxC+rhb9RD4w/1+/pZ4KLAi/0WGyC+TZGr/q4FNdjvxwnOLeMikMJpMvZAieoUCmm6HSIyWuA== X-Received: by 2002:a05:6402:2d9:: with SMTP id b25mr7156625edx.383.1637660920366; Tue, 23 Nov 2021 01:48:40 -0800 (PST) From: Martin Kletzander To: libvir-list@redhat.com Subject: [PATCH v3 1/2] util: Add virProcessGetStat Date: Tue, 23 Nov 2021 10:48:05 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1637660941559100001 Content-Type: text/plain; charset="utf-8" This reads and separates all fields from /proc//stat or /proc//task//stat as there are easy mistakes to be done in the implementation. Some tests are added to show it works correctly. No number parsing is done as it would be unused for most of the fields most, if not a= ll, of the time. No struct is used for the result as the length can vary (new fields can be added in the future). Signed-off-by: Martin Kletzander Reviewed-by: J=C3=A1n Tomko --- src/libvirt_private.syms | 1 + src/util/virprocess.c | 77 +++++++++++++++++++++++ src/util/virprocess.h | 66 ++++++++++++++++++++ tests/meson.build | 1 + tests/virprocessstatdata/complex/stat | 2 + tests/virprocessstatdata/simple/stat | 1 + tests/virprocessstattest.c | 88 +++++++++++++++++++++++++++ 7 files changed, 236 insertions(+) create mode 100644 tests/virprocessstatdata/complex/stat create mode 100644 tests/virprocessstatdata/simple/stat create mode 100644 tests/virprocessstattest.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a7bc50a4d16d..7a4e7d7d6f40 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3099,6 +3099,7 @@ virProcessGetMaxMemLock; virProcessGetNamespaces; virProcessGetPids; virProcessGetStartTime; +virProcessGetStat; virProcessGroupGet; virProcessGroupKill; virProcessKill; diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 6de3f36f529c..aab51962acfc 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -1721,3 +1721,80 @@ virProcessSetScheduler(pid_t pid G_GNUC_UNUSED, } =20 #endif /* !WITH_SCHED_SETSCHEDULER */ + +/* + * Get all stat fields for a process based on pid and tid: + * - pid =3D=3D 0 && tid =3D=3D 0 =3D> /proc/self/stat + * - pid !=3D 0 && tid =3D=3D 0 =3D> /proc//stat + * - pid =3D=3D 0 && tid !=3D 0 =3D> /proc/self/task//stat + * - pid !=3D 0 && tid !=3D 0 =3D> /proc//task//stat + * and return them as array of strings. + */ +GStrv +virProcessGetStat(pid_t pid, + pid_t tid) +{ + int len =3D 10 * 1024; /* 10kB ought to be enough for everyone */ + g_autofree char *buf =3D NULL; + g_autofree char *path =3D NULL; + GStrv rest =3D NULL; + GStrv ret =3D NULL; + char *comm =3D NULL; + char *rparen =3D NULL; + size_t nrest =3D 0; + + if (pid) { + if (tid) + path =3D g_strdup_printf("/proc/%d/task/%d/stat", (int)pid, (i= nt)tid); + else + path =3D g_strdup_printf("/proc/%d/stat", (int)pid); + } else { + if (tid) + path =3D g_strdup_printf("/proc/self/task/%d/stat", (int)tid); + else + path =3D g_strdup("/proc/self/stat"); + } + + len =3D virFileReadAllQuiet(path, len, &buf); + if (len < 0) + return NULL; + + /* eliminate trailing spaces */ + while (len > 0 && g_ascii_isspace(buf[--len])) + buf[len] =3D '\0'; + + /* Find end of the first field */ + if (!(comm =3D strchr(buf, ' '))) + return NULL; + *comm =3D '\0'; + + /* Check start of the second field (filename of the executable, in + * parentheses) */ + comm++; + if (*comm !=3D '(') + return NULL; + comm++; + + /* Check end of the second field (last closing parenthesis) */ + rparen =3D strrchr(comm, ')'); + if (!rparen) + return NULL; + *rparen =3D '\0'; + + /* We need to check that the next char is not '\0', but why not just o= pt in + * for the safer way of checking whether it is ' ' (space) instead */ + if (rparen[1] !=3D ' ') + return NULL; + + rest =3D g_strsplit(rparen + 2, " ", 0); + nrest =3D g_strv_length(rest); + ret =3D g_new0(char *, nrest + 3); + ret[0] =3D g_strdup(buf); + ret[1] =3D g_strdup(comm); + memcpy(ret + 2, rest, nrest * sizeof(char *)); + + /* Do not use g_strfreev() as individual elements they were moved to @= ret. */ + VIR_FREE(rest); + + return ret; +} diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 9910331a0caa..82b740396499 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -117,6 +117,72 @@ int virProcessSetupPrivateMountNS(void); int virProcessSetScheduler(pid_t pid, virProcessSchedPolicy policy, int priority); + +GStrv virProcessGetStat(pid_t pid, pid_t tid); + +/* These constants are modelled after proc(5) */ +enum { + VIR_PROCESS_STAT_PID, + VIR_PROCESS_STAT_COMM, + VIR_PROCESS_STAT_STATE, + VIR_PROCESS_STAT_PPID, + VIR_PROCESS_STAT_PGRP, + VIR_PROCESS_STAT_SESSION, + VIR_PROCESS_STAT_TTY_NR, + VIR_PROCESS_STAT_TPGID, + VIR_PROCESS_STAT_FLAGS, + VIR_PROCESS_STAT_MINFLT, + VIR_PROCESS_STAT_CMINFLT, + VIR_PROCESS_STAT_MAJFLT, + VIR_PROCESS_STAT_CMAJFLT, + VIR_PROCESS_STAT_UTIME, + VIR_PROCESS_STAT_STIME, + VIR_PROCESS_STAT_CUTIME, + VIR_PROCESS_STAT_CSTIME, + VIR_PROCESS_STAT_PRIORITY, + VIR_PROCESS_STAT_NICE, + VIR_PROCESS_STAT_NUM_THREADS, + VIR_PROCESS_STAT_ITREALVALUE, + VIR_PROCESS_STAT_STARTTIME, + VIR_PROCESS_STAT_VSIZE, + VIR_PROCESS_STAT_RSS, + VIR_PROCESS_STAT_RSSLIM, + VIR_PROCESS_STAT_STARTCODE, + VIR_PROCESS_STAT_ENDCODE, + VIR_PROCESS_STAT_STARTSTACK, + VIR_PROCESS_STAT_KSTKESP, + VIR_PROCESS_STAT_KSTKEIP, + VIR_PROCESS_STAT_SIGNAL, + VIR_PROCESS_STAT_BLOCKED, + VIR_PROCESS_STAT_SIGIGNORE, + VIR_PROCESS_STAT_SIGCATCH, + VIR_PROCESS_STAT_WCHAN, + VIR_PROCESS_STAT_NSWAP, + VIR_PROCESS_STAT_CNSWAP, + VIR_PROCESS_STAT_EXIT_SIGNAL, + VIR_PROCESS_STAT_PROCESSOR, + VIR_PROCESS_STAT_RT_PRIORITY, + VIR_PROCESS_STAT_POLICY, + VIR_PROCESS_STAT_DELAYACCT_BLKIO_TICKS, + VIR_PROCESS_STAT_GUEST_TIME, + VIR_PROCESS_STAT_CGUEST_TIME, + VIR_PROCESS_STAT_START_DATA, + VIR_PROCESS_STAT_END_DATA, + VIR_PROCESS_STAT_START_BRK, + VIR_PROCESS_STAT_ARG_START, + VIR_PROCESS_STAT_ARG_END, + VIR_PROCESS_STAT_ENV_START, + VIR_PROCESS_STAT_ENV_END, + VIR_PROCESS_STAT_EXIT_CODE, +}; + +/* + * At the time of writing there are 52 values reported in /proc/.../stat, = the + * line below checks that the last one has the right value, increase accor= dingly + * based on proc(5) whenever adding new fields. +*/ +G_STATIC_ASSERT(VIR_PROCESS_STAT_EXIT_CODE =3D=3D 51); + typedef enum { VIR_PROCESS_NAMESPACE_MNT =3D (1 << 1), VIR_PROCESS_NAMESPACE_IPC =3D (1 << 2), diff --git a/tests/meson.build b/tests/meson.build index 1948c07ae385..f75c24872086 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -347,6 +347,7 @@ if host_machine.system() =3D=3D 'linux' { 'name': 'scsihosttest' }, { 'name': 'vircaps2xmltest', 'link_whole': [ test_file_wrapper_lib ] }, { 'name': 'virnetdevbandwidthtest' }, + { 'name': 'virprocessstattest', 'link_whole': [ test_file_wrapper_lib = ] }, { 'name': 'virresctrltest', 'link_whole': [ test_file_wrapper_lib ] }, { 'name': 'virscsitest' }, { 'name': 'virusbtest' }, diff --git a/tests/virprocessstatdata/complex/stat b/tests/virprocessstatda= ta/complex/stat new file mode 100644 index 000000000000..df0ecc149c6f --- /dev/null +++ b/tests/virprocessstatdata/complex/stat @@ -0,0 +1,2 @@ +1 (this) is ( a weird ) +)( (command ( ) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24= 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49= 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74= 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99= 100 diff --git a/tests/virprocessstatdata/simple/stat b/tests/virprocessstatdat= a/simple/stat new file mode 100644 index 000000000000..97d68735370d --- /dev/null +++ b/tests/virprocessstatdata/simple/stat @@ -0,0 +1 @@ +1 (command) 3 4 5 diff --git a/tests/virprocessstattest.c b/tests/virprocessstattest.c new file mode 100644 index 000000000000..8fb82c48ef33 --- /dev/null +++ b/tests/virprocessstattest.c @@ -0,0 +1,88 @@ +#include + +#include "testutils.h" +#include "virfilewrapper.h" +#include "virprocess.h" + + +struct testData { + const char *filename; + const char *command; + size_t count; + bool self; +}; + + +static int +test_virProcessGetStat(const void *opaque) +{ + struct testData *data =3D (struct testData *) opaque; + g_autofree char *data_dir =3D NULL; + g_auto(GStrv) proc_stat =3D NULL; + size_t len =3D 0; + id_t id =3D data->self ? 0 : -1; + const char *command =3D NULL; + + data_dir =3D g_strdup_printf("%s/virprocessstatdata/%s/", + abs_srcdir, data->filename); + + /* We are using predictable id of -1 because this case we will clearly= see + * that the test failed in case of virFileWrapper failure */ + if (id) + virFileWrapperAddPrefix("/proc/-1/task/-1/", data_dir); + else + virFileWrapperAddPrefix("/proc/self/", data_dir); + + proc_stat =3D virProcessGetStat(id, id); + + virFileWrapperClearPrefixes(); + + if (!proc_stat) { + fprintf(stderr, "Could not get process stats\n"); + return -1; + } + + len =3D g_strv_length(proc_stat); + if (data->count !=3D len) { + fprintf(stderr, "Count incorrect, expected %zu, got %zu\n", + data->count, len); + return -1; + } + + command =3D proc_stat[VIR_PROCESS_STAT_COMM]; + if (!STREQ_NULLABLE(data->command, command)) { + fprintf(stderr, "Command incorrect, expected %s, got %s\n", + data->command, command); + return -1; + } + + return 0; +} + + +static int +mymain(void) +{ + struct testData data =3D {0}; + int ret =3D 0; + +#define DO_TEST(_filename, _command, _count, _self) \ + do { \ + data =3D (struct testData){ \ + .filename =3D _filename, \ + .command =3D _command, \ + .count =3D _count, \ + .self =3D _self, \ + }; \ + if (virTestRun("Reading process stat: " _filename, \ + test_virProcessGetStat, &data) < 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST("simple", "command", 5, true); + DO_TEST("complex", "this) is ( a \t weird )\n)( (command ( ", 100, fal= se); + + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN(mymain) --=20 2.34.0 From nobody Fri Apr 26 13:50:37 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1637660934; cv=none; d=zohomail.com; s=zohoarc; b=cYki/7y8/ei5HjDSQsSQMwcQPiJYjQWEsmIGE9bDawXb68esKC7C/IgMF1QncVfBB111/+yFcF2dZ55H7PsFHJOZ3u7PuRDMQIZMCiw+y9qDxWGYyQ6prgg45jn/hMRkHl7PC8q1rCqmlpzDMHKq1jdlxLCZnehO9LNLLpEUFEo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1637660934; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=37LSyIvuSpc8ljKk0EeyVt5tNcZYRwzSSlFu62Bzv8o=; b=GSl0vRplRcw3OaITz7DpbjKZZpdkpHqPgv3RKPiQ4c/kreSLmsapFwGkz3v/HgCrk2BV1kdrYrppfseGVgipF1VLdcWnm2+0aePeLeaLuI+GNWKtmL0JDuvyLdN3eCG49Y8632XfIpu9YWVu7pXdpJwogaiu1V7r1fCg8aMj+2M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1637660934587612.6237329184223; Tue, 23 Nov 2021 01:48:54 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-560-1zS_2qNeNGK0gFAXSwJRNg-1; Tue, 23 Nov 2021 04:48:50 -0500 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 93F3118125C0; Tue, 23 Nov 2021 09:48:45 +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 20B151981F; Tue, 23 Nov 2021 09:48:45 +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 720F84A703; Tue, 23 Nov 2021 09:48:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 1AN9mhLB007099 for ; Tue, 23 Nov 2021 04:48:43 -0500 Received: by smtp.corp.redhat.com (Postfix) id E294540CFD0D; Tue, 23 Nov 2021 09:48:42 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast01.extmail.prod.ext.rdu2.redhat.com [10.11.55.17]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DD74C40CFD04 for ; Tue, 23 Nov 2021 09:48:42 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C20CC85A5B9 for ; Tue, 23 Nov 2021 09:48:42 +0000 (UTC) Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-544-N7JKPtSyMU69iR5wTMs2Kg-1; Tue, 23 Nov 2021 04:48:41 -0500 Received: by mail-ed1-f70.google.com with SMTP id k7-20020aa7c387000000b003e7ed87fb31so17430076edq.3 for ; Tue, 23 Nov 2021 01:48:41 -0800 (PST) Received: from wheatley.localdomain (nat-pool-brq-t.redhat.com. [213.175.37.10]) by smtp.gmail.com with ESMTPSA id z22sm5867702edd.78.2021.11.23.01.48.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Nov 2021 01:48:39 -0800 (PST) Received: from wheatley.redhat.com (wheatley.k8r.cz [127.0.0.1]) by wheatley.localdomain (Postfix) with ESMTP id 1478020BC4F8 for ; Tue, 23 Nov 2021 10:48:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637660933; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=37LSyIvuSpc8ljKk0EeyVt5tNcZYRwzSSlFu62Bzv8o=; b=MBoZ6nn0tCKPslrLXvvLYM1R+TWtYi3fC9YT0yEakPwCuYewZ2m3Odv0EIDDnGQbbGty5m 3YEHtEOax9v7a0OKqYXJA0/ZkhWn3l1oZkkzS8TDjeSHVfnoblRNsBliI0lrX8GcU6iXjA ngPPrEG1MsruNNx+NiaSeSUIyyh0/TM= X-MC-Unique: 1zS_2qNeNGK0gFAXSwJRNg-1 X-MC-Unique: N7JKPtSyMU69iR5wTMs2Kg-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=37LSyIvuSpc8ljKk0EeyVt5tNcZYRwzSSlFu62Bzv8o=; b=kPDVxyYZLPJrf76TQu0YG/35UNDAurVIJvBT/LPXwlVASU1M5dY9pzQ71HG9DzEkFV 6yf3+OVKlXx3v3E+w4LvODe6bBwlI5PGHgwic3x+aEnAybmNe8KTPVa7T6u05UlKp67q +cG+JvdMUUzZpinhJ55u8fBrHMr+nXM+CmveXNWhd5krZcmdWOOwdERST0kGO8b81y7E wVYb8Ce6h+8s6pPbCoGekWzShi72rlfL8ViMkRQHuEwJb2yD6xb3RUguKUXAPoVMDKMb XBhnkIU0UX/lE2HPpuLTD/7uzMpdwJ7FoAfc8MmQSD1njIm7AeifYdqKlAKP5mZ/pJVR 0bfg== X-Gm-Message-State: AOAM533/inR9ripdAF2ErFHnxtfhW/HvcDw18KcoSDRgfFC0CgwudpkR OzKPBsYvZB46GwtOF+QsL5M1Cb2Ao7HtQFFtfI9B7a9LTI1oaD7nFM19PfFqI8aSIrR06yK8xpZ qgsyUIVzJTyLUHs5gRDvu6HKyW39eYIRtKpEP5hdAJ1QzcND3hkjcWX3uAoHoFOQ8Gwm3dCU= X-Received: by 2002:a17:906:79c8:: with SMTP id m8mr5457607ejo.511.1637660920255; Tue, 23 Nov 2021 01:48:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJzkr4HGlFlZdSDF139lGl/WPnq1iIsYfrHUnnGwBFGkBXFaTt4YXqRcXzDqfYGfZi1exCJzZw== X-Received: by 2002:a17:906:79c8:: with SMTP id m8mr5457586ejo.511.1637660920057; Tue, 23 Nov 2021 01:48:40 -0800 (PST) From: Martin Kletzander To: libvir-list@redhat.com Subject: [PATCH v3 2/2] Use virProcessGetStat Date: Tue, 23 Nov 2021 10:48:06 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 X-loop: libvir-list@redhat.com 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1637660935065100001 Content-Type: text/plain; charset="utf-8" This eliminates one incorrect parsing implementation which relied on the command field not having a closing bracket. This possibility is already tested against in the virProcessGetStat() tests. Signed-off-by: Martin Kletzander Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_driver.c | 34 ++++++------------------------ src/util/virprocess.c | 48 ++++++------------------------------------ 2 files changed, 13 insertions(+), 69 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d954635dde2a..16d449913ca7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1399,36 +1399,18 @@ qemuGetSchedInfo(unsigned long long *cpuWait, =20 static int qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, - pid_t pid, int tid) + pid_t pid, pid_t tid) { - g_autofree char *proc =3D NULL; - FILE *pidinfo; + g_auto(GStrv) proc_stat =3D virProcessGetStat(pid, tid); unsigned long long usertime =3D 0, systime =3D 0; long rss =3D 0; int cpu =3D 0; =20 - /* In general, we cannot assume pid_t fits in int; but /proc parsing - * is specific to Linux where int works fine. */ - if (tid) - proc =3D g_strdup_printf("/proc/%d/task/%d/stat", (int)pid, tid); - else - proc =3D g_strdup_printf("/proc/%d/stat", (int)pid); - if (!proc) - return -1; - - pidinfo =3D fopen(proc, "r"); - - /* See 'man proc' for information about what all these fields are. We'= re - * only interested in a very few of them */ - if (!pidinfo || - fscanf(pidinfo, - /* pid -> stime */ - "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %= llu %llu" - /* cutime -> endcode */ - "%*d %*d %*d %*d %*d %*d %*u %*u %ld %*u %*u %*u" - /* startstack -> processor */ - "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d", - &usertime, &systime, &rss, &cpu) !=3D 4) { + if (!proc_stat || + virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_UTIME], NULL, 10, &us= ertime) < 0 || + virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_STIME], NULL, 10, &sy= stime) < 0 || + virStrToLong_l(proc_stat[VIR_PROCESS_STAT_RSS], NULL, 10, &rss) < = 0 || + virStrToLong_i(proc_stat[VIR_PROCESS_STAT_PROCESSOR], NULL, 10, &c= pu) < 0) { VIR_WARN("cannot parse process status data"); } =20 @@ -1450,8 +1432,6 @@ qemuGetProcessInfo(unsigned long long *cpuTime, int *= lastCpu, long *vm_rss, VIR_DEBUG("Got status for %d/%d user=3D%llu sys=3D%llu cpu=3D%d rss=3D= %ld", (int)pid, tid, usertime, systime, cpu, rss); =20 - VIR_FORCE_FCLOSE(pidinfo); - return 0; } =20 diff --git a/src/util/virprocess.c b/src/util/virprocess.c index aab51962acfc..20d04bad6f26 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -1153,56 +1153,20 @@ virProcessSetMaxCoreSize(pid_t pid G_GNUC_UNUSED, int virProcessGetStartTime(pid_t pid, unsigned long long *timestamp) { - char *tmp; - int len; - g_autofree char *filename =3D NULL; - g_autofree char *buf =3D NULL; - g_auto(GStrv) tokens =3D NULL; - - filename =3D g_strdup_printf("/proc/%llu/stat", (long long)pid); - - if ((len =3D virFileReadAll(filename, 1024, &buf)) < 0) - return -1; + g_auto(GStrv) proc_stat =3D virProcessGetStat(pid, 0); =20 - /* start time is the token at index 19 after the '(process name)' entr= y - since only this - * field can contain the ')' character, search backwards for this to a= void malicious - * processes trying to fool us - */ - - if (!(tmp =3D strrchr(buf, ')'))) { + if (!proc_stat || g_strv_length(proc_stat) < 22) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot find start time in %s"), - filename); + _("Cannot find start time for pid %d"), (int)pid); return -1; } - tmp +=3D 2; /* skip ') ' */ - if ((tmp - buf) >=3D len) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot find start time in %s"), - filename); - return -1; - } - - tokens =3D g_strsplit(tmp, " ", 0); =20 - if (!tokens || - g_strv_length(tokens) < 20) { + if (virStrToLong_ull(proc_stat[21], NULL, 10, timestamp) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot find start time in %s"), - filename); + _("Cannot parse start time %s for pid %d"), + proc_stat[21], (int)pid); return -1; } - - if (virStrToLong_ull(tokens[19], - NULL, - 10, - timestamp) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot parse start time %s in %s"), - tokens[19], filename); - return -1; - } - return 0; } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) --=20 2.34.0