From nobody Fri Sep 5 22:26:35 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=oracle.com ARC-Seal: i=1; a=rsa-sha256; t=1658854676; cv=none; d=zohomail.com; s=zohoarc; b=hW8umT3UMol266kWO1IjKRYz8IDekXgITa+fJK+mJa4CbXRtScKIWeY6jfmRo3TpJS/LSn7xxkc4RMCZ0qVXhf8zDbCOzvhxFkN7J37N5C2KJRL4LhTLCHG0rJvoJ/fCMefQ7jmxQq1Y72cgi6D8gPCmNa31hhf4NtukSzesM6o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1658854676; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=0FXxfcuX+isM/WZ7So7KOzTnYv4rPmh6nZLqhSmQbwI=; b=MzYMRvTNNhPup5cMQmUddWRtss4p2GHBWhpEF1bbN8dJet1lwdJUK9bW2Vx6ueHb84zHCxPCZrZicvun8kTIYDGKd+xLFgEBUwTIZcBthRzJsqraXRkzmECZD7kCXGtByj345hAUxqrmfbIImJJdHztQ5jV2IPfRriPnJEhc5Uo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 165885467661757.860617388001174; Tue, 26 Jul 2022 09:57:56 -0700 (PDT) Received: from localhost ([::1]:41084 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oGNsZ-0001MD-HX for importer@patchew.org; Tue, 26 Jul 2022 12:57:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35380) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oGNAD-0003hy-TR for qemu-devel@nongnu.org; Tue, 26 Jul 2022 12:12:05 -0400 Received: from mx0b-00069f02.pphosted.com ([205.220.177.32]:45888) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oGNAB-0006Gv-BZ for qemu-devel@nongnu.org; Tue, 26 Jul 2022 12:12:05 -0400 Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26QFnQMm006253; Tue, 26 Jul 2022 16:11:39 GMT Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.appoci.oracle.com [138.1.37.129]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3hg940pu40-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 26 Jul 2022 16:11:39 +0000 Received: from pps.filterd (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 26QF5NqW006270; Tue, 26 Jul 2022 16:11:38 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3hh65bq2jv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 26 Jul 2022 16:11:37 +0000 Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 26QG5uTL023334; Tue, 26 Jul 2022 16:11:37 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 3hh65bq0y5-37; Tue, 26 Jul 2022 16:11:37 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2022-7-12; bh=0FXxfcuX+isM/WZ7So7KOzTnYv4rPmh6nZLqhSmQbwI=; b=1CVgjzsXE8Wqw/jCRU1qEkL1+OWzkFEtold1Tj7d9VoJYJ+v5fPVmElUCXCD+/dNGXgm cxeiuAq6dGHdh0d/ifOXXGHFsbGkiIa91qac0pDWj+UpIT5bOgIN7zNzLQdOdf3vNBFo EtOgUxsJGOm9lQvAM1BR1RR7kFsECT0MWU3Ba5kcqczv3N0AN1uAoT8hdEpDlXrwjFJW Tutgs8lCTzJN86GpWb2WWPGlCArdVQ6+nS2y2Pu0iiNWVdApRYgPr9tBC2FhlL+zNbfC hAGU3Z6vK1OtfP5E6HufPN24rNwLcrAOrJUN2PQTrmrnzk5AuA5KCA7MGhEcxyfAJONl Jg== From: Steve Sistare To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Stefan Hajnoczi , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Alex=20Benn=C3=A9e?= , "Dr. David Alan Gilbert" , "Michael S. Tsirkin" , Marcel Apfelbaum , Alex Williamson , "Daniel P. Berrange" , Juan Quintela , Markus Armbruster , Eric Blake , Jason Zeng , Zheng Chuan , Steve Sistare , Mark Kanda , Guoyi Tu , Peter Maydell , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Igor Mammedov , David Hildenbrand , John Snow , Peng Liang Subject: [PATCH V9 36/46] chardev: cpr framework Date: Tue, 26 Jul 2022 09:10:33 -0700 Message-Id: <1658851843-236870-37-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1658851843-236870-1-git-send-email-steven.sistare@oracle.com> References: <1658851843-236870-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-26_04,2022-07-26_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 malwarescore=0 phishscore=0 spamscore=0 mlxlogscore=999 suspectscore=0 bulkscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2206140000 definitions=main-2207260063 X-Proofpoint-GUID: P3UQ7OklpxvNxfil2E3RfzqT6jGzXCrW X-Proofpoint-ORIG-GUID: P3UQ7OklpxvNxfil2E3RfzqT6jGzXCrW Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.177.32; envelope-from=steven.sistare@oracle.com; helo=mx0b-00069f02.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @oracle.com) X-ZM-MESSAGEID: 1658854679100100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add QEMU_CHAR_FEATURE_CPR for devices that support cpr-exec by preserving an open descriptor across exec. Add the chardev reopen-on-cpr option for devices that should be closed on cpr and reopened after exec. Enable cpr for a chardev if it has QEMU_CHAR_FEATURE_CPR and reopen-on-cpr is false. Allow cpr-save if either QEMU_CHAR_FEATURE_CPR or reopen-on-cpr is true for all chardevs in the configuration. Signed-off-by: Steve Sistare --- chardev/char.c | 49 +++++++++++++++++++++++++++++++++++++++++++++-= --- include/chardev/char.h | 5 +++++ qapi/char.json | 7 ++++++- qemu-options.hx | 26 ++++++++++++++++++++++---- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/chardev/char.c b/chardev/char.c index 0169d8d..01755d7 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -36,6 +36,8 @@ #include "qemu/help_option.h" #include "qemu/module.h" #include "qemu/option.h" +#include "migration/cpr-state.h" +#include "migration/blocker.h" #include "qemu/id.h" #include "qemu/coroutine.h" #include "qemu/yank.h" @@ -236,26 +238,55 @@ int qemu_chr_add_client(Chardev *s, int fd) static void qemu_char_open(Chardev *chr, ChardevBackend *backend, bool *be_opened, Error **errp) { + ERRP_GUARD(); + g_autofree char *fdname =3D NULL; + ChardevClass *cc =3D CHARDEV_GET_CLASS(chr); /* Any ChardevCommon member would work */ ChardevCommon *common =3D backend ? backend->u.null.data : NULL; + bool has_logfile =3D (common && common->has_logfile); + bool has_feature_cpr; =20 - if (common && common->has_logfile) { + if (has_logfile) { int flags =3D O_WRONLY; + fdname =3D g_strdup_printf("%s_log", chr->label); if (common->has_logappend && common->logappend) { flags |=3D O_APPEND; } else { flags |=3D O_TRUNC; } - chr->logfd =3D qemu_create(common->logfile, flags, 0666, errp); + chr->logfd =3D cpr_find_fd(fdname, 0); + if (chr->logfd < 0) { + chr->logfd =3D qemu_create(common->logfile, flags, 0666, errp); + } if (chr->logfd < 0) { return; } } =20 + chr->reopen_on_cpr =3D (common && common->reopen_on_cpr); + if (cc->open) { cc->open(chr, backend, be_opened, errp); + if (*errp) { + return; + } + } + + /* Evaluate this after the open method sets the feature */ + has_feature_cpr =3D qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_CPR); + chr->cpr_enabled =3D !chr->reopen_on_cpr && has_feature_cpr; + + if (!chr->reopen_on_cpr && !has_feature_cpr) { + chr->cpr_blocker =3D NULL; + error_setg(&chr->cpr_blocker, + "chardev %s -> %s does not allow cpr. See reopen-on-cpr.", + chr->label, chr->filename); + migrate_add_blockers(&chr->cpr_blocker, errp, MIG_MODE_CPR_EXEC, -= 1); + + } else if (chr->cpr_enabled && has_logfile) { + cpr_resave_fd(fdname, 0, chr->logfd); } } =20 @@ -297,11 +328,16 @@ static void char_finalize(Object *obj) if (chr->be) { chr->be->chr =3D NULL; } - g_free(chr->filename); - g_free(chr->label); if (chr->logfd !=3D -1) { + g_autofree char *fdname =3D g_strdup_printf("%s_log", chr->label); + if (chr->cpr_enabled) { + cpr_delete_fd(fdname, 0); + } close(chr->logfd); } + migrate_del_blocker(&chr->cpr_blocker); + g_free(chr->filename); + g_free(chr->label); qemu_mutex_destroy(&chr->chr_write_lock); } =20 @@ -501,6 +537,8 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommo= n *backend) =20 backend->has_logappend =3D true; backend->logappend =3D qemu_opt_get_bool(opts, "logappend", false); + + backend->reopen_on_cpr =3D qemu_opt_get_bool(opts, "reopen-on-cpr", fa= lse); } =20 static const ChardevClass *char_get_class(const char *driver, Error **errp) @@ -942,6 +980,9 @@ QemuOptsList qemu_chardev_opts =3D { },{ .name =3D "abstract", .type =3D QEMU_OPT_BOOL, + },{ + .name =3D "reopen-on-cpr", + .type =3D QEMU_OPT_BOOL, #endif }, { /* end of list */ } diff --git a/include/chardev/char.h b/include/chardev/char.h index a319b5f..bbf2560 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -50,6 +50,8 @@ typedef enum { /* Whether the gcontext can be changed after calling * qemu_chr_be_update_read_handlers() */ QEMU_CHAR_FEATURE_GCONTEXT, + /* Whether the device supports cpr */ + QEMU_CHAR_FEATURE_CPR, =20 QEMU_CHAR_FEATURE_LAST, } ChardevFeature; @@ -67,6 +69,9 @@ struct Chardev { int be_open; /* used to coordinate the chardev-change special-case: */ bool handover_yank_instance; + bool reopen_on_cpr; + bool cpr_enabled; + Error *cpr_blocker; GSource *gsource; GMainContext *gcontext; DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); diff --git a/qapi/char.json b/qapi/char.json index 923dc50..0c3558e 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -204,12 +204,17 @@ # @logfile: The name of a logfile to save output # @logappend: true to append instead of truncate # (default to false to truncate) +# @reopen-on-cpr: if true, close device's fd on cpr-save and reopen it aft= er +# cpr-exec. Set this to allow CPR on a device that does not +# support QEMU_CHAR_FEATURE_CPR. defaults to false. +# since 7.1. # # Since: 2.6 ## { 'struct': 'ChardevCommon', 'data': { '*logfile': 'str', - '*logappend': 'bool' } } + '*logappend': 'bool', + '*reopen-on-cpr': 'bool' } } =20 ## # @ChardevFile: diff --git a/qemu-options.hx b/qemu-options.hx index 3ed9270..ea79afa 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3295,43 +3295,57 @@ DEFHEADING(Character device options:) =20 DEF("chardev", HAS_ARG, QEMU_OPTION_chardev, "-chardev help\n" - "-chardev null,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend=3Don= |off]\n" + "-chardev null,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend=3Don= |off][,reopen-on-cpr=3Don|off]\n" "-chardev socket,id=3Did[,host=3Dhost],port=3Dport[,to=3Dto][,ipv4=3Do= n|off][,ipv6=3Don|off][,nodelay=3Don|off]\n" " [,server=3Don|off][,wait=3Don|off][,telnet=3Don|off][,websoc= ket=3Don|off][,reconnect=3Dseconds][,mux=3Don|off]\n" - " [,logfile=3DPATH][,logappend=3Don|off][,tls-creds=3DID][,tls= -authz=3DID] (tcp)\n" + " [,logfile=3DPATH][,logappend=3Don|off][,tls-creds=3DID][,tls= -authz=3DID][,reopen-on-cpr=3Don|off] (tcp)\n" "-chardev socket,id=3Did,path=3Dpath[,server=3Don|off][,wait=3Don|off]= [,telnet=3Don|off][,websocket=3Don|off][,reconnect=3Dseconds]\n" - " [,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|off][,abstr= act=3Don|off][,tight=3Don|off] (unix)\n" + " [,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|off][,abstr= act=3Don|off][,tight=3Don|off][,reopen-on-cpr=3Don|off] (unix)\n" "-chardev udp,id=3Did[,host=3Dhost],port=3Dport[,localaddr=3Dlocaladdr= ]\n" " [,localport=3Dlocalport][,ipv4=3Don|off][,ipv6=3Don|off][,mu= x=3Don|off]\n" - " [,logfile=3DPATH][,logappend=3Don|off]\n" + " [,logfile=3DPATH][,logappend=3Don|off][,reopen-on-cpr=3Don|o= ff]\n" "-chardev msmouse,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend= =3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev vc,id=3Did[[,width=3Dwidth][,height=3Dheight]][[,cols=3Dcols= ][,rows=3Drows]]\n" " [,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev ringbuf,id=3Did[,size=3Dsize][,logfile=3DPATH][,logappend=3D= on|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev file,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][,lo= gappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev pipe,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][,lo= gappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" #ifdef _WIN32 "-chardev console,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend= =3Don|off]\n" "-chardev serial,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][,= logappend=3Don|off]\n" #else "-chardev pty,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|= off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev stdio,id=3Did[,mux=3Don|off][,signal=3Don|off][,logfile=3DPA= TH][,logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" #endif #ifdef CONFIG_BRLAPI "-chardev braille,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend= =3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" #endif #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__Dragon= Fly__) "-chardev serial,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][,= logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev tty,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][,log= append=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" #endif #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) "-chardev parallel,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH]= [,logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev parport,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][= ,logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" #endif #if defined(CONFIG_SPICE) "-chardev spicevmc,id=3Did,name=3Dname[,debug=3Ddebug][,logfile=3DPATH= ][,logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" "-chardev spiceport,id=3Did,name=3Dname[,debug=3Ddebug][,logfile=3DPAT= H][,logappend=3Don|off]\n" + " [,reopen-on-cpr=3Don|off]\n" #endif , QEMU_ARCH_ALL ) @@ -3406,6 +3420,10 @@ The general form of a character device option is: ``logappend`` option controls whether the log file will be truncated or appended to when opened. =20 + Every backend supports the ``reopen-on-cpr`` option. If on, the + devices's descriptor is closed during cpr save, and reopened after exe= c. + This is useful for devices that do not support cpr. + The available backends are: =20 ``-chardev null,id=3Did`` --=20 1.8.3.1