[PATCH v6 2/4] ndctl, monitor: add ndctl monitor daemon
This patch adds the body file of ndctl monitor daemon. Signed-off-by: QI Fuli--- builtin.h | 1 + ndctl/Makefile.am | 3 +- ndctl/monitor.c | 460 ++ ndctl/ndctl.c | 1 + 4 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 ndctl/monitor.c diff --git a/builtin.h b/builtin.h index d3cc723..675a6ce 100644 --- a/builtin.h +++ b/builtin.h @@ -39,6 +39,7 @@ int cmd_inject_error(int argc, const char **argv, void *ctx); int cmd_wait_scrub(int argc, const char **argv, void *ctx); int cmd_start_scrub(int argc, const char **argv, void *ctx); int cmd_list(int argc, const char **argv, void *ctx); +int cmd_monitor(int argc, const char **argv, void *ctx); #ifdef ENABLE_TEST int cmd_test(int argc, const char **argv, void *ctx); #endif diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am index d22a379..7dbf223 100644 --- a/ndctl/Makefile.am +++ b/ndctl/Makefile.am @@ -16,7 +16,8 @@ ndctl_SOURCES = ndctl.c \ util/json-smart.c \ util/json-firmware.c \ inject-error.c \ - inject-smart.c + inject-smart.c \ + monitor.c if ENABLE_DESTRUCTIVE ndctl_SOURCES += ../test/blk_namespaces.c \ diff --git a/ndctl/monitor.c b/ndctl/monitor.c new file mode 100644 index 000..ab6e701 --- /dev/null +++ b/ndctl/monitor.c @@ -0,0 +1,460 @@ +/* + * Copyright(c) 2018, FUJITSU LIMITED. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BUF_SIZE 2048 + +static enum log_destination { + LOG_DESTINATION_STDERR = 1, + LOG_DESTINATION_SYSLOG = 2, + LOG_DESTINATION_FILE = 3, +} log_destination = LOG_DESTINATION_SYSLOG; + +static struct { + const char *logfile; + const char *config_file; + bool daemon; +} monitor; + +struct monitor_dimm_node { + struct ndctl_dimm *dimm; + int health_eventfd; + struct list_node list; +}; + +struct monitor_filter_arg { + struct list_head mdimm; + int maxfd_dimm; + int num_dimm; + unsigned long flags; +}; + +struct util_filter_params param; + +static int did_fail; + +#define fail(fmt, ...) \ +do { \ + did_fail = 1; \ + err(ctx, "ndctl-%s:%s:%d: " fmt, \ + VERSION, __func__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +static bool is_dir(char *filepath) +{ + DIR *dir = opendir(filepath); + if (dir) { + closedir(dir); + return true; + } + return false; +} + +static int recur_mkdir(char *filepath, mode_t mode) +{ + char *p; + char *buf = (char *)malloc(strlen(filepath) + 4); + + strcpy(buf, filepath); + for (p = strchr(buf + 1, '/'); p; p = strchr(p + 1, '/')) { + *p = '\0'; + if (!is_dir(buf)) { + if (mkdir(buf, mode) < 0) { + free(buf); + return -1; + } + } + *p = '/'; + } + + free(buf); + return 0; +} + +static void set_value(const char **arg, char *val) +{ + struct strbuf value = STRBUF_INIT; + size_t arg_len = *arg ? strlen(*arg) : 0; + + if (arg_len) { + strbuf_add(, *arg, arg_len); + strbuf_addstr(, " "); + } + strbuf_addstr(, val); + *arg = strbuf_detach(, NULL); +} + +static void logreport(struct ndctl_ctx *ctx, int priority, const char *file, + int line, const char *fn, const char *format, va_list args) +{ + char *log_dir; + char *buf = (char *)malloc(BUF_SIZE); + vsnprintf(buf, BUF_SIZE, format, args); + + switch (log_destination) { + case LOG_DESTINATION_STDERR: + fprintf(stderr, "%s\n", buf); + goto end; + + case LOG_DESTINATION_SYSLOG: + syslog(priority, "%s\n", buf); + goto end; + + case LOG_DESTINATION_FILE: + log_dir = dirname(strdup(monitor.logfile)); + if (!is_dir(log_dir) && recur_mkdir(log_dir, 0744) != 0) + goto log_file_err; + FILE *f = fopen(monitor.logfile, "a+"); + if (!f) + goto log_file_err; + fprintf(f, "%s\n", buf); + fclose(f); +
[PATCH v6 3/4] ndctl, monitor: add default configuration file
This patch adds the default configuration file of ndctl monitor. Users can change the configuration by editing this file or by using [--config-file=] option to override this one. The monitor started by systemd follows the configuration in this file. Signed-off-by: QI Fuli--- ndctl/Makefile.am | 5 + ndctl/monitor.conf | 37 + 2 files changed, 42 insertions(+) create mode 100644 ndctl/monitor.conf diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am index 7dbf223..ae3d894 100644 --- a/ndctl/Makefile.am +++ b/ndctl/Makefile.am @@ -42,3 +42,8 @@ ndctl_SOURCES += ../test/libndctl.c \ ../test/multi-pmem.c \ ../test/core.c endif + +monitor_config_file = monitor.conf +monitor_configdir = /etc/ndctl/ +monitor_config_DATA = $(monitor_config_file) +EXTRA_DIST += $(monitor_config_file) diff --git a/ndctl/monitor.conf b/ndctl/monitor.conf new file mode 100644 index 000..13ad7b0 --- /dev/null +++ b/ndctl/monitor.conf @@ -0,0 +1,37 @@ +# This is the main ndctl monitor configuration file. It contains the +# configuration directives that give ndctl monitor instructions. +# You can change the configuration of ndctl monitor by editing this +# file or by using [--config-file=] option to override this one. +# The changed value will work after restart ndctl monitor service. + +# In this file, lines starting with a hash (#) are comments. +# The configurations shold follow = style. +# Multiple space-seperated values are allowed, but except the following +# charecters: : # ? / \ % " ' + +# The dimms to monitor are filtered via dimm's name by setting key "dimm". +# If this value is different from the value of [--dimm=] option, +# both of the values will work. +# dimm = all + +# The dimms to monitor are filtered via its parent bus by setting key "bus". +# If this value is different from the value of [--bus=] option, +# both of the values will work. +# bus = all + +# The dimms to monitor are filtered via region by setting key "region". +# If this value is different from the value of [--namespace=] option, +# both of the values will work. +# region = all + +# The dimms to monitor are filtered via namespace by setting key "namespace". +# If this value is different from the value of [--namespace=] option, +# both of the values will work. +# namespace = all + +# Users can choose to output the notifications to syslog (logfile=syslog), +# stderr (logfile=stderr) or to write into a special file (logfile=) +# by setting key "logfile". +# If this value is in conflict with the value of [--logfile=] option, +# this value will be ignored. +# logfile = /var/log/ndctl/monitor.log -- 2.17.0.140.g0b0cc9f86 ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm
[PATCH v6 4/4] ndctl, monitor: add the unit file of systemd for ndctl-monitor service
This patch adds the systemd unit file for ndctl-monitor service. The systemd unit directory can be configured by setting environment variable "--with-systemd-unit-dir[=DIR]". Signed-off-by: QI Fuli--- autogen.sh | 3 ++- configure.ac| 22 ++ ndctl/Makefile.am | 4 ndctl/ndctl-monitor.service | 7 +++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 ndctl/ndctl-monitor.service diff --git a/autogen.sh b/autogen.sh index a23cf53..b226c7a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -17,7 +17,8 @@ libdir() { args="--prefix=/usr \ --sysconfdir=/etc \ ---libdir=$(libdir /usr/lib)" +--libdir=$(libdir /usr/lib) \ +--with-systemd-unit-dir" echo echo "" diff --git a/configure.ac b/configure.ac index cddad16..fd227eb 100644 --- a/configure.ac +++ b/configure.ac @@ -135,6 +135,27 @@ AC_CHECK_FUNCS([ \ secure_getenv\ ]) +PKG_PROG_PKG_CONFIG +AC_ARG_WITH([systemd-unit-dir], + AS_HELP_STRING([--with-systemd-unit-dir[=DIR]], + [Directory for systemd service files]), + [], + [with_systemd_unit_dir=yes]) + +if test "x$with_systemd_unit_dir" = "xyes"; then + def_systemd_unit_dir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd) + if test "x$def_systemd_unit_dir" = "x"; then + AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package]) + with_systemd_unit_dir=no + else + with_systemd_unit_dir="$def_systemd_unit_dir" + fi +fi + +AS_IF([test "x$with_systemd_unit_dir" != "xno"], + [AC_SUBST([systemd_unitdir], [$with_systemd_unit_dir])]) +AM_CONDITIONAL([ENABLE_SYSTEMD_UNIT_DIR], [test "x$with_systemd_unit_dir" != "xno"]) + my_CFLAGS="\ -Wall \ -Wchar-subscripts \ @@ -172,6 +193,7 @@ AC_MSG_RESULT([ sysconfdir: ${sysconfdir} libdir: ${libdir} includedir: ${includedir} + systemd-unit-dir: ${systemd_unitdir} compiler: ${CC} cflags: ${CFLAGS} diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am index ae3d894..9d008d5 100644 --- a/ndctl/Makefile.am +++ b/ndctl/Makefile.am @@ -47,3 +47,7 @@ monitor_config_file = monitor.conf monitor_configdir = /etc/ndctl/ monitor_config_DATA = $(monitor_config_file) EXTRA_DIST += $(monitor_config_file) + +if ENABLE_SYSTEMD_UNIT_DIR +systemd_unit_DATA = ndctl-monitor.service +endif diff --git a/ndctl/ndctl-monitor.service b/ndctl/ndctl-monitor.service new file mode 100644 index 000..44f9326 --- /dev/null +++ b/ndctl/ndctl-monitor.service @@ -0,0 +1,7 @@ +[Unit] +Description=Ndctl Monitor Daemon + +[Service] +Type=forking +ExecStart=/usr/bin/ndctl monitor --daemon +ExecStop=/bin/kill ${MAINPID} -- 2.17.0.140.g0b0cc9f86 ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm
[PATCH v6 0/4] ndctl, monitor: add ndctl monitor daemon
This is the v6 patch for ndctl monitor daemon, a tiny daemon to monitor the smart events of nvdimm DIMMs. Users can run a monitor as a one-shot command or a daemon in background by using the [--daemon] option. DIMMs to monitor can be selected by [--dimm] [--bus] [--region] [--namespace] options, these options support multiple space-seperated arguments. When a smart event fires, monitor daemon will log the notifications which including dimm health status to syslog or a logfile by setting [--logfile=] option. monitor also can output the notifications to stderr when it run as one-shot command by setting [--logfile=]. The notifications follow json format and can be consumed by log collectors like Fluentd. Users can change the configuration of monitor by editing the default configuration file /etc/ndctl/monitor.conf or by using [--config-file=] option to override the default configuration. Users can start a monitor daemon by the following command: # ndctl monitor --daemon --logfile /var/log/ndctl/monitor.log Also, a monitor daemon can be started by systemd: # systemctl start ndctl-monitor.service In this case, monitor daemon follows the default configuration file /etc/ndctl/monitor.conf. Signed-off-by: QI Fuli --- Change log since v5: - Fixing systemd unit file cannot be installed bug - Adding license to ./util/abspath.c Change log since v4: - Adding OPTION_FILENAME to make sure filename is correct - Adding configuration file - Adding [--config-file] option to override the default configuration - Making some options support multiple space-seperated arguments - Making systemctl enable ndctl-monitor.service command work - Making systemctl restart ndctl-monitor.service command work - Making the directory of systemd unit file to be configurable - Changing log_file() and log_syslog() to logreport() - Changing date format in notification to nanoseconds since epoch - Changing select() to epoll() - Adding filter_bus() and filter_region() Change log since v3: - Removing create-monitor, show-monitor, list-monitor, destroy-monitor - Adding [--daemon] option to run ndctl monitor as a daemon - Using systemd to manage ndctl monitor daemon - Replacing filter_monitor_dimm() with filter_dimm() Change log since v2: - Changing the interface of daemon to the ndctl command line - Changing the name of daemon form "nvdimmd" to "monitor" - Removing the config file, unit_file, nvdimmd dir - Removing nvdimmd_test program - Adding ndctl/monitor.c Change log since v1: - Adding a config file(/etc/nvdimmd/nvdimmd.conf) - Using struct log_ctx instead of syslog() - Using log_syslog() to save the notify messages to syslog - Using log_file() to save the notify messages to special file - Adding LOG_NOTICE level to log_priority - Using automake instead of Makefile - Adding a new util file(nvdimmd/util.c) including helper functions needed for nvdimm daemon - Adding nvdimmd_test program QI Fuli (4): ndctl, util: add OPTION_FILENAME to parse_opt_type ndctl, monitor: add ndctl monitor daemon ndctl, monitor: add default configuration file ndctl, monitor: add the unit file of systemd for ndctl-monitor service Makefile.am | 3 +- autogen.sh | 3 +- builtin.h | 1 + configure.ac| 22 ++ ndctl/Makefile.am | 12 +- ndctl/monitor.c | 460 ndctl/monitor.conf | 37 +++ ndctl/ndctl-monitor.service | 7 + ndctl/ndctl.c | 1 + util/abspath.c | 29 +++ util/help.c | 5 - util/parse-options.c| 47 +++- util/parse-options.h| 11 +- util/util.h | 7 + 14 files changed, 629 insertions(+), 16 deletions(-) create mode 100644 ndctl/monitor.c create mode 100644 ndctl/monitor.conf create mode 100644 ndctl/ndctl-monitor.service create mode 100644 util/abspath.c -- 2.17.0.140.g0b0cc9f86 ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm
[PATCH v6 1/4] ndctl, util: add OPTION_FILENAME to parse_opt_type
This patch borrows the OPTION_FILENAME from git to ndctl to make sure filename is correct. Some related refactoring is also included: - adds parse_options_prefix() interface - moves is_absolute from util/help.c to util/util.c - adds a new file util/abspath.c Signed-off-by: QI Fuli--- Makefile.am | 3 ++- util/abspath.c | 29 +++ util/help.c | 5 - util/parse-options.c | 47 ++-- util/parse-options.h | 11 +-- util/util.h | 7 +++ 6 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 util/abspath.c diff --git a/Makefile.am b/Makefile.am index b538b1f..e0c463a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -69,6 +69,7 @@ libutil_a_SOURCES = \ util/strbuf.c \ util/wrapper.c \ util/filter.c \ - util/bitmap.c + util/bitmap.c \ + util/abspath.c nobase_include_HEADERS = daxctl/libdaxctl.h diff --git a/util/abspath.c b/util/abspath.c new file mode 100644 index 000..09bbd27 --- /dev/null +++ b/util/abspath.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* originally copied from git/abspath.c */ + +#include +#include + +char *prefix_filename(const char *pfx, const char *arg) +{ + struct strbuf path = STRBUF_INIT; + size_t pfx_len = pfx ? strlen(pfx) : 0; + + if (!pfx_len) + ; + else if (is_absolute_path(arg)) + pfx_len = 0; + else + strbuf_add(, pfx, pfx_len); + + strbuf_addstr(, arg); + return strbuf_detach(, NULL); +} + +void fix_filename(const char *prefix, const char **file) +{ + if (!file || !*file || !prefix || is_absolute_path(*file) + || !strcmp("-", *file)) + return; + *file = prefix_filename(prefix, *file); +} diff --git a/util/help.c b/util/help.c index 8b8f951..2d57fa1 100644 --- a/util/help.c +++ b/util/help.c @@ -89,11 +89,6 @@ static char *cmd_to_page(const char *cmd, char **page, const char *util_name) return *page; } -static int is_absolute_path(const char *path) -{ - return path[0] == '/'; -} - static const char *system_path(const char *path) { static const char *prefix = PREFIX; diff --git a/util/parse-options.c b/util/parse-options.c index 751c091..c781174 100644 --- a/util/parse-options.c +++ b/util/parse-options.c @@ -55,6 +55,7 @@ static int get_value(struct parse_opt_ctx_t *p, { const char *s, *arg = NULL; const int unset = flags & OPT_UNSET; + int err; if (unset && p->opt) return opterror(opt, "takes no value", flags); @@ -77,6 +78,7 @@ static int get_value(struct parse_opt_ctx_t *p, case OPTION_ARGUMENT: case OPTION_GROUP: case OPTION_STRING: + case OPTION_FILENAME: case OPTION_INTEGER: case OPTION_UINTEGER: case OPTION_LONG: @@ -121,6 +123,19 @@ static int get_value(struct parse_opt_ctx_t *p, return get_arg(p, opt, flags, (const char **)opt->value); return 0; + case OPTION_FILENAME: + err = 0; + if (unset) + *(const char **)opt->value = NULL; + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) + *(const char **)opt->value = (const char *)opt->defval; + else + err = get_arg(p, opt, flags, (const char **)opt->value); + + if (!err) + fix_filename(p->prefix, (const char **)opt->value); + return err; + case OPTION_CALLBACK: if (unset) return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; @@ -339,13 +354,14 @@ static void check_typos(const char *arg, const struct option *options) } } -void parse_options_start(struct parse_opt_ctx_t *ctx, -int argc, const char **argv, int flags) +void parse_options_start(struct parse_opt_ctx_t *ctx, int argc, + const char **argv, const char *prefix, int flags) { memset(ctx, 0, sizeof(*ctx)); ctx->argc = argc - 1; ctx->argv = argv + 1; ctx->out = argv; + ctx->prefix = prefix; ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0); ctx->flags = flags; if ((flags & PARSE_OPT_KEEP_UNKNOWN) && @@ -453,8 +469,10 @@ int parse_options_end(struct parse_opt_ctx_t *ctx) return ctx->cpidx + ctx->argc; } -int parse_options_subcommand(int argc, const char **argv, const struct option *options, - const char *const subcommands[], const char *usagestr[], int flags) +static int parse_options_subcommand_prefix(int argc, const char **argv, + const char *prefix, const struct option *options, +
ypqianafktavg
The original message was received at Mon, 7 May 2018 11:32:16 +0800 from lists.01.org [155.162.146.209] - The following addresses had permanent fatal errors -- Transcript of session follows - while talking to lists.01.org.: >>> MAIL From:"Bounced mail" <<< 501 "Bounced mail" ... Refused ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm
RE: [PATCH v5 1/4] ndctl, util: add OPTION_FILENAME to parse_opt_type
> -Original Message- > From: Dan Williams [mailto:dan.j.willi...@intel.com] > Sent: Friday, May 4, 2018 12:26 PM > To: Qi, Fuli/斉 福利> Cc: linux-nvdimm > Subject: Re: [PATCH v5 1/4] ndctl, util: add OPTION_FILENAME to parse_opt_type > > On Thu, Apr 26, 2018 at 4:30 AM, QI Fuli wrote: > > This patch borrows the OPTION_FILENAME from git to ndctl to make sure > > filename is correct. Some related refactoring is also included: > > - adds parse_options_prefix() interface > > - moves is_absolute from util/help.c to util/util.c > > - adds a new file util/abspath.c > > > > Signed-off-by: QI Fuli > > > [..] > > diff --git a/util/abspath.c b/util/abspath.c new file mode 100644 > > index 000..fdf4090 > > --- /dev/null > > +++ b/util/abspath.c > > @@ -0,0 +1,28 @@ > > +/* originally copied from git */ > > Lets say the source file name that it came from in and get and add the > license. > > /* SPDX-License-Identifier: GPL-2.0 */ > /* originally copied from git/abspath.c */ > > Otherwise, this patch looks good to me. > Thank you for your comment. I will make a new version and add the license. ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm
RE: [PATCH v2] ndctl, filter: fix "keyword 'all' is ignored" in util__filter()
> -Original Message- > From: Verma, Vishal L [mailto:vishal.l.ve...@intel.com] > Sent: Thursday, May 3, 2018 6:38 AM > To: linux-nvdimm@lists.01.org; Qi, Fuli/斉 福利> Subject: Re: [PATCH v2] ndctl, filter: fix "keyword 'all' is ignored" in > util__filter() > > On Thu, 2018-04-26 at 09:56 +0900, QI Fuli wrote: > > This is a follow up patch for commit c70adc3cf6bf ("ndctl, filter: > > refactor > > util__filter() to support multiple space-seperated arguments") > > refactored util__filter() to support multiple space-seperated > > arguments. > > But, when the keyword "all" is included in space-seperated arguments, > > it will be treaded as 's name. This patch fixes it. > > > > Signed-off-by: QI Fuli > > > > Change log since v1: > > - Removing the strcmp(__ident, "all") == 0 at the top of > > util__filter() > > - Changing the strcmp(ident, "all") == 0 to strcmp(name, "all") == 0 > > > > --- > > util/filter.c | 20 > > 1 file changed, 16 insertions(+), 4 deletions(-) > > Thanks, applied. Just as a future note, you should have the "changes since v1" > notes below the '---' marker (between the --- and the first file diffstat). > This > prevents it from being picked up as part of the commit message. > > Thanks, > -Vishal > Thank you for your comment. I will take an eye on it. Best, - Qi > > > > diff --git a/util/filter.c b/util/filter.c index 0d3cc02..1734bce > > 100644 > > --- a/util/filter.c > > +++ b/util/filter.c > > @@ -31,7 +31,7 @@ struct ndctl_bus *util_bus_filter(struct ndctl_bus > > *bus, const char *__ident) > > unsigned long bus_id, id; > > const char *provider, *devname, *name; > > > > - if (!__ident || strcmp(__ident, "all") == 0) > > + if (!__ident) > > return bus; > > > > ident = strdup(__ident); > > @@ -40,6 +40,9 @@ struct ndctl_bus *util_bus_filter(struct ndctl_bus > > *bus, const char *__ident) > > > > for (name = strtok_r(ident, " ", ); name; > > name = strtok_r(NULL, " ", )) { > > + if (strcmp(name, "all") == 0) > > + break; > > + > > bus_id = strtoul(ident, , 0); > > if (end == ident || end[0]) > > bus_id = ULONG_MAX; > > @@ -69,7 +72,7 @@ struct ndctl_region *util_region_filter(struct > > ndctl_region *region, > > const char *name, *region_name; > > unsigned long region_id, id; > > > > - if (!__ident || strcmp(__ident, "all") == 0) > > + if (!__ident) > > return region; > > > > ident = strdup(__ident); > > @@ -78,6 +81,9 @@ struct ndctl_region *util_region_filter(struct > > ndctl_region *region, > > > > for (name = strtok_r(ident, " ", ); name; > > name = strtok_r(NULL, " ", )) { > > + if (strcmp(name, "all") == 0) > > + break; > > + > > region_id = strtoul(ident, , 0); > > if (end == ident || end[0]) > > region_id = ULONG_MAX; > > @@ -106,7 +112,7 @@ struct ndctl_namespace > > *util_namespace_filter(struct ndctl_namespace *ndns, > > const char *name; > > char *ident, *save; > > > > - if (!__ident || strcmp(__ident, "all") == 0) > > + if (!__ident) > > return ndns; > > > > ident = strdup(__ident); > > @@ -115,6 +121,9 @@ struct ndctl_namespace > > *util_namespace_filter(struct ndctl_namespace *ndns, > > > > for (name = strtok_r(ident, " ", ); name; > > name = strtok_r(NULL, " ", )) { > > + if (strcmp(name, "all") == 0) > > + break; > > + > > if (strcmp(name, ndctl_namespace_get_devname(ndns)) == > > 0) > > break; > > > > @@ -137,7 +146,7 @@ struct ndctl_dimm *util_dimm_filter(struct > > ndctl_dimm *dimm, > > const char *name, *dimm_name; > > unsigned long dimm_id, id; > > > > - if (!__ident || strcmp(__ident, "all") == 0) > > + if (!__ident) > > return dimm; > > > > ident = strdup(__ident); > > @@ -146,6 +155,9 @@ struct ndctl_dimm *util_dimm_filter(struct > > ndctl_dimm *dimm, > > > > for (name = strtok_r(ident, " ", ); name; > > name = strtok_r(NULL, " ", )) { > > + if (strcmp(name, "all") == 0) > > + break; > > + > > dimm_id = strtoul(ident, , 0); > > if (end == ident || end[0]) > > dimm_id = ULONG_MAX; ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm
Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
Hi Wei Yang, On 04/26/18 at 09:18am, Wei Yang wrote: > On Thu, Apr 19, 2018 at 08:18:46AM +0800, Baoquan He wrote: > >The struct resource uses singly linked list to link siblings. It's not > >easy to do reverse iteration on sibling list. So replace it with list_head. > > > > Hi, Baoquan > > Besides changing the data structure, I have another proposal to do the reverse > iteration. Which means it would not affect other users, if you just want a > reverse iteration. > > BTW, I don't think Andrew suggest to use linked-list directly. What he wants > is a better solution to your first proposal in > https://patchwork.kernel.org/patch/10300819/. > > Below is my proposal of resource reverse iteration without changing current > design. I got your mail and read it, then interrupted by other thing and forgot replying, sorry. I am fine with your code change. As I said before, I have tried to change code per reviewers' comment, then let reviewers decide which way is better. Please feel free to post formal patches and joining discussion about this issue. Thanks Baoquan > > From 5d7145d44fe48b98572a03884fa3a3aa82e3cef9 Mon Sep 17 00:00:00 2001 > From: Wei Yang> Date: Sat, 24 Mar 2018 23:25:46 +0800 > Subject: [PATCH] kernel/resource: add walk_system_ram_res_rev() > > As discussed on https://patchwork.kernel.org/patch/10300819/, this patch > comes up with a variant implementation of walk_system_ram_res_rev(), which > uses iteration instead of allocating array to store those resources. > > Signed-off-by: Wei Yang > --- > include/linux/ioport.h | 3 ++ > kernel/resource.c | 113 > + > 2 files changed, 116 insertions(+) > > diff --git a/include/linux/ioport.h b/include/linux/ioport.h > index da0ebaec25f0..473f1d9cb97e 100644 > --- a/include/linux/ioport.h > +++ b/include/linux/ioport.h > @@ -277,6 +277,9 @@ extern int > walk_system_ram_res(u64 start, u64 end, void *arg, > int (*func)(struct resource *, void *)); > extern int > +walk_system_ram_res_rev(u64 start, u64 end, void *arg, > + int (*func)(struct resource *, void *)); > +extern int > walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 > end, > void *arg, int (*func)(struct resource *, void *)); > > diff --git a/kernel/resource.c b/kernel/resource.c > index 769109f20fb7..d4ec5fbc6875 100644 > --- a/kernel/resource.c > +++ b/kernel/resource.c > @@ -73,6 +73,38 @@ static struct resource *next_resource(struct resource *p, > bool sibling_only) > return p->sibling; > } > > +static struct resource *prev_resource(struct resource *p, bool sibling_only) > +{ > + struct resource *prev; > + if (NULL == iomem_resource.child) > + return NULL; > + > + if (p == NULL) { > + prev = iomem_resource.child; > + while (prev->sibling) > + prev = prev->sibling; > + } else { > + if (p->parent->child == p) { > + return p->parent; > + } > + > + for (prev = p->parent->child; prev->sibling != p; > + prev = prev->sibling) {} > + } > + > + /* Caller wants to traverse through siblings only */ > + if (sibling_only) > + return prev; > + > + for (;prev->child;) { > + prev = prev->child; > + > + while (prev->sibling) > + prev = prev->sibling; > + } > + return prev; > +} > + > static void *r_next(struct seq_file *m, void *v, loff_t *pos) > { > struct resource *p = v; > @@ -401,6 +433,47 @@ static int find_next_iomem_res(struct resource *res, > unsigned long desc, > return 0; > } > > +/* > + * Finds the highest iomem resource existing within [res->start.res->end). > + * The caller must specify res->start, res->end, res->flags, and optionally > + * desc. If found, returns 0, res is overwritten, if not found, returns -1. > + * This function walks the whole tree and not just first level children until > + * and unless first_level_children_only is true. > + */ > +static int find_prev_iomem_res(struct resource *res, unsigned long desc, > +bool first_level_children_only) > +{ > + struct resource *p; > + > + BUG_ON(!res); > + BUG_ON(res->start >= res->end); > + > + read_lock(_lock); > + > + for (p = prev_resource(NULL, first_level_children_only); p; > + p = prev_resource(p, first_level_children_only)) { > + if ((p->flags & res->flags) != res->flags) > + continue; > + if ((desc != IORES_DESC_NONE) && (desc != p->desc)) > + continue; > + if (p->end < res->start || p->child == iomem_resource.child) { > + p = NULL; > + break; > + } > + if ((p->end >= res->start)
Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
On 04/26/18 at 11:01am, kbuild test robot wrote: > Hi Baoquan, > > I love your patch! Yet something to improve: > > [auto build test ERROR on linus/master] > [also build test ERROR on v4.17-rc2 next-20180424] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180419-223752 > config: microblaze-mmu_defconfig (attached as .config) > compiler: microblaze-linux-gcc (GCC) 7.2.0 > reproduce: > wget > https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O > ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=microblaze > > All errors (new ones prefixed by >>): Thanks, below patch can fix it. Will repost including the fix. diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 161f9758c631..56d189cb4be4 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -533,7 +533,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, res->flags = range.flags; res->start = range.cpu_addr; res->end = range.cpu_addr + range.size - 1; - res->parent = res->child = res->sibling = NULL; + res->parent = NULL; + INIT_LIST_HEAD(>child); + INIT_LIST_HEAD(>sibling); } } @@ -625,28 +627,31 @@ EXPORT_SYMBOL(pcibios_add_device); static int __init reparent_resources(struct resource *parent, struct resource *res) { - struct resource *p, **pp; - struct resource **firstpp = NULL; + struct resource *p, *first = NULL; - for (pp = >child; (p = *pp) != NULL; pp = >sibling) { + list_for_each_entry(p, >child, sibling) { if (p->end < res->start) continue; if (res->end < p->start) break; if (p->start < res->start || p->end > res->end) return -1; /* not completely contained */ - if (firstpp == NULL) - firstpp = pp; + if (first == NULL) + first = p; } - if (firstpp == NULL) + if (first == NULL) return -1; /* didn't find any conflicting entries? */ res->parent = parent; - res->child = *firstpp; - res->sibling = *pp; - *firstpp = res; - *pp = NULL; - for (p = res->child; p != NULL; p = p->sibling) { - p->parent = res; + list_add(>sibling, >sibling.prev); + INIT_LIST_HEAD(>child); + + /* +* From first to p's previous sibling, they all fall into +* res's region, change them as res's children. +*/ + list_cut_position(>child, first->sibling.prev, res->sibling.prev); + list_for_each_entry(p, >child, sibling) { +p->parent = new; pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", p->name, (unsigned long long)p->start, > >arch/microblaze/pci/pci-common.c: In function > 'pci_process_bridge_OF_ranges': > >> arch/microblaze/pci/pci-common.c:536:44: error: incompatible types when > >> assigning to type 'struct list_head' from type 'void *' >res->parent = res->child = res->sibling = NULL; >^ >arch/microblaze/pci/pci-common.c: In function 'reparent_resources': > >> arch/microblaze/pci/pci-common.c:631:10: error: assignment from > >> incompatible pointer type [-Werror=incompatible-pointer-types] > for (pp = >child; (p = *pp) != NULL; pp = >sibling) { > ^ >arch/microblaze/pci/pci-common.c:631:50: error: assignment from > incompatible pointer type [-Werror=incompatible-pointer-types] > for (pp = >child; (p = *pp) != NULL; pp = >sibling) { > ^ > >> arch/microblaze/pci/pci-common.c:644:13: error: incompatible types when > >> assigning to type 'struct list_head' from type 'struct resource *' > res->child = *firstpp; > ^ >arch/microblaze/pci/pci-common.c:645:15: error: incompatible types when > assigning to type 'struct list_head' from type 'struct resource *' > res->sibling = *pp; > ^ > >> arch/microblaze/pci/pci-common.c:648:9: error: incompatible types when > >> assigning to type 'struct resource *' from type 'struct list_head' > for (p = res->child; p != NULL; p = p->sibling) { > ^ >arch/microblaze/pci/pci-common.c:648:36: error: incompatible types when > assigning to type 'struct resource *' from type 'struct
Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
On 04/26/18 at 11:23am, kbuild test robot wrote: > Hi Baoquan, > > I love your patch! Yet something to improve: > > [auto build test ERROR on linus/master] > [also build test ERROR on v4.17-rc2 next-20180424] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180419-223752 > config: xtensa-common_defconfig (attached as .config) > compiler: xtensa-linux-gcc (GCC) 7.2.0 > reproduce: > wget > https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O > ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=xtensa > > All errors (new ones prefixed by >>): > >In file included from arch/xtensa/lib/pci-auto.c:22:0: >arch/xtensa/include/asm/pci-bridge.h: In function 'pcibios_init_resource': > >> arch/xtensa/include/asm/pci-bridge.h:74:15: error: incompatible types when > >> assigning to type 'struct list_head' from type 'void *' > res->sibling = NULL; > ^ >arch/xtensa/include/asm/pci-bridge.h:75:13: error: incompatible types when > assigning to type 'struct list_head' from type 'void *' > res->child = NULL; Thanks, below fix can fix it. diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h index 0b68c76ec1e6..f487b06817df 100644 --- a/arch/xtensa/include/asm/pci-bridge.h +++ b/arch/xtensa/include/asm/pci-bridge.h @@ -71,8 +71,8 @@ static inline void pcibios_init_resource(struct resource *res, res->flags = flags; res->name = name; res->parent = NULL; - res->sibling = NULL; - res->child = NULL; + INIT_LIST_HEAD(>child); + INIT_LIST_HEAD(>sibling); } > ^ > > vim +74 arch/xtensa/include/asm/pci-bridge.h > > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 65 > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 66 static > inline void pcibios_init_resource(struct resource *res, > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 67 > unsigned long start, unsigned long end, int flags, char *name) > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 68 { > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 69 > res->start = start; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 70 > res->end = end; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 71 > res->flags = flags; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 72 > res->name = name; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 73 > res->parent = NULL; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 @74 > res->sibling = NULL; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 75 > res->child = NULL; > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 76 } > 9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 77 > > :: The code at line 74 was first introduced by commit > :: 9a8fd5589902153a134111ed7a40f9cca1f83254 [PATCH] xtensa: Architecture > support for Tensilica Xtensa Part 6 > > :: TO: Chris Zankel> :: CC: Linus Torvalds > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation ___ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm