Skip to content

[meta] attrversion.sh: only emit versions for attributes in the checked-out headers - #2363

Open
terence-nexthop wants to merge 1 commit into
opencomputeproject:masterfrom
terence-nexthop:attrversion-only-checked-out-attrs
Open

terence-nexthop wants to merge 1 commit into
opencomputeproject:masterfrom
terence-nexthop:attrversion-only-checked-out-attrs

Conversation

@terence-nexthop

Copy link
Copy Markdown

Fixes #2361

Problem

meta/attrversion.sh collects SAI_METADATA_ATTR_VERSION_* from every vX.Y.Z tag from v1.10.0 up. A clone usually carries all upstream tags, including releases published after the checked-out commit or cut on newer release branches. So the script emitted defines for attributes that do not exist in the checked-out headers, and its output changed whenever a new release was tagged.

For example, v1.17.5 checked out in a clone that has v1.19.1 produces 5,821 defines for the 2,650 attributes in its headers. sonic-sairedis's SWIG binding turns every define into a constant, and the extra ones push pysairedis_wrap.cpp past GCC's max-gcse-memory (-Werror=disabled-optimization). That broke builds of unchanged pinned commits once v1.19.1 was tagged (worked around in sonic-net/sonic-sairedis#2108 and #2109).

Change

The script keeps scanning the same tags, but it now buffers the scan and only prints a define for attributes found in the checked-out headers (committed HEAD or working tree). Every remaining attribute keeps the version of the first tag that contains it, as before.

-        perl -ne '/^(\S+):..\/(\S+)\/\S+.h:\s+(SAI_\w+_ATTR_\w+)/;
-        print "#define SAI_METADATA_ATTR_VERSION_$3 \"$1\" /* $2 */\n" if not defined $h{$3};$h{$3}=1' > $OUTPUT
+        perl -ne '/^(\S+):..\/(\S+)\/\S+.h:\s+(SAI_\w+_ATTR_\w+)/ or next;
+        push @attrs, [$1, $2, $3]; $head{$3} = 1 if $1 eq "HEAD";
+        END { for (@attrs) { my ($ver, $dir, $attr) = @$_;
+            print "#define SAI_METADATA_ATTR_VERSION_$attr \"$ver\" /* $dir */\n" if $head{$attr} and not $h{$attr}++ } }' > $OUTPUT

Why not git tag --merged HEAD (as suggested in #2361)

Point releases are tagged on release branches, and those tags are usually not ancestors of master or of later branches. With --merged HEAD, attributes first released in a point release get the next ancestor tag's version instead. That changes 106 versions on master, 94 on v1.18 and 59 on v1.17. For example, SAI_ACL_TABLE_ATTR_FIELD_NEXT_HOP_USER_META moves from v1.17.1 to v1.18.0. These versions feed sai_attr_metadata_t.apiversion, which syncd compares with the vendor's sai_query_api_version().

Ignoring tags newer than inc/saiversion.h was also considered. It mislabels attributes too, because master's version often lags release-branch point releases: at f60c11f (1.18.0, with v1.18.1 already released) it changes 12 attributes from v1.18.1 to HEAD.

Testing

All tests were run against a full clone with tags up to v1.19.1, comparing the old and new script on the same commit. The v1.19 branch tip is currently the same commit as master, so the master results cover it:

Checkout Before After Attributes in headers Versions changed
master / v1.19 fc7e71b (1.19.1) 5,821 5,809 5,809 0
v1.18 c67f115 (1.18.1) 5,821 2,710 2,710 0
v1.17 0ac228e (1.17.5) 5,821 2,650 2,650 0
master f60c11f (1.18.0) 5,821 2,763 2,763 0
  • Full meta make: run as in CI (plain, and with doc/custom-headers copied into custom/) on master/v1.19, v1.18 and v1.17, in a Debian bookworm environment with doxygen 1.9.4 and GCC 12.
    • All generated files, including saimetadata.c, are byte-identical. The only exception is SAI_METADATA_HAVE_ATTR_VERSION in saimetadata.h.
    • No build logs no version defined.
    • On the release branches, make was run with size.sh pointed at HEAD. Its hardcoded origin/master fails the struct-size check there, whichever version of this script is used.
  • HEAD label: attributes that are not in any release (the custom-header attributes, a local commit, an uncommitted edit) are still labelled HEAD.
  • Removed defines:
    • On master, the 12 removed are for DASH meter attributes (SAI_METER_BUCKET_ATTR_* and related) that Convert DASH meter bucket object to table entry #2056 removed from the headers.
    • On release branches, the others removed are attributes that only exist in later releases.

Notes

  • What still depends on the clone's tags: the set of defines now depends only on the checkout. An attribute's version can still change if a release containing it is tagged later. For example, an attribute that is labelled HEAD today, or labelled with a later branch's release, gets the version of the first release that contains it, wherever that release was tagged. That's what the version means. It doesn't change the number of defines.
  • Shallow clones and clones without tags: these behave as before.

…ed-out headers

attrversion.sh collects SAI_METADATA_ATTR_VERSION_* from every vX.Y.Z tag
from v1.10.0 up. A clone usually carries all upstream tags, including
releases published after the checked-out commit or on newer release
branches, so attributes that do not exist in the checked-out headers were
emitted too, and the output changed whenever a new release was tagged.

For example, v1.17.5 checked out in a clone that has v1.19.1 produced
5821 defines for 2650 attributes in its headers. Downstream users that
build metadata from a pinned SAI (e.g. the sonic-sairedis Python binding)
saw unchanged sources start failing to build once v1.19.1 was tagged.

Keep scanning the same tags, but only emit a define for attributes found
in the checked-out headers. Unlike restricting to tags merged into HEAD,
this keeps backported attributes at the point release that first shipped
them. Every remaining attribute keeps the version of the first tag that
contains it, so the generated metadata is unchanged apart from
SAI_METADATA_HAVE_ATTR_VERSION; defines for attributes removed from the
headers (e.g. the DASH meter bucket attributes) are dropped.

Fixes opencomputeproject#2361

Signed-off-by: Terence Hui <terence@nexthop.ai>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@bingwang-ms

Copy link
Copy Markdown
Contributor

Thanks for digging into this and for the detailed writeup on #2361 — you're right that git tag --merged HEAD would have been the wrong fix. I verified the regression it would've caused: point releases are tagged on release branches that often aren't ancestors of master/later branches, so scoping tags by ancestry would've bumped the recorded version for attributes first shipped in a point release to the next ancestor tag's version instead — a real correctness problem since apiversion is compared against a vendor's sai_query_api_version() at runtime.

I reproduced your results independently: checked out v1.17.5 in a full clone (tags up to v1.19.1 present) and ran the old vs. new script.

  • Old script: 5,821 defines (polluted by attributes from tags/branches not applicable to this checkout)
  • New script: 2,650 defines — exactly matches the real attribute count in v1.17.5's headers
  • Diffed the version value for every attribute common to both outputs: zero differences — confirms no regression in "earliest version introduced" semantics, only removal of bogus entries for attributes that don't exist in the checked-out headers.

This matches your test table exactly. The approach (buffer all tag/attr pairs, gate emission on presence in the HEAD header scan, keep earliest-tag-wins ordering) is correct and nicely sidesteps the release-branch-ancestry problem without needing to scope the tag scan itself.

LGTM — approving. Would also support backporting this to v1.19, v1.18, and v1.17 as you suggested, since those are the branches actually consumed downstream (e.g. sonic-sairedis pins against them).

Comment thread meta/attrversion.sh
# A clone usually carries every upstream tag, including releases published
# after (or on branches newer than) the checked-out commit. Only emit versions
# for attributes present in the checked-out headers, so that the output does not
# depend on which tags exist in the clone.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i already replied on issue for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

attrversion.sh scans all local git tags instead of tags reachable from the checked-out commit, causing non-reproducible builds

3 participants