From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.5 required=3.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_MUTT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1C1DC282D7 for ; Sat, 2 Feb 2019 16:08:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7E79E20857 for ; Sat, 2 Feb 2019 16:08:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="fcYt/aGq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728195AbfBBQIp (ORCPT ); Sat, 2 Feb 2019 11:08:45 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:33179 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727843AbfBBQIp (ORCPT ); Sat, 2 Feb 2019 11:08:45 -0500 Received: by mail-wm1-f67.google.com with SMTP id r24so6749543wmh.0 for ; Sat, 02 Feb 2019 08:08:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=NJwNXhBQKNJZy4BWeepTYDimaIm19qi+ssW16uOjt/c=; b=fcYt/aGqY1yxB/WqBJix21FER2quFAaBJW2xDShJdHi8HR1n3O6+ikNtL5blozd+u1 EC0zGDUsRhnFsPCFAPrCpiuM0A42131W3aFIXVdft5H0xp/FdNBq0cysdIPlBXs3UZ6Q QuCbZacMojEZWincRjFQ/p0Pa5uk+5k1OvYnPo+rQOUi42gPqGCfu6+IdwJ3wvvtfjRp q4+9Gc0BoiQMmpwvNFWzrzQwd4s4+BIrXKWjdS6kAMDj9HmZOFyCv+JIan5ED3bz/DE7 seOVmgzlp3a9V7HZMtCoqJUBPMFO5KBbyJOyiX+wbxHYVFAPYQm2sDi2XTNSFZ84hXFX jNcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=NJwNXhBQKNJZy4BWeepTYDimaIm19qi+ssW16uOjt/c=; b=ttbrsNBKJ64kghG0m65xqLbk/EcySFUAIYY5VU6WZAevFJgVVhukQuLXOlPPBA+oQI uYYZ5iMBcKdwDVXFB/Qgswf6X9A5LF2aaSYLNiF1VdDMzJ6wD4Eec27br7O9ld+snIE5 nfLwh4bmE8FRXGOxfdODhIGohoGqEmDfo+UobtVJ5H9n+gPqkZOnoxRlk0KSuTE+yt/J g1PW9ipD0ZapyUfmaTRYKWt+Spy9ZP49WnTc0hsUIDrQbA7pVSpTz/Tr12Q98uRyKFRN sfGJpDV5hkkqr00FXmZ68SWpq4UU3Ex90lfXh+fXKciien2/DRv+Dj8bXmMM6w/6df5L yyiA== X-Gm-Message-State: AHQUAuYRbirThI4OmyqEqkQuMF1pCJeTx+WX7q1o0poNBqo52o/4YweX MmPfGnl2rPz3cdIbJUnZuTz/4g== X-Google-Smtp-Source: AHgI3IbOwHCgiULpKCOboz9eMg3CO+9DKHWKMRRUuNlRl0U4o5QPSCEmaGE8FhiAyBfgJwkz7yoAtw== X-Received: by 2002:a1c:c181:: with SMTP id r123mr6800533wmf.8.1549123722583; Sat, 02 Feb 2019 08:08:42 -0800 (PST) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id y14sm7756629wro.92.2019.02.02.08.08.41 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 02 Feb 2019 08:08:42 -0800 (PST) Date: Sat, 2 Feb 2019 16:59:38 +0100 From: Jiri Pirko To: Jakub Kicinski Cc: dsahern@gmail.com, stephen@networkplumber.org, netdev@vger.kernel.org, oss-drivers@netronome.com Subject: Re: [PATCH iproute2-next] devlink: add info subcommand Message-ID: <20190202155938.GE2778@nanopsycho> References: <20190202000338.30820-1-jakub.kicinski@netronome.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190202000338.30820-1-jakub.kicinski@netronome.com> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Sat, Feb 02, 2019 at 01:03:38AM CET, jakub.kicinski@netronome.com wrote: >Add support for reading the device serial number and versions >from the kernel. > >RFCv2: > - make info subcommand of dev. Please add some examples of inputs and outputs. > >Signed-off-by: Jakub Kicinski >--- > devlink/devlink.c | 207 +++++++++++++++++++++++++++++++++++++++++ > man/man8/devlink-dev.8 | 36 +++++++ > 2 files changed, 243 insertions(+) > >diff --git a/devlink/devlink.c b/devlink/devlink.c >index 3651e90c1159..3ab046ace8f8 100644 >--- a/devlink/devlink.c >+++ b/devlink/devlink.c >@@ -199,6 +199,7 @@ static void ifname_map_free(struct ifname_map *ifname_map) > #define DL_OPT_REGION_SNAPSHOT_ID BIT(22) > #define DL_OPT_REGION_ADDRESS BIT(23) > #define DL_OPT_REGION_LENGTH BIT(24) >+#define DL_OPT_VERSIONS_TYPE BIT(25) Why "type"? Confusing. > > struct dl_opts { > uint32_t present; /* flags of present items */ >@@ -230,6 +231,7 @@ struct dl_opts { > uint32_t region_snapshot_id; > uint64_t region_address; > uint64_t region_length; >+ int versions_attr; > }; > > struct dl { >@@ -383,6 +385,13 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = { > [DEVLINK_ATTR_REGION_CHUNK_DATA] = MNL_TYPE_BINARY, > [DEVLINK_ATTR_REGION_CHUNK_ADDR] = MNL_TYPE_U64, > [DEVLINK_ATTR_REGION_CHUNK_LEN] = MNL_TYPE_U64, >+ [DEVLINK_ATTR_INFO_DRIVER_NAME] = MNL_TYPE_STRING, >+ [DEVLINK_ATTR_INFO_SERIAL_NUMBER] = MNL_TYPE_STRING, >+ [DEVLINK_ATTR_INFO_VERSION_FIXED] = MNL_TYPE_NESTED, >+ [DEVLINK_ATTR_INFO_VERSION_RUNNING] = MNL_TYPE_NESTED, >+ [DEVLINK_ATTR_INFO_VERSION_STORED] = MNL_TYPE_NESTED, >+ [DEVLINK_ATTR_INFO_VERSION_NAME] = MNL_TYPE_STRING, >+ [DEVLINK_ATTR_INFO_VERSION_VALUE] = MNL_TYPE_STRING, > }; > > static int attr_cb(const struct nlattr *attr, void *data) >@@ -943,6 +952,21 @@ static int param_cmode_get(const char *cmodestr, > return 0; > } > >+static int versions_type_get(const char *typestr, int *p_attr) >+{ >+ if (strcmp(typestr, "fixed") == 0) { >+ *p_attr = DEVLINK_ATTR_INFO_VERSION_FIXED; >+ } else if (strcmp(typestr, "stored") == 0) { >+ *p_attr = DEVLINK_ATTR_INFO_VERSION_STORED; >+ } else if (strcmp(typestr, "running") == 0) { >+ *p_attr = DEVLINK_ATTR_INFO_VERSION_RUNNING; >+ } else { >+ pr_err("Unknown versions type \"%s\"\n", typestr); >+ return -EINVAL; >+ } >+ return 0; >+} >+ > static int dl_argv_parse(struct dl *dl, uint32_t o_required, > uint32_t o_optional) > { >@@ -1178,6 +1202,19 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, > if (err) > return err; > o_found |= DL_OPT_REGION_LENGTH; >+ } else if (dl_argv_match(dl, "versions") && >+ (o_all & DL_OPT_VERSIONS_TYPE)) { >+ const char *versionstr; >+ >+ dl_arg_inc(dl); >+ err = dl_argv_str(dl, &versionstr); >+ if (err) >+ return err; >+ err = versions_type_get(versionstr, >+ &opts->versions_attr); >+ if (err) >+ return err; >+ o_found |= DL_OPT_VERSIONS_TYPE; > } else { > pr_err("Unknown option \"%s\"\n", dl_argv(dl)); > return -EINVAL; >@@ -1443,6 +1480,9 @@ static void cmd_dev_help(void) > pr_err(" devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n"); > pr_err(" devlink dev param show [DEV name PARAMETER]\n"); > pr_err(" devlink dev reload DEV\n"); >+ pr_err(" devlink dev info [ DEV [ { versions [ VTYPE ] } ] ]\n"); >+ pr_err("\n"); >+ pr_err(" VTYPE := { fixed | running | stored }\n"); So you would like to filter according to the version type? Why? > } > > static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name, >@@ -1775,6 +1815,30 @@ static void pr_out_array_end(struct dl *dl) > } > } > >+static void pr_out_object_start(struct dl *dl, const char *name) >+{ >+ if (dl->json_output) { >+ jsonw_name(dl->jw, name); >+ jsonw_start_object(dl->jw); >+ } else { >+ __pr_out_indent_inc(); >+ __pr_out_newline(); >+ pr_out("%s:", name); >+ __pr_out_indent_inc(); >+ __pr_out_newline(); >+ } >+} >+ >+static void pr_out_object_end(struct dl *dl) >+{ >+ if (dl->json_output) { >+ jsonw_end_object(dl->jw); >+ } else { >+ __pr_out_indent_dec(); >+ __pr_out_indent_dec(); >+ } >+} >+ > static void pr_out_entry_start(struct dl *dl) > { > if (dl->json_output) >@@ -2415,6 +2479,146 @@ static int cmd_dev_reload(struct dl *dl) > return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); > } > >+static void pr_out_versions_single(struct dl *dl, const struct nlmsghdr *nlh, >+ const char *name, int type) >+{ >+ struct nlattr *version; >+ >+ if (dl->opts.versions_attr && dl->opts.versions_attr != type) >+ return; >+ >+ mnl_attr_for_each(version, nlh, sizeof(struct genlmsghdr)) { >+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; >+ const char *ver_value; >+ const char *ver_name; >+ int err; >+ >+ if (mnl_attr_get_type(version) != type) >+ continue; >+ >+ err = mnl_attr_parse_nested(version, attr_cb, tb); >+ if (err != MNL_CB_OK) >+ continue; >+ >+ if (!tb[DEVLINK_ATTR_INFO_VERSION_NAME] || >+ !tb[DEVLINK_ATTR_INFO_VERSION_VALUE]) >+ continue; >+ >+ if (name) { >+ pr_out_object_start(dl, name); >+ name = NULL; >+ } >+ >+ ver_name = mnl_attr_get_str(tb[DEVLINK_ATTR_INFO_VERSION_NAME]); >+ ver_value = mnl_attr_get_str(tb[DEVLINK_ATTR_INFO_VERSION_VALUE]); >+ >+ pr_out_str(dl, ver_name, ver_value); >+ if (!dl->json_output) >+ __pr_out_newline(); >+ } >+ >+ if (!name) >+ pr_out_object_end(dl); >+} >+ >+static void pr_out_info(struct dl *dl, const struct nlmsghdr *nlh, >+ struct nlattr **tb, bool has_versions) >+{ >+ __pr_out_handle_start(dl, tb, true, false); >+ >+ __pr_out_indent_inc(); >+ if (!dl->opts.versions_attr && tb[DEVLINK_ATTR_INFO_DRIVER_NAME]) { >+ struct nlattr *nla_drv = tb[DEVLINK_ATTR_INFO_DRIVER_NAME]; >+ >+ __pr_out_newline(); >+ pr_out_str(dl, "driver", mnl_attr_get_str(nla_drv)); >+ } >+ >+ if (!dl->opts.versions_attr && tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER]) { >+ struct nlattr *nla_sn = tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER]; >+ >+ __pr_out_newline(); >+ pr_out_str(dl, "serial_number", mnl_attr_get_str(nla_sn)); >+ } >+ __pr_out_indent_dec(); >+ >+ if (has_versions) { >+ pr_out_object_start(dl, "versions"); >+ >+ pr_out_versions_single(dl, nlh, "fixed", >+ DEVLINK_ATTR_INFO_VERSION_FIXED); >+ pr_out_versions_single(dl, nlh, "running", >+ DEVLINK_ATTR_INFO_VERSION_RUNNING); >+ pr_out_versions_single(dl, nlh, "stored", >+ DEVLINK_ATTR_INFO_VERSION_STORED); >+ >+ pr_out_object_end(dl); >+ } >+ >+ pr_out_handle_end(dl); >+} >+ >+static int cmd_versions_show_cb(const struct nlmsghdr *nlh, void *data) >+{ >+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); >+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; >+ bool has_versions, has_info; >+ struct dl *dl = data; >+ >+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); >+ >+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME]) >+ return MNL_CB_ERROR; >+ >+ has_versions = tb[DEVLINK_ATTR_INFO_VERSION_FIXED] || >+ tb[DEVLINK_ATTR_INFO_VERSION_RUNNING] || >+ tb[DEVLINK_ATTR_INFO_VERSION_STORED]; >+ has_info = tb[DEVLINK_ATTR_INFO_DRIVER_NAME] || >+ tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER] || >+ has_versions; >+ >+ if (has_info) >+ pr_out_info(dl, nlh, tb, has_versions); >+ >+ return MNL_CB_OK; >+} >+ >+static void cmd_dev_info_help(void) >+{ >+ pr_err("Usage: devlink dev info [ DEV [ { versions [ VTYPE ] } ] ]\n"); >+ pr_err("\n"); >+ pr_err(" VTYPE := { fixed | running | stored }\n"); >+} >+ >+static int cmd_dev_info(struct dl *dl) >+{ >+ struct nlmsghdr *nlh; >+ uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; >+ int err; >+ >+ if (dl_argv_match(dl, "help")) { >+ cmd_dev_info_help(); >+ return 0; >+ } >+ >+ if (dl_argc(dl) == 0) >+ flags |= NLM_F_DUMP; >+ >+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_INFO_GET, flags); >+ >+ if (dl_argc(dl) > 0) { >+ err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, >+ DL_OPT_VERSIONS_TYPE); >+ if (err) >+ return err; >+ } >+ >+ pr_out_section_start(dl, "info"); >+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_versions_show_cb, dl); >+ pr_out_section_end(dl); >+ return err; >+} >+ > static int cmd_dev(struct dl *dl) > { > if (dl_argv_match(dl, "help")) { >@@ -2433,6 +2637,9 @@ static int cmd_dev(struct dl *dl) > } else if (dl_argv_match(dl, "param")) { > dl_arg_inc(dl); > return cmd_dev_param(dl); >+ } else if (dl_argv_match(dl, "info")) { >+ dl_arg_inc(dl); >+ return cmd_dev_info(dl); > } > pr_err("Command \"%s\" not found\n", dl_argv(dl)); > return -ENOENT; >diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 >index d985da172aa0..5b05298f88bf 100644 >--- a/man/man8/devlink-dev.8 >+++ b/man/man8/devlink-dev.8 >@@ -63,6 +63,17 @@ devlink-dev \- devlink device configuration > .BR "devlink dev reload" > .IR DEV > >+.ti -8 >+.BR "devlink dev info" >+.RI "[ " DEV >+.RI "[" >+.BR versions >+.RI "{ " >+.BR fixed " | " running " | " stored >+.RI "} " >+.RI "]" >+.RI "]" >+ > .SH "DESCRIPTION" > .SS devlink dev show - display devlink device attributes > >@@ -151,6 +162,31 @@ If this argument is omitted all parameters supported by devlink devices are list > .I "DEV" > - Specifies the devlink device to reload. > >+.SS devlink dev info - display device information. >+Display device information provided by the driver. This command can be used >+to query versions of the hardware components or device components which >+can't be updated ( >+.I fixed >+) as well as device firmware which can be updated. For firmware components >+.I running >+displays the versions of firmware currently loaded into the device, while >+.I stored >+reports the versions in device's flash. >+.I Running >+and >+.I stored >+versions may differ after flash has been updated, but before reboot. >+ >+.PP >+.I "DEV" >+- specifies the devlink device to show. >+If this argument is omitted all devices are listed. >+ >+.PP >+.BR versions " { " fixed " | " running " | " stored " } " >+- specifies the versions category to show. >+If this argument is omitted all categories are listed. >+ > .SH "EXAMPLES" > .PP > devlink dev show >-- >2.19.2 >