From nobody Sat Apr 27 00:28:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.74 as permitted sender) client-ip=63.128.21.74; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-74.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.74 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=1584552778; cv=none; d=zohomail.com; s=zohoarc; b=YXs8z34OW6yNXwVOIKP7a1EixFoIAuB4i+9R7Y1chTcVMgbPsH7D+KVaT7blxpsxYZPsBVU3eRSi6cxzOv2jbGS3RsqybwTf3RX+1d7YISI+G3G4bGut1ZI7CJpdSKA6xC3YwV/ctPqA8kVf5W5XYjOkcG4mf0Gn74qsDqjXaPU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1584552778; 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=QJ+xutWREE4GK3Cx8I5HO46PDMHDibUvnheH4q1IjRw=; b=LhpsOJ6yDJXMeinXJHy5Pl5BSRRU4BgxZ8V3NL4fUy/CqEoVc02GQ/9wAmGjcYwNRMCSO8uiyppE6eWco9s9hY3Zq18DYweKHa0DsKo7K9Z4uag40F9UYAian3LroEl1QfBuP/ioOqkoCaB9VP/T9/8ty/w7YUeSBIQ3ENkIOho= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.74 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-74.mimecast.com (us-smtp-delivery-74.mimecast.com [63.128.21.74]) by mx.zohomail.com with SMTPS id 1584552778529436.83710157433836; Wed, 18 Mar 2020 10:32:58 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-176-P45OXwj8MjOJS38o3tuyVQ-1; Wed, 18 Mar 2020 13:32:54 -0400 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2DD226D95A; Wed, 18 Mar 2020 17:32:34 +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 031145DA82; Wed, 18 Mar 2020 17:32:34 +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 8762E18089CF; Wed, 18 Mar 2020 17:32:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 02IHWVj8029282 for ; Wed, 18 Mar 2020 13:32:31 -0400 Received: by smtp.corp.redhat.com (Postfix) id E267417B91; Wed, 18 Mar 2020 17:32:31 +0000 (UTC) Received: from localhost.localdomain (unknown [10.40.192.91]) by smtp.corp.redhat.com (Postfix) with ESMTP id 61BB6627D8 for ; Wed, 18 Mar 2020 17:32:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1584552777; 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=QJ+xutWREE4GK3Cx8I5HO46PDMHDibUvnheH4q1IjRw=; b=dokU0MuF/5Tix0uSJTLM1ApywvN8c3F+r0Pmn7kIM3/Az7EP8wNOr4dzo93qgmtUVh6LMo DZc6oxw4qnfkyfZJd7zYDqdJh9TVFP06nwUbSiw90s8NHt3t2PwpNRXGQS7VwWhJMYur7P U16sUAVcpIvM2CyjUCPF+1V0i0QVVfw= X-MC-Unique: P45OXwj8MjOJS38o3tuyVQ-1 From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 5/6] virprocess: Passthru error from virProcessRunInForkHelper Date: Wed, 18 Mar 2020 18:32:15 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 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.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" When running a function in a forked child, so far the only thing we could report is exit status of the child and the error message. However, it may be beneficial to the caller to know the actual error that happened in the child. Signed-off-by: Michal Privoznik Reviewed-by: Pavel Mores --- build-aux/syntax-check.mk | 2 +- src/util/virprocess.c | 51 ++++++++++++++++++++++++++++++++++++--- tests/commandtest.c | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk index 3020921be8..2a38c03ba9 100644 --- a/build-aux/syntax-check.mk +++ b/build-aux/syntax-check.mk @@ -1987,7 +1987,7 @@ exclude_file_name_regexp--sc_flags_usage =3D \ exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics =3D \ ^(src/rpc/gendispatch\.pl$$|tests/) =20 -exclude_file_name_regexp--sc_po_check =3D ^(docs/|src/rpc/gendispatch\.pl$= $) +exclude_file_name_regexp--sc_po_check =3D ^(docs/|src/rpc/gendispatch\.pl$= $|tests/commandtest.c$$) =20 exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY =3D \ ^(build-aux/syntax-check\.mk|include/libvirt/virterror\.h|src/remote/rem= ote_daemon_dispatch\.c|src/util/virerror\.c|docs/internals/oomtesting\.html= \.in)$$ diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 24135070b7..e8674402f9 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -1126,6 +1126,23 @@ virProcessRunInMountNamespace(pid_t pid G_GNUC_UNUSE= D, =20 =20 #ifndef WIN32 +typedef struct { + int code; + int domain; + char message[VIR_ERROR_MAX_LENGTH]; + virErrorLevel level; + char str1[VIR_ERROR_MAX_LENGTH]; + char str2[VIR_ERROR_MAX_LENGTH]; + /* str3 doesn't seem to be used. Ignore it. */ + int int1; + int int2; +} errorData; + +typedef union { + errorData data; + char bindata[sizeof(errorData)]; +} errorDataBin; + static int virProcessRunInForkHelper(int errfd, pid_t ppid, @@ -1134,9 +1151,19 @@ virProcessRunInForkHelper(int errfd, { if (cb(ppid, opaque) < 0) { virErrorPtr err =3D virGetLastError(); + errorDataBin bin =3D { 0 }; + if (err) { - size_t len =3D strlen(err->message) + 1; - ignore_value(safewrite(errfd, err->message, len)); + bin.data.code =3D err->code; + bin.data.domain =3D err->domain; + ignore_value(virStrcpy(bin.data.message, err->message, sizeof(= bin.data.message))); + bin.data.level =3D err->level; + ignore_value(virStrcpy(bin.data.str1, err->str1, sizeof(bin.da= ta.str1))); + ignore_value(virStrcpy(bin.data.str2, err->str2, sizeof(bin.da= ta.str2))); + bin.data.int1 =3D err->int1; + bin.data.int2 =3D err->int2; + + ignore_value(safewrite(errfd, bin.bindata, sizeof(bin))); } =20 return -1; @@ -1188,16 +1215,32 @@ virProcessRunInFork(virProcessForkCallback cb, } else { int status; g_autofree char *buf =3D NULL; + errorDataBin bin; + int nread; =20 VIR_FORCE_CLOSE(errfd[1]); - ignore_value(virFileReadHeaderFD(errfd[0], 1024, &buf)); + nread =3D virFileReadHeaderFD(errfd[0], sizeof(bin), &buf); ret =3D virProcessWait(child, &status, false); if (ret =3D=3D 0) { ret =3D status =3D=3D EXIT_CANCELED ? -1 : status; if (ret) { virReportError(VIR_ERR_INTERNAL_ERROR, _("child reported (status=3D%d): %s"), - status, NULLSTR(buf)); + status, NULLSTR(bin.data.message)); + + if (nread =3D=3D sizeof(bin)) { + memcpy(bin.bindata, buf, sizeof(bin)); + virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, + bin.data.domain, + bin.data.code, + bin.data.level, + bin.data.str1, + bin.data.str2, + NULL, + bin.data.int1, + bin.data.int2, + "%s", bin.data.message); + } } } } diff --git a/tests/commandtest.c b/tests/commandtest.c index a64aa9ad33..f4a2c67c05 100644 --- a/tests/commandtest.c +++ b/tests/commandtest.c @@ -1257,6 +1257,48 @@ static int test27(const void *unused G_GNUC_UNUSED) } =20 =20 +static int +test28Callback(pid_t pid G_GNUC_UNUSED, + void *opaque G_GNUC_UNUSED) +{ + virReportSystemError(ENODATA, "%s", "some error message"); + return -1; +} + + +static int +test28(const void *unused G_GNUC_UNUSED) +{ + /* Not strictly a virCommand test, but this is the easiest place + * to test this lower-level interface. */ + virErrorPtr err; + + if (virProcessRunInFork(test28Callback, NULL) !=3D -1) { + fprintf(stderr, "virProcessRunInFork did not fail\n"); + return -1; + } + + if (!(err =3D virGetLastError())) { + fprintf(stderr, "Expected error but got nothing\n"); + return -1; + } + + if (!(err->code =3D=3D VIR_ERR_SYSTEM_ERROR && + err->domain =3D=3D 0 && + STREQ(err->message, "some error message: No data available") && + err->level =3D=3D VIR_ERR_ERROR && + STREQ(err->str1, "%s") && + STREQ(err->str2, "some error message: No data available") && + err->int1 =3D=3D ENODATA && + err->int2 =3D=3D -1)) { + fprintf(stderr, "Unexpected error object\n"); + return -1; + } + + return 0; +} + + static int mymain(void) { @@ -1354,6 +1396,7 @@ mymain(void) DO_TEST(test25); DO_TEST(test26); DO_TEST(test27); + DO_TEST(test28); =20 return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; } --=20 2.24.1