From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D1289210DF5C4 for ; Tue, 7 Aug 2018 17:03:18 -0700 (PDT) From: "Verma, Vishal L" Subject: Re: [PATCH 1/2] Create Intel pmem shutdown latch rule Date: Wed, 8 Aug 2018 00:02:59 +0000 Message-ID: <1533686577.18175.67.camel@intel.com> References: <20180807222656.14346-1-keith.busch@intel.com> In-Reply-To: <20180807222656.14346-1-keith.busch@intel.com> Content-Language: en-US Content-ID: <763C7A34DE436A42ADFA455C9DC03D84@intel.com> MIME-Version: 1.0 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" To: "Busch, Keith" , "Jiang, Dave" , "linux-nvdimm@lists.01.org" List-ID: On Tue, 2018-08-07 at 16:26 -0600, Keith Busch wrote: > This patch provides a udev rule and the program it runs for Intel > nvdimms. The program the rule executes runs two commands to allow > applications to manage unsafe shutdowns. > > The first command enables the shutdown latch. Without this, the last > shutdown status will remain fixed to the status set when the latch was > last enabled. > > The second command retrieves the unclean shutdown counts and saves it > in a known location. Only root can access the health's shutdown count, > so we have to stash it somewhere accessible to non-privileged users. A > successful execution of the rule will write USC to the run time tmpfs > location. By default, the location will be set to: > > /run/ndctl//usc > > A distro may change this location using the '--with-tmpfsdir=[DIR]'. > > Reading the file will report the count observed when the dimm was > added. > > Signed-off-by: Keith Busch > --- > .gitignore | 1 + > Makefile.am | 3 + > configure.ac | 10 ++++ > contrib/80-intel-pmem.rules | 1 + > ndctl.spec.in | 5 +- > ndctl/Makefile.am | 5 ++ > ndctl/latch-shutdown.c | 140 ++++++++++++++++++++++++++++++++++++++++++++ > 7 files changed, 164 insertions(+), 1 deletion(-) > create mode 100644 contrib/80-intel-pmem.rules > create mode 100644 ndctl/latch-shutdown.c > > diff --git a/.gitignore b/.gitignore > index 1016b3b..1601738 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -25,6 +25,7 @@ daxctl/lib/libdaxctl.pc > *.a > ndctl/lib/libndctl.pc > ndctl/ndctl > +ndctl/latch-shutdown > rhel/ > sles/ndctl.spec > util/log.lo > diff --git a/Makefile.am b/Makefile.am > index e0c463a..9d3913e 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -42,6 +42,9 @@ bashcompletiondir = $(BASH_COMPLETION_DIR) > dist_bashcompletion_DATA = contrib/ndctl > endif > > +udevrulesdir = $(UDEVDIR)/rules.d > +dist_udevrules_DATA = contrib/80-intel-pmem.rules > + > noinst_LIBRARIES = libccan.a > libccan_a_SOURCES = \ > ccan/str/str.h \ > diff --git a/configure.ac b/configure.ac > index cf44260..15f336b 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -143,7 +143,16 @@ AC_CHECK_FUNCS([ \ > secure_getenv\ > ]) > > +AC_ARG_WITH([tmpfsdir], > + [AS_HELP_STRING([--with-tmpfsdir=DIR], [Directory for temporary runtime files])], > + [tmpfsdir=$withval], > + [tmpfsdir="/run"]) > + > +UDEVDIR="$(pkg-config udev --variable=udevdir)" > +AC_SUBST([UDEVDIR]) > + > my_CFLAGS="\ > +-D DEF_TMPFS_DIR='\"${tmpfsdir}/ndctl\"' \ > -Wall \ > -Wchar-subscripts \ > -Wformat-security \ > @@ -182,6 +191,7 @@ AC_MSG_RESULT([ > > prefix: ${prefix} > sysconfdir: ${sysconfdir} > + tmpfsdir: ${tmpfsdir} > libdir: ${libdir} > includedir: ${includedir} > > diff --git a/contrib/80-intel-pmem.rules b/contrib/80-intel-pmem.rules > new file mode 100644 > index 0000000..20fcef9 > --- /dev/null > +++ b/contrib/80-intel-pmem.rules > @@ -0,0 +1 @@ > +ACTION=="add", KERNEL=="nmem*", RUN+="latch-shutdown $kernel" > diff --git a/ndctl.spec.in b/ndctl.spec.in > index e2c879c..25edf7e 100644 > --- a/ndctl.spec.in > +++ b/ndctl.spec.in > @@ -90,7 +90,7 @@ control API for these devices. > %build > echo %{version} > version > ./autogen.sh > -%configure --disable-static --disable-silent-rules > +%configure --disable-static --disable-silent-rules --with-tmpfsdir=%{_tmpfilesdir} One more thing - looks like tmpfilesdir expands to: $ rpm --eval "%{_tmpfilesdir}" /usr/lib/tmpfiles.d And using it requires a specific config file as described in the following places: https://fedoraproject.org/wiki/Packaging:Tmpfiles.d http://0pointer.de/public/systemd-man/tmpfiles.d.html So for this, I think we can simply drop the --with-tmpfsdir=%{_tmpfilesdir} to configure above, and let autoconf use its default. If a distro wanted to change that location, they still have the option of doing it be passing something else to configure. > make %{?_smp_mflags} > > %install > @@ -109,6 +109,7 @@ make check > %postun -n DAX_LNAME -p /sbin/ldconfig > > %define bashcompdir %(pkg-config --variable=completionsdir bash-completion) > +%define udevdir %(pkg-config --variable=udevdir udev) > > %files > %defattr(-,root,root) > @@ -116,6 +117,8 @@ make check > %{_bindir}/ndctl > %{_mandir}/man1/ndctl* > %{bashcompdir}/ > +%{_udevrulesdir}/80-intel-pmem.rules > +%{udevdir}/latch-shutdown > > %files -n daxctl > %defattr(-,root,root) > diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am > index 0f56871..155179b 100644 > --- a/ndctl/Makefile.am > +++ b/ndctl/Makefile.am > @@ -41,3 +41,8 @@ ndctl_SOURCES += ../test/libndctl.c \ > ../test/core.c \ > test.c > endif > + > +latch_shutdowndir = $(UDEVDIR) > +latch_shutdown_PROGRAMS = latch-shutdown > +latch_shutdown_SOURCES = latch-shutdown.c > +latch_shutdown_LDADD = lib/libndctl.la > diff --git a/ndctl/latch-shutdown.c b/ndctl/latch-shutdown.c > new file mode 100644 > index 0000000..704fb8f > --- /dev/null > +++ b/ndctl/latch-shutdown.c > @@ -0,0 +1,140 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* Copyright(c) 2018 Intel Corporation. All rights reserved. */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + * mkdir_p > + * > + * Copied from util-linux lib/fileutils.c > + */ > +static int mkdir_p(const char *path, mode_t mode) > +{ > + char *p, *dir; > + int rc = 0; > + > + if (!path || !*path) > + return -EINVAL; > + > + dir = p = strdup(path); > + if (!dir) > + return -ENOMEM; > + > + if (*p == '/') > + p++; > + > + while (p && *p) { > + char *e = strchr(p, '/'); > + if (e) > + *e = '\0'; > + if (*p) { > + rc = mkdir(dir, mode); > + if (rc && errno != EEXIST) > + break; > + rc = 0; > + } > + if (!e) > + break; > + *e = '/'; > + p = e + 1; > + } > + > + free(dir); > + return rc; > +} > + > +static struct ndctl_dimm *find_dimm(struct ndctl_ctx *ctx, char *devname) > +{ > + struct ndctl_bus *bus; > + struct ndctl_dimm *dimm; > + > + ndctl_bus_foreach(ctx, bus) { > + ndctl_dimm_foreach(bus, dimm) { > + if (strcmp(ndctl_dimm_get_devname(dimm), devname) == 0) > + return dimm; > + } > + } > + return NULL; > +} > + > +int main(int argc, char *argv[]) > +{ > + struct ndctl_ctx *ctx; > + struct ndctl_cmd *cmd; > + struct ndctl_dimm *dimm = NULL; > + char *path, *usc, count[16]; > + const char *id; > + unsigned int shutdown; > + int rc, fd; > + > + if (argc < 2) > + return EINVAL; > + > + rc = ndctl_new(&ctx); > + if (rc) > + return ENOMEM; > + > + dimm = find_dimm(ctx, argv[1]); > + if (!dimm) > + return ENODEV; > + > + cmd = ndctl_dimm_cmd_new_ack_shutdown_count(dimm); > + if (!cmd) > + return ENOMEM; > + > + rc = ndctl_cmd_submit(cmd); > + if (rc) > + return rc; > + ndctl_cmd_unref(cmd); > + > + id = ndctl_dimm_get_unique_id(dimm); > + if (!id) > + return ENXIO; > + > + cmd = ndctl_dimm_cmd_new_smart(dimm); > + if (!cmd) > + return ENOMEM; > + > + rc = ndctl_cmd_submit(cmd); > + if (rc) > + return rc; > + > + shutdown = ndctl_cmd_smart_get_shutdown_count(cmd); > + ndctl_cmd_unref(cmd); > + > + rc = asprintf(&path, DEF_TMPFS_DIR "/%s", id); > + if (rc < 0) > + return ENOMEM; > + ndctl_unref(ctx); > + > + rc = mkdir_p(path, 0755); > + if (rc) > + return rc; > + > + rc = asprintf(&usc, "%s/usc", path); > + if (rc < 0) > + return ENOMEM; > + free(path); > + > + fd = open(usc, O_WRONLY | O_CREAT, 0644); > + if (!fd) > + return errno; > + free(usc); > + > + rc = snprintf(count, sizeof(count), "%u\n", shutdown); > + if (rc < 0) > + return rc; > + > + if (write(fd, count, strlen(count))) > + return errno; > + return 0; > +} _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm