From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f176.google.com (mail-wr0-f176.google.com [209.85.128.176]) by dpdk.org (Postfix) with ESMTP id 5B86BF970 for ; Fri, 3 Mar 2017 16:40:53 +0100 (CET) Received: by mail-wr0-f176.google.com with SMTP id g10so76179681wrg.2 for ; Fri, 03 Mar 2017 07:40:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=NGwBvm+V93DrpgyJfpMbCQ9Ra7pdiMJKRV1HMaWiC1U=; b=DiI6BkI9s8tLb/piR8k27RU1+G0cMGc4l8mGVFzn4eCgvDF/Q09EuDAssZOPH4Z/Ue JLEzAm3PtlgP6hqAX2w7SFPPgGmbx+b2Cv5PgCz4YidSuFVP7tccju54VFOrZIo1d0KV EvK9HEvnqzPopzgKUCJDIh319eFilFON4JYqbsVaZ8/V2wgQdHziEX5+bPN+JLMgkU7l 2wN7DVCTZn7C0aPz+4E3rT+6T+vPQSbEoqXoDeuIwr0mbSksUEwh1Dzlvmp/41yeUX9x zjNUU9NF9bIkySf0qOHP+ez2e3v+8RX6s9DRD7ct9sW2LgAa4mD5BUnVvpGEg1Zf16BZ kQ/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=NGwBvm+V93DrpgyJfpMbCQ9Ra7pdiMJKRV1HMaWiC1U=; b=Id7ckxFBEJgtx/XEiNn0plRjtyMgfM4DXMS0tldf8GNa7nKv5+fhsHew+NCTiiARMb Hkh4UHFpdE1uKKBWNRMyDG3FqAvr9xj1MF2SIRRJZMZr73CWHiD6cJTEKUbdvpkL+yKy VRfQkkJyKB2zpKTMqz7TLNfJL8tS9ldjm3xj+d4kox36sEOHe2J+CuNihoZzmRPsOpQ+ neyz+ib8HlG7Bs6PvG6fGNZAClYFLBqwE9RfGiZYjwFHWkmoJ0/iPbU2PvsM0OaZwOfl 3qQh+SDgMBzZQkmza7IewlihTIKXV1k3VB5i4P3Fma6ejXOvuJkTGyFxebz3oAnKm7HJ nDfg== X-Gm-Message-State: AMke39nhKhE3BP7VUjxRZVUyLABgQuRh3si2q4+VOv+K1gUfUYK339HHyxhJNLWLTrz9GWJm X-Received: by 10.223.166.7 with SMTP id k7mr3020179wrc.52.1488555651459; Fri, 03 Mar 2017 07:40:51 -0800 (PST) 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 63sm3486280wmp.9.2017.03.03.07.40.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Mar 2017 07:40:51 -0800 (PST) From: Gaetan Rivet To: dev@dpdk.org Date: Fri, 3 Mar 2017 16:40:30 +0100 Message-Id: <9e230b6fec17e05d004184accd10dbc9f50976ca.1488550982.git.gaetan.rivet@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: Subject: [dpdk-dev] [PATCH 08/12] 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: , X-List-Received-Date: Fri, 03 Mar 2017 15:40:53 -0000 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 --- drivers/net/failsafe/failsafe_args.c | 102 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 3 files changed, 113 insertions(+) diff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c index 773b322..839831f 100644 --- a/drivers/net/failsafe/failsafe_args.c +++ b/drivers/net/failsafe/failsafe_args.c @@ -112,6 +112,80 @@ parse_device(struct sub_device *sdev, char *args) return 0; } +static void +sanitize_cmdline(char *args) +{ + size_t len; + + len = strnlen(args, DEVARGS_MAXLEN); + args[len - 1] = '\0'; +} + +static int +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; + + DEBUG("'%s'", cmdline); + if (cmdline == NULL && + sdev->cmdline == NULL) { + /* debug: should never happen to a user */ + DEBUG("Invalid command line"); + return -EINVAL; + } + if (sdev->cmdline == NULL) { + char *new_str; + + len = strlen(cmdline) + 1; + new_str = rte_realloc(sdev->cmdline, len, + RTE_CACHE_LINE_SIZE); + if (new_str == NULL) { + ERROR("Command line allocation failed"); + return -ENOMEM; + } + sdev->cmdline = new_str; + snprintf(sdev->cmdline, len, "%s", cmdline); + } else { + if (strcmp(sdev->cmdline, cmdline)) + DEBUG("cmd mismatch: '%s' != '%s'", + sdev->cmdline, cmdline); + cmdline = sdev->cmdline; + } + old_err = errno; + fp = popen(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; + } + sanitize_cmdline(output); + ret = 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 parse_device_param(struct rte_eth_dev *dev, const char *param, uint8_t head) @@ -146,6 +220,14 @@ parse_device_param(struct rte_eth_dev *dev, const char *param, ret = parse_device(sdev, args); if (ret) goto free_args; + } else if (strncmp(param, "exec", 4) == 0) { + ret = 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; @@ -347,6 +429,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; } @@ -377,3 +461,21 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, return parse_sub_devices(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 = 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 9f4a0a0..2d90bcb 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 8659c6f..c1aa24d 100644 --- a/drivers/net/failsafe/failsafe_private.h +++ b/drivers/net/failsafe/failsafe_private.h @@ -94,6 +94,9 @@ struct sub_device { struct rte_eth_dev_data data; /* Device state machine */ enum dev_state state; + + /* Some device are defined as a command line */ + char *cmdline; }; struct fs_priv { @@ -140,6 +143,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 */ -- 2.1.4