get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/807504/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 807504,
    "url": "http://patchwork.ozlabs.org/api/patches/807504/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/1504081950-2528-6-git-send-email-peterx@redhat.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1504081950-2528-6-git-send-email-peterx@redhat.com>",
    "list_archive_url": null,
    "date": "2017-08-30T08:32:02",
    "name": "[RFC,v2,05/33] migration: better error handling with QEMUFile",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "7b283512646b41fe07e01115e555c6f993f743c8",
    "submitter": {
        "id": 67717,
        "url": "http://patchwork.ozlabs.org/api/people/67717/?format=api",
        "name": "Peter Xu",
        "email": "peterx@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/1504081950-2528-6-git-send-email-peterx@redhat.com/mbox/",
    "series": [
        {
            "id": 552,
            "url": "http://patchwork.ozlabs.org/api/series/552/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=552",
            "date": "2017-08-30T08:31:59",
            "name": "Migration: postcopy failure recovery",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/552/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/807504/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/807504/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)",
            "ext-mx04.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com",
            "ext-mx04.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=peterx@redhat.com"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xhzd66xHrz9t2Q\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed, 30 Aug 2017 18:46:34 +1000 (AEST)",
            "from localhost ([::1]:49075 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dmydr-0001Rx-QL\n\tfor incoming@patchwork.ozlabs.org; Wed, 30 Aug 2017 04:46:31 -0400",
            "from eggs.gnu.org ([2001:4830:134:3::10]:33971)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <peterx@redhat.com>) id 1dmyQp-0006xf-Ro\n\tfor qemu-devel@nongnu.org; Wed, 30 Aug 2017 04:33:08 -0400",
            "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <peterx@redhat.com>) id 1dmyQo-0003D2-IM\n\tfor qemu-devel@nongnu.org; Wed, 30 Aug 2017 04:33:03 -0400",
            "from mx1.redhat.com ([209.132.183.28]:37404)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <peterx@redhat.com>) id 1dmyQo-0003CU-9R\n\tfor qemu-devel@nongnu.org; Wed, 30 Aug 2017 04:33:02 -0400",
            "from smtp.corp.redhat.com\n\t(int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 4BAF18047F;\n\tWed, 30 Aug 2017 08:33:01 +0000 (UTC)",
            "from pxdev.xzpeter.org.com (dhcp-14-103.nay.redhat.com\n\t[10.66.14.103])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 8F35B84792;\n\tWed, 30 Aug 2017 08:32:55 +0000 (UTC)"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com 4BAF18047F",
        "From": "Peter Xu <peterx@redhat.com>",
        "To": "qemu-devel@nongnu.org",
        "Date": "Wed, 30 Aug 2017 16:32:02 +0800",
        "Message-Id": "<1504081950-2528-6-git-send-email-peterx@redhat.com>",
        "In-Reply-To": "<1504081950-2528-1-git-send-email-peterx@redhat.com>",
        "References": "<1504081950-2528-1-git-send-email-peterx@redhat.com>",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.15",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.28]);\n\tWed, 30 Aug 2017 08:33:01 +0000 (UTC)",
        "X-detected-operating-system": "by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]",
        "X-Received-From": "209.132.183.28",
        "Subject": "[Qemu-devel] [RFC v2 05/33] migration: better error handling with\n\tQEMUFile",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.21",
        "Precedence": "list",
        "List-Id": "<qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Cc": "Laurent Vivier <lvivier@redhat.com>,\n\tAndrea Arcangeli <aarcange@redhat.com>, \n\tJuan Quintela <quintela@redhat.com>,\n\tAlexey Perevalov <a.perevalov@samsung.com>, peterx@redhat.com,\n\t\"Dr . David Alan Gilbert\" <dgilbert@redhat.com>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"
    },
    "content": "If the postcopy down due to some reason, we can always see this on dst:\n\n  qemu-system-x86_64: RP: Received invalid message 0x0000 length 0x0000\n\nHowever in most cases that's not the real issue. The problem is that\nqemu_get_be16() has no way to show whether the returned data is valid or\nnot, and we are _always_ assuming it is valid. That's possibly not wise.\n\nThe best approach to solve this would be: refactoring QEMUFile interface\nto allow the APIs to return error if there is. However it needs quite a\nbit of work and testing. For now, let's explicitly check the validity\nfirst before using the data in all places for qemu_get_*().\n\nThis patch tries to fix most of the cases I can see. Only if we are with\nthis, can we make sure we are processing the valid data, and also can we\nmake sure we can capture the channel down events correctly.\n\nSigned-off-by: Peter Xu <peterx@redhat.com>\n---\n migration/migration.c |  5 +++++\n migration/ram.c       | 22 ++++++++++++++++++----\n migration/savevm.c    | 41 +++++++++++++++++++++++++++++++++++++++--\n 3 files changed, 62 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/migration/migration.c b/migration/migration.c\nindex c818412..92bf9b8 100644\n--- a/migration/migration.c\n+++ b/migration/migration.c\n@@ -1543,6 +1543,11 @@ static void *source_return_path_thread(void *opaque)\n         header_type = qemu_get_be16(rp);\n         header_len = qemu_get_be16(rp);\n \n+        if (qemu_file_get_error(rp)) {\n+            mark_source_rp_bad(ms);\n+            goto out;\n+        }\n+\n         if (header_type >= MIG_RP_MSG_MAX ||\n             header_type == MIG_RP_MSG_INVALID) {\n             error_report(\"RP: Received invalid message 0x%04x length 0x%04x\",\ndiff --git a/migration/ram.c b/migration/ram.c\nindex affb20c..7e20097 100644\n--- a/migration/ram.c\n+++ b/migration/ram.c\n@@ -2417,7 +2417,7 @@ static int ram_load_postcopy(QEMUFile *f)\n     void *last_host = NULL;\n     bool all_zero = false;\n \n-    while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {\n+    while (!(flags & RAM_SAVE_FLAG_EOS)) {\n         ram_addr_t addr;\n         void *host = NULL;\n         void *page_buffer = NULL;\n@@ -2426,6 +2426,16 @@ static int ram_load_postcopy(QEMUFile *f)\n         uint8_t ch;\n \n         addr = qemu_get_be64(f);\n+\n+        /*\n+         * If qemu file error, we should stop here, and then \"addr\"\n+         * may be invalid\n+         */\n+        ret = qemu_file_get_error(f);\n+        if (ret) {\n+            break;\n+        }\n+\n         flags = addr & ~TARGET_PAGE_MASK;\n         addr &= TARGET_PAGE_MASK;\n \n@@ -2506,6 +2516,13 @@ static int ram_load_postcopy(QEMUFile *f)\n             error_report(\"Unknown combination of migration flags: %#x\"\n                          \" (postcopy mode)\", flags);\n             ret = -EINVAL;\n+            break;\n+        }\n+\n+        /* Detect for any possible file errors */\n+        if (qemu_file_get_error(f)) {\n+            ret = qemu_file_get_error(f);\n+            break;\n         }\n \n         if (place_needed) {\n@@ -2520,9 +2537,6 @@ static int ram_load_postcopy(QEMUFile *f)\n                                           place_source, block);\n             }\n         }\n-        if (!ret) {\n-            ret = qemu_file_get_error(f);\n-        }\n     }\n \n     return ret;\ndiff --git a/migration/savevm.c b/migration/savevm.c\nindex fdd15fa..7172f14 100644\n--- a/migration/savevm.c\n+++ b/migration/savevm.c\n@@ -1720,6 +1720,11 @@ static int loadvm_process_command(QEMUFile *f)\n     cmd = qemu_get_be16(f);\n     len = qemu_get_be16(f);\n \n+    /* Check validity before continue processing of cmds */\n+    if (qemu_file_get_error(f)) {\n+        return qemu_file_get_error(f);\n+    }\n+\n     trace_loadvm_process_command(cmd, len);\n     if (cmd >= MIG_CMD_MAX || cmd == MIG_CMD_INVALID) {\n         error_report(\"MIG_CMD 0x%x unknown (len 0x%x)\", cmd, len);\n@@ -1785,6 +1790,7 @@ static int loadvm_process_command(QEMUFile *f)\n  */\n static bool check_section_footer(QEMUFile *f, SaveStateEntry *se)\n {\n+    int ret;\n     uint8_t read_mark;\n     uint32_t read_section_id;\n \n@@ -1795,6 +1801,13 @@ static bool check_section_footer(QEMUFile *f, SaveStateEntry *se)\n \n     read_mark = qemu_get_byte(f);\n \n+    ret = qemu_file_get_error(f);\n+    if (ret) {\n+        error_report(\"%s: Read section footer failed: %d\",\n+                     __func__, ret);\n+        return false;\n+    }\n+\n     if (read_mark != QEMU_VM_SECTION_FOOTER) {\n         error_report(\"Missing section footer for %s\", se->idstr);\n         return false;\n@@ -1830,6 +1843,13 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis)\n     instance_id = qemu_get_be32(f);\n     version_id = qemu_get_be32(f);\n \n+    ret = qemu_file_get_error(f);\n+    if (ret) {\n+        error_report(\"%s: Failed to read instance/version ID: %d\",\n+                     __func__, ret);\n+        return ret;\n+    }\n+\n     trace_qemu_loadvm_state_section_startfull(section_id, idstr,\n             instance_id, version_id);\n     /* Find savevm section */\n@@ -1877,6 +1897,13 @@ qemu_loadvm_section_part_end(QEMUFile *f, MigrationIncomingState *mis)\n \n     section_id = qemu_get_be32(f);\n \n+    ret = qemu_file_get_error(f);\n+    if (ret) {\n+        error_report(\"%s: Failed to read section ID: %d\",\n+                     __func__, ret);\n+        return ret;\n+    }\n+\n     trace_qemu_loadvm_state_section_partend(section_id);\n     QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {\n         if (se->load_section_id == section_id) {\n@@ -1944,8 +1971,14 @@ static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis)\n     uint8_t section_type;\n     int ret = 0;\n \n-    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {\n-        ret = 0;\n+    while (true) {\n+        section_type = qemu_get_byte(f);\n+\n+        if (qemu_file_get_error(f)) {\n+            ret = qemu_file_get_error(f);\n+            break;\n+        }\n+\n         trace_qemu_loadvm_state_section(section_type);\n         switch (section_type) {\n         case QEMU_VM_SECTION_START:\n@@ -1969,6 +2002,10 @@ static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis)\n                 goto out;\n             }\n             break;\n+        case QEMU_VM_EOF:\n+            /* This is the end of migration */\n+            goto out;\n+            break;\n         default:\n             error_report(\"Unknown savevm section type %d\", section_type);\n             ret = -EINVAL;\n",
    "prefixes": [
        "RFC",
        "v2",
        "05/33"
    ]
}