Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ndctl for openSUSE:Factory checked in at 2023-02-25 19:54:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ndctl (Old) and /work/SRC/openSUSE:Factory/.ndctl.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ndctl" Sat Feb 25 19:54:41 2023 rev:43 rq:1067562 version:76 Changes: -------- --- /work/SRC/openSUSE:Factory/ndctl/ndctl.changes 2023-01-14 20:31:50.533256972 +0100 +++ /work/SRC/openSUSE:Factory/.ndctl.new.31432/ndctl.changes 2023-02-25 19:54:51.735174342 +0100 @@ -1,0 +2,11 @@ +Thu Feb 23 09:40:09 UTC 2023 - Michal Suchanek <msucha...@suse.com> + +- Update to version 76 + * daxctl-online-memory: fix a memblock enumeration off-by-one + * daxctl-online-memory: tolerate non-memblock sysfs attrs that start with 'memory_' + * cxl-monitor: new command to monitor CXL events +- Add build fixes for TW and Leap + + cxl-monitor-fix-include-paths-for-tracefs-and-tracee.patch + + cxl-event-trace-use-the-wrapped-util_json_new_u64.patch + +------------------------------------------------------------------- Old: ---- ndctl-75.tar.gz New: ---- cxl-event-trace-use-the-wrapped-util_json_new_u64.patch cxl-monitor-fix-include-paths-for-tracefs-and-tracee.patch ndctl-76.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ndctl.spec ++++++ --- /var/tmp/diff_new_pack.lCGEkw/_old 2023-02-25 19:54:53.331184178 +0100 +++ /var/tmp/diff_new_pack.lCGEkw/_new 2023-02-25 19:54:53.335184203 +0100 @@ -25,7 +25,7 @@ %define lname libndctl6 %define dname libndctl-devel Name: ndctl -Version: 75 +Version: 76 Release: 0 Summary: Manage "libnvdimm" subsystem devices (Non-volatile Memory) License: GPL-2.0-only @@ -33,7 +33,9 @@ URL: https://github.com/pmem/ndctl Source0: https://github.com/pmem/ndctl/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: ndctl-rpmlintrc -Patch14: harden_ndctl-monitor.service.patch +Patch: harden_ndctl-monitor.service.patch +Patch1: cxl-monitor-fix-include-paths-for-tracefs-and-tracee.patch +Patch2: cxl-event-trace-use-the-wrapped-util_json_new_u64.patch BuildRequires: keyutils-devel BuildRequires: libiniparser-devel BuildRequires: libtool @@ -45,6 +47,8 @@ BuildRequires: pkgconfig(json) BuildRequires: pkgconfig(json-c) BuildRequires: pkgconfig(libkmod) +BuildRequires: pkgconfig(libtraceevent) +BuildRequires: pkgconfig(libtracefs) BuildRequires: pkgconfig(libudev) BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(udev) @@ -150,10 +154,10 @@ fi %preun -%service_del_preun ndctl-monitor.service +%service_del_preun ndctl-monitor.service cxl-monitor.service %postun -%service_del_postun ndctl-monitor.service +%service_del_postun ndctl-monitor.service cxl-monitor.service %posttrans # Migration of modprobe.conf files to _modprobedir @@ -182,6 +186,7 @@ %config(noreplace) %{_sysconfdir}/ndctl.conf.d/ndctl.conf %dir %{_modprobedir} %{_modprobedir}/nvdimm-security.conf +%{_unitdir}/cxl-monitor.service %{_unitdir}/ndctl-monitor.service %dir %{_datadir}/bash-completion/ %dir %{_datadir}/bash-completion/completions/ ++++++ cxl-event-trace-use-the-wrapped-util_json_new_u64.patch ++++++ >From a440fd8ceb772af58ebeb770e56f9d20db96dde2 Mon Sep 17 00:00:00 2001 From: Vishal Verma <vishal.l.ve...@intel.com> Date: Thu, 23 Feb 2023 22:45:39 -0700 Subject: [PATCH 2/2] cxl/event-trace: use the wrapped util_json_new_u64() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream: Submitted https://patchwork.kernel.org/project/linux-nvdimm/patch/20230223-meson-build-fixes-v1-2-5fae3b606...@intel.com The json-c API json_object_new_uint64() is relatively new, and some distros may not have it available. There is already a wrapped version in util/json.h which falls back to the int64 API, based on meson's determination of the availability of the uint64 version at compile time. Replace the direct uint64 calls with this wrapped version. Link: https://github.com/pmem/ndctl/issues/233 Fixes: 8dedc6cf5e85 ("cxl: add a helper to parse trace events into a json object") Reported-by: Michal Suchánek <msucha...@suse.de> Cc: Dave Jiang <dave.ji...@intel.com> Cc: Dan Williams <dan.j.willi...@intel.com> Signed-off-by: Vishal Verma <vishal.l.ve...@intel.com> Reviewed-by: Ira Weiny <ira.we...@intel.com> --- cxl/event_trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cxl/event_trace.c b/cxl/event_trace.c index 926f446..db8cc85 100644 --- a/cxl/event_trace.c +++ b/cxl/event_trace.c @@ -25,7 +25,7 @@ static struct json_object *num_to_json(void *num, int elem_size, unsigned long f if (sign) return json_object_new_int64(*(int64_t *)num); else - return json_object_new_uint64(*(uint64_t *)num); + return util_json_new_u64(*(uint64_t *)num); } /* All others fit in a signed 64 bit */ @@ -98,7 +98,7 @@ static int cxl_event_to_json(struct tep_event *event, struct tep_record *record, } json_object_object_add(jevent, "event", jobj); - jobj = json_object_new_uint64(record->ts); + jobj = util_json_new_u64(record->ts); if (!jobj) { rc = -ENOMEM; goto err_jevent; -- 2.39.1 ++++++ cxl-monitor-fix-include-paths-for-tracefs-and-tracee.patch ++++++ >From db693a9eabe7dd6d4eccf5187b92481f3684698d Mon Sep 17 00:00:00 2001 From: Vishal Verma <vishal.l.ve...@intel.com> Date: Thu, 23 Feb 2023 22:45:38 -0700 Subject: [PATCH 1/2] cxl/monitor: fix include paths for tracefs and traceevent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream: Submitted https://patchwork.kernel.org/project/linux-nvdimm/patch/20230223-meson-build-fixes-v1-1-5fae3b606...@intel.com Distros vary on whether the above headers are placed in {prefix}/libtracefs/ or {prefix}/tracefs/, and likewise for traceevent. Since both of these libraries do ship with pkgconfig info to determine the exact include path, the respective #include statements can drop the {lib}trace{fs,event}/ prefix. Since the libraries are declared using meson's dependency() function, it already does the requisite pkgconfig parsing. Drop the above prefixes to allow the includes work on all distros. Link: https://github.com/pmem/ndctl/issues/234 Fixes: 8dedc6cf5e85 ("cxl: add a helper to parse trace events into a json object") Fixes: 7b237bc7a8ae ("cxl: add a helper to go through all current events and parse them") Reported-by: Michal Suchánek <msucha...@suse.de> Cc: Dave Jiang <dave.ji...@intel.com> Cc: Dan Williams <dan.j.willi...@intel.com> Signed-off-by: Vishal Verma <vishal.l.ve...@intel.com> Reviewed-by: Ira Weiny <ira.we...@intel.com> --- cxl/event_trace.c | 4 ++-- cxl/monitor.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cxl/event_trace.c b/cxl/event_trace.c index 76dd4e7..926f446 100644 --- a/cxl/event_trace.c +++ b/cxl/event_trace.c @@ -2,14 +2,14 @@ // Copyright (C) 2022, Intel Corp. All rights reserved. #include <stdio.h> #include <errno.h> +#include <event-parse.h> #include <json-c/json.h> #include <util/json.h> #include <util/util.h> #include <util/strbuf.h> #include <ccan/list/list.h> #include <uuid/uuid.h> -#include <traceevent/event-parse.h> -#include <tracefs/tracefs.h> +#include <tracefs.h> #include "event_trace.h" #define _GNU_SOURCE diff --git a/cxl/monitor.c b/cxl/monitor.c index 749f472..e3469b9 100644 --- a/cxl/monitor.c +++ b/cxl/monitor.c @@ -4,6 +4,7 @@ #include <stdio.h> #include <unistd.h> #include <errno.h> +#include <event-parse.h> #include <json-c/json.h> #include <libgen.h> #include <time.h> @@ -16,8 +17,7 @@ #include <util/strbuf.h> #include <sys/epoll.h> #include <sys/stat.h> -#include <traceevent/event-parse.h> -#include <tracefs/tracefs.h> +#include <tracefs.h> #include <cxl/libcxl.h> /* reuse the core log helpers for the monitor logger */ -- 2.39.1 ++++++ harden_ndctl-monitor.service.patch ++++++ --- /var/tmp/diff_new_pack.lCGEkw/_old 2023-02-25 19:54:53.379184474 +0100 +++ /var/tmp/diff_new_pack.lCGEkw/_new 2023-02-25 19:54:53.383184498 +0100 @@ -1,7 +1,7 @@ -Index: ndctl-71.1/ndctl/ndctl-monitor.service +Index: ndctl-76/ndctl/ndctl-monitor.service =================================================================== ---- ndctl-71.1.orig/ndctl/ndctl-monitor.service -+++ ndctl-71.1/ndctl/ndctl-monitor.service +--- ndctl-76.orig/ndctl/ndctl-monitor.service ++++ ndctl-76/ndctl/ndctl-monitor.service @@ -2,6 +2,17 @@ Description=Ndctl Monitor Daemon @@ -16,8 +16,30 @@ +ProtectKernelLogs=true +ProtectControlGroups=true +RestrictRealtime=true -+# end of automatic additions ++# end of automatic additions Type=simple ExecStart=/usr/bin/ndctl monitor +Index: ndctl-76/cxl/cxl-monitor.service +=================================================================== +--- ndctl-76.orig/cxl/cxl-monitor.service ++++ ndctl-76/cxl/cxl-monitor.service +@@ -2,6 +2,17 @@ + Description=CXL Monitor Daemon + + [Service] ++# added automatically, for details please see ++# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort ++ProtectSystem=full ++ProtectHome=true ++ProtectHostname=true ++ProtectKernelTunables=true ++ProtectKernelModules=true ++ProtectKernelLogs=true ++ProtectControlGroups=true ++RestrictRealtime=true ++# end of automatic additions + Type=simple + ExecStart=/usr/bin/cxl monitor + ++++++ ndctl-75.tar.gz -> ndctl-76.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/Documentation/cxl/cxl-monitor.txt new/ndctl-76/Documentation/cxl/cxl-monitor.txt --- old/ndctl-75/Documentation/cxl/cxl-monitor.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/ndctl-76/Documentation/cxl/cxl-monitor.txt 2023-02-22 23:35:07.000000000 +0100 @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 + +cxl-monitor(1) +============== + +NAME +---- +cxl-monitor - Monitor the CXL trace events + +SYNOPSIS +-------- +[verse] +'cxl monitor' [<options>] + +DESCRIPTION +----------- +cxl-monitor is used for monitoring the CXL trace events emitted by +the kernel and convert them to json objects and dumping the json format +notifications to standard output or a logfile. + +EXAMPLES +-------- + +Run a monitor as a daemon to monitor events and output to a log file. +[verse] +cxl monitor --daemon --log=/var/log/cxl-monitor.log + +Run a monitor as a one-shot command and output the notifications to stdio. +[verse] +cxl monitor + +Run a monitor daemon as a system service +[verse] +systemctl start cxl-monitor.service + +OPTIONS +------- +-l:: +--log=:: + Send log messages to the specified destination. + - "<file>": + Send log messages to specified <file>. When fopen() is not able + to open <file>, log messages will be forwarded to syslog. + - "standard": + Send messages to standard output. + +The default log destination is '/var/log/cxl-monitor.log' if "--daemon" is specified, +otherwise 'standard'. Note that standard and relative path for <file> +will not work if "--daemon" is specified. + +--daemon:: + Run a monitor as a daemon. + +include::verbose-option.txt[] + +include::human-option.txt[] + +include::../copyright.txt[] + +SEE ALSO +-------- +linkcxl:cxl-list[1] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/Documentation/cxl/meson.build new/ndctl-76/Documentation/cxl/meson.build --- old/ndctl-75/Documentation/cxl/meson.build 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/Documentation/cxl/meson.build 2023-02-22 23:35:07.000000000 +0100 @@ -45,6 +45,7 @@ 'cxl-disable-region.txt', 'cxl-enable-region.txt', 'cxl-destroy-region.txt', + 'cxl-monitor.txt', ] foreach man : cxl_manpages diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/builtin.h new/ndctl-76/cxl/builtin.h --- old/ndctl-75/cxl/builtin.h 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/cxl/builtin.h 2023-02-22 23:35:07.000000000 +0100 @@ -22,4 +22,5 @@ int cmd_enable_region(int argc, const char **argv, struct cxl_ctx *ctx); int cmd_disable_region(int argc, const char **argv, struct cxl_ctx *ctx); int cmd_destroy_region(int argc, const char **argv, struct cxl_ctx *ctx); +int cmd_monitor(int argc, const char **argv, struct cxl_ctx *ctx); #endif /* _CXL_BUILTIN_H_ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/cxl-monitor.service new/ndctl-76/cxl/cxl-monitor.service --- old/ndctl-75/cxl/cxl-monitor.service 1970-01-01 01:00:00.000000000 +0100 +++ new/ndctl-76/cxl/cxl-monitor.service 2023-02-22 23:35:07.000000000 +0100 @@ -0,0 +1,9 @@ +[Unit] +Description=CXL Monitor Daemon + +[Service] +Type=simple +ExecStart=/usr/bin/cxl monitor + +[Install] +WantedBy=multi-user.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/cxl.c new/ndctl-76/cxl/cxl.c --- old/ndctl-75/cxl/cxl.c 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/cxl/cxl.c 2023-02-22 23:35:07.000000000 +0100 @@ -76,6 +76,7 @@ { "enable-region", .c_fn = cmd_enable_region }, { "disable-region", .c_fn = cmd_disable_region }, { "destroy-region", .c_fn = cmd_destroy_region }, + { "monitor", .c_fn = cmd_monitor }, }; int main(int argc, const char **argv) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/event_trace.c new/ndctl-76/cxl/event_trace.c --- old/ndctl-75/cxl/event_trace.c 1970-01-01 01:00:00.000000000 +0100 +++ new/ndctl-76/cxl/event_trace.c 2023-02-22 23:35:07.000000000 +0100 @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2022, Intel Corp. All rights reserved. +#include <stdio.h> +#include <errno.h> +#include <json-c/json.h> +#include <util/json.h> +#include <util/util.h> +#include <util/strbuf.h> +#include <ccan/list/list.h> +#include <uuid/uuid.h> +#include <traceevent/event-parse.h> +#include <tracefs/tracefs.h> +#include "event_trace.h" + +#define _GNU_SOURCE +#include <string.h> + +static struct json_object *num_to_json(void *num, int elem_size, unsigned long flags) +{ + bool sign = flags & TEP_FIELD_IS_SIGNED; + int64_t val = 0; + + /* special case 64 bit as the call depends on sign */ + if (elem_size == 8) { + if (sign) + return json_object_new_int64(*(int64_t *)num); + else + return json_object_new_uint64(*(uint64_t *)num); + } + + /* All others fit in a signed 64 bit */ + switch (elem_size) { + case 1: + if (sign) + val = *(int8_t *)num; + else + val = *(uint8_t *)num; + break; + case 2: + if (sign) + val = *(int16_t *)num; + else + val = *(uint16_t *)num; + break; + case 4: + if (sign) + val = *(int32_t *)num; + else + val = *(uint32_t *)num; + break; + default: + /* + * Odd sizes are converted in the kernel to one of the above. + * It is an error to see them here. + */ + return NULL; + } + + return json_object_new_int64(val); +} + +static int cxl_event_to_json(struct tep_event *event, struct tep_record *record, + struct list_head *jlist_head) +{ + struct json_object *jevent, *jobj, *jarray; + struct tep_format_field **fields; + struct jlist_node *jnode; + int i, j, rc = 0; + + jnode = malloc(sizeof(*jnode)); + if (!jnode) + return -ENOMEM; + + jevent = json_object_new_object(); + if (!jevent) { + rc = -ENOMEM; + goto err_jnode; + } + jnode->jobj = jevent; + + fields = tep_event_fields(event); + if (!fields) { + rc = -ENOENT; + goto err_jevent; + } + + jobj = json_object_new_string(event->system); + if (!jobj) { + rc = -ENOMEM; + goto err_jevent; + } + json_object_object_add(jevent, "system", jobj); + + jobj = json_object_new_string(event->name); + if (!jobj) { + rc = -ENOMEM; + goto err_jevent; + } + json_object_object_add(jevent, "event", jobj); + + jobj = json_object_new_uint64(record->ts); + if (!jobj) { + rc = -ENOMEM; + goto err_jevent; + } + json_object_object_add(jevent, "timestamp", jobj); + + for (i = 0; fields[i]; i++) { + struct tep_format_field *f = fields[i]; + int len; + + if (f->flags & TEP_FIELD_IS_STRING) { + char *str; + + str = tep_get_field_raw(NULL, event, f->name, record, &len, 0); + if (!str) + continue; + + jobj = json_object_new_string(str); + if (!jobj) { + rc = -ENOMEM; + goto err_jevent; + } + + json_object_object_add(jevent, f->name, jobj); + } else if (f->flags & TEP_FIELD_IS_ARRAY) { + unsigned char *data; + int chunks; + + data = tep_get_field_raw(NULL, event, f->name, record, &len, 0); + if (!data) + continue; + + jarray = json_object_new_array(); + if (!jarray) { + rc = -ENOMEM; + goto err_jevent; + } + + chunks = f->size / f->elementsize; + for (j = 0; j < chunks; j++) { + jobj = num_to_json(data, f->elementsize, f->flags); + if (!jobj) { + json_object_put(jarray); + rc = -ENOMEM; + goto err_jevent; + } + json_object_array_add(jarray, jobj); + data += f->elementsize; + } + + json_object_object_add(jevent, f->name, jarray); + } else { /* single number */ + unsigned char *data; + char *tmp; + + data = tep_get_field_raw(NULL, event, f->name, record, &len, 0); + if (!data) + continue; + + /* check to see if we have a UUID */ + tmp = strcasestr(f->type, "uuid_t"); + if (tmp) { + char uuid[40]; + + uuid_unparse(data, uuid); + jobj = json_object_new_string(uuid); + if (!jobj) { + rc = -ENOMEM; + goto err_jevent; + } + + json_object_object_add(jevent, f->name, jobj); + continue; + } + + jobj = num_to_json(data, f->elementsize, f->flags); + if (!jobj) { + rc = -ENOMEM; + goto err_jevent; + } + + json_object_object_add(jevent, f->name, jobj); + } + } + + list_add_tail(jlist_head, &jnode->list); + return 0; + +err_jevent: + json_object_put(jevent); +err_jnode: + free(jnode); + return rc; +} + +static int cxl_event_parse(struct tep_event *event, struct tep_record *record, + int cpu, void *ctx) +{ + struct event_ctx *event_ctx = (struct event_ctx *)ctx; + + /* Filter out all the events that the caller isn't interested in. */ + if (strcmp(event->system, event_ctx->system) != 0) + return 0; + + if (event_ctx->event_name) { + if (strcmp(event->name, event_ctx->event_name) != 0) + return 0; + } + + if (event_ctx->parse_event) + return event_ctx->parse_event(event, record, + &event_ctx->jlist_head); + + return cxl_event_to_json(event, record, &event_ctx->jlist_head); +} + +int cxl_parse_events(struct tracefs_instance *inst, struct event_ctx *ectx) +{ + struct tep_handle *tep; + int rc; + + tep = tracefs_local_events(NULL); + if (!tep) + return -ENOMEM; + + rc = tracefs_iterate_raw_events(tep, inst, NULL, 0, cxl_event_parse, + ectx); + tep_free(tep); + return rc; +} + +int cxl_event_tracing_enable(struct tracefs_instance *inst, const char *system, + const char *event) +{ + int rc; + + rc = tracefs_event_enable(inst, system, event); + if (rc == -1) + return -errno; + + if (tracefs_trace_is_on(inst)) + return 0; + + tracefs_trace_on(inst); + return 0; +} + +int cxl_event_tracing_disable(struct tracefs_instance *inst) +{ + return tracefs_trace_off(inst); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/event_trace.h new/ndctl-76/cxl/event_trace.h --- old/ndctl-75/cxl/event_trace.h 1970-01-01 01:00:00.000000000 +0100 +++ new/ndctl-76/cxl/event_trace.h 2023-02-22 23:35:07.000000000 +0100 @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2022 Intel Corporation. All rights reserved. */ +#ifndef __CXL_EVENT_TRACE_H__ +#define __CXL_EVENT_TRACE_H__ + +#include <json-c/json.h> +#include <ccan/list/list.h> + +struct jlist_node { + struct json_object *jobj; + struct list_node list; +}; + +struct event_ctx { + const char *system; + struct list_head jlist_head; + const char *event_name; /* optional */ + int (*parse_event)(struct tep_event *event, struct tep_record *record, + struct list_head *jlist_head); /* optional */ +}; + +int cxl_parse_events(struct tracefs_instance *inst, struct event_ctx *ectx); +int cxl_event_tracing_enable(struct tracefs_instance *inst, const char *system, + const char *event); +int cxl_event_tracing_disable(struct tracefs_instance *inst); + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/lib/libcxl.c new/ndctl-76/cxl/lib/libcxl.c --- old/ndctl-75/cxl/lib/libcxl.c 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/cxl/lib/libcxl.c 2023-02-22 23:35:07.000000000 +0100 @@ -3091,9 +3091,6 @@ struct cxl_command_info *cinfo = &query->commands[cmd->query_idx]; size_t size; - if (!query) - return -EINVAL; - size = sizeof(struct cxl_send_command); cmd->send_cmd = calloc(1, size); if (!cmd->send_cmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/meson.build new/ndctl-76/cxl/meson.build --- old/ndctl-75/cxl/meson.build 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/cxl/meson.build 2023-02-22 23:35:07.000000000 +0100 @@ -7,8 +7,14 @@ 'memdev.c', 'json.c', 'filter.c', + 'event_trace.c', + 'monitor.c', ] +if get_option('systemd').enabled() + install_data('cxl-monitor.service', install_dir : systemdunitdir) +endif + cxl_tool = executable('cxl', cxl_src, include_directories : root_inc, @@ -19,6 +25,8 @@ kmod, json, versiondep, + traceevent, + tracefs, ], install : true, install_dir : rootbindir, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/cxl/monitor.c new/ndctl-76/cxl/monitor.c --- old/ndctl-75/cxl/monitor.c 1970-01-01 01:00:00.000000000 +0100 +++ new/ndctl-76/cxl/monitor.c 2023-02-22 23:35:07.000000000 +0100 @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2022, Intel Corp. All rights reserved. +/* Some bits copied from ndctl monitor code */ +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <json-c/json.h> +#include <libgen.h> +#include <time.h> +#include <dirent.h> +#include <ccan/list/list.h> +#include <util/json.h> +#include <util/util.h> +#include <util/parse-options.h> +#include <util/parse-configs.h> +#include <util/strbuf.h> +#include <sys/epoll.h> +#include <sys/stat.h> +#include <traceevent/event-parse.h> +#include <tracefs/tracefs.h> +#include <cxl/libcxl.h> + +/* reuse the core log helpers for the monitor logger */ +#ifndef ENABLE_LOGGING +#define ENABLE_LOGGING +#endif +#ifndef ENABLE_DEBUG +#define ENABLE_DEBUG +#endif +#include <util/log.h> + +#include "event_trace.h" + +static const char *cxl_system = "cxl"; +const char *default_log = "/var/log/cxl-monitor.log"; + +static struct monitor { + const char *log; + struct log_ctx ctx; + FILE *log_file; + bool human; + bool verbose; + bool daemon; +} monitor; + +static int monitor_event(struct cxl_ctx *ctx) +{ + int fd, epollfd, rc = 0, timeout = -1; + struct epoll_event ev, *events; + struct tracefs_instance *inst; + struct event_ctx ectx; + int jflag; + + events = calloc(1, sizeof(struct epoll_event)); + if (!events) { + err(&monitor, "alloc for events error\n"); + return -ENOMEM; + } + + epollfd = epoll_create1(0); + if (epollfd == -1) { + rc = -errno; + err(&monitor, "epoll_create1() error: %d\n", rc); + goto epoll_err; + } + + inst = tracefs_instance_create("cxl_monitor"); + if (!inst) { + rc = -errno; + err(&monitor, "tracefs_instance_create( failed: %d\n", rc); + goto inst_err; + } + + fd = tracefs_instance_file_open(inst, "trace_pipe", -1); + if (fd < 0) { + rc = fd; + err(&monitor, "tracefs_instance_file_open() err: %d\n", rc); + goto inst_file_err; + } + + memset(&ev, 0, sizeof(ev)); + ev.events = EPOLLIN; + ev.data.fd = fd; + + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) != 0) { + rc = -errno; + err(&monitor, "epoll_ctl() error: %d\n", rc); + goto epoll_ctl_err; + } + + rc = cxl_event_tracing_enable(inst, cxl_system, NULL); + if (rc < 0) { + err(&monitor, "cxl_trace_event_enable() failed: %d\n", rc); + goto event_en_err; + } + + memset(&ectx, 0, sizeof(ectx)); + ectx.system = cxl_system; + if (monitor.human) + jflag = JSON_C_TO_STRING_PRETTY; + else + jflag = JSON_C_TO_STRING_PLAIN; + + while (1) { + struct jlist_node *jnode, *next; + + rc = epoll_wait(epollfd, events, 1, timeout); + if (rc < 0) { + rc = -errno; + if (errno != EINTR) + err(&monitor, "epoll_wait error: %d\n", -errno); + break; + } + + list_head_init(&ectx.jlist_head); + rc = cxl_parse_events(inst, &ectx); + if (rc < 0) + goto parse_err; + + if (list_empty(&ectx.jlist_head)) + continue; + + list_for_each_safe(&ectx.jlist_head, jnode, next, list) { + notice(&monitor, "%s\n", + json_object_to_json_string_ext(jnode->jobj, jflag)); + list_del(&jnode->list); + json_object_put(jnode->jobj); + free(jnode); + } + } + +parse_err: + if (cxl_event_tracing_disable(inst) < 0) + err(&monitor, "failed to disable tracing\n"); +event_en_err: +epoll_ctl_err: + close(fd); +inst_file_err: + tracefs_instance_free(inst); +inst_err: + close(epollfd); +epoll_err: + free(events); + return rc; +} + +int cmd_monitor(int argc, const char **argv, struct cxl_ctx *ctx) +{ + const struct option options[] = { + OPT_FILENAME('l', "log", &monitor.log, + "<file> | standard", + "where to output the monitor's notification"), + OPT_BOOLEAN('\0', "daemon", &monitor.daemon, + "run cxl monitor as a daemon"), + OPT_BOOLEAN('u', "human", &monitor.human, + "use human friendly output formats"), + OPT_BOOLEAN('v', "verbose", &monitor.verbose, + "emit extra debug messages to log"), + OPT_END(), + }; + const char * const u[] = { + "cxl monitor [<options>]", + NULL + }; + const char *prefix ="./"; + int rc = 0, i; + + argc = parse_options_prefix(argc, argv, prefix, options, u, 0); + for (i = 0; i < argc; i++) + error("unknown parameter \"%s\"\n", argv[i]); + if (argc) + usage_with_options(u, options); + + log_init(&monitor.ctx, "cxl/monitor", "CXL_MONITOR_LOG"); + monitor.ctx.log_fn = log_standard; + + if (monitor.verbose) + monitor.ctx.log_priority = LOG_DEBUG; + else + monitor.ctx.log_priority = LOG_INFO; + + if (monitor.log) { + if (strncmp(monitor.log, "./", 2) != 0) + fix_filename(prefix, (const char **)&monitor.log); + if (strncmp(monitor.log, "./standard", 10) == 0 && !monitor.daemon) { + monitor.ctx.log_fn = log_standard; + } else { + const char *log = monitor.log; + + if (!monitor.log) + log = default_log; + monitor.log_file = fopen(log, "a+"); + if (!monitor.log_file) { + rc = -errno; + error("open %s failed: %d\n", monitor.log, rc); + goto out; + } + monitor.ctx.log_fn = log_file; + } + } + + if (monitor.daemon) { + if (daemon(0, 0) != 0) { + err(&monitor, "daemon start failed\n"); + goto out; + } + info(&monitor, "cxl monitor daemon started.\n"); + } + + rc = monitor_event(ctx); + +out: + if (monitor.log_file) + fclose(monitor.log_file); + return rc; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/daxctl/lib/libdaxctl.c new/ndctl-76/daxctl/lib/libdaxctl.c --- old/ndctl-75/daxctl/lib/libdaxctl.c 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/daxctl/lib/libdaxctl.c 2023-02-22 23:35:07.000000000 +0100 @@ -1477,7 +1477,7 @@ err(ctx, "%s: Unable to determine resource\n", devname); return -EACCES; } - dev_end = dev_start + daxctl_dev_get_size(dev); + dev_end = dev_start + daxctl_dev_get_size(dev) - 1; memblock_size = daxctl_memory_get_block_size(mem); if (!memblock_size) { @@ -1552,6 +1552,8 @@ errno = 0; while ((de = readdir(node_dir)) != NULL) { if (strncmp(de->d_name, "memory", 6) == 0) { + if (strncmp(de->d_name, "memory_", 7) == 0) + continue; rc = memblock_in_dev(mem, de->d_name); if (rc < 0) goto out_dir; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/git-version new/ndctl-76/git-version --- old/ndctl-75/git-version 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/git-version 2023-02-22 23:35:07.000000000 +0100 @@ -19,7 +19,7 @@ fi } -DEF_VER=75 +DEF_VER=76 LF=' ' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/meson.build new/ndctl-76/meson.build --- old/ndctl-75/meson.build 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/meson.build 2023-02-22 23:35:07.000000000 +0100 @@ -1,5 +1,5 @@ project('ndctl', 'c', - version : '74', + version : '76', license : [ 'GPL-2.0', 'LGPL-2.1', @@ -143,6 +143,9 @@ libudev = dependency('libudev') uuid = dependency('uuid') json = dependency('json-c') +traceevent = dependency('libtraceevent') +tracefs = dependency('libtracefs') + if get_option('docs').enabled() if get_option('asciidoctor').enabled() asciidoc = find_program('asciidoctor', required : true) @@ -292,15 +295,15 @@ add_project_arguments('-include', 'config.h', language : 'c') LIBNDCTL_CURRENT=27 -LIBNDCTL_REVISION=0 +LIBNDCTL_REVISION=1 LIBNDCTL_AGE=21 LIBDAXCTL_CURRENT=6 -LIBDAXCTL_REVISION=1 +LIBDAXCTL_REVISION=2 LIBDAXCTL_AGE=5 LIBCXL_CURRENT=4 -LIBCXL_REVISION=0 +LIBCXL_REVISION=1 LIBCXL_AGE=3 root_inc = include_directories(['.', 'ndctl', ]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/ndctl/lib/msft.c new/ndctl-76/ndctl/lib/msft.c --- old/ndctl-75/ndctl/lib/msft.c 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/ndctl/lib/msft.c 2023-02-22 23:35:07.000000000 +0100 @@ -2,6 +2,7 @@ // Copyright (C) 2016-2017 Dell, Inc. // Copyright (C) 2016 Hewlett Packard Enterprise Development LP // Copyright (C) 2016-2020, Intel Corporation. +/* Copyright (C) 2022 iXsystems, Inc. */ #include <stdlib.h> #include <limits.h> #include <util/log.h> @@ -12,12 +13,39 @@ #define CMD_MSFT(_c) ((_c)->msft) #define CMD_MSFT_SMART(_c) (CMD_MSFT(_c)->u.smart.data) +static const char *msft_cmd_desc(int fn) +{ + static const char * const descs[] = { + [NDN_MSFT_CMD_CHEALTH] = "critical_health", + [NDN_MSFT_CMD_NHEALTH] = "nvdimm_health", + [NDN_MSFT_CMD_EHEALTH] = "es_health", + }; + const char *desc; + + if (fn >= (int) ARRAY_SIZE(descs)) + return "unknown"; + desc = descs[fn]; + if (!desc) + return "unknown"; + return desc; +} + +static bool msft_cmd_is_supported(struct ndctl_dimm *dimm, int cmd) +{ + /* Handle this separately to support monitor mode */ + if (cmd == ND_CMD_SMART) + return true; + + return !!(dimm->cmd_mask & (1ULL << cmd)); +} + static u32 msft_get_firmware_status(struct ndctl_cmd *cmd) { return cmd->msft->u.smart.status; } -static struct ndctl_cmd *msft_dimm_cmd_new_smart(struct ndctl_dimm *dimm) +static struct ndctl_cmd *alloc_msft_cmd(struct ndctl_dimm *dimm, + unsigned int func, size_t in_size, size_t out_size) { struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm); struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); @@ -30,12 +58,12 @@ return NULL; } - if (test_dimm_dsm(dimm, NDN_MSFT_CMD_SMART) == DIMM_DSM_UNSUPPORTED) { + if (test_dimm_dsm(dimm, func) == DIMM_DSM_UNSUPPORTED) { dbg(ctx, "unsupported function\n"); return NULL; } - size = sizeof(*cmd) + sizeof(struct ndn_pkg_msft); + size = sizeof(*cmd) + sizeof(struct nd_cmd_pkg) + in_size + out_size; cmd = calloc(1, size); if (!cmd) return NULL; @@ -48,22 +76,27 @@ msft = CMD_MSFT(cmd); msft->gen.nd_family = NVDIMM_FAMILY_MSFT; - msft->gen.nd_command = NDN_MSFT_CMD_SMART; + msft->gen.nd_command = func; msft->gen.nd_fw_size = 0; - msft->gen.nd_size_in = offsetof(struct ndn_msft_smart, status); - msft->gen.nd_size_out = sizeof(msft->u.smart); + msft->gen.nd_size_in = in_size; + msft->gen.nd_size_out = out_size; msft->u.smart.status = 0; cmd->get_firmware_status = msft_get_firmware_status; return cmd; } +static struct ndctl_cmd *msft_dimm_cmd_new_smart(struct ndctl_dimm *dimm) +{ + return alloc_msft_cmd(dimm, NDN_MSFT_CMD_NHEALTH, 0, + sizeof(struct ndn_msft_smart)); +} + static int msft_smart_valid(struct ndctl_cmd *cmd) { if (cmd->type != ND_CMD_CALL || - cmd->size != sizeof(*cmd) + sizeof(struct ndn_pkg_msft) || CMD_MSFT(cmd)->gen.nd_family != NVDIMM_FAMILY_MSFT || - CMD_MSFT(cmd)->gen.nd_command != NDN_MSFT_CMD_SMART || + CMD_MSFT(cmd)->gen.nd_command != NDN_MSFT_CMD_NHEALTH || cmd->status != 0) return cmd->status < 0 ? cmd->status : -EINVAL; return 0; @@ -80,28 +113,33 @@ } /* below health data can be retrieved via MSFT _DSM function 11 */ - return NDN_MSFT_SMART_HEALTH_VALID | - NDN_MSFT_SMART_TEMP_VALID | - NDN_MSFT_SMART_USED_VALID; + return ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID | + ND_SMART_USED_VALID | ND_SMART_ALARM_VALID; } -static unsigned int num_set_bit_health(__u16 num) +static unsigned int msft_cmd_smart_get_health(struct ndctl_cmd *cmd) { - int i; - __u16 n = num & 0x7FFF; - unsigned int count = 0; + unsigned int health = 0; + int rc; - for (i = 0; i < 15; i++) - if (!!(n & (1 << i))) - count++; + rc = msft_smart_valid(cmd); + if (rc < 0) { + errno = -rc; + return UINT_MAX; + } - return count; + if (CMD_MSFT_SMART(cmd)->nvm_lifetime == 0) + health |= ND_SMART_FATAL_HEALTH; + if (CMD_MSFT_SMART(cmd)->health != 0 || + CMD_MSFT_SMART(cmd)->err_thresh_stat != 0) + health |= ND_SMART_CRITICAL_HEALTH; + if (CMD_MSFT_SMART(cmd)->warn_thresh_stat != 0) + health |= ND_SMART_NON_CRITICAL_HEALTH; + return health; } -static unsigned int msft_cmd_smart_get_health(struct ndctl_cmd *cmd) +static unsigned int msft_cmd_smart_get_media_temperature(struct ndctl_cmd *cmd) { - unsigned int health; - unsigned int num; int rc; rc = msft_smart_valid(cmd); @@ -110,21 +148,13 @@ return UINT_MAX; } - num = num_set_bit_health(CMD_MSFT_SMART(cmd)->health); - if (num == 0) - health = 0; - else if (num < 2) - health = ND_SMART_NON_CRITICAL_HEALTH; - else if (num < 3) - health = ND_SMART_CRITICAL_HEALTH; - else - health = ND_SMART_FATAL_HEALTH; - - return health; + return CMD_MSFT_SMART(cmd)->temp * 16; } -static unsigned int msft_cmd_smart_get_media_temperature(struct ndctl_cmd *cmd) +static unsigned int msft_cmd_smart_get_alarm_flags(struct ndctl_cmd *cmd) { + __u8 stat; + unsigned int flags = 0; int rc; rc = msft_smart_valid(cmd); @@ -133,7 +163,13 @@ return UINT_MAX; } - return CMD_MSFT_SMART(cmd)->temp * 16; + stat = CMD_MSFT_SMART(cmd)->err_thresh_stat | + CMD_MSFT_SMART(cmd)->warn_thresh_stat; + if (stat & 3) /* NVM_LIFETIME/ES_LIFETIME */ + flags |= ND_SMART_SPARE_TRIP; + if (stat & 4) /* ES_TEMP */ + flags |= ND_SMART_CTEMP_TRIP; + return flags; } static unsigned int msft_cmd_smart_get_life_used(struct ndctl_cmd *cmd) @@ -171,10 +207,13 @@ } struct ndctl_dimm_ops * const msft_dimm_ops = &(struct ndctl_dimm_ops) { + .cmd_desc = msft_cmd_desc, + .cmd_is_supported = msft_cmd_is_supported, .new_smart = msft_dimm_cmd_new_smart, .smart_get_flags = msft_cmd_smart_get_flags, .smart_get_health = msft_cmd_smart_get_health, .smart_get_media_temperature = msft_cmd_smart_get_media_temperature, + .smart_get_alarm_flags = msft_cmd_smart_get_alarm_flags, .smart_get_life_used = msft_cmd_smart_get_life_used, .xlat_firmware_status = msft_cmd_xlat_firmware_status, }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/ndctl/lib/msft.h new/ndctl-76/ndctl/lib/msft.h --- old/ndctl-75/ndctl/lib/msft.h 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/ndctl/lib/msft.h 2023-02-22 23:35:07.000000000 +0100 @@ -2,21 +2,16 @@ /* Copyright (C) 2016-2017 Dell, Inc. */ /* Copyright (C) 2016 Hewlett Packard Enterprise Development LP */ /* Copyright (C) 2014-2020, Intel Corporation. */ +/* Copyright (C) 2022 iXsystems, Inc. */ #ifndef __NDCTL_MSFT_H__ #define __NDCTL_MSFT_H__ enum { - NDN_MSFT_CMD_QUERY = 0, - - /* non-root commands */ - NDN_MSFT_CMD_SMART = 11, + NDN_MSFT_CMD_CHEALTH = 10, + NDN_MSFT_CMD_NHEALTH = 11, + NDN_MSFT_CMD_EHEALTH = 12, }; -/* NDN_MSFT_CMD_SMART */ -#define NDN_MSFT_SMART_HEALTH_VALID ND_SMART_HEALTH_VALID -#define NDN_MSFT_SMART_TEMP_VALID ND_SMART_TEMP_VALID -#define NDN_MSFT_SMART_USED_VALID ND_SMART_USED_VALID - /* * This is actually function 11 data, * This is the closest I can find to match smart diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/ndctl/monitor.c new/ndctl-76/ndctl/monitor.c --- old/ndctl-75/ndctl/monitor.c 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/ndctl/monitor.c 2023-02-22 23:35:07.000000000 +0100 @@ -33,7 +33,6 @@ const char *log; const char *configs; const char *dimm_event; - FILE *log_file; bool daemon; bool human; bool verbose; @@ -61,38 +60,6 @@ VERSION, __func__, __LINE__, ##__VA_ARGS__); \ } while (0) -static void log_syslog(struct log_ctx *ctx, int priority, const char *file, - int line, const char *fn, const char *format, va_list args) -{ - vsyslog(priority, format, args); -} - -static void log_standard(struct log_ctx *ctx, int priority, const char *file, - int line, const char *fn, const char *format, va_list args) -{ - if (priority == 6) - vfprintf(stdout, format, args); - else - vfprintf(stderr, format, args); -} - -static void log_file(struct log_ctx *ctx, int priority, const char *file, - int line, const char *fn, const char *format, va_list args) -{ - FILE *f = monitor.log_file; - - if (priority != LOG_NOTICE) { - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - fprintf(f, "[%10ld.%09ld] [%d] ", ts.tv_sec, ts.tv_nsec, getpid()); - vfprintf(f, format, args); - } else - vfprintf(f, format, args); - - fflush(f); -} - static struct json_object *dimm_event_to_json(struct monitor_dimm *mdimm) { struct json_object *jevent, *jobj; @@ -648,8 +615,8 @@ else if (strncmp(monitor.log, "./standard", 10) == 0) monitor.ctx.log_fn = log_standard; else { - monitor.log_file = fopen(monitor.log, "a+"); - if (!monitor.log_file) { + monitor.ctx.log_file = fopen(monitor.log, "a+"); + if (!monitor.ctx.log_file) { error("open %s failed\n", monitor.log); rc = -errno; goto out; @@ -694,8 +661,8 @@ rc = monitor_event(ctx, &mfa); out: - if (monitor.log_file) - fclose(monitor.log_file); + if (monitor.ctx.log_file) + fclose(monitor.ctx.log_file); if (path) free(path); return rc; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/ndctl.spec.in new/ndctl-76/ndctl.spec.in --- old/ndctl-75/ndctl.spec.in 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/ndctl.spec.in 2023-02-22 23:35:07.000000000 +0100 @@ -31,6 +31,8 @@ BuildRequires: systemd-rpm-macros BuildRequires: iniparser-devel BuildRequires: meson +BuildRequires: libtraceevent-devel +BuildRequires: libtracefs-devel %description Utility library for managing the "libnvdimm" subsystem. The "libnvdimm" @@ -200,6 +202,7 @@ %{_bindir}/cxl %{_mandir}/man1/cxl* %{bashcompdir}/cxl +%{_unitdir}/cxl-monitor.service %files -n LNAME %defattr(-,root,root) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/test/cxl-xor-region.sh new/ndctl-76/test/cxl-xor-region.sh --- old/ndctl-75/test/cxl-xor-region.sh 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/test/cxl-xor-region.sh 2023-02-22 23:35:07.000000000 +0100 @@ -4,7 +4,7 @@ . $(dirname $0)/common -rc=1 +rc=77 set -ex @@ -15,6 +15,7 @@ modprobe -r cxl_test modprobe cxl_test interleave_arithmetic=1 udevadm settle +rc=1 # THEORY OF OPERATION: Create x1,2,3,4 regions to exercise the XOR math # option of the CXL driver. As with other cxl_test tests, changes to the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/test/security.sh new/ndctl-76/test/security.sh --- old/ndctl-75/test/security.sh 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/test/security.sh 2023-02-22 23:35:07.000000000 +0100 @@ -225,6 +225,7 @@ fi modprobe "$KMOD_TEST" +cxl list setup check_prereq "keyctl" rc=1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/util/log.c new/ndctl-76/util/log.c --- old/ndctl-75/util/log.c 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/util/log.c 2023-02-22 23:35:07.000000000 +0100 @@ -2,11 +2,45 @@ // Copyright (C) 2016-2020, Intel Corporation. All rights reserved. #include <syslog.h> #include <stdlib.h> +#include <unistd.h> #include <ctype.h> #include <string.h> #include <errno.h> +#include <time.h> #include <util/log.h> +void log_syslog(struct log_ctx *ctx, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + vsyslog(priority, format, args); +} + +void log_standard(struct log_ctx *ctx, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + if (priority == 6) + vfprintf(stdout, format, args); + else + vfprintf(stderr, format, args); +} + +void log_file(struct log_ctx *ctx, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + FILE *f = ctx->log_file; + + if (priority != LOG_NOTICE) { + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &ts); + fprintf(f, "[%10ld.%09ld] [%d] ", ts.tv_sec, ts.tv_nsec, + getpid()); + } + + vfprintf(f, format, args); + fflush(f); +} + void do_log(struct log_ctx *ctx, int priority, const char *file, int line, const char *fn, const char *format, ...) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ndctl-75/util/log.h new/ndctl-76/util/log.h --- old/ndctl-75/util/log.h 2023-01-13 05:56:10.000000000 +0100 +++ new/ndctl-76/util/log.h 2023-02-22 23:35:07.000000000 +0100 @@ -14,9 +14,15 @@ log_fn log_fn; const char *owner; int log_priority; + FILE *log_file; }; - +void log_syslog(struct log_ctx *ctx, int priority, const char *file, int line, + const char *fn, const char *format, va_list args); +void log_standard(struct log_ctx *ctx, int priority, const char *file, int line, + const char *fn, const char *format, va_list args); +void log_file(struct log_ctx *ctx, int priority, const char *file, int line, + const char *fn, const char *format, va_list args); void do_log(struct log_ctx *ctx, int priority, const char *file, int line, const char *fn, const char *format, ...) __attribute__((format(printf, 6, 7)));