get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 28577,
    "url": "https://patches.dpdk.org/api/patches/28577/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20170911084635.11707-1-olivier.matz@6wind.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20170911084635.11707-1-olivier.matz@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20170911084635.11707-1-olivier.matz@6wind.com",
    "date": "2017-09-11T08:46:35",
    "name": "[dpdk-dev,v3] devtools: rework abi checker script",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5b73aebf8ebdc0e58b3b4f6fab8a71a561dfa24c",
    "submitter": {
        "id": 8,
        "url": "https://patches.dpdk.org/api/people/8/?format=api",
        "name": "Olivier Matz",
        "email": "olivier.matz@6wind.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20170911084635.11707-1-olivier.matz@6wind.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/28577/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/28577/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 4DE0F7CB6;\n\tMon, 11 Sep 2017 10:46:58 +0200 (CEST)",
            "from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com\n\t[62.23.145.76]) by dpdk.org (Postfix) with ESMTP id 282B0F1F\n\tfor <dev@dpdk.org>; Mon, 11 Sep 2017 10:46:57 +0200 (CEST)",
            "from glumotte.dev.6wind.com (unknown [10.16.0.195])\n\tby proxy.6wind.com (Postfix) with ESMTP id D31D4CEE8B;\n\tMon, 11 Sep 2017 10:43:03 +0200 (CEST)"
        ],
        "From": "Olivier Matz <olivier.matz@6wind.com>",
        "To": "dev@dpdk.org,\n\tnhorman@tuxdriver.com,\n\tbruce.richardson@intel.com",
        "Date": "Mon, 11 Sep 2017 10:46:35 +0200",
        "Message-Id": "<20170911084635.11707-1-olivier.matz@6wind.com>",
        "X-Mailer": "git-send-email 2.11.0",
        "In-Reply-To": "<20170911081801.tnf7qtt4qq5jkofe@neon>",
        "References": "<20170911081801.tnf7qtt4qq5jkofe@neon>",
        "Subject": "[dpdk-dev] [PATCH v3] devtools: rework abi checker script",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The initial version of the script had some limitations:\n- cannot work on a non-clean workspace\n- environment variables are not documented\n- no compilation log in case of failure\n- return success even it abi is incompatible\n\nThis patch addresses these issues and rework the code.\n\nSigned-off-by: Olivier Matz <olivier.matz@6wind.com>\n---\n\nv2->v3:\n- fix when not launched from dpdk root dir\n- use \"-Og -Wno-error\" instead of \"-O0\"\n- fix typo in commit log\n\nv1->v2:\n- use /usr/bin/env to find bash (which is required)\n- fix displayed path to html reports\n- reword help for -f option\n\n devtools/validate-abi.sh | 392 ++++++++++++++++++++++++-----------------------\n 1 file changed, 200 insertions(+), 192 deletions(-)",
    "diff": "diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh\nindex 0accc99b1..8a512aa3b 100755\n--- a/devtools/validate-abi.sh\n+++ b/devtools/validate-abi.sh\n@@ -1,7 +1,8 @@\n-#!/bin/sh\n+#!/usr/bin/env bash\n #   BSD LICENSE\n #\n #   Copyright(c) 2015 Neil Horman. All rights reserved.\n+#   Copyright(c) 2017 6WIND S.A.\n #   All rights reserved.\n #\n #   Redistribution and use in source and binary forms, with or without\n@@ -27,236 +28,243 @@\n #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n \n-TAG1=$1\n-TAG2=$2\n-TARGET=$3\n-ABI_DIR=`mktemp -d -p /tmp ABI.XXXXXX`\n+set -e\n \n-usage() {\n-\techo \"$0 <REV1> <REV2> <TARGET>\"\n-}\n+abicheck=abi-compliance-checker\n+abidump=abi-dumper\n+default_dst=abi-check\n+default_target=x86_64-native-linuxapp-gcc\n \n-log() {\n-\tlocal level=$1\n-\tshift\n-\techo \"$*\"\n+# trap on error\n+err_report() {\n+    echo \"$0: error at line $1\"\n }\n+trap 'err_report $LINENO' ERR\n \n-validate_tags() {\n+print_usage () {\n+\tcat <<- END_OF_HELP\n+\t$(basename $0) [options] <rev1> <rev2>\n \n-\tif [ -z \"$HASH1\" ]\n-\tthen\n-\t\techo \"invalid revision: $TAG1\"\n-\t\treturn\n-\tfi\n-\tif [ -z \"$HASH2\" ]\n-\tthen\n-\t\techo \"invalid revision: $TAG2\"\n-\t\treturn\n-\tfi\n+\tThis script compares the ABI of 2 git revisions of the current\n+\tworkspace. The output is a html report and a compilation log.\n+\n+\tThe objective is to make sure that applications built against\n+\tDSOs from the first revision can still run when executed using\n+\tthe DSOs built from the second revision.\n+\n+\t<rev1> and <rev2> are git commit id or tags.\n+\n+\tOptions:\n+\t  -h\t\tshow this help\n+\t  -j <num>\tenable parallel compilation with <num> threads\n+\t  -v\t\tshow compilation logs on the console\n+\t  -d <dir>\tchange working directory (default is ${default_dst})\n+\t  -t <target>\tthe dpdk target to use (default is ${default_target})\n+\t  -f\t\toverwrite existing files in destination directory\n+\n+\tThe script returns 0 on success, or the value of last failing\n+\tcall of ${abicheck} (incompatible abi or the tool has run with errors).\n+\tThe errors returned by ${abidump} are ignored.\n+\n+\tEND_OF_HELP\n }\n \n-validate_args() {\n-\tif [ -z \"$TAG1\" ]\n-\tthen\n-\t\techo \"Must Specify REV1\"\n-\t\treturn\n-\tfi\n-\tif [ -z \"$TAG2\" ]\n-\tthen\n-\t\techo \"Must Specify REV2\"\n-\t\treturn\n-\tfi\n-\tif [ -z \"$TARGET\" ]\n-\tthen\n-\t\techo \"Must Specify a build target\"\n+# log in the file, and on stdout if verbose\n+# $1: level string\n+# $2: string to be logged\n+log() {\n+\techo \"$1: $2\"\n+\tif [ \"${verbose}\" != \"true\" ]; then\n+\t\techo \"$1: $2\" >&3\n \tfi\n }\n \n+# launch a command and log it, taking care of surrounding spaces with quotes\n+cmd() {\n+\tlocal i s whitespace\n+\ts=\"\"\n+\twhitespace=\"[[:space:]]\"\n+\tfor i in \"$@\"; do\n+\t\tif [[ $i =~ $whitespace ]]; then\n+\t\t\ti=\\\"$i\\\"\n+\t\tfi\n+\t\tif [ -z \"$s\" ]; then\n+\t\t\ts=\"$i\"\n+\t\telse\n+\t\t\ts=\"$s $i\"\n+\t\tfi\n+\tdone\n+\n+\tlog \"CMD\" \"$s\"\n+\t\"$@\"\n+}\n \n-cleanup_and_exit() {\n-\trm -rf $ABI_DIR\n-\tgit checkout $CURRENT_BRANCH\n-\texit $1\n+# redirect or copy stderr/stdout to a file\n+# the syntax is unfamiliar, but it makes the rest of the\n+# code easier to read, avoiding the use of pipes\n+set_log_file() {\n+\t# save original stdout and stderr in fd 3 and 4\n+\texec 3>&1\n+\texec 4>&2\n+\t# create a new fd 5 that send to a file\n+\texec 5> >(cat > $1)\n+\t# send stdout and stderr to fd 5\n+\tif [ \"${verbose}\" = \"true\" ]; then\n+\t\texec 1> >(tee /dev/fd/5 >&3)\n+\t\texec 2> >(tee /dev/fd/5 >&4)\n+\telse\n+\t\texec 1>&5\n+\t\texec 2>&5\n+\tfi\n }\n \n # Make sure we configure SHARED libraries\n # Also turn off IGB and KNI as those require kernel headers to build\n fixup_config() {\n-\tsed -i -e\"$ a\\CONFIG_RTE_BUILD_SHARED_LIB=y\" config/defconfig_$TARGET\n-\tsed -i -e\"$ a\\CONFIG_RTE_NEXT_ABI=n\" config/defconfig_$TARGET\n-\tsed -i -e\"$ a\\CONFIG_RTE_EAL_IGB_UIO=n\" config/defconfig_$TARGET\n-\tsed -i -e\"$ a\\CONFIG_RTE_LIBRTE_KNI=n\" config/defconfig_$TARGET\n-\tsed -i -e\"$ a\\CONFIG_RTE_KNI_KMOD=n\" config/defconfig_$TARGET\n+\tlocal conf=config/defconfig_$target\n+\tcmd sed -i -e\"$ a\\CONFIG_RTE_BUILD_SHARED_LIB=y\" $conf\n+\tcmd sed -i -e\"$ a\\CONFIG_RTE_NEXT_ABI=n\" $conf\n+\tcmd sed -i -e\"$ a\\CONFIG_RTE_EAL_IGB_UIO=n\" $conf\n+\tcmd sed -i -e\"$ a\\CONFIG_RTE_LIBRTE_KNI=n\" $conf\n+\tcmd sed -i -e\"$ a\\CONFIG_RTE_KNI_KMOD=n\" $conf\n }\n \n-###########################################\n-#START\n-############################################\n+# build dpdk for the given tag and dump abi\n+# $1: hash of the revision\n+gen_abi() {\n+\tlocal i oldpwd\n+\n+\toldpwd=${PWD}\n+\tcmd git clone $(dirname $0)/.. ${dst}/${1}\n+\tcmd cd ${dst}/${1}\n+\n+\tlog \"INFO\" \"Checking out version ${1} of the dpdk\"\n+\t# Move to the old version of the tree\n+\tcmd git checkout ${1}\n+\n+\tfixup_config\n+\n+\t# Now configure the build\n+\tlog \"INFO\" \"Configuring DPDK ${1}\"\n+\tcmd make config T=$target O=$target > ${dst}/log 2>&1\n+\n+\t# Checking abi compliance relies on using the dwarf information in\n+\t# the shared objects. Build with -g to include them.\n+\tlog \"INFO\" \"Building DPDK ${1}. This might take a moment\"\n+\tcmd make -j$parallel O=$target V=1 EXTRA_CFLAGS=\"-g -Og -Wno-error\" \\\n+\t    EXTRA_LDFLAGS=\"-g\" || log \"INFO\" \"The build failed\"\n+\n+\t# Move to the lib directory\n+\tcmd cd ${PWD}/$target/lib\n+\tlog \"INFO\" \"Collecting ABI information for ${1}\"\n+\tfor i in *.so; do\n+\t\t[ -e \"$i\" ] || break\n+\t\tcmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true\n+\t\t# hack to ignore empty SymbolsInfo section (no public ABI)\n+\t\tif grep -q \"'SymbolInfo' => {},\" $dst/${1}/${i}.dump \\\n+\t\t\t\t2> /dev/null; then\n+\t\t\tlog \"INFO\" \"${i} has no public ABI, remove dump file\"\n+\t\t\tcmd rm -f $dst/${1}/${i}.dump\n+\t\tfi\n+\tdone\n+\tcmd cd ${oldpwd}\n+}\n \n-#trap on ctrl-c to clean up\n-trap cleanup_and_exit SIGINT\n+verbose=false\n+parallel=1\n+dst=${default_dst}\n+target=${default_target}\n+force=0\n+while getopts j:vd:t:fh ARG ; do\n+\tcase $ARG in\n+\t\tj ) parallel=$OPTARG ;;\n+\t\tv ) verbose=true ;;\n+\t\td ) dst=$OPTARG ;;\n+\t\tt ) target=$OPTARG ;;\n+\t\tf ) force=1 ;;\n+\t\th ) print_usage ; exit 0 ;;\n+\t\t? ) print_usage ; exit 1 ;;\n+\tesac\n+done\n+shift $(($OPTIND - 1))\n \n-if [ -z \"$DPDK_MAKE_JOBS\" ]\n-then\n-\t# This counts the number of cpus on the system\n-\tif [ -e /usr/bin/lscpu ]\n-\tthen\n-\t\tDPDK_MAKE_JOBS=`lscpu -p=cpu | grep -v \"#\" | wc -l`\n-\telse\n-\t\tDPDK_MAKE_JOBS=1\n-\tfi\n+if [ $# != 2 ]; then\n+\tprint_usage\n+\texit 1\n fi\n \n-#Save the current branch\n-CURRENT_BRANCH=`git branch | grep \\* | cut -d' ' -f2`\n+tag1=$1\n+tag2=$2\n \n-if [ -z \"$CURRENT_BRANCH\" ]\n-then\n-\tCURRENT_BRANCH=`git log --pretty=format:%H HEAD~1..HEAD`\n-fi\n+# convert path to absolute\n+case \"${dst}\" in\n+\t/*) ;;\n+\t*) dst=${PWD}/${dst} ;;\n+esac\n \n-if [ -n \"$VERBOSE\" ]\n-then\n-\texport VERBOSE=/dev/stdout\n-else\n-\texport VERBOSE=/dev/null\n+if [ -e \"${dst}\" -a \"$force\" = 0 ]; then\n+\techo \"The ${dst} directory is not empty. Remove it, use another\"\n+\techo \"one (-d <dir>), or force overriding (-f)\"\n+\texit 1\n fi\n \n-# Validate that we have all the arguments we need\n-res=$(validate_args)\n-if [ -n \"$res\" ]\n-then\n-\techo $res\n-\tusage\n-\tcleanup_and_exit 1\n-fi\n+rm -rf ${dst}\n+mkdir -p ${dst}\n+set_log_file ${dst}/abi-check.log\n+log \"INFO\" \"Logs available in ${dst}/abi-check.log\"\n \n-HASH1=$(git show -s --format=%H \"$TAG1\" -- 2> /dev/null | tail -1)\n-HASH2=$(git show -s --format=%H \"$TAG2\" -- 2> /dev/null | tail -1)\n+command -v ${abicheck} || log \"INFO\" \"Can't find ${abicheck} utility\"\n+command -v ${abidump} || log \"INFO\" \"Can't find ${abidump} utility\"\n \n-# Make sure our tags exist\n-res=$(validate_tags)\n-if [ -n \"$res\" ]\n-then\n-\techo $res\n-\tcleanup_and_exit 1\n-fi\n+hash1=$(git show -s --format=%h \"$tag1\" -- 2> /dev/null | tail -1)\n+hash2=$(git show -s --format=%h \"$tag2\" -- 2> /dev/null | tail -1)\n \n # Make hashes available in output for non-local reference\n-TAG1=\"$TAG1 ($HASH1)\"\n-TAG2=\"$TAG2 ($HASH2)\"\n-\n-ABICHECK=`which abi-compliance-checker 2>/dev/null`\n-if [ $? -ne 0 ]\n-then\n-\tlog \"INFO\" \"Can't find abi-compliance-checker utility\"\n-\tcleanup_and_exit 1\n-fi\n-\n-ABIDUMP=`which abi-dumper 2>/dev/null`\n-if [ $? -ne 0 ]\n-then\n-\tlog \"INFO\" \"Can't find abi-dumper utility\"\n-\tcleanup_and_exit 1\n-fi\n+tag1=\"$tag1 ($hash1)\"\n+tag2=\"$tag2 ($hash2)\"\n \n-log \"INFO\" \"We're going to check and make sure that applications built\"\n-log \"INFO\" \"against DPDK DSOs from version $TAG1 will still run when executed\"\n-log \"INFO\" \"against DPDK DSOs built from version $TAG2.\"\n-log \"INFO\" \"\"\n-\n-# Check to make sure we have a clean tree\n-git status | grep -q clean\n-if [ $? -ne 0 ]\n-then\n-\tlog \"WARN\" \"Working directory not clean, aborting\"\n-\tcleanup_and_exit 1\n+if [ \"$hash1\" = \"$hash2\" ]; then\n+\tlog \"ERROR\" \"$tag1 and $tag2 are the same revisions\"\n+\texit 1\n fi\n \n-# Move to the root of the git tree\n-cd $(dirname $0)/..\n+cmd mkdir -p ${dst}\n \n-log \"INFO\" \"Checking out version $TAG1 of the dpdk\"\n-# Move to the old version of the tree\n-git checkout $HASH1\n+# dump abi for each revision\n+gen_abi ${hash1}\n+gen_abi ${hash2}\n \n-fixup_config\n+# compare the abi dumps\n+ret=0\n+list=\"\"\n+for i in ${dst}/${hash2}/*.dump; do\n+\tname=`basename $i`\n+\tlibname=${name%.dump}\n \n-# Checking abi compliance relies on using the dwarf information in\n-# The shared objects.  Thats only included in the DSO's if we build\n-# with -g\n-export EXTRA_CFLAGS=\"$EXTRA_CFLAGS -g -O0\"\n-export EXTRA_LDFLAGS=\"$EXTRA_LDFLAGS -g\"\n-\n-# Now configure the build\n-log \"INFO\" \"Configuring DPDK $TAG1\"\n-make config T=$TARGET O=$TARGET > $VERBOSE 2>&1\n-\n-log \"INFO\" \"Building DPDK $TAG1. This might take a moment\"\n-make -j$DPDK_MAKE_JOBS O=$TARGET > $VERBOSE 2>&1\n-\n-if [ $? -ne 0 ]\n-then\n-\tlog \"INFO\" \"THE BUILD FAILED.  ABORTING\"\n-\tcleanup_and_exit 1\n-fi\n+\tif [ ! -f $dst/${hash1}/$name ]; then\n+\t\tlog \"INFO\" \"$NAME does not exist in $tag1. skipping...\"\n+\t\tcontinue\n+\tfi\n \n-# Move to the lib directory\n-cd $TARGET/lib\n-log \"INFO\" \"COLLECTING ABI INFORMATION FOR $TAG1\"\n-for i in `ls *.so`\n-do\n-\t$ABIDUMP $i -o $ABI_DIR/$i-ABI-0.dump -lver $HASH1\n+\tlocal_ret=0\n+\tcmd $abicheck -l $libname \\\n+\t    -old $dst/${hash1}/$name -new $dst/${hash2}/$name || local_ret=$?\n+\tif [ $local_ret != 0 ]; then\n+\t\tlog \"NOTICE\" \"$abicheck returned $local_ret\"\n+\t\tret=$local_ret\n+\t\tlist=\"$list $libname\"\n+\tfi\n done\n-cd ../..\n-\n-# Now clean the tree, checkout the second tag, and rebuild\n-git clean -f -d\n-git reset --hard\n-# Move to the new version of the tree\n-log \"INFO\" \"Checking out version $TAG2 of the dpdk\"\n-git checkout $HASH2\n-\n-fixup_config\n-\n-# Now configure the build\n-log \"INFO\" \"Configuring DPDK $TAG2\"\n-make config T=$TARGET O=$TARGET > $VERBOSE 2>&1\n-\n-log \"INFO\" \"Building DPDK $TAG2. This might take a moment\"\n-make -j$DPDK_MAKE_JOBS O=$TARGET > $VERBOSE 2>&1\n \n-if [ $? -ne 0 ]\n-then\n-\tlog \"INFO\" \"THE BUILD FAILED.  ABORTING\"\n-\tcleanup_and_exit 1\n+if [ $ret != 0 ]; then\n+\tlog \"NOTICE\" \"At least one call to $abicheck returned an error.\"\n+\tlog \"NOTICE\" \"ABI may be incompatible, please check logs for details.\"\n+\tlog \"NOTICE\" \"Incompatible list: $list\"\n+else\n+\tlog \"NOTICE\" \"No error detected, ABI is compatible.\"\n fi\n \n-cd $TARGET/lib\n-log \"INFO\" \"COLLECTING ABI INFORMATION FOR $TAG2\"\n-for i in `ls *.so`\n-do\n-\t$ABIDUMP $i -o $ABI_DIR/$i-ABI-1.dump -lver $HASH2\n-done\n-cd ../..\n-\n-# Start comparison of ABI dumps\n-for i in `ls $ABI_DIR/*-1.dump`\n-do\n-\tNEWNAME=`basename $i`\n-\tOLDNAME=`basename $i | sed -e\"s/1.dump/0.dump/\"`\n-\tLIBNAME=`basename $i | sed -e\"s/-ABI-1.dump//\"`\n-\n-\tif [ ! -f $ABI_DIR/$OLDNAME ]\n-\tthen\n-\t\tlog \"INFO\" \"$OLDNAME DOES NOT EXIST IN $TAG1. SKIPPING...\"\n-\tfi\n-\n-\t#compare the abi dumps\n-\t$ABICHECK -l $LIBNAME -old $ABI_DIR/$OLDNAME -new $ABI_DIR/$NEWNAME\n-done\n+log \"INFO\" \"Logs are in ${dst}/abi-check.log\"\n+log \"INFO\" \"HTML reports are in ${dst}/${hash2}/compat_reports directory\"\n \n-git reset --hard\n-log \"INFO\" \"ABI CHECK COMPLETE.  REPORTS ARE IN compat_report directory\"\n-cleanup_and_exit 0\n+exit $ret\n",
    "prefixes": [
        "dpdk-dev",
        "v3"
    ]
}