Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Feb 2010 18:03:39 -0800
From:      Garrett Cooper <gcooper@FreeBSD.org>
To:        trhodes@freebsd.org
Cc:        current@freebsd.org
Subject:   Draft script for identifying [and someday documenting] tunables
Message-ID:  <364299f41002041803m60604979n1f2534e8d5e20af0@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
--0016e64b970e381515047ed0dc7b
Content-Type: text/plain; charset=ISO-8859-1

Hi Tom, and other CURRENT folks,
    One of the items that needs to be fixed up on the documentation
page from what I've seen is that the kernel sysctl and tunables
information needs to be properly updated because it's either the
description is missing, out-of-date, or the sysctl OID or tunable has
been removed, etc.
    I came up with this [relatively] simple script for parsing
tunables -- took a crack at trying to get sysctl support in as well,
but hit a brick wall because the method for walking over the source
tree is fairly basic. What should be done to catch everything in an
automated manner is that there need to be some preprocessor defines
plugged into the tunable and sysctl macros so that it prints out the
proper description for the properties under inspection.
    Anyhow, if someone can propose a way to do that quickly and
cleanly, I'll write up a more standardized proposal with basic code
that can get plugged into the headers, so it punts out this info for
the script, which will produce an automated mapping of what tunables
are used, and the complete sysctl MIB.
Thanks!
-Garrett

#!/usr/bin/env python
"""

Traverse a source tree to produce a list of FreeBSD sysctls and tunables
for documentation purposes.

Copyright (c) 1992-2010 Cisco Systems, Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

"""

# NOTE: this is done in python because it's more flexible than sed, awk, etc.
#
# XXX (gcooper):
# 1. FreeBSD kernel tunables should be defined in an easy-to-understand
# self-documenting method as they aren't today (you can grab the information
# from the sysctl description, but it's messy parsing the description if it's
# not in the same file or the immediate area around the tunable definition);
# hence the description parsing is disabled.
# 2. This data should be piped via subprocess through cpp(1) to look at the
# tunable data, probably.
#

import optparse
import os
import re

PARSE_SYSCTLS, PARSE_TUNABLES = 1, 2
SYSCTL_RE = re.compile('^\s*SYSCTL_[A-Z_]+\s*\("(.+)", .+, "(.+)"\)')
TUNABLE_RE = re.compile('^\s*TUNABLE_[A-Z]+\s*\("([a-z\.]+)", .+\)')

class KernelProperty(object):
    """ A generic class for Sysctl and Tunable objects """

    def __init__ (self, name, **kwargs):
        """ Tunable objects constructor.

        name - tunable name; required.
        description - tunable description; optional.
        file - file where the info was spotted; optional.
        line - line where the tunable was defined; optional.

        XXX (gcooper): description is hardwired to None -- make this a
        requirement when self-documenting tunable info is completed...
        """
        if not name:
            raise ValueError('name must be defined to a non-zero length string')

        for i in [ 'description', 'file', 'line' ]:
            setattr(self, i, kwargs.get(i))

        #if not description:
        #    raise ValueError('description must be defined to a non-zero '
        #                     'length string')
        self.name = name

    def __str__ (self):
        """ `Prints' out the KernelProperty object in stringized form.

        The format is as follows:

        1. name
        2. file:line name
        3. name = "description"
        4. file:line name = "description"

        The format printed out all depends on the data provided by
        parse_kernel_objects(...).

        """

        # Provide the file / line info.
        # pylint: disable-msg=E1101
        if self.file and self.line:
            # pylint: disable-msg=E1101
            prefix = '%s:%d: ' % (self.file, self.line)
        else:
            prefix = ''

        # Omit the description.
        # pylint: disable-msg=E1101
        if self.description:
            # pylint: disable-msg=E1101
            suffix = ' = "%s"' % (self.description,)
        else:
            suffix = ''

        # NOTE (gcooper): if either prefix or suffix is empty, there will be
        # nasty heading / trailing whitespace. Hence, I used + concatenation
        # instead of ' '.join([..]), because this is considerably cheaper to
        # do than '%s%s%s' (and far less braindead)...
        return prefix + self.name + suffix

class Sysctl(KernelProperty):
    """ A class corresponding to a kernel sysctl OID property.
    """

class Tunable(KernelProperty):
    """ A class corresponding to a kernel tunable object.
    """

def main():
    """ Main function of course. """

    parser = optparse.OptionParser()

    parser.add_option('-d', '--srcdir', dest='srcdir', default='/usr/src/sys',
                      help=('source directory to look for sysctls and '
                            'tunables in'))

    #
    # XXX (gcooper): this is more difficult to do as the descriptions
    # themselves span multiple lines. Needless to say, it's a Orlando Bloom-ing
    # parsing mess...
    #
    #parser.add_option('-s', '--sysctl', dest='parse_sysctls', default=False,
    #                  action='store_true',
    #                  help='look for sysctls OIDs')

    parser.add_option('-t', '--tunable', dest='parse_tunables', default=False,
                      action='store_true',
                      help='look for tunables')

    parser.add_option('-v', '--verbose', dest='verbose', default=False,
                      action='store_true',
                      help='include file/line results for tunables.')

    opts, __ = parser.parse_args()

    kknobs = 0

    # XXX (garrcoop): sysctl parsing's a pain -- so it's disabled...
    # See above comment.
    kknobs = PARSE_TUNABLES
    #
    #if opts.parse_sysctls:
    #    kknobs |= PARSE_SYSCTLS
    #if opts.parse_tunables:
    #    kknobs |= PARSE_TUNABLES
    #
    #if not kknobs:
    #    kknobs = PARSE_SYSCTLS


    sysctls, tunables = comb_tree_for_kernel_objects(opts.srcdir,
                                                     kernel_knobs=kknobs,
                                                     verbose_info=opts.verbose,)

    if sysctls:
        print '\n'.join([ 'Sysctls:' ] + map(str, sysctls))

    if tunables:
        print '\n'.join([ 'Tunables:' ] + map(str, tunables))

def comb_tree_for_kernel_objects(srcdir, kernel_knobs, verbose_info=False):
    """ Comb a tree looking for kernel tunables in files under srcdir.

    - Returns a list of Tunable objects found in srcdir.
    - The file and line number the tunable was found on will be saved when
      verbose_info is set to True. See the Tunable class for more
      details.
    """

    sysctls = []
    tunables = []

    # Doing this makes relpath considerably simpler and cleaner than doing it
    # inside the loop.
    os.chdir(srcdir)

    for root, __, files in os.walk(srcdir):

        for _file in files:

            _file = os.path.relpath(os.path.join(root, _file))
            _sysctls, _tunables = parse_kernel_objects(_file, kernel_knobs,
                                                       verbose_info)
            sysctls.extend(_sysctls)
            tunables.extend(_tunables)

    return sysctls, tunables

def parse_kernel_objects(_file, kernel_knobs, verbose_info=False):
    """ Comb a tree looking for kernel tunables.

    - Returns a tuple of lists containing Sysctl and Tunable objects
      found in _file.
    - The file and line number the tunable was found on will be saved when
      verbose_info is set to True. See the KernelProperty class for more
      details.
    """

    kwargs = { }
    sysctls = []
    tunables = []

    parse_sysctls = kernel_knobs & PARSE_SYSCTLS
    parse_tunables = kernel_knobs & PARSE_TUNABLES

    if not (parse_sysctls or parse_tunables):
        # Needs to be an inclusive or of PARSE_SYSCTLS, PARSE_TUNABLES, or a
        # combination of the two knobs.
        raise ValueError('invalid value for kernel_knobs: %s'
                         % str(kernel_knobs))

    if verbose_info:
        kwargs['file'] = _file

    fd = open(_file, 'r')
    try:
        lines = fd.readlines()
    finally:
        fd.close()

    kwargs['line'] = 0

    for line in lines:

        kwargs['line'] += 1

        if parse_tunables:
            match = TUNABLE_RE.match(line)
        else:
            match = None

        if match:
            tunables.append(Tunable(match.group(1), **kwargs))
        elif parse_sysctls:
            match = SYSCTL_RE.match(line)
            if match:
                sysctls.append(Sysctl(match.group(1),
                                      description=match.group(2), **kwargs))

    return sysctls, tunables

if __name__ == '__main__':
    main()

--0016e64b970e381515047ed0dc7b
Content-Type: application/octet-stream; 
	name="find_freebsd_kernel_properties.py"
Content-Disposition: attachment; filename="find_freebsd_kernel_properties.py"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_g5ac0vbr0

IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIgoKVHJhdmVyc2UgYSBzb3VyY2UgdHJlZSB0byBwcm9k
dWNlIGEgbGlzdCBvZiBGcmVlQlNEIHN5c2N0bHMgYW5kIHR1bmFibGVzCmZvciBkb2N1bWVudGF0
aW9uIHB1cnBvc2VzLgoKQ29weXJpZ2h0IChjKSAxOTkyLTIwMTAgQ2lzY28gU3lzdGVtcywgSW5j
LiBBbGwgcmlnaHRzIHJlc2VydmVkLgoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2Ug
YW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Cm1vZGlmaWNhdGlvbiwgYXJlIHBlcm1p
dHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwphcmUgbWV0OgoxLiBS
ZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHly
aWdodAogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5n
IGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJv
ZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlv
bnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKICAgZG9jdW1lbnRhdGlvbiBh
bmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KClRI
SVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIEFVVEhPUiBBTkQgQ09OVFJJQlVUT1JTIGBg
QVMgSVMnJyBBTkQKQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcs
IEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCklNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFC
SUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCkFSRSBESVNDTEFJTUVE
LiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxF
CkZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZ
LCBPUiBDT05TRVFVRU5USUFMCkRBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRP
LCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCk9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVT
RSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQpIT1dFVkVSIENB
VVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1Qs
IFNUUklDVApMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVS
V0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCk9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUs
IEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKU1VDSCBEQU1BR0UuCgoiIiIK
CiMgTk9URTogdGhpcyBpcyBkb25lIGluIHB5dGhvbiBiZWNhdXNlIGl0J3MgbW9yZSBmbGV4aWJs
ZSB0aGFuIHNlZCwgYXdrLCBldGMuCiMKIyBYWFggKGdjb29wZXIpOgojIDEuIEZyZWVCU0Qga2Vy
bmVsIHR1bmFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGluIGFuIGVhc3ktdG8tdW5kZXJzdGFuZAoj
IHNlbGYtZG9jdW1lbnRpbmcgbWV0aG9kIGFzIHRoZXkgYXJlbid0IHRvZGF5ICh5b3UgY2FuIGdy
YWIgdGhlIGluZm9ybWF0aW9uCiMgZnJvbSB0aGUgc3lzY3RsIGRlc2NyaXB0aW9uLCBidXQgaXQn
cyBtZXNzeSBwYXJzaW5nIHRoZSBkZXNjcmlwdGlvbiBpZiBpdCdzCiMgbm90IGluIHRoZSBzYW1l
IGZpbGUgb3IgdGhlIGltbWVkaWF0ZSBhcmVhIGFyb3VuZCB0aGUgdHVuYWJsZSBkZWZpbml0aW9u
KTsKIyBoZW5jZSB0aGUgZGVzY3JpcHRpb24gcGFyc2luZyBpcyBkaXNhYmxlZC4KIyAyLiBUaGlz
IGRhdGEgc2hvdWxkIGJlIHBpcGVkIHZpYSBzdWJwcm9jZXNzIHRocm91Z2ggY3BwKDEpIHRvIGxv
b2sgYXQgdGhlCiMgdHVuYWJsZSBkYXRhLCBwcm9iYWJseS4KIwoKaW1wb3J0IG9wdHBhcnNlCmlt
cG9ydCBvcwppbXBvcnQgcmUKClBBUlNFX1NZU0NUTFMsIFBBUlNFX1RVTkFCTEVTID0gMSwgMgpT
WVNDVExfUkUgPSByZS5jb21waWxlKCdeXHMqU1lTQ1RMX1tBLVpfXStccypcKCIoLispIiwgLiss
ICIoLispIlwpJykKVFVOQUJMRV9SRSA9IHJlLmNvbXBpbGUoJ15ccypUVU5BQkxFX1tBLVpdK1xz
KlwoIihbYS16XC5dKykiLCAuK1wpJykKCmNsYXNzIEtlcm5lbFByb3BlcnR5KG9iamVjdCk6CiAg
ICAiIiIgQSBnZW5lcmljIGNsYXNzIGZvciBTeXNjdGwgYW5kIFR1bmFibGUgb2JqZWN0cyAiIiIK
CiAgICBkZWYgX19pbml0X18gKHNlbGYsIG5hbWUsICoqa3dhcmdzKToKICAgICAgICAiIiIgVHVu
YWJsZSBvYmplY3RzIGNvbnN0cnVjdG9yLgoKICAgICAgICBuYW1lIC0gdHVuYWJsZSBuYW1lOyBy
ZXF1aXJlZC4KICAgICAgICBkZXNjcmlwdGlvbiAtIHR1bmFibGUgZGVzY3JpcHRpb247IG9wdGlv
bmFsLgogICAgICAgIGZpbGUgLSBmaWxlIHdoZXJlIHRoZSBpbmZvIHdhcyBzcG90dGVkOyBvcHRp
b25hbC4KICAgICAgICBsaW5lIC0gbGluZSB3aGVyZSB0aGUgdHVuYWJsZSB3YXMgZGVmaW5lZDsg
b3B0aW9uYWwuCgogICAgICAgIFhYWCAoZ2Nvb3Blcik6IGRlc2NyaXB0aW9uIGlzIGhhcmR3aXJl
ZCB0byBOb25lIC0tIG1ha2UgdGhpcyBhCiAgICAgICAgcmVxdWlyZW1lbnQgd2hlbiBzZWxmLWRv
Y3VtZW50aW5nIHR1bmFibGUgaW5mbyBpcyBjb21wbGV0ZWQuLi4KICAgICAgICAiIiIKICAgICAg
ICBpZiBub3QgbmFtZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignbmFtZSBtdXN0IGJl
IGRlZmluZWQgdG8gYSBub24temVybyBsZW5ndGggc3RyaW5nJykKCiAgICAgICAgZm9yIGkgaW4g
WyAnZGVzY3JpcHRpb24nLCAnZmlsZScsICdsaW5lJyBdOgogICAgICAgICAgICBzZXRhdHRyKHNl
bGYsIGksIGt3YXJncy5nZXQoaSkpCgogICAgICAgICNpZiBub3QgZGVzY3JpcHRpb246CiAgICAg
ICAgIyAgICByYWlzZSBWYWx1ZUVycm9yKCdkZXNjcmlwdGlvbiBtdXN0IGJlIGRlZmluZWQgdG8g
YSBub24temVybyAnCiAgICAgICAgIyAgICAgICAgICAgICAgICAgICAgICdsZW5ndGggc3RyaW5n
JykKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCgogICAgZGVmIF9fc3RyX18gKHNlbGYpOgogICAg
ICAgICIiIiBgUHJpbnRzJyBvdXQgdGhlIEtlcm5lbFByb3BlcnR5IG9iamVjdCBpbiBzdHJpbmdp
emVkIGZvcm0uCgogICAgICAgIFRoZSBmb3JtYXQgaXMgYXMgZm9sbG93czoKCiAgICAgICAgMS4g
bmFtZQogICAgICAgIDIuIGZpbGU6bGluZSBuYW1lCiAgICAgICAgMy4gbmFtZSA9ICJkZXNjcmlw
dGlvbiIKICAgICAgICA0LiBmaWxlOmxpbmUgbmFtZSA9ICJkZXNjcmlwdGlvbiIKCiAgICAgICAg
VGhlIGZvcm1hdCBwcmludGVkIG91dCBhbGwgZGVwZW5kcyBvbiB0aGUgZGF0YSBwcm92aWRlZCBi
eSAKICAgICAgICBwYXJzZV9rZXJuZWxfb2JqZWN0cyguLi4pLgoKICAgICAgICAiIiIKCiAgICAg
ICAgIyBQcm92aWRlIHRoZSBmaWxlIC8gbGluZSBpbmZvLgogICAgICAgICMgcHlsaW50OiBkaXNh
YmxlLW1zZz1FMTEwMQogICAgICAgIGlmIHNlbGYuZmlsZSBhbmQgc2VsZi5saW5lOgogICAgICAg
ICAgICAjIHB5bGludDogZGlzYWJsZS1tc2c9RTExMDEKICAgICAgICAgICAgcHJlZml4ID0gJyVz
OiVkOiAnICUgKHNlbGYuZmlsZSwgc2VsZi5saW5lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAg
IHByZWZpeCA9ICcnCgogICAgICAgICMgT21pdCB0aGUgZGVzY3JpcHRpb24uCiAgICAgICAgIyBw
eWxpbnQ6IGRpc2FibGUtbXNnPUUxMTAxCiAgICAgICAgaWYgc2VsZi5kZXNjcmlwdGlvbjoKICAg
ICAgICAgICAgIyBweWxpbnQ6IGRpc2FibGUtbXNnPUUxMTAxCiAgICAgICAgICAgIHN1ZmZpeCA9
ICcgPSAiJXMiJyAlIChzZWxmLmRlc2NyaXB0aW9uLCkKICAgICAgICBlbHNlOgogICAgICAgICAg
ICBzdWZmaXggPSAnJwoKICAgICAgICAjIE5PVEUgKGdjb29wZXIpOiBpZiBlaXRoZXIgcHJlZml4
IG9yIHN1ZmZpeCBpcyBlbXB0eSwgdGhlcmUgd2lsbCBiZQogICAgICAgICMgbmFzdHkgaGVhZGlu
ZyAvIHRyYWlsaW5nIHdoaXRlc3BhY2UuIEhlbmNlLCBJIHVzZWQgKyBjb25jYXRlbmF0aW9uCiAg
ICAgICAgIyBpbnN0ZWFkIG9mICcgJy5qb2luKFsuLl0pLCBiZWNhdXNlIHRoaXMgaXMgY29uc2lk
ZXJhYmx5IGNoZWFwZXIgdG8KICAgICAgICAjIGRvIHRoYW4gJyVzJXMlcycgKGFuZCBmYXIgbGVz
cyBicmFpbmRlYWQpLi4uCiAgICAgICAgcmV0dXJuIHByZWZpeCArIHNlbGYubmFtZSArIHN1ZmZp
eAoKY2xhc3MgU3lzY3RsKEtlcm5lbFByb3BlcnR5KToKICAgICIiIiBBIGNsYXNzIGNvcnJlc3Bv
bmRpbmcgdG8gYSBrZXJuZWwgc3lzY3RsIE9JRCBwcm9wZXJ0eS4KICAgICIiIgoKY2xhc3MgVHVu
YWJsZShLZXJuZWxQcm9wZXJ0eSk6CiAgICAiIiIgQSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIGEg
a2VybmVsIHR1bmFibGUgb2JqZWN0LgogICAgIiIiCgpkZWYgbWFpbigpOgogICAgIiIiIE1haW4g
ZnVuY3Rpb24gb2YgY291cnNlLiAiIiIKCiAgICBwYXJzZXIgPSBvcHRwYXJzZS5PcHRpb25QYXJz
ZXIoKQoKICAgIHBhcnNlci5hZGRfb3B0aW9uKCctZCcsICctLXNyY2RpcicsIGRlc3Q9J3NyY2Rp
cicsIGRlZmF1bHQ9Jy91c3Ivc3JjL3N5cycsCiAgICAgICAgICAgICAgICAgICAgICBoZWxwPSgn
c291cmNlIGRpcmVjdG9yeSB0byBsb29rIGZvciBzeXNjdGxzIGFuZCAnCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAndHVuYWJsZXMgaW4nKSkKCiAgICAjCiAgICAjIFhYWCAoZ2Nvb3Blcik6
IHRoaXMgaXMgbW9yZSBkaWZmaWN1bHQgdG8gZG8gYXMgdGhlIGRlc2NyaXB0aW9ucwogICAgIyB0
aGVtc2VsdmVzIHNwYW4gbXVsdGlwbGUgbGluZXMuIE5lZWRsZXNzIHRvIHNheSwgaXQncyBhIE9y
bGFuZG8gQmxvb20taW5nCiAgICAjIHBhcnNpbmcgbWVzcy4uLgogICAgIwogICAgI3BhcnNlci5h
ZGRfb3B0aW9uKCctcycsICctLXN5c2N0bCcsIGRlc3Q9J3BhcnNlX3N5c2N0bHMnLCBkZWZhdWx0
PUZhbHNlLAogICAgIyAgICAgICAgICAgICAgICAgIGFjdGlvbj0nc3RvcmVfdHJ1ZScsCiAgICAj
ICAgICAgICAgICAgICAgICAgaGVscD0nbG9vayBmb3Igc3lzY3RscyBPSURzJykKCiAgICBwYXJz
ZXIuYWRkX29wdGlvbignLXQnLCAnLS10dW5hYmxlJywgZGVzdD0ncGFyc2VfdHVuYWJsZXMnLCBk
ZWZhdWx0PUZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgYWN0aW9uPSdzdG9yZV90cnVlJywK
ICAgICAgICAgICAgICAgICAgICAgIGhlbHA9J2xvb2sgZm9yIHR1bmFibGVzJykKCiAgICBwYXJz
ZXIuYWRkX29wdGlvbignLXYnLCAnLS12ZXJib3NlJywgZGVzdD0ndmVyYm9zZScsIGRlZmF1bHQ9
RmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICBhY3Rpb249J3N0b3JlX3RydWUnLAogICAgICAg
ICAgICAgICAgICAgICAgaGVscD0naW5jbHVkZSBmaWxlL2xpbmUgcmVzdWx0cyBmb3IgdHVuYWJs
ZXMuJykKCiAgICBvcHRzLCBfXyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKCiAgICBra25vYnMgPSAw
CgogICAgIyBYWFggKGdhcnJjb29wKTogc3lzY3RsIHBhcnNpbmcncyBhIHBhaW4gLS0gc28gaXQn
cyBkaXNhYmxlZC4uLgogICAgIyBTZWUgYWJvdmUgY29tbWVudC4KICAgIGtrbm9icyA9IFBBUlNF
X1RVTkFCTEVTCiAgICAjCiAgICAjaWYgb3B0cy5wYXJzZV9zeXNjdGxzOgogICAgIyAgICBra25v
YnMgfD0gUEFSU0VfU1lTQ1RMUwogICAgI2lmIG9wdHMucGFyc2VfdHVuYWJsZXM6CiAgICAjICAg
IGtrbm9icyB8PSBQQVJTRV9UVU5BQkxFUwogICAgIwogICAgI2lmIG5vdCBra25vYnM6CiAgICAj
ICAgIGtrbm9icyA9IFBBUlNFX1NZU0NUTFMKICAgIAogCiAgICBzeXNjdGxzLCB0dW5hYmxlcyA9
IGNvbWJfdHJlZV9mb3Jfa2VybmVsX29iamVjdHMob3B0cy5zcmNkaXIsCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VybmVsX2tub2JzPWtrbm9i
cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2
ZXJib3NlX2luZm89b3B0cy52ZXJib3NlLCkKCiAgICBpZiBzeXNjdGxzOgogICAgICAgIHByaW50
ICdcbicuam9pbihbICdTeXNjdGxzOicgXSArIG1hcChzdHIsIHN5c2N0bHMpKQoKICAgIGlmIHR1
bmFibGVzOgogICAgICAgIHByaW50ICdcbicuam9pbihbICdUdW5hYmxlczonIF0gKyBtYXAoc3Ry
LCB0dW5hYmxlcykpCgpkZWYgY29tYl90cmVlX2Zvcl9rZXJuZWxfb2JqZWN0cyhzcmNkaXIsIGtl
cm5lbF9rbm9icywgdmVyYm9zZV9pbmZvPUZhbHNlKToKICAgICIiIiBDb21iIGEgdHJlZSBsb29r
aW5nIGZvciBrZXJuZWwgdHVuYWJsZXMgaW4gZmlsZXMgdW5kZXIgc3JjZGlyLgoKICAgIC0gUmV0
dXJucyBhIGxpc3Qgb2YgVHVuYWJsZSBvYmplY3RzIGZvdW5kIGluIHNyY2Rpci4KICAgIC0gVGhl
IGZpbGUgYW5kIGxpbmUgbnVtYmVyIHRoZSB0dW5hYmxlIHdhcyBmb3VuZCBvbiB3aWxsIGJlIHNh
dmVkIHdoZW4KICAgICAgdmVyYm9zZV9pbmZvIGlzIHNldCB0byBUcnVlLiBTZWUgdGhlIFR1bmFi
bGUgY2xhc3MgZm9yIG1vcmUKICAgICAgZGV0YWlscy4KICAgICIiIgoKICAgIHN5c2N0bHMgPSBb
XQogICAgdHVuYWJsZXMgPSBbXQoKICAgICMgRG9pbmcgdGhpcyBtYWtlcyByZWxwYXRoIGNvbnNp
ZGVyYWJseSBzaW1wbGVyIGFuZCBjbGVhbmVyIHRoYW4gZG9pbmcgaXQKICAgICMgaW5zaWRlIHRo
ZSBsb29wLgogICAgb3MuY2hkaXIoc3JjZGlyKQoKICAgIGZvciByb290LCBfXywgZmlsZXMgaW4g
b3Mud2FsayhzcmNkaXIpOgoKICAgICAgICBmb3IgX2ZpbGUgaW4gZmlsZXM6CgogICAgICAgICAg
ICBfZmlsZSA9IG9zLnBhdGgucmVscGF0aChvcy5wYXRoLmpvaW4ocm9vdCwgX2ZpbGUpKQogICAg
ICAgICAgICBfc3lzY3RscywgX3R1bmFibGVzID0gcGFyc2Vfa2VybmVsX29iamVjdHMoX2ZpbGUs
IGtlcm5lbF9rbm9icywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIHZlcmJvc2VfaW5mbykKICAgICAgICAgICAgc3lzY3Rscy5leHRlbmQoX3N5
c2N0bHMpCiAgICAgICAgICAgIHR1bmFibGVzLmV4dGVuZChfdHVuYWJsZXMpCgogICAgcmV0dXJu
IHN5c2N0bHMsIHR1bmFibGVzCgpkZWYgcGFyc2Vfa2VybmVsX29iamVjdHMoX2ZpbGUsIGtlcm5l
bF9rbm9icywgdmVyYm9zZV9pbmZvPUZhbHNlKToKICAgICIiIiBDb21iIGEgdHJlZSBsb29raW5n
IGZvciBrZXJuZWwgdHVuYWJsZXMuCgogICAgLSBSZXR1cm5zIGEgdHVwbGUgb2YgbGlzdHMgY29u
dGFpbmluZyBTeXNjdGwgYW5kIFR1bmFibGUgb2JqZWN0cwogICAgICBmb3VuZCBpbiBfZmlsZS4K
ICAgIC0gVGhlIGZpbGUgYW5kIGxpbmUgbnVtYmVyIHRoZSB0dW5hYmxlIHdhcyBmb3VuZCBvbiB3
aWxsIGJlIHNhdmVkIHdoZW4KICAgICAgdmVyYm9zZV9pbmZvIGlzIHNldCB0byBUcnVlLiBTZWUg
dGhlIEtlcm5lbFByb3BlcnR5IGNsYXNzIGZvciBtb3JlCiAgICAgIGRldGFpbHMuCiAgICAiIiIK
CiAgICBrd2FyZ3MgPSB7IH0KICAgIHN5c2N0bHMgPSBbXQogICAgdHVuYWJsZXMgPSBbXQoKICAg
IHBhcnNlX3N5c2N0bHMgPSBrZXJuZWxfa25vYnMgJiBQQVJTRV9TWVNDVExTCiAgICBwYXJzZV90
dW5hYmxlcyA9IGtlcm5lbF9rbm9icyAmIFBBUlNFX1RVTkFCTEVTCgogICAgaWYgbm90IChwYXJz
ZV9zeXNjdGxzIG9yIHBhcnNlX3R1bmFibGVzKToKICAgICAgICAjIE5lZWRzIHRvIGJlIGFuIGlu
Y2x1c2l2ZSBvciBvZiBQQVJTRV9TWVNDVExTLCBQQVJTRV9UVU5BQkxFUywgb3IgYQogICAgICAg
ICMgY29tYmluYXRpb24gb2YgdGhlIHR3byBrbm9icy4KICAgICAgICByYWlzZSBWYWx1ZUVycm9y
KCdpbnZhbGlkIHZhbHVlIGZvciBrZXJuZWxfa25vYnM6ICVzJwogICAgICAgICAgICAgICAgICAg
ICAgICAgJSBzdHIoa2VybmVsX2tub2JzKSkKCiAgICBpZiB2ZXJib3NlX2luZm86CiAgICAgICAg
a3dhcmdzWydmaWxlJ10gPSBfZmlsZQoKICAgIGZkID0gb3BlbihfZmlsZSwgJ3InKQogICAgdHJ5
OgogICAgICAgIGxpbmVzID0gZmQucmVhZGxpbmVzKCkKICAgIGZpbmFsbHk6CiAgICAgICAgZmQu
Y2xvc2UoKQoKICAgIGt3YXJnc1snbGluZSddID0gMAoKICAgIGZvciBsaW5lIGluIGxpbmVzOgoK
ICAgICAgICBrd2FyZ3NbJ2xpbmUnXSArPSAxIAoKICAgICAgICBpZiBwYXJzZV90dW5hYmxlczoK
ICAgICAgICAgICAgbWF0Y2ggPSBUVU5BQkxFX1JFLm1hdGNoKGxpbmUpCiAgICAgICAgZWxzZToK
ICAgICAgICAgICAgbWF0Y2ggPSBOb25lCgogICAgICAgIGlmIG1hdGNoOgogICAgICAgICAgICB0
dW5hYmxlcy5hcHBlbmQoVHVuYWJsZShtYXRjaC5ncm91cCgxKSwgKiprd2FyZ3MpKQogICAgICAg
IGVsaWYgcGFyc2Vfc3lzY3RsczoKICAgICAgICAgICAgbWF0Y2ggPSBTWVNDVExfUkUubWF0Y2go
bGluZSkKICAgICAgICAgICAgaWYgbWF0Y2g6CiAgICAgICAgICAgICAgICBzeXNjdGxzLmFwcGVu
ZChTeXNjdGwobWF0Y2guZ3JvdXAoMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgZGVzY3JpcHRpb249bWF0Y2guZ3JvdXAoMiksICoqa3dhcmdzKSkKCiAgICByZXR1cm4g
c3lzY3RscywgdHVuYWJsZXMKCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICBtYWluKCkK
--0016e64b970e381515047ed0dc7b--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?364299f41002041803m60604979n1f2534e8d5e20af0>