From patchwork Wed Nov 4 07:03:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 83653 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 88A14A04E7; Wed, 4 Nov 2020 08:04:14 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E1A8AC7F2; Wed, 4 Nov 2020 08:03:58 +0100 (CET) Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) by dpdk.org (Postfix) with ESMTP id 477ACC7EC for ; Wed, 4 Nov 2020 08:03:56 +0100 (CET) Received: by mail-pg1-f170.google.com with SMTP id h6so15786250pgk.4 for ; Tue, 03 Nov 2020 23:03:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e62eUSfYVM32CBxr7qEPtl3Cg2KA1jl/r9oJeSqgJeo=; b=yztRbIpC33wqAhWJa7qw1G1wbU4ZnmAg2Tn8jNJw9v+jOiLfImg6hQ+GcaSBQaUBqP FnbhlZb7X1oUsqUR3VrFsPTVqaMyggYam9idQXH850sMvZwAic5Bzqk+enQURuFJg4iA KTevxNpxJALWRQkX9vrp8glYzPbK0x/nia/mn9414Sa2mK4ZJm0g0gZDb042eD2fT0iM aGrQZDz7GtnL3e3wxe5QMMit1XwKnPYlUZ8PuVCytk4mSkTIGkFTsTZxpsQFN/Sdg5Xi a5X9MEFpe6QFv/AUof0VP7cizF9wBbDLryOiCScyhPcacysC5fNlljwmDT45WeNAy1g2 3cTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e62eUSfYVM32CBxr7qEPtl3Cg2KA1jl/r9oJeSqgJeo=; b=QMUIengqwK8ZAykbeB+BqxUrU6RNGsFPYWlf1fttd4DomhhBLprfGPsThO0dGm88bs xnCso5Mv3C6H5MHQ5dPnuNBdj6C0PcAa77d/cnSPbIgDQLmOpI13hlKvGVg0mqeL3tcY 3gnDlj9MpXtFIDYCF0vqploJsk+cXNZEG/3xgAMcGNKVPCN8TT3xukky67fQ6vybVx7z WHIv1QkDizgTJ/yWEEu62B0lluNzE0fr6PJN5fRHePHu1tOjCEdRBSjx6kV2M2a6Iilk BTpahk7xmzlkUVTiQ7aB2vOF1xfxDHslrPRWCOuPVezZsZEJM6YeOGh25KhZVxSr1oHI zFag== X-Gm-Message-State: AOAM531HL6V+LHODqhOJNWhVikKTbO+HnCMzjItfdKMBsZsi/+GIQ6Wc iusPluKwVl8tHIE78zAGPvyzutm3enTMMLri X-Google-Smtp-Source: ABdhPJwmiz85hl7Ycw/JqSGMIL+vu7fSSKs5+cDRziZ2dNZaZnjfvFa7yGiF+P/funzV79MwlL2BUw== X-Received: by 2002:a63:f445:: with SMTP id p5mr19928168pgk.293.1604473433899; Tue, 03 Nov 2020 23:03:53 -0800 (PST) Received: from hermes.corp.microsoft.com (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id z21sm1181177pfa.158.2020.11.03.23.03.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Nov 2020 23:03:53 -0800 (PST) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Date: Tue, 3 Nov 2020 23:03:45 -0800 Message-Id: <20201104070350.28224-2-stephen@networkplumber.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201104070350.28224-1-stephen@networkplumber.org> References: <20200906013133.26360-12-stephen@networkplumber.org> <20201104070350.28224-1-stephen@networkplumber.org> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 1/6] dpdk-devbind: use argparse instead of getopt X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Using the python standard argument parser instead of C library style getopt gives a number of advantages such as checking for conflicting arguments, restricting choices, and automatically generating help messages. The result is similar to the original the only visible change is that some of the help messages are now less wordy. Signed-off-by: Stephen Hemminger --- usertools/dpdk-devbind.py | 203 ++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 117 deletions(-) diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py index 99112b7ab794..e0b74c5a3e41 100755 --- a/usertools/dpdk-devbind.py +++ b/usertools/dpdk-devbind.py @@ -5,8 +5,9 @@ import sys import os -import getopt import subprocess +import argparse + from glob import glob from os.path import exists, abspath, dirname, basename from os.path import join as path_join @@ -82,82 +83,6 @@ force_flag = False args = [] - -def usage(): - '''Print usage information for the program''' - argv0 = basename(sys.argv[0]) - print(""" -Usage: ------- - - %(argv0)s [options] DEVICE1 DEVICE2 .... - -where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax -or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may -also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc. -If devices are specified using PCI bus:device:func format, then -shell wildcards and ranges may be used, e.g. 80:04.*, 80:04.[0-3] - -Options: - --help, --usage: - Display usage information and quit - - -s, --status: - Print the current status of all known network, crypto, event - and mempool devices. - For each device, it displays the PCI domain, bus, slot and function, - along with a text description of the device. Depending upon whether the - device is being used by a kernel driver, the igb_uio driver, or no - driver, other relevant information will be displayed: - * the Linux interface name e.g. if=eth0 - * the driver being used e.g. drv=igb_uio - * any suitable drivers not currently using that device - e.g. unused=igb_uio - NOTE: if this flag is passed along with a bind/unbind option, the - status display will always occur after the other operations have taken - place. - - --status-dev: - Print the status of given device group. Supported device groups are: - "net", "baseband", "crypto", "event", "mempool" and "compress" - - -b driver, --bind=driver: - Select the driver to use or \"none\" to unbind the device - - -u, --unbind: - Unbind a device (Equivalent to \"-b none\") - - --force: - By default, network devices which are used by Linux - as indicated by - having routes in the routing table - cannot be modified. Using the - --force flag overrides this behavior, allowing active links to be - forcibly unbound. - WARNING: This can lead to loss of network connection and should be used - with caution. - -Examples: ---------- - -To display current device status: - %(argv0)s --status - -To display current network device status: - %(argv0)s --status-dev net - -To bind eth1 from the current driver and move to use igb_uio - %(argv0)s --bind=igb_uio eth1 - -To unbind 0000:01:00.0 from using any driver - %(argv0)s -u 0000:01:00.0 - -To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver - %(argv0)s -b ixgbe 02:00.0 02:00.1 - -To bind all functions on device 0000:02:00 to ixgbe kernel driver - %(argv0)s -b ixgbe 02:00.* - - """ % locals()) # replace items from local variables - # check if a specific kernel module is loaded def module_is_loaded(module): global loaded_modules @@ -677,38 +602,93 @@ def parse_args(): global status_dev global force_flag global args - if len(sys.argv) <= 1: - usage() - sys.exit(0) - try: - opts, args = getopt.getopt(sys.argv[1:], "b:us", - ["help", "usage", "status", "status-dev=", - "force", "bind=", "unbind", ]) - except getopt.GetoptError as error: - print(str(error)) - print("Run '%s --usage' for further information" % sys.argv[0]) + parser = argparse.ArgumentParser( + description='Utility to bind and unbind devices from Linux kernel', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: +--------- + +To display current device status: + %(prog)s --status + +To display current network device status: + %(prog)s --status-dev net + +To bind eth1 from the current driver and move to use vfio-pci + %(prog)s --bind=vfio-pci eth1 + +To unbind 0000:01:00.0 from using any driver + %(prog)s -u 0000:01:00.0 + +To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver + %(prog)s -b ixgbe 02:00.0 02:00.1 +""") + + parser.add_argument( + '-s', + '--status', + action='store_true', + help="Print the current status of all known devices.") + parser.add_argument( + '--status-dev', + help="Print the status of given device group.", + choices=['net', 'baseband', 'crypto', 'event', 'mempool', 'compress']) + bind_group = parser.add_mutually_exclusive_group() + bind_group.add_argument( + '-b', + '--bind', + metavar='DRIVER', + help="Select the driver to use or \"none\" to unbind the device") + bind_group.add_argument( + '-u', + '--unbind', + action='store_true', + help="Unbind a device (equivalent to \"-b none\")") + parser.add_argument( + '--force', + action='store_true', + help=""" +Override restriction on binding devices in use by Linux" +WARNING: This can lead to loss of network connection and should be used with caution. +""") + parser.add_argument( + 'devices', + metavar='DEVICE', + nargs='*', + help=""" +Device specified as PCI "domain:bus:slot.func" syntax or "bus:slot.func" syntax. +For devices bound to Linux kernel drivers, they may be referred to by interface name. +""") + + opt = parser.parse_args() + + if opt.status_dev: + status_flag = True + status_dev = opt.status_dev + if opt.status: + status_flag = True + status_dev = "all" + if opt.force: + force_flag = True + if opt.bind: + b_flag = opt.bind + elif opt.unbind: + b_flag = "none" + args = opt.devices + + if not b_flag and not status_flag: + print("Error: No action specified for devices. " + "Please give a --bind, --ubind or --status option", + file=sys.stderr) + parser.print_usage() sys.exit(1) - for opt, arg in opts: - if opt == "--help" or opt == "--usage": - usage() - sys.exit(0) - if opt == "--status-dev": - status_flag = True - status_dev = arg - if opt == "--status" or opt == "-s": - status_flag = True - status_dev = "all" - if opt == "--force": - force_flag = True - if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind": - if b_flag is not None: - sys.exit("Error: binding and unbinding are mutually exclusive") - if opt == "-u" or opt == "--unbind": - b_flag = "none" - else: - b_flag = arg + if b_flag and not args: + print("Error: No devices specified.", file=sys.stderr) + parser.print_usage() + sys.exit(1) # resolve any PCI globs in the args new_args = [] @@ -723,17 +703,6 @@ def do_arg_actions(): global force_flag global args - if b_flag is None and not status_flag: - print("Error: No action specified for devices. " - "Please give a -b or -u option", file=sys.stderr) - usage() - sys.exit(1) - - if b_flag is not None and len(args) == 0: - print("Error: No devices specified.", file=sys.stderr) - usage() - sys.exit(1) - if b_flag == "none" or b_flag == "None": unbind_all(args, force_flag) elif b_flag is not None: