From patchwork Sun Jun 30 19:44:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sistare X-Patchwork-Id: 13717319 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2554FC27C4F for ; Sun, 30 Jun 2024 19:44:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sO0TC-0007V5-Mj; Sun, 30 Jun 2024 15:44:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T9-0007Tq-HN for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:15 -0400 Received: from mx0b-00069f02.pphosted.com ([205.220.177.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T6-0006Ox-7G for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:13 -0400 Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45UJhqpn010343; Sun, 30 Jun 2024 19:44:11 GMT 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-2023-11-20; bh=IXh6m3asos4UP9HPCXWfQF0AlWmbA78YTfoerjXjQno=; b= ZVSlbCj7jYH0Dhwy3yVeLvyd+WSYnB449Z2kyw/Cqqdtpx0mM4AnkuzkWWA3C6iY lbClVNr/3v7bjKUtyy0PgY3o8/g+VnBo+ImtBEouzXaF73ze1AcOhUWCYCvaN4Yu fxjRKBhmAphoGoMX/JFvsWDZelKZFlCqJjvj8cratTKE3E+p+8h/W1L20UJfklpN 5Wdm8UcsgoPO2gc+BXJzvBZ8wLMqSbEC1B88GfWWPHXhulVOsItpDhFWwS7kN+jp BdqEBdEV4Ul2wKbIDAiEwEHgcErxDujjZ+ld54LscVwXbVwjERLbJ870ZjJPmK0f himMvZ7MQJs6Qn0Fs2k/vQ== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4029vshev6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:10 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 45UFGr6t022884; Sun, 30 Jun 2024 19:44:09 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4028q5gg4m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:09 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJg4f2039161; Sun, 30 Jun 2024 19:44:09 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4028q5gg4e-2; Sun, 30 Jun 2024 19:44:09 +0000 From: Steve Sistare To: qemu-devel@nongnu.org Cc: Peter Xu , Fabiano Rosas , Markus Armbruster , Steve Sistare Subject: [RFC V1 1/6] migration: SCM_RIGHTS for QEMUFile Date: Sun, 30 Jun 2024 12:44:03 -0700 Message-Id: <1719776648-435073-2-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> References: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2406180000 definitions=main-2406300157 X-Proofpoint-GUID: 6PRp8zLHKnqQuANrWClotloXtUfbE5h9 X-Proofpoint-ORIG-GUID: 6PRp8zLHKnqQuANrWClotloXtUfbE5h9 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_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Define functions to put/get file descriptors to/from a QEMUFile, for qio channels that support SCM_RIGHTS. Maintain ordering such that put(A), put(fd), put(B) followed by get(A), get(fd), get(B) always succeeds. Other get orderings may succeed but are not guaranteed. Signed-off-by: Steve Sistare --- migration/qemu-file.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++--- migration/qemu-file.h | 2 ++ migration/trace-events | 2 ++ 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/migration/qemu-file.c b/migration/qemu-file.c index b6d2f58..424c27d 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -37,6 +37,11 @@ #define IO_BUF_SIZE 32768 #define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64) +typedef struct FdEntry { + QTAILQ_ENTRY(FdEntry) entry; + int fd; +} FdEntry; + struct QEMUFile { QIOChannel *ioc; bool is_writable; @@ -51,6 +56,9 @@ struct QEMUFile { int last_error; Error *last_error_obj; + + bool fd_pass; + QTAILQ_HEAD(, FdEntry) fds; }; /* @@ -109,6 +117,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable) object_ref(ioc); f->ioc = ioc; f->is_writable = is_writable; + f->fd_pass = qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS); + QTAILQ_INIT(&f->fds); return f; } @@ -310,6 +320,10 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) int len; int pending; Error *local_error = NULL; + g_autofree int *fds = NULL; + size_t nfd = 0; + int **pfds = f->fd_pass ? &fds : NULL; + size_t *pnfd = f->fd_pass ? &nfd : NULL; assert(!qemu_file_is_writable(f)); @@ -325,10 +339,9 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) } do { - len = qio_channel_read(f->ioc, - (char *)f->buf + pending, - IO_BUF_SIZE - pending, - &local_error); + struct iovec iov = { f->buf + pending, IO_BUF_SIZE - pending }; + len = qio_channel_readv_full(f->ioc, &iov, 1, pfds, pnfd, 0, + &local_error); if (len == QIO_CHANNEL_ERR_BLOCK) { if (qemu_in_coroutine()) { qio_channel_yield(f->ioc, G_IO_IN); @@ -348,9 +361,65 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) qemu_file_set_error_obj(f, len, local_error); } + for (int i = 0; i < nfd; i++) { + FdEntry *fde = g_new0(FdEntry, 1); + fde->fd = fds[i]; + QTAILQ_INSERT_TAIL(&f->fds, fde, entry); + } + return len; } +int qemu_file_put_fd(QEMUFile *f, int fd) +{ + int ret = 0; + QIOChannel *ioc = qemu_file_get_ioc(f); + Error *err = NULL; + struct iovec iov = { (void *)" ", 1 }; + + /* + * Send a dummy byte so qemu_fill_buffer on the receiving side does not + * fail with a len=0 error. Flush first to maintain ordering wrt other + * data. + */ + + qemu_fflush(f); + if (qio_channel_writev_full(ioc, &iov, 1, &fd, 1, 0, &err) < 1) { + error_report_err(error_copy(err)); + qemu_file_set_error_obj(f, -EIO, err); + ret = -1; + } + trace_qemu_file_put_fd(f->ioc->name, fd, ret); + return 0; +} + +int qemu_file_get_fd(QEMUFile *f) +{ + int fd = -1; + FdEntry *fde; + + if (!f->fd_pass) { + Error *err = NULL; + error_setg(&err, "%s does not support fd passing", f->ioc->name); + error_report_err(error_copy(err)); + qemu_file_set_error_obj(f, -EIO, err); + goto out; + } + + /* Force the dummy byte and its fd passenger to appear. */ + qemu_peek_byte(f, 0); + + fde = QTAILQ_FIRST(&f->fds); + if (fde) { + qemu_get_byte(f); /* Drop the dummy byte */ + fd = fde->fd; + QTAILQ_REMOVE(&f->fds, fde, entry); + } +out: + trace_qemu_file_get_fd(f->ioc->name, fd); + return fd; +} + /** Closes the file * * Returns negative error value if any error happened on previous operations or @@ -361,11 +430,17 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) */ int qemu_fclose(QEMUFile *f) { + FdEntry *fde, *next; int ret = qemu_fflush(f); int ret2 = qio_channel_close(f->ioc, NULL); if (ret >= 0) { ret = ret2; } + QTAILQ_FOREACH_SAFE(fde, &f->fds, entry, next) { + warn_report("qemu_fclose: received fd %d was never claimed", fde->fd); + close(fde->fd); + g_free(fde); + } g_clear_pointer(&f->ioc, object_unref); error_free(f->last_error_obj); g_free(f); diff --git a/migration/qemu-file.h b/migration/qemu-file.h index 11c2120..3e47a20 100644 --- a/migration/qemu-file.h +++ b/migration/qemu-file.h @@ -79,5 +79,7 @@ size_t qemu_get_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen, off_t pos); QIOChannel *qemu_file_get_ioc(QEMUFile *file); +int qemu_file_put_fd(QEMUFile *f, int fd); +int qemu_file_get_fd(QEMUFile *f); #endif diff --git a/migration/trace-events b/migration/trace-events index 173f2c0..064b22d 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -88,6 +88,8 @@ put_qlist_end(const char *field_name, const char *vmsd_name) "%s(%s)" # qemu-file.c qemu_file_fclose(void) "" +qemu_file_put_fd(const char *name, int fd, int ret) "ioc %s, fd %d -> status %d" +qemu_file_get_fd(const char *name, int fd) "ioc %s -> fd %d" # ram.c get_queued_page(const char *block_name, uint64_t tmp_offset, unsigned long page_abs) "%s/0x%" PRIx64 " page_abs=0x%lx" From patchwork Sun Jun 30 19:44:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sistare X-Patchwork-Id: 13717321 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5A22AC30659 for ; Sun, 30 Jun 2024 19:44:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sO0TE-0007Vc-VY; Sun, 30 Jun 2024 15:44:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T9-0007Tp-H8 for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:15 -0400 Received: from mx0b-00069f02.pphosted.com ([205.220.177.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T6-0006P0-FF for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:14 -0400 Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45UGEQx3019999; Sun, 30 Jun 2024 19:44:11 GMT 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-2023-11-20; bh=ebp9rJDFJtzKf5X44bz9xoGS+p+nfvIXI79Rl9Jsp8w=; b= oiHYpFkWmYegd45QCoZQm3J2uApk0gAOeZ6caCRbt12aHoi48iV86LmqJ15NgNYR FIiAXnFHYVN+PPOdoqXnPqA+tQ4R7k3VtXC/7HRct9DjdlveH9jKR9cTxAKGB/8c d9erlFHSwvVliiLXLGDsLRKJeKF1AU/3QTw9XBT9Q530g+42y8PGoKuw+7a72s/Q GJP+g82TPwC/6WCERWx3GZEgJs28o4/dJ/tRqrYfjkldEzW/IXRk1TGpfTf10/Wx kutQBqA1SIYozBfEC2+sKpgSSugT9diULNG4E7MCcpwmmaLaguk8CnU8SxL3ygZ+ yRz3bn6DXPTCHBK83hC02A== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 402922sg33-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:11 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 45UGm6ie022878; Sun, 30 Jun 2024 19:44:10 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4028q5gg4r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:10 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJg4f4039161; Sun, 30 Jun 2024 19:44:09 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4028q5gg4e-3; Sun, 30 Jun 2024 19:44:09 +0000 From: Steve Sistare To: qemu-devel@nongnu.org Cc: Peter Xu , Fabiano Rosas , Markus Armbruster , Steve Sistare Subject: [RFC V1 2/6] migration: VMSTATE_FD Date: Sun, 30 Jun 2024 12:44:04 -0700 Message-Id: <1719776648-435073-3-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> References: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2406180000 definitions=main-2406300157 X-Proofpoint-GUID: p7XxOdfryqpXh-q-cZf0MG9uKGAqukEw X-Proofpoint-ORIG-GUID: p7XxOdfryqpXh-q-cZf0MG9uKGAqukEw 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_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Define VMSTATE_FD for declaring a file descriptor field in a VMStateDescription. Signed-off-by: Steve Sistare --- include/migration/vmstate.h | 9 +++++++++ migration/vmstate-types.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index f313f2f..a1dfab4 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -230,6 +230,7 @@ extern const VMStateInfo vmstate_info_uint8; extern const VMStateInfo vmstate_info_uint16; extern const VMStateInfo vmstate_info_uint32; extern const VMStateInfo vmstate_info_uint64; +extern const VMStateInfo vmstate_info_fd; /** Put this in the stream when migrating a null pointer.*/ #define VMS_NULLPTR_MARKER (0x30U) /* '0' */ @@ -902,6 +903,9 @@ extern const VMStateInfo vmstate_info_qlist; #define VMSTATE_UINT64_V(_f, _s, _v) \ VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t) +#define VMSTATE_FD_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, vmstate_info_fd, int32_t) + #ifdef CONFIG_LINUX #define VMSTATE_U8_V(_f, _s, _v) \ @@ -936,6 +940,9 @@ extern const VMStateInfo vmstate_info_qlist; #define VMSTATE_UINT64(_f, _s) \ VMSTATE_UINT64_V(_f, _s, 0) +#define VMSTATE_FD(_f, _s) \ + VMSTATE_FD_V(_f, _s, 0) + #ifdef CONFIG_LINUX #define VMSTATE_U8(_f, _s) \ @@ -1009,6 +1016,8 @@ extern const VMStateInfo vmstate_info_qlist; #define VMSTATE_UINT64_TEST(_f, _s, _t) \ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint64, uint64_t) +#define VMSTATE_FD_TEST(_f, _s, _t) \ + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_fd, int32_t) #define VMSTATE_TIMER_PTR_TEST(_f, _s, _test) \ VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *) diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c index e83bfcc..6e45a4a 100644 --- a/migration/vmstate-types.c +++ b/migration/vmstate-types.c @@ -314,6 +314,38 @@ const VMStateInfo vmstate_info_uint64 = { .put = put_uint64, }; +/* File descriptor communicated via SCM_RIGHTS */ + +static int get_fd(QEMUFile *f, void *pv, size_t size, + const VMStateField *field) +{ + int32_t *v = pv; + qemu_get_sbe32s(f, v); + if (*v < 0) { + return 0; + } + *v = qemu_file_get_fd(f); + return 0; +} + +static int put_fd(QEMUFile *f, void *pv, size_t size, + const VMStateField *field, JSONWriter *vmdesc) +{ + int32_t *v = pv; + + qemu_put_sbe32s(f, v); + if (*v < 0) { + return 0; + } + return qemu_file_put_fd(f, *v); +} + +const VMStateInfo vmstate_info_fd = { + .name = "fd", + .get = get_fd, + .put = put_fd, +}; + static int get_nullptr(QEMUFile *f, void *pv, size_t size, const VMStateField *field) From patchwork Sun Jun 30 19:44:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sistare X-Patchwork-Id: 13717325 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0AE4CC27C4F for ; Sun, 30 Jun 2024 19:45:17 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sO0TH-0007WZ-GG; Sun, 30 Jun 2024 15:44:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0TF-0007Vh-4j for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:22 -0400 Received: from mx0a-00069f02.pphosted.com ([205.220.165.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T6-0006P2-O5 for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:17 -0400 Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45UJdPwK028776; Sun, 30 Jun 2024 19:44:11 GMT 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-2023-11-20; bh=n82o1TU97EyS5y3b5BxzvwF+Cm4itWy9ULFCdnBgjAg=; b= Fk89f9ZAGHOQWZFiaGSVJtmMzkVmubV77ZLgUCSBJ1yHQbKqnRZ71UonPvAOeeF3 bf5O7p4I6b5pLULvuqQvd2XGWsKCtz9xKYn9bAGI5VDNh9hYwqYI2zGtyBLL5VXy 4WbfoQ8gmWDLvdywne5s/4ktTWvE4P54eKVv2C1bPpWw1deHyZRLaxJz5uclmVIa bTuE2XnG/7Ea+Jk+rB665FZLtycic0Foj/Q+owOv1COunG4QN1oa7y/y4t/YMXet 3n1gNX8h0p2iz5alUf4ElqqjcdX71kJlHFDn2KUoT7vW9rDS+4Kc8+rSC0jJAQK7 txUFv+zisXYCGFNnqQsngQ== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 402a591esm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:11 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 45UIQkq7022828; Sun, 30 Jun 2024 19:44:10 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4028q5gg4t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:10 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJg4f6039161; Sun, 30 Jun 2024 19:44:10 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4028q5gg4e-4; Sun, 30 Jun 2024 19:44:10 +0000 From: Steve Sistare To: qemu-devel@nongnu.org Cc: Peter Xu , Fabiano Rosas , Markus Armbruster , Steve Sistare Subject: [RFC V1 3/6] migration: cpr-transfer save and load Date: Sun, 30 Jun 2024 12:44:05 -0700 Message-Id: <1719776648-435073-4-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> References: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2406180000 definitions=main-2406300157 X-Proofpoint-GUID: PYcfq5jlILKbDAdOwoZ_6tB574kteNxp X-Proofpoint-ORIG-GUID: PYcfq5jlILKbDAdOwoZ_6tB574kteNxp Received-SPF: pass client-ip=205.220.165.32; envelope-from=steven.sistare@oracle.com; helo=mx0a-00069f02.pphosted.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add functions to create a QEMUFile based on a unix URI, for saving or loading, for use by cpr-transfer mode to preserve CPR state. Signed-off-by: Steve Sistare --- include/migration/cpr.h | 3 ++ migration/cpr-transfer.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ migration/meson.build | 1 + 3 files changed, 85 insertions(+) create mode 100644 migration/cpr-transfer.c diff --git a/include/migration/cpr.h b/include/migration/cpr.h index c6c60f8..9aae94c 100644 --- a/include/migration/cpr.h +++ b/include/migration/cpr.h @@ -32,4 +32,7 @@ bool cpr_exec_has_state(void); void cpr_exec_unpersist_state(void); void cpr_mig_init(void); void cpr_unpreserve_fds(void); + +QEMUFile *cpr_transfer_output(const char *uri, Error **errp); +QEMUFile *cpr_transfer_input(const char *uri, Error **errp); #endif diff --git a/migration/cpr-transfer.c b/migration/cpr-transfer.c new file mode 100644 index 0000000..fb9ecd8 --- /dev/null +++ b/migration/cpr-transfer.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022, 2024 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "io/channel-file.h" +#include "io/channel-socket.h" +#include "io/net-listener.h" +#include "migration/cpr.h" +#include "migration/migration.h" +#include "migration/savevm.h" +#include "migration/qemu-file.h" +#include "migration/vmstate.h" + +QEMUFile *cpr_transfer_output(const char *uri, Error **errp) +{ + g_autoptr(MigrationChannel) channel = NULL; + QIOChannel *ioc; + + if (!migrate_uri_parse(uri, &channel, errp)) { + return NULL; + } + + if (channel->addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET && + channel->addr->u.socket.type == SOCKET_ADDRESS_TYPE_UNIX) { + + QIOChannelSocket *sioc = qio_channel_socket_new(); + SocketAddress *saddr = &channel->addr->u.socket; + + if (qio_channel_socket_connect_sync(sioc, saddr, errp)) { + object_unref(OBJECT(sioc)); + return NULL; + } + ioc = QIO_CHANNEL(sioc); + + } else { + error_setg(errp, "bad cpr-uri %s; must be unix:", uri); + return NULL; + } + + qio_channel_set_name(ioc, "cpr-out"); + return qemu_file_new_output(ioc); +} + +QEMUFile *cpr_transfer_input(const char *uri, Error **errp) +{ + g_autoptr(MigrationChannel) channel = NULL; + QIOChannel *ioc; + + if (!migrate_uri_parse(uri, &channel, errp)) { + return NULL; + } + + if (channel->addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET && + channel->addr->u.socket.type == SOCKET_ADDRESS_TYPE_UNIX) { + + QIOChannelSocket *sioc; + SocketAddress *saddr = &channel->addr->u.socket; + QIONetListener *listener = qio_net_listener_new(); + + qio_net_listener_set_name(listener, "cpr-socket-listener"); + if (qio_net_listener_open_sync(listener, saddr, 1, errp) < 0) { + object_unref(OBJECT(listener)); + return NULL; + } + + sioc = qio_net_listener_wait_client(listener); + ioc = QIO_CHANNEL(sioc); + + } else { + error_setg(errp, "bad cpr-uri %s; must be unix:", uri); + return NULL; + } + + qio_channel_set_name(ioc, "cpr-in"); + return qemu_file_new_input(ioc); +} diff --git a/migration/meson.build b/migration/meson.build index dd1d315..f722980 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -15,6 +15,7 @@ system_ss.add(files( 'channel-block.c', 'cpr.c', 'cpr-exec.c', + 'cpr-transfer.c', 'dirtyrate.c', 'exec.c', 'fd.c', From patchwork Sun Jun 30 19:44:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sistare X-Patchwork-Id: 13717322 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9E09EC3065B for ; Sun, 30 Jun 2024 19:44:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sO0TE-0007Vb-2Y; Sun, 30 Jun 2024 15:44:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T9-0007Tr-Hg for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:15 -0400 Received: from mx0a-00069f02.pphosted.com ([205.220.165.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T7-0006P8-7f for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:15 -0400 Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45UJeY26019514; Sun, 30 Jun 2024 19:44:12 GMT 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-2023-11-20; bh=ML9qM6rxVCGfCedMBnF3XKpZc6Rsg+VBcxi7zNFyK94=; b= eBSoLi5+26Z4rhWPsUP1ZpDAPLz0+PkzVmZDp8Tft2wbRJ47C7FLCeTSqcPLjaOS uHEBTIlZ2RolRHj7mueRanvQEZ6Zo4mUJL514JZNpzqRw8piAwBE/FZGdB7QMWB6 eD3SAoaB44iKtfHenLlxfkF9Q+RAQXHbyLm/gi5rg1I2J/kRCQzyKcV66YFoYk2P H3fR+gDIr4MwI/iEPuNnZ6U6bkGgofdIWn93r58y5CV7iOGXc4ZKIDHrqRfpw1FP R3jBxAtSuOuKQ19wXjq11YA1UXZNqVEKCcMMd6Oy0f/JwaOWwuR8bOmD9NYjHA1F 9FItNoswRM8ljDi8/O59ug== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 40296asgax-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:11 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 45UGXkta022842; Sun, 30 Jun 2024 19:44:11 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4028q5gg4x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:11 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJg4f8039161; Sun, 30 Jun 2024 19:44:10 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4028q5gg4e-5; Sun, 30 Jun 2024 19:44:10 +0000 From: Steve Sistare To: qemu-devel@nongnu.org Cc: Peter Xu , Fabiano Rosas , Markus Armbruster , Steve Sistare Subject: [RFC V1 4/6] migration: cpr-uri parameter Date: Sun, 30 Jun 2024 12:44:06 -0700 Message-Id: <1719776648-435073-5-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> References: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2406180000 definitions=main-2406300157 X-Proofpoint-GUID: 98izb5R0Xgqy5teZWjqMxzEPkSpk1W-X X-Proofpoint-ORIG-GUID: 98izb5R0Xgqy5teZWjqMxzEPkSpk1W-X Received-SPF: pass client-ip=205.220.165.32; envelope-from=steven.sistare@oracle.com; helo=mx0a-00069f02.pphosted.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Define the cpr-uri migration parameter to specify the URI to which CPR vmstate is saved for cpr-transfer mode. Signed-off-by: Steve Sistare --- migration/migration-hmp-cmds.c | 10 ++++++++++ migration/options.c | 29 +++++++++++++++++++++++++++++ migration/options.h | 1 + qapi/migration.json | 12 ++++++++++++ 4 files changed, 52 insertions(+) diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c index 16a4b00..4ede831 100644 --- a/migration/migration-hmp-cmds.c +++ b/migration/migration-hmp-cmds.c @@ -371,6 +371,11 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) params->direct_io ? "on" : "off"); } + assert(params->cpr_uri); + monitor_printf(mon, "%s: '%s'\n", + MigrationParameter_str(MIGRATION_PARAMETER_CPR_URI), + params->cpr_uri); + assert(params->has_cpr_exec_command); monitor_print_cpr_exec_command(mon, params->cpr_exec_command); } @@ -650,6 +655,11 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) p->has_direct_io = true; visit_type_bool(v, param, &p->direct_io, &err); break; + case MIGRATION_PARAMETER_CPR_URI: + p->cpr_uri = g_new0(StrOrNull, 1); + p->cpr_uri->type = QTYPE_QSTRING; + visit_type_str(v, param, &p->cpr_uri->u.s, &err); + break; case MIGRATION_PARAMETER_CPR_EXEC_COMMAND: { g_autofree char **strv = g_strsplit(valuestr ?: "", " ", -1); strList **tail = &p->cpr_exec_command; diff --git a/migration/options.c b/migration/options.c index b8d5f72..7526f9f 100644 --- a/migration/options.c +++ b/migration/options.c @@ -163,6 +163,8 @@ Property migration_properties[] = { DEFINE_PROP_ZERO_PAGE_DETECTION("zero-page-detection", MigrationState, parameters.zero_page_detection, ZERO_PAGE_DETECTION_MULTIFD), + DEFINE_PROP_STRING("cpr-uri", MigrationState, + parameters.cpr_uri), /* Migration capabilities */ DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE), @@ -848,6 +850,13 @@ ZeroPageDetection migrate_zero_page_detection(void) return s->parameters.zero_page_detection; } +const char *migrate_cpr_uri(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.cpr_uri; +} + /* parameters helpers */ AnnounceParameters *migrate_announce_params(void) @@ -931,6 +940,7 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) params->zero_page_detection = s->parameters.zero_page_detection; params->has_direct_io = true; params->direct_io = s->parameters.direct_io; + params->cpr_uri = g_strdup(s->parameters.cpr_uri); params->has_cpr_exec_command = true; params->cpr_exec_command = QAPI_CLONE(strList, s->parameters.cpr_exec_command); @@ -967,6 +977,7 @@ void migrate_params_init(MigrationParameters *params) params->has_mode = true; params->has_zero_page_detection = true; params->has_direct_io = true; + params->cpr_uri = g_strdup(""); params->has_cpr_exec_command = true; } @@ -1257,9 +1268,15 @@ static void migrate_params_test_apply(MigrateSetParameters *params, dest->direct_io = params->direct_io; } + if (params->cpr_uri) { + assert(params->cpr_uri->type == QTYPE_QSTRING); + dest->cpr_uri = params->cpr_uri->u.s; + } + if (params->has_cpr_exec_command) { dest->cpr_exec_command = params->cpr_exec_command; } + } static void migrate_params_apply(MigrateSetParameters *params, Error **errp) @@ -1390,6 +1407,12 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) s->parameters.direct_io = params->direct_io; } + if (params->cpr_uri) { + g_free(s->parameters.cpr_uri); + assert(params->cpr_uri->type == QTYPE_QSTRING); + s->parameters.cpr_uri = g_strdup(params->cpr_uri->u.s); + } + if (params->has_cpr_exec_command) { qapi_free_strList(s->parameters.cpr_exec_command); s->parameters.cpr_exec_command = @@ -1421,6 +1444,12 @@ void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) params->tls_authz->u.s = strdup(""); } + if (params->cpr_uri && params->cpr_uri->type == QTYPE_QNULL) { + qobject_unref(params->cpr_uri->u.n); + params->cpr_uri->type = QTYPE_QSTRING; + params->cpr_uri->u.s = strdup(""); + } + migrate_params_test_apply(params, &tmp); if (!migrate_params_check(&tmp, errp)) { diff --git a/migration/options.h b/migration/options.h index a239702..7492fcf 100644 --- a/migration/options.h +++ b/migration/options.h @@ -85,6 +85,7 @@ const char *migrate_tls_creds(void); const char *migrate_tls_hostname(void); uint64_t migrate_xbzrle_cache_size(void); ZeroPageDetection migrate_zero_page_detection(void); +const char *migrate_cpr_uri(void); /* parameters helpers */ diff --git a/qapi/migration.json b/qapi/migration.json index 4e626df..df62456 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -851,6 +851,9 @@ # only has effect if the @mapped-ram capability is enabled. # (Since 9.1) # +# @cpr-uri: URI for an additional migration channel needed by +# @cpr-transfer mode. (Since 9.1) +# # @cpr-exec-command: Command to start the new QEMU process when @mode # is @cpr-exec. The first list element is the program's filename, # the remainder its arguments. (Since 9.1) @@ -881,6 +884,7 @@ 'mode', 'zero-page-detection', 'direct-io', + 'cpr-uri', 'cpr-exec-command'] } ## @@ -1031,6 +1035,9 @@ # only has effect if the @mapped-ram capability is enabled. # (Since 9.1) # +# @cpr-uri: URI for an additional migration channel needed by +# @cpr-transfer mode. (Since 9.1) +# # @cpr-exec-command: Command to start the new QEMU process when @mode # is @cpr-exec. The first list element is the program's filename, # the remainder its arguments. (Since 9.1) @@ -1076,6 +1083,7 @@ '*mode': 'MigMode', '*zero-page-detection': 'ZeroPageDetection', '*direct-io': 'bool', + '*cpr-uri': 'StrOrNull', '*cpr-exec-command': [ 'str' ]} } ## @@ -1240,6 +1248,9 @@ # only has effect if the @mapped-ram capability is enabled. # (Since 9.1) # +# @cpr-uri: URI for an additional migration channel needed by +# @cpr-transfer mode. (Since 9.1) +# # @cpr-exec-command: Command to start the new QEMU process when @mode # is @cpr-exec. The first list element is the program's filename, # the remainder its arguments. (Since 9.1) @@ -1282,6 +1293,7 @@ '*mode': 'MigMode', '*zero-page-detection': 'ZeroPageDetection', '*direct-io': 'bool', + '*cpr-uri': 'str', '*cpr-exec-command': [ 'str' ]} } ## From patchwork Sun Jun 30 19:44:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sistare X-Patchwork-Id: 13717324 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D1F3FC27C4F for ; Sun, 30 Jun 2024 19:45:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sO0TH-0007WX-8N; Sun, 30 Jun 2024 15:44:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0TB-0007Uz-CS for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:18 -0400 Received: from mx0b-00069f02.pphosted.com ([205.220.177.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T9-0006PH-6J for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:16 -0400 Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45UJQ35x023391; Sun, 30 Jun 2024 19:44:12 GMT 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-2023-11-20; bh=9Y7ApIw+kdZCxeBA8qrFl0dOmwypQLJ9kWdBmcX/gU4=; b= Mlf5lsu8sWM0161zNqzzVL6DoxjjFwmhcY4Dppnov79QUJytoCUsAnPEDpaJjiAs I/MQH4hfNC4S38V6T1v9pRHjCRKHYtYa2QiQvcrB7RVyfsVDvcSIEwZec7J2LpFP 4JWPcZ2OUfRMfzaU2MAEnohP/+pIz/jMTn7qphQ9kRc3VbgrIpWQTVO0rRSIShOz tR0kySS+ADkfDsVcxSYPGkKX67eqUlKxluBhyFUJDkobzIyiqyYPl0bgKAh1+5zu Lzycqd3+tHbyOX5MCS7qAuJhKk5CFxT9MdZgS0IhJGnTh6E0rxMZH6pu2rE3r3Kl YT2NZEdhsBIJiK7fPKhEWQ== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4028pchg4h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:12 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 45UGm6if022878; Sun, 30 Jun 2024 19:44:11 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4028q5gg51-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:11 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJg4fA039161; Sun, 30 Jun 2024 19:44:11 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4028q5gg4e-6; Sun, 30 Jun 2024 19:44:11 +0000 From: Steve Sistare To: qemu-devel@nongnu.org Cc: Peter Xu , Fabiano Rosas , Markus Armbruster , Steve Sistare Subject: [RFC V1 5/6] migration: cpr-uri option Date: Sun, 30 Jun 2024 12:44:07 -0700 Message-Id: <1719776648-435073-6-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> References: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2406180000 definitions=main-2406300157 X-Proofpoint-GUID: JKJu6hpwTwyMDLs0z6qGVqga0ibtNx_7 X-Proofpoint-ORIG-GUID: JKJu6hpwTwyMDLs0z6qGVqga0ibtNx_7 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_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Define the cpr-uri QEMU command-line option to specify the URI from which CPR vmstate is loaded for cpr-transfer mode. Signed-off-by: Steve Sistare --- include/migration/cpr.h | 1 + migration/cpr.c | 7 +++++++ qemu-options.hx | 8 ++++++++ system/vl.c | 3 +++ 4 files changed, 19 insertions(+) diff --git a/include/migration/cpr.h b/include/migration/cpr.h index 9aae94c..bc62493 100644 --- a/include/migration/cpr.h +++ b/include/migration/cpr.h @@ -22,6 +22,7 @@ int cpr_find_fd(const char *name, int id); int cpr_walk_fd(cpr_walk_fd_cb cb); void cpr_resave_fd(const char *name, int id, int fd); +void cpr_set_cpr_uri(const char *uri); int cpr_state_save(Error **errp); int cpr_state_load(Error **errp); diff --git a/migration/cpr.c b/migration/cpr.c index f756c15..50c130c 100644 --- a/migration/cpr.c +++ b/migration/cpr.c @@ -157,6 +157,13 @@ static const VMStateDescription vmstate_cpr_state = { }; /*************************************************************************/ +static char *cpr_uri; + +void cpr_set_cpr_uri(const char *uri) +{ + cpr_uri = g_strdup(uri); +} + int cpr_state_save(Error **errp) { int ret; diff --git a/qemu-options.hx b/qemu-options.hx index 595b693..a6b5253 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4776,6 +4776,14 @@ SRST ERST +DEF("cpr-uri", HAS_ARG, QEMU_OPTION_cpr_uri, \ + "-cpr-uri unix:socketpath\n", + QEMU_ARCH_ALL) +SRST +``-cpr-uri unix:socketpath`` + URI for incoming CPR state, for the cpr-transfer migration mode. +ERST + DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \ "-incoming tcp:[host]:port[,to=maxport][,ipv4=on|off][,ipv6=on|off]\n" \ "-incoming rdma:host:port[,ipv4=on|off][,ipv6=on|off]\n" \ diff --git a/system/vl.c b/system/vl.c index 6521ee3..32015ac 100644 --- a/system/vl.c +++ b/system/vl.c @@ -3483,6 +3483,9 @@ void qemu_init(int argc, char **argv) exit(1); } break; + case QEMU_OPTION_cpr_uri: + cpr_set_cpr_uri(optarg); + break; case QEMU_OPTION_incoming: if (!incoming) { runstate_set(RUN_STATE_INMIGRATE); From patchwork Sun Jun 30 19:44:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sistare X-Patchwork-Id: 13717323 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5CD65C41513 for ; Sun, 30 Jun 2024 19:44:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sO0TG-0007Vf-BV; Sun, 30 Jun 2024 15:44:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0TD-0007VS-7o for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:19 -0400 Received: from mx0a-00069f02.pphosted.com ([205.220.165.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sO0T9-0006PM-8u for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:44:17 -0400 Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45UIt2tQ001382; Sun, 30 Jun 2024 19:44:12 GMT 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-2023-11-20; bh=x1dv9hWX4cv1NLONXGlwM/BmSZbx5fqeVP4rekggHKw=; b= HdFk8IVCTdPmXQ8eNBNWYq+a/fM3/nbnDUjx8bbrzIJ/BwqnGe2TX0b6UmRCziJP 1LHmNZv9tgvAMnicRrBHbHJkTyihsf8jwbtRNXWsTm5Z+FjWe4mmKuhNA9hcSPiR LrIYegWsEqPBJFmZmXaJRJOIo1Cu7FNe01SwURu3YP6PVZg9/c9ldPERXRi/qJy9 GDL2Eb29Sw5OWpJqGbuKo4mBr0TF3GswfWZY+FTpoeN10NqZ0kWFKXxypnyuS0UG KiW36KAh7/2iq9BmCfso4u/8sb5suRw2Q8KaPYrC/WjmM1ytUUzBlZUMEp31we3c 7qh5LobJLtsJnb5n/Z6jZw== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 402att9e35-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:12 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 45UIQkq8022828; Sun, 30 Jun 2024 19:44:12 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4028q5gg56-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 30 Jun 2024 19:44:11 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJg4fC039161; Sun, 30 Jun 2024 19:44:11 GMT Received: from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4028q5gg4e-7; Sun, 30 Jun 2024 19:44:11 +0000 From: Steve Sistare To: qemu-devel@nongnu.org Cc: Peter Xu , Fabiano Rosas , Markus Armbruster , Steve Sistare Subject: [RFC V1 6/6] migration: cpr-transfer mode Date: Sun, 30 Jun 2024 12:44:08 -0700 Message-Id: <1719776648-435073-7-git-send-email-steven.sistare@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> References: <1719776648-435073-1-git-send-email-steven.sistare@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2406180000 definitions=main-2406300157 X-Proofpoint-GUID: L_XSFKqj8i95tp29-x2LZ87MWGjNHHdl X-Proofpoint-ORIG-GUID: L_XSFKqj8i95tp29-x2LZ87MWGjNHHdl Received-SPF: pass client-ip=205.220.165.32; envelope-from=steven.sistare@oracle.com; helo=mx0a-00069f02.pphosted.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add the cpr-transfer migration mode. Usage: qemu-system-$arch -machine anon-alloc=memfd ... start new QEMU with "-incoming -cpr-uri " Issue commands to old QEMU: migrate_set_parameter mode cpr-transfer migrate_set_parameter cpr-uri migrate -d The migrate command stops the VM, saves CPR state to uri-2, saves normal migration state to uri-1, and old QEMU enters the postmigrate state. The user starts new QEMU on the same host as old QEMU, with the same arguments as old QEMU, plus the -incoming option. Guest RAM is preserved in place, albeit with new virtual addresses in new QEMU. This mode requires a second migration channel, specified by the cpr-uri migration property on the outgoing side, and by the cpr-uri QEMU command-line option on the incoming side. The channel must be a type, such as unix socket, that supports SCM_RIGHTS. Memory-backend objects must have the share=on attribute, but memory-backend-epc is not supported. The VM must be started with the '-machine anon-alloc=memfd' option, which allows anonymous memory to be transferred in place to the new process. The memfds are kept open by sending the descriptors to new QEMU via the cpr-uri, which must support SCM_RIGHTS, and they are mmap'd in new QEMU. Signed-off-by: Steve Sistare --- migration/cpr.c | 9 ++++++++- migration/migration.c | 37 +++++++++++++++++++++++++++++++++++++ migration/ram.c | 1 + migration/vmstate-types.c | 5 +++-- qapi/migration.json | 26 +++++++++++++++++++++++++- stubs/vmstate.c | 7 +++++++ 6 files changed, 81 insertions(+), 4 deletions(-) diff --git a/migration/cpr.c b/migration/cpr.c index 50c130c..7ac01a9 100644 --- a/migration/cpr.c +++ b/migration/cpr.c @@ -58,7 +58,7 @@ static const VMStateDescription vmstate_cpr_fd = { VMSTATE_UINT32(namelen, CprFd), VMSTATE_VBUFFER_ALLOC_UINT32(name, CprFd, 0, NULL, namelen), VMSTATE_INT32(id, CprFd), - VMSTATE_INT32(fd, CprFd), + VMSTATE_FD(fd, CprFd), VMSTATE_END_OF_LIST() } }; @@ -172,6 +172,8 @@ int cpr_state_save(Error **errp) if (mode == MIG_MODE_CPR_EXEC) { f = cpr_exec_output(errp); + } else if (mode == MIG_MODE_CPR_TRANSFER) { + f = cpr_transfer_output(migrate_cpr_uri(), errp); } else { return 0; } @@ -209,6 +211,11 @@ int cpr_state_load(Error **errp) */ if (cpr_exec_has_state()) { f = cpr_exec_input(errp); + if (cpr_uri) { + warn_report("ignoring cpr-uri option for migration mode cpr-exec"); + } + } else if (cpr_uri) { + f = cpr_transfer_input(cpr_uri, errp); } else { return 0; } diff --git a/migration/migration.c b/migration/migration.c index a4a020e..65a36a6 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -77,6 +77,7 @@ static NotifierWithReturnList migration_state_notifiers[MIG_MODE__MAX] = { NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_NORMAL), NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_REBOOT), NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_EXEC), + NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_TRANSFER), }; /* Messages sent on the return path from destination to source */ @@ -205,6 +206,12 @@ migration_channels_and_transport_compatible(MigrationAddress *addr, return false; } + if (migrate_mode() == MIG_MODE_CPR_TRANSFER && + addr->transport == MIGRATION_ADDRESS_TYPE_FILE) { + error_setg(errp, "Migration requires streamable transport (eg unix)"); + return false; + } + return true; } @@ -1697,6 +1704,7 @@ bool migrate_mode_is_cpr(MigrationState *s) { MigMode mode = s->parameters.mode; return mode == MIG_MODE_CPR_REBOOT || + mode == MIG_MODE_CPR_TRANSFER || mode == MIG_MODE_CPR_EXEC; } @@ -2038,6 +2046,12 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp) return false; } + if (migrate_mode() == MIG_MODE_CPR_TRANSFER && + !s->parameters.cpr_uri) { + error_setg(errp, "cpr-transfer mode requires setting cpr-uri"); + return false; + } + if (migration_is_blocked(errp)) { return false; } @@ -2144,6 +2158,29 @@ void qmp_migrate(const char *uri, bool has_channels, goto out; } + /* + * For cpr-transfer mode, the target first reads CPR state, which cannot + * complete until cpr_state_save above finishes, then the target creates + * the migration channel and listens. We must wait for the channel to + * be created before connecting to it. + * + * This implementation of waiting is a hack. It restricts the channel + * type, and will loop forever if the target dies. It should be defined + * as a main-loop event that calls connect on the back end. + */ + if (s->parameters.mode == MIG_MODE_CPR_TRANSFER) { + SocketAddress *saddr = &addr->u.socket; + if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET && + saddr->type == SOCKET_ADDRESS_TYPE_UNIX) { + while (access(saddr->u.fd.str, F_OK)) { + usleep(1000000); + } + } else { + error_setg(&local_err, "cpr-transfer requires a unix channel"); + goto out; + } + } + if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { SocketAddress *saddr = &addr->u.socket; if (saddr->type == SOCKET_ADDRESS_TYPE_INET || diff --git a/migration/ram.c b/migration/ram.c index 45b8f00..1e1e05e 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -219,6 +219,7 @@ bool migrate_ram_is_ignored(RAMBlock *block) MigMode mode = migrate_mode(); return !qemu_ram_is_migratable(block) || mode == MIG_MODE_CPR_EXEC || + mode == MIG_MODE_CPR_TRANSFER || (migrate_ignore_shared() && qemu_ram_is_shared(block) && qemu_ram_is_named_file(block)); } diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c index 6e45a4a..618b7fb 100644 --- a/migration/vmstate-types.c +++ b/migration/vmstate-types.c @@ -15,6 +15,7 @@ #include "qemu-file.h" #include "migration.h" #include "migration/vmstate.h" +#include "migration/client-options.h" #include "qemu/error-report.h" #include "qemu/queue.h" #include "trace.h" @@ -321,7 +322,7 @@ static int get_fd(QEMUFile *f, void *pv, size_t size, { int32_t *v = pv; qemu_get_sbe32s(f, v); - if (*v < 0) { + if (*v < 0 || migrate_mode() == MIG_MODE_CPR_EXEC) { return 0; } *v = qemu_file_get_fd(f); @@ -334,7 +335,7 @@ static int put_fd(QEMUFile *f, void *pv, size_t size, int32_t *v = pv; qemu_put_sbe32s(f, v); - if (*v < 0) { + if (*v < 0 || migrate_mode() == MIG_MODE_CPR_EXEC) { return 0; } return qemu_file_put_fd(f, *v); diff --git a/qapi/migration.json b/qapi/migration.json index df62456..cd2d949 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -626,9 +626,33 @@ # with the '-machine anon-alloc=memfd' option. # # (since 9.1) +# +# @cpr-transfer: This mode allows the user to transfer a guest to a +# new QEMU instance on the same host with minimal guest pause +# time, by preserving guest RAM in place, albeit with new virtual +# addresses in new QEMU. +# +# The user starts new QEMU on the same host as old QEMU, with the +# the same arguments as old QEMU, plus the -incoming option. The +# user issues the migrate command to old QEMU, which stops the VM, +# saves state to the migration channels, and enters the postmigrate +# state. Execution resumes in new QEMU. Guest RAM is preserved in +# place, albeit with new virtual addresses in new QEMU. +# +# This mode requires a second migration channel, specified by the +# cpr-uri migration property on the outgoing side, and by +# the cpr-uri QEMU command-line option on the incoming +# side. The channel must be a type, such as unix socket, that +# supports SCM_RIGHTS. +# +# Memory-backend objects must have the share=on attribute, but +# memory-backend-epc is not supported. The VM must be started +# with the '-machine anon-alloc=memfd' option. +# +# (since 9.1) ## { 'enum': 'MigMode', - 'data': [ 'normal', 'cpr-reboot', 'cpr-exec' ] } + 'data': [ 'normal', 'cpr-reboot', 'cpr-exec', 'cpr-transfer' ] } ## # @ZeroPageDetection: diff --git a/stubs/vmstate.c b/stubs/vmstate.c index 8513d92..c190762 100644 --- a/stubs/vmstate.c +++ b/stubs/vmstate.c @@ -1,5 +1,7 @@ #include "qemu/osdep.h" #include "migration/vmstate.h" +#include "qapi/qapi-types-migration.h" +#include "migration/client-options.h" int vmstate_register_with_alias_id(VMStateIf *obj, uint32_t instance_id, @@ -21,3 +23,8 @@ bool vmstate_check_only_migratable(const VMStateDescription *vmsd) { return true; } + +MigMode migrate_mode(void) +{ + return MIG_MODE_NORMAL; +}