diff mbox

[RFC,v2,4/7] ndctl: nvdimmd: add body file of nvdimm daemon

Message ID 20171114074704.3446-5-qi.fuli@jp.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

QI Fuli Nov. 14, 2017, 7:47 a.m. UTC
This patch adds the body file of nvdimm daemon and compiles nvdimmd
with automake.

Signed-off-by: QI Fuli <qi.fuli@jp.fujitsu.com>
---
 Makefile.am         |   2 +-
 configure.ac        |   1 +
 nvdimmd/Makefile.am |  19 +++++++++
 nvdimmd/nvdimmd.c   | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 nvdimmd/Makefile.am
 create mode 100644 nvdimmd/nvdimmd.c

Comments

Dan Williams Nov. 20, 2017, 9:31 p.m. UTC | #1
On Mon, Nov 13, 2017 at 11:47 PM, QI Fuli <qi.fuli@jp.fujitsu.com> wrote:
> This patch adds the body file of nvdimm daemon and compiles nvdimmd
> with automake.
>
> Signed-off-by: QI Fuli <qi.fuli@jp.fujitsu.com>
> ---
>  Makefile.am         |   2 +-
>  configure.ac        |   1 +
>  nvdimmd/Makefile.am |  19 +++++++++
>  nvdimmd/nvdimmd.c   | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 133 insertions(+), 1 deletion(-)
>  create mode 100644 nvdimmd/Makefile.am
>  create mode 100644 nvdimmd/nvdimmd.c
>
> diff --git a/Makefile.am b/Makefile.am
> index b538b1f..ff91439 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -1,7 +1,7 @@
>  include Makefile.am.in
>
>  ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
> -SUBDIRS = . daxctl/lib ndctl/lib ndctl daxctl
> +SUBDIRS = . daxctl/lib ndctl/lib ndctl daxctl nvdimmd
>  if ENABLE_DOCS
>  SUBDIRS += Documentation/ndctl Documentation/daxctl
>  endif
> diff --git a/configure.ac b/configure.ac
> index 5b10381..3ce71e3 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -274,6 +274,7 @@ AC_CONFIG_FILES([
>          daxctl/lib/Makefile
>          ndctl/lib/Makefile
>          ndctl/Makefile
> +       nvdimmd/Makefile
>          daxctl/Makefile
>          test/Makefile
>          Documentation/ndctl/Makefile
> diff --git a/nvdimmd/Makefile.am b/nvdimmd/Makefile.am
> new file mode 100644
> index 0000000..9883edd
> --- /dev/null
> +++ b/nvdimmd/Makefile.am
> @@ -0,0 +1,19 @@
> +include $(top_srcdir)/Makefile.am.in
> +
> +bin_PROGRAMS = nvdimmd
> +
> +nvdimmd_SOURCES =\
> +               nvdimmd.c \
> +               libnvdimmd.c \
> +               util.c \
> +               ../util/log.c \
> +               ../util/json.c \
> +               ../ndctl/util/json-smart.c
> +
> +nvdimmd_LDADD = ../ndctl/lib/libndctl.la \
> +               ../daxctl/lib/libdaxctl.la \
> +               ../libutil.a \
> +               $(KMOD_LIBS) \
> +               $(JSON_LIBS) \
> +               $(UUID_LIBS) \
> +               $(UDEV_LIBS)
> diff --git a/nvdimmd/nvdimmd.c b/nvdimmd/nvdimmd.c
> new file mode 100644
> index 0000000..f451751
> --- /dev/null
> +++ b/nvdimmd/nvdimmd.c
> @@ -0,0 +1,112 @@
> +/*
> + * Copyright (c) 2017, 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.
> + */
> +
> +/*
> + * Nvdimm daemon is used to monitor the features of over threshold events.
> + * It automatically searches and monitors all of the dimms which support smart
> + * threshold. When an over threshold event fires, it will write a notification
> + * into the system log.
> + */
> +
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <signal.h>
> +#include <sys/stat.h>
> +#include <syslog.h>
> +#include <errno.h>
> +#include <ndctl/lib/private.h>
> +#include "libnvdimmd.h"
> +
> +static int wait_threshold_notify(struct ndctl_ctx *ctx)
> +{
> +       int rc, maxfd, cnt_dimm;
> +       struct threshold_dimm *t_dimm;
> +
> +       t_dimm = calloc(NUM_MAX_DIMM, sizeof(struct threshold_dimm));
> +       if (!t_dimm) {
> +               err(ctx, "t_dimm memory not allocated");
> +               goto out;
> +       }
> +
> +       fd_set fds;
> +       FD_ZERO(&fds);
> +
> +       cnt_dimm = get_threshold_dimm(ctx, t_dimm, &fds, &maxfd);
> +       if (cnt_dimm == 0) {
> +               err(ctx, "no dimm supports over threshold notification\n");
> +               goto out;
> +       }
> +
> +       rc = select(maxfd + 1, NULL, NULL, &fds, NULL);
> +       if (rc < 1) {
> +               if (rc == 0)
> +                       err(ctx, "select unexpected timeout\n");
> +               else
> +                       err(ctx, "select %s\n", strerror(errno));
> +               goto out;
> +       }
> +
> +       log_notify(ctx, t_dimm, cnt_dimm, fds, rc);
> +
> +       free(t_dimm);
> +       return 0;
> +
> +out:
> +       return 1;
> +}
> +
> +static void nvdimmd_log_init(struct ndctl_ctx *ctx, int priority,
> +                               const char *owner, const char *log_env)
> +{
> +       log_init(&ctx->ctx, owner, log_env);
> +       ndctl_set_log_priority(ctx, priority);
> +       if (strcmp(nvdimmd_cf->logfile, "syslog") == 0)
> +               ndctl_set_log_fn(ctx, log_syslog);
> +       else
> +               ndctl_set_log_fn(ctx, log_file);
> +}
> +
> +int main(void)
> +{
> +       if (daemon(0, 0) != 0) {
> +               syslog(LOG_ERR, "nvdimmd error: daemon start failed\n");
> +               exit(EXIT_FAILURE);
> +       }
> +       struct ndctl_ctx *ctx;
> +       int rc, ret = 0;
> +       const char *conf_path = "/etc/nvdimmd/nvdimmd.conf";
> +
> +       syslog(LOG_INFO, "nvdimmd: started\n");
> +
> +       if (get_nvdimmd_conf(conf_path) != 0) {
> +               syslog(LOG_ERR, "nvdimmd.conf error \n");
> +               goto out;
> +       }
> +
> +       while (ret == 0) {
> +               rc = ndctl_new(&ctx);
> +               if (rc)
> +                       goto out;
> +
> +               nvdimmd_log_init(ctx, LOG_NOTICE, "nvdimmd", "NVDIMMD_LOG");
> +               ret = wait_threshold_notify(ctx);
> +               ndctl_unref(ctx);

We shouldn't need to setup and teardown the ndctl_ctx after each wake up.

In general I think we need to start with the end result of what data
and events do want to emit and have in the logs and then work
backwards from there. I think the first step is define a set of event
names and event record details.
diff mbox

Patch

diff --git a/Makefile.am b/Makefile.am
index b538b1f..ff91439 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@ 
 include Makefile.am.in
 
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-SUBDIRS = . daxctl/lib ndctl/lib ndctl daxctl
+SUBDIRS = . daxctl/lib ndctl/lib ndctl daxctl nvdimmd
 if ENABLE_DOCS
 SUBDIRS += Documentation/ndctl Documentation/daxctl
 endif
diff --git a/configure.ac b/configure.ac
index 5b10381..3ce71e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -274,6 +274,7 @@  AC_CONFIG_FILES([
         daxctl/lib/Makefile
         ndctl/lib/Makefile
         ndctl/Makefile
+	nvdimmd/Makefile
         daxctl/Makefile
         test/Makefile
         Documentation/ndctl/Makefile
diff --git a/nvdimmd/Makefile.am b/nvdimmd/Makefile.am
new file mode 100644
index 0000000..9883edd
--- /dev/null
+++ b/nvdimmd/Makefile.am
@@ -0,0 +1,19 @@ 
+include $(top_srcdir)/Makefile.am.in
+
+bin_PROGRAMS = nvdimmd
+
+nvdimmd_SOURCES =\
+		nvdimmd.c \
+		libnvdimmd.c \
+		util.c \
+		../util/log.c \
+		../util/json.c \
+		../ndctl/util/json-smart.c
+
+nvdimmd_LDADD = ../ndctl/lib/libndctl.la \
+		../daxctl/lib/libdaxctl.la \
+		../libutil.a \
+		$(KMOD_LIBS) \
+		$(JSON_LIBS) \
+		$(UUID_LIBS) \
+		$(UDEV_LIBS)
diff --git a/nvdimmd/nvdimmd.c b/nvdimmd/nvdimmd.c
new file mode 100644
index 0000000..f451751
--- /dev/null
+++ b/nvdimmd/nvdimmd.c
@@ -0,0 +1,112 @@ 
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * Nvdimm daemon is used to monitor the features of over threshold events.
+ * It automatically searches and monitors all of the dimms which support smart
+ * threshold. When an over threshold event fires, it will write a notification
+ * into the system log.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <errno.h>
+#include <ndctl/lib/private.h>
+#include "libnvdimmd.h"
+
+static int wait_threshold_notify(struct ndctl_ctx *ctx)
+{
+	int rc, maxfd, cnt_dimm;
+	struct threshold_dimm *t_dimm;
+
+	t_dimm = calloc(NUM_MAX_DIMM, sizeof(struct threshold_dimm));
+	if (!t_dimm) {
+		err(ctx, "t_dimm memory not allocated");
+		goto out;
+	}
+
+	fd_set fds;
+	FD_ZERO(&fds);
+
+	cnt_dimm = get_threshold_dimm(ctx, t_dimm, &fds, &maxfd);
+	if (cnt_dimm == 0) {
+		err(ctx, "no dimm supports over threshold notification\n");
+		goto out;
+	}
+
+	rc = select(maxfd + 1, NULL, NULL, &fds, NULL);
+	if (rc < 1) {
+		if (rc == 0)
+			err(ctx, "select unexpected timeout\n");
+		else
+			err(ctx, "select %s\n", strerror(errno));
+		goto out;
+	}
+
+	log_notify(ctx, t_dimm, cnt_dimm, fds, rc);
+
+	free(t_dimm);
+	return 0;
+
+out:
+	return 1;
+}
+
+static void nvdimmd_log_init(struct ndctl_ctx *ctx, int priority,
+				const char *owner, const char *log_env)
+{
+	log_init(&ctx->ctx, owner, log_env);
+	ndctl_set_log_priority(ctx, priority);
+	if (strcmp(nvdimmd_cf->logfile, "syslog") == 0)
+		ndctl_set_log_fn(ctx, log_syslog);
+	else
+		ndctl_set_log_fn(ctx, log_file);
+}
+
+int main(void)
+{
+	if (daemon(0, 0) != 0) {
+		syslog(LOG_ERR, "nvdimmd error: daemon start failed\n");
+		exit(EXIT_FAILURE);
+	}
+	struct ndctl_ctx *ctx;
+	int rc, ret = 0;
+	const char *conf_path = "/etc/nvdimmd/nvdimmd.conf";
+
+	syslog(LOG_INFO, "nvdimmd: started\n");
+
+	if (get_nvdimmd_conf(conf_path) != 0) {
+		syslog(LOG_ERR, "nvdimmd.conf error \n");
+		goto out;
+	}
+
+	while (ret == 0) {
+		rc = ndctl_new(&ctx);
+		if (rc)
+			goto out;
+
+		nvdimmd_log_init(ctx, LOG_NOTICE, "nvdimmd", "NVDIMMD_LOG");
+		ret = wait_threshold_notify(ctx);
+		ndctl_unref(ctx);
+	}
+
+	syslog(LOG_INFO, "nvdimmd: ended\n");
+	return 0;
+
+out:
+	return 1;
+}