From patchwork Tue Jul 18 12:48:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Ga=C3=ABtan_Rivet?= X-Patchwork-Id: 27024 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 2203F7CB4; Tue, 18 Jul 2017 14:48:56 +0200 (CEST) Received: from mail-wr0-f178.google.com (mail-wr0-f178.google.com [209.85.128.178]) by dpdk.org (Postfix) with ESMTP id 984A258F6 for ; Tue, 18 Jul 2017 14:48:44 +0200 (CEST) Received: by mail-wr0-f178.google.com with SMTP id y43so27864313wrd.3 for ; Tue, 18 Jul 2017 05:48:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=fH9HD3QsGjVMAapAToHyc8VnmFDaB80FJSiNWnWpsK0=; b=zpGLZYGfyLXGUmGg4tvzyMtJ7PMQwZluADqVf/6u2ptKgHUjohtY8m/hyuaYh/j3uL jJcQyB6MWTyQwtURt7prfE+FklVAHaBcRU5OVpvX4mrA80+0TzyNGpZcchYg3q2gHuvL 72aXGIK63aIZBBfBfL2HPW/LMqZGAkhEOuIndSK4iBEAk09dryrF0IVo76OnD3y9+oGT O8eTMAmP0rgRmpV4c5mCD8vJz4DqCeD2w8aZDe089ko2Ifj0qHrjeAKhjPqTN07aYubm SvuwHRROEgOZTSTa8WTTdWG43JcK98T1N98QZl4476Vb61iHDrPdHN4qJ2++LvoYBw/m M1Rg== 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:in-reply-to:references; bh=fH9HD3QsGjVMAapAToHyc8VnmFDaB80FJSiNWnWpsK0=; b=Ur9n4yQEyzb1L4LJ+5v595pTjgG8s7GCqRzU1ZdTcXr4TQBUNsaR3Sm4OgxIPsYGsp 5Scx13j7f0ErDUcXIB+OCihku7Lwf0U+uAQ8Sq3Vs/CeMzNgLqWfiNTrLl7Os6KjsUHr F8iX58c54LINAr725DXH5F3z0uK8yIvSXgyDQDhoE35kp/z7zLlNjtLBfWpjysPcfCxz Eny+m3N2v0haakdrCPs3Pys82cMLRvELDjZn3oKHqOPSU+paBiEo50bKpoxcCW2Ued5Z Tz+4dsmBgMchWGKpjNtlkh7Lk2NIJHcxZG3TdkczPwzZbIpgrb97v3TkbtoNs5/Q/hyi i10w== X-Gm-Message-State: AIVw11180VbUnmpsrlIXin6iJLtCN8mS8JitSZyxgO4tv7EyEeXGH4BR 3W15AJXPD0+HdMztrz4= X-Received: by 10.28.174.204 with SMTP id x195mr1383300wme.116.1500382123731; Tue, 18 Jul 2017 05:48:43 -0700 (PDT) Received: from bidouze.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id j8sm1033960wrj.10.2017.07.18.05.48.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Jul 2017 05:48:43 -0700 (PDT) From: Gaetan Rivet To: dev@dpdk.org Cc: Gaetan Rivet Date: Tue, 18 Jul 2017 14:48:16 +0200 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v11 05/11] net/failsafe: add flexible device definition 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" Add the "exec" device type. The parameters given to this type of device will be executed in a shell. The output of this command is then used as a definition for a device. That command can be re-interpreted if the related device is not plugged-in. It allows for a device definition to react to system changes (e.g. changing PCI bus for a given device). Signed-off-by: Gaetan Rivet Acked-by: Olga Shern --- doc/guides/nics/fail_safe.rst | 20 +++++++ drivers/net/failsafe/failsafe_args.c | 98 ++++++++++++++++++++++++++++++++- drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/fail_safe.rst b/doc/guides/nics/fail_safe.rst index 0005892..c81f06a 100644 --- a/doc/guides/nics/fail_safe.rst +++ b/doc/guides/nics/fail_safe.rst @@ -87,6 +87,19 @@ Fail-safe command line parameters additional sub-device parameters if need be. They will be passed on to the sub-device. +- **exec()** parameter + + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. + - **mac** parameter [MAC address] This parameter allows the user to set a default MAC address to the fail-safe @@ -134,6 +147,13 @@ This section shows some example of using **testpmd** with a fail-safe PMD. --vdev 'net_failsafe0,mac=de:ad:be:ef:01:02,dev(84:00.0),dev(net_ring0)' -w 81:00.0 -- -i +#. Start testpmd using a flexible device definition + + .. code-block:: console + + $RTE_TARGET/build/app/testpmd -c 0xff -n 4 --no-pci \ + --vdev='net_failsafe0,exec(echo 84:00.0)' -- -i + Using the Fail-safe PMD from an application ------------------------------------------- diff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c index 733344e..ec3db55 100644 --- a/drivers/net/failsafe/failsafe_args.c +++ b/drivers/net/failsafe/failsafe_args.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -97,6 +98,72 @@ fs_parse_device(struct sub_device *sdev, char *args) return 0; } +static void +fs_sanitize_cmdline(char *args) +{ + size_t len; + + len = strnlen(args, DEVARGS_MAXLEN); + args[len - 1] = '\0'; +} + +static int +fs_execute_cmd(struct sub_device *sdev, char *cmdline) +{ + FILE *fp; + /* store possible newline as well */ + char output[DEVARGS_MAXLEN + 1]; + size_t len; + int old_err; + int ret; + + RTE_ASSERT(cmdline != NULL || sdev->cmdline != NULL); + if (sdev->cmdline == NULL) { + size_t i; + + len = strlen(cmdline) + 1; + sdev->cmdline = calloc(1, len); + if (sdev->cmdline == NULL) { + ERROR("Command line allocation failed"); + return -ENOMEM; + } + snprintf(sdev->cmdline, len, "%s", cmdline); + /* Replace all commas in the command line by spaces */ + for (i = 0; i < len; i++) + if (sdev->cmdline[i] == ',') + sdev->cmdline[i] = ' '; + } + DEBUG("'%s'", sdev->cmdline); + old_err = errno; + fp = popen(sdev->cmdline, "r"); + if (fp == NULL) { + ret = errno; + ERROR("popen: %s", strerror(errno)); + errno = old_err; + return ret; + } + /* We only read one line */ + if (fgets(output, sizeof(output) - 1, fp) == NULL) { + DEBUG("Could not read command output"); + return -ENODEV; + } + fs_sanitize_cmdline(output); + ret = fs_parse_device(sdev, output); + if (ret) { + ERROR("Parsing device '%s' failed", output); + goto ret_pclose; + } +ret_pclose: + ret = pclose(fp); + if (ret) { + ret = errno; + ERROR("pclose: %s", strerror(errno)); + errno = old_err; + return ret; + } + return ret; +} + static int fs_parse_device_param(struct rte_eth_dev *dev, const char *param, uint8_t head) @@ -131,6 +198,14 @@ fs_parse_device_param(struct rte_eth_dev *dev, const char *param, ret = fs_parse_device(sdev, args); if (ret) goto free_args; + } else if (strncmp(param, "exec", 4) == 0) { + ret = fs_execute_cmd(sdev, args); + if (ret == -ENODEV) { + DEBUG("Reading device info from command line failed"); + ret = 0; + } + if (ret) + goto free_args; } else { ERROR("Unrecognized device type: %.*s", (int)b, param); return -EINVAL; @@ -328,6 +403,8 @@ failsafe_args_free(struct rte_eth_dev *dev) uint8_t i; FOREACH_SUBDEV(sdev, i, dev) { + rte_free(sdev->cmdline); + sdev->cmdline = NULL; free(sdev->devargs.args); sdev->devargs.args = NULL; } @@ -342,7 +419,8 @@ fs_count_device(struct rte_eth_dev *dev, const char *param, while (param[b] != '(' && param[b] != '\0') b++; - if (strncmp(param, "dev", b) != 0) { + if (strncmp(param, "dev", b) != 0 && + strncmp(param, "exec", b) != 0) { ERROR("Unrecognized device type: %.*s", (int)b, param); return -EINVAL; } @@ -357,3 +435,21 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, return fs_parse_sub_devices(fs_count_device, dev, params); } + +int +failsafe_args_parse_subs(struct rte_eth_dev *dev) +{ + struct sub_device *sdev; + uint8_t i; + int ret = 0; + + FOREACH_SUBDEV(sdev, i, dev) { + if (sdev->state >= DEV_PARSED) + continue; + if (sdev->cmdline) + ret = fs_execute_cmd(sdev, sdev->cmdline); + if (ret == 0) + sdev->state = DEV_PARSED; + } + return 0; +} diff --git a/drivers/net/failsafe/failsafe_ether.c b/drivers/net/failsafe/failsafe_ether.c index 7910952..2a1535e 100644 --- a/drivers/net/failsafe/failsafe_ether.c +++ b/drivers/net/failsafe/failsafe_ether.c @@ -188,6 +188,13 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev) int ret; uint8_t i; + if (PRIV(dev)->state < DEV_PARSED) + return 0; + + ret = failsafe_args_parse_subs(dev); + if (ret) + return ret; + if (PRIV(dev)->state < DEV_PROBED) return 0; ret = failsafe_eal_init(dev); diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h index a46d1ea..2342646 100644 --- a/drivers/net/failsafe/failsafe_private.h +++ b/drivers/net/failsafe/failsafe_private.h @@ -44,6 +44,7 @@ #define PMD_FAILSAFE_HOTPLUG_POLL_KVARG "hotplug_poll" #define PMD_FAILSAFE_PARAM_STRING \ "dev()," \ + "exec()," \ "mac=mac_addr," \ "hotplug_poll=u64" \ "" @@ -87,6 +88,8 @@ struct sub_device { struct rte_eth_dev *edev; /* Device state machine */ enum dev_state state; + /* Some device are defined as a command line */ + char *cmdline; }; struct fs_priv { @@ -135,6 +138,7 @@ uint16_t failsafe_tx_burst(void *txq, int failsafe_args_parse(struct rte_eth_dev *dev, const char *params); void failsafe_args_free(struct rte_eth_dev *dev); int failsafe_args_count_subdevice(struct rte_eth_dev *dev, const char *params); +int failsafe_args_parse_subs(struct rte_eth_dev *dev); /* EAL */