From: Keith Busch Date: Thu, 6 Feb 2020 20:53:30 +0000 (-0800) Subject: Add a telemetry scan example X-Git-Tag: v1.0-rc0~199 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=b4cd4f848e70f22682f1cb3de311f473981d278b;p=users%2Fsagi%2Flibnvme.git Add a telemetry scan example Copy the liburing directory structure and start adding examples. The first example monitors all devices for telemetry events, and if available will write out the telemetry log to a file in /var/log/. While developing the example, some other misc fixes and updates were added to the library code. Signed-off-by: Keith Busch --- diff --git a/Makefile b/Makefile index 800b9e88..32bc5afc 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,70 @@ -CFLAGS = -O2 -g -Wall -Werror -std=gnu99 -D_GNU_SOURCE -LDFLAGS = -Ilib -Llib -lnvme +NAME=libnvme +SPECFILE=$(NAME).spec +VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) +TAG = $(NAME)-$(VERSION) +RPMBUILD=$(shell `which rpmbuild >&/dev/null` && echo "rpmbuild" || echo "rpm") -QUIET_CC = @echo ' ' CC $@; +INSTALL=install -test: test/test.c libnvme - $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) $< -o test/test $(LDFLAGS) +default: all -libnvme: - @$(MAKE) -C lib/ +all: + @$(MAKE) -C src + @$(MAKE) -C test + @$(MAKE) -C examples + +runtests: all + @$(MAKE) -C test runtests +runtests-loop: + @$(MAKE) -C test runtests-loop + +config-host.mak: configure + @if [ ! -e "$@" ]; then \ + echo "Running configure ..."; \ + ./configure; \ + else \ + echo "$@ is out-of-date, running configure"; \ + sed -n "/.*Configured with/s/[^:]*: //p" "$@" | sh; \ + fi + +ifneq ($(MAKECMDGOALS),clean) +include config-host.mak +endif + +%.pc: %.pc.in config-host.mak $(SPECFILE) + sed -e "s%@prefix@%$(prefix)%g" \ + -e "s%@libdir@%$(libdir)%g" \ + -e "s%@includedir@%$(includedir)%g" \ + -e "s%@NAME@%$(NAME)%g" \ + -e "s%@VERSION@%$(VERSION)%g" \ + $< >$@ + +install: $(NAME).pc + @$(MAKE) -C src install prefix=$(DESTDIR)$(prefix) includedir=$(DESTDIR)$(includedir) libdir=$(DESTDIR)$(libdir) + $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc + $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man2 + $(INSTALL) -m 644 man/*.2 $(DESTDIR)$(mandir)/man2 + +install-tests: + @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) clean: - rm -f test/test - $(MAKE) -C lib clean + @rm -f config-host.mak config-host.h cscope.out $(NAME).pc + @$(MAKE) -C src clean + @$(MAKE) -C test clean + @$(MAKE) -C examples clean + +cscope: + @cscope -b -R + +tag-archive: + @git tag $(TAG) + +create-archive: + @git archive --prefix=$(NAME)-$(VERSION)/ -o $(NAME)-$(VERSION).tar.gz $(TAG) + @echo "The final archive is ./$(NAME)-$(VERSION).tar.gz." +archive: clean tag-archive create-archive -.PHONY: libnvme test +srpm: create-archive + $(RPMBUILD) --define "_sourcedir `pwd`" --define "_srcrpmdir `pwd`" --nodeps -bs $(SPECFILE) diff --git a/Makefile.quiet b/Makefile.quiet new file mode 100644 index 00000000..8eac349a --- /dev/null +++ b/Makefile.quiet @@ -0,0 +1,10 @@ +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_LINK = @echo ' ' LINK $@; + QUIET_AR = @echo ' ' AR $@; + QUIET_RANLIB = @echo '' RANLIB $@; +endif +endif + + diff --git a/configure b/configure new file mode 100755 index 00000000..63d26a50 --- /dev/null +++ b/configure @@ -0,0 +1,191 @@ +#!/bin/sh +# +# +if test ! -z "$TMPDIR" ; then + TMPDIR1="${TMPDIR}" +elif test ! -z "$TEMPDIR" ; then + TMPDIR1="${TEMPDIR}" +else + TMPDIR1="/tmp" +fi + +cc=gcc +ld=ld + +for opt do + optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') + case "$opt" in + --help|-h) show_help=yes + ;; + --prefix=*) prefix="$optarg" + ;; + --includedir=*) includedir="$optarg" + ;; + --libdir=*) libdir="$optarg" + ;; + --mandir=*) mandir="$optarg" + ;; + --datadir=*) datadir="$optarg" + ;; + *) + echo "ERROR: unkown option $opt" + echo "Try '$0 --help' for more information" + exit 1 + ;; + esac +done + +if test -z "$prefix"; then + prefix=/usr +fi +if test -z "$includedir"; then + includedir="$prefix/include" +fi +if test -z "$libdir"; then + libdir="$prefix/lib" +fi +if test -z "$mandir"; then + mandir="$prefix/man" +fi +if test -z "$datadir"; then + datadir="$prefix/share" +fi + +if test "$show_help" = "yes"; then +cat < $config_host_h +echo " * Automatically generated by configure - do not modify" >> $config_host_h +printf " * Configured with:" >> $config_host_h +printf " * '%s'" "$0" "$@" >> $config_host_h +echo "" >> $config_host_h +echo " */" >> $config_host_h + +echo "# Automatically generated by configure - do not modify" > $config_host_mak +printf "# Configured with:" >> $config_host_mak +printf " '%s'" "$0" "$@" >> $config_host_mak +echo >> $config_host_mak + +do_cc() { + # Run the compiler, capturing its output to the log. + echo $cc "$@" >> config.log + $cc "$@" >> config.log 2>&1 || return $? + # Test passed. If this is an --enable-werror build, rerun + # the test with -Werror and bail out if it fails. This + # makes warning-generating-errors in configure test code + # obvious to developers. + if test "$werror" != "yes"; then + return 0 + fi + # Don't bother rerunning the compile if we were already using -Werror + case "$*" in + *-Werror*) + return 0 + ;; + esac + echo $cc -Werror "$@" >> config.log + $cc -Werror "$@" >> config.log 2>&1 && return $? + echo "ERROR: configure test passed without -Werror but failed with -Werror." + echo "This is probably a bug in the configure script. The failing command" + echo "will be at the bottom of config.log." + fatal "You can run configure with --disable-werror to bypass this check." +} + +compile_object() { + do_cc $CFLAGS -c -o $TMPO $TMPC +} + +compile_prog() { + local_cflags="$1" + local_ldflags="$2 $LIBS" + echo "Compiling test case $3" >> config.log + do_cc $CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags +} + +has() { + type "$1" >/dev/null 2>&1 +} + +output_mak() { + echo "$1=$2" >> $config_host_mak +} + +output_sym() { + output_mak "$1" "y" + echo "#define $1" >> $config_host_h +} + +print_and_output_mak() { + print_config "$1" "$2" + output_mak "$1" "$2" +} + +print_and_output_mak "prefix" "$prefix" +print_and_output_mak "includedir" "$includedir" +print_and_output_mak "libdir" "$libdir" +print_and_output_mak "mandir" "$mandir" +print_and_output_mak "datadir" "$datadir" + +########################################## +# check for libuuid +libuuid="no" +${ld} -o /dev/null -luuid >/dev/null 2>&1 +if [ $? -eq 0 ]; then + libuuid="yes" +fi +print_config "libuuid" "${libuuid}" + +########################################## +# check for SystemD +havesystemd="no" +pkg-config --exists systemd --atleast-version=232 +if [ $? -eq 0 ]; then + havesystemd="yes" +fi +print_config "havesystemd" "${havesystemd}" + +if test "$libuuid" = "yes"; then + output_sym "LIBUUID" + echo "override LDFLAGS += -luuid" >> $config_host_mak + echo "override LIB_DEPENDS += uuid" >> $config_host_mak +fi +if test "$havesystemd" = "yes"; then + output_sym "HAVE_SYSTEMD" + echo "override LDFLAGS += -lsystemd" >> $config_host_mak +fi diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 00000000..baa7b083 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,22 @@ +CFLAGS ?= -g -O2 +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ + +include ../Makefile.quiet + +ifneq ($(MAKECMDGOALS),clean) +include ../config-host.mak +endif + +all_targets += nvme-telemetry + +all: $(all_targets) + +test_srcs := nvme-telemetry + +test_objs := $(patsubst %.c,%.ol,$(test_srcs)) + +%: %.c + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + +clean: + @rm -f $(all_targets) $(test_objs) diff --git a/examples/nvme-telemetry.c b/examples/nvme-telemetry.c new file mode 100644 index 00000000..1705462a --- /dev/null +++ b/examples/nvme-telemetry.c @@ -0,0 +1,158 @@ +/** + * Open all nvme controller's uevent and listen for changes. If NVME_AEN event + * is observed with controller telemetry data, read the log and save it to a + * file in /var/log/ with the device's unique name and epoch timestamp. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +struct events { + nvme_ctrl_t c; + int uevent_fd; +}; + +static int open_uevent(nvme_ctrl_t c) +{ + char buf[0x1000]; + if (snprintf(buf, sizeof(buf), "%s/uevent", nvme_ctrl_get_sysfs_dir(c)) < 0) + return -1; + return open(buf, O_RDONLY); +} + +static void save_telemetry(nvme_ctrl_t c) +{ + char buf[0x1000]; + __u32 log_size; + int ret, fd; + void *log; + time_t s; + + ret = nvme_get_telemetry_log(nvme_ctrl_get_fd(c), false, true, 3, &log, + &log_size); + if (ret) + return; + + /* Clear the log (rae == false) to see new telemetry events later */ + nvme_get_log_telemetry_ctrl(nvme_ctrl_get_fd(c), false, 0, sizeof(buf), + buf); + memset(buf, 0, sizeof(buf)); + + s = time(NULL); + ret = snprintf(buf, sizeof(buf), "/var/log/%s-telemetry-%ld", + nvme_ctrl_get_subsysnqn(c), s); + if (ret < 0) { + free(log); + return; + } + + fd = open(buf, O_CREAT|O_WRONLY, S_IRUSR|S_IRGRP); + if (fd < 0) { + free(log); + return; + } + + ret = write(fd, log, log_size); + if (ret < 0) + printf("failed to write telemetry log\n"); + else + printf("telemetry log save as %s, wrote:%d size:%d\n", buf, + ret, log_size); + + close(fd); + free(log); +} + +static void check_telemetry(nvme_ctrl_t c, int ufd) +{ + char buf[0x1000] = { 0 }; + char *p, *ptr; + + if (read(ufd, buf, sizeof(buf)) < 0) + return; + + ptr = buf; + while ((p = strsep(&ptr, "\n")) != NULL) { + __u32 aen, type, info, lid; + + if (sscanf(p, "NVME_AEN=0x%08x", &aen) != 1) + break; + + type = aen & 0x07; + info = (aen >> 8) & 0xff; + lid = (aen >> 16) & 0xff; + + printf("%s: aen type:%x info:%x lid:%d\n", + nvme_ctrl_get_name(c), type, info, lid); + if (type == NVME_AER_NOTICE && + info == NVME_AER_NOTICE_TELEMETRY) + save_telemetry(c); + } +} + +static void wait_events(fd_set *fds, struct events *e, int nr) +{ + int ret, i; + + for (i = 0; i < nr; i++) + check_telemetry(e[i].c, e[i].uevent_fd); + + while (1) { + ret = select(nr, fds, NULL, NULL, NULL); + if (ret < 0) + return; + + for (i = 0; i < nr; i++) { + if (!FD_ISSET(e[i].uevent_fd, fds)) + continue; + check_telemetry(e[i].c, e[i].uevent_fd); + } + } +} + +int main() +{ + struct events *e; + fd_set fds; + int i = 0; + + nvme_subsystem_t s; + nvme_ctrl_t c; + nvme_root_t r; + + r = nvme_scan(); + if (!r) + return EXIT_FAILURE; + + nvme_for_each_subsystem(r, s) + nvme_subsystem_for_each_ctrl(s, c) + i++; + + e = calloc(i, sizeof(e)); + FD_ZERO(&fds); + i = 0; + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + int fd = open_uevent(c); + + if (fd < 0) + continue; + FD_SET(fd, &fds); + e[i].uevent_fd = fd; + e[i].c = c; + i++; + } + } + + wait_events(&fds, e, i); + nvme_free_tree(r); + free(e); + + return EXIT_SUCCESS; +} diff --git a/lib/libnvme.pc.in b/libnvme.pc.in similarity index 84% rename from lib/libnvme.pc.in rename to libnvme.pc.in index 224dd54f..a1867aac 100644 --- a/lib/libnvme.pc.in +++ b/libnvme.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: @NAME@ Version: @VERSION@ Description: Manage "libnvme" subsystem devices (Non-volatile Memory Express) -URL: http://github.com/linux-nvme/nvme-cli/ +URL: http://github.com/linux-nvme/libnvme/ Libs: -L${libdir} -lnvme Cflags: -I${includedir} diff --git a/lib/libnvme.spec b/libnvme.spec similarity index 77% rename from lib/libnvme.spec rename to libnvme.spec index d131af9f..f3407d88 100644 --- a/lib/libnvme.spec +++ b/libnvme.spec @@ -1,44 +1,36 @@ Name: libnvme Version: 0.1 -Release: 1 +Release: 0 Summary: Linux-native nvme device management library License: LGPLv2+ -Group: System Environment/Libraries Source: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-root URL: http://github.com/linux-nvme/nvme-cli +BuildRequires: gcc %description -Provides library functions for accessing and managing nvme devices. +Provides library functions for accessing and managing nvme devices on a Linux +system. %package devel Summary: Development files for Linux-native nvme -Group: Development/System Requires: libnvme Provides: libnvme.so.1 %description devel This package provides header files to include and libraries to link with -for the Linux-native nvme. +for Linux-native nvme device maangement. %prep %setup %build ./configure --prefix=/usr --libdir=/%{_libdir} --mandir=/usr/share/man -make -%install -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT - -make install DESTDIR=$RPM_BUILD_ROOT - -%clean -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +%make_build -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig +%install +%make_install %files %defattr(-,root,root) diff --git a/lib/Makefile b/src/Makefile similarity index 100% rename from lib/Makefile rename to src/Makefile diff --git a/lib/libnvme.h b/src/libnvme.h similarity index 100% rename from lib/libnvme.h rename to src/libnvme.h diff --git a/lib/libnvme.map b/src/libnvme.map similarity index 100% rename from lib/libnvme.map rename to src/libnvme.map diff --git a/lib/nvme/cmd.h b/src/nvme/cmd.h similarity index 82% rename from lib/nvme/cmd.h rename to src/nvme/cmd.h index 1b34d744..3c80f45d 100644 --- a/lib/nvme/cmd.h +++ b/src/nvme/cmd.h @@ -118,29 +118,29 @@ enum nvme_identify_cns { * NVME_LOG_LID_PERSISTENT_EVENT: * NVME_LOG_LID_LBA_STATUS: * NVME_LOG_LID_ENDURANCE_GRP_EVT: - * NVME_LOG_LID_DISC: + * NVME_LOG_LID_DISCOVER: * NVME_LOG_LID_RESERVATION: * NVME_LOG_LID_SANITIZE: */ enum nvme_cmd_get_log_lid { NVME_LOG_LID_ERROR = 0x01, NVME_LOG_LID_SMART = 0x02, - NVME_LOG_LID_FW_SLOT = 0x03, - NVME_LOG_LID_CHANGED_NS = 0x04, + NVME_LOG_LID_FW_SLOT = 0x03, + NVME_LOG_LID_CHANGED_NS = 0x04, NVME_LOG_LID_CMD_EFFECTS = 0x05, - NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, + NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, NVME_LOG_LID_TELEMETRY_HOST = 0x07, NVME_LOG_LID_TELEMETRY_CTRL = 0x08, - NVME_LOG_LID_ENDURANCE_GROUP = 0x09, + NVME_LOG_LID_ENDURANCE_GROUP = 0x09, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, NVME_LOG_LID_ANA = 0x0c, - NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, - NVME_LOG_LID_LBA_STATUS = 0x0e, - NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, - NVME_LOG_LID_DISC = 0x70, + NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, + NVME_LOG_LID_LBA_STATUS = 0x0e, + NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_DISCOVER = 0x70, NVME_LOG_LID_RESERVATION = 0x80, - NVME_LOG_LID_SANITIZE = 0x81, + NVME_LOG_LID_SANITIZE = 0x81, }; /** @@ -503,7 +503,8 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); +int nvme_identify_allocated_ns_list(int fd, __u32 nsid, + struct nvme_ns_list *list); /** * nvme_identify_ctrl_list() - Retrieves identify controller list @@ -576,7 +577,8 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset); +int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, + struct nvme_id_nvmset_list *nvmset); /** * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller @@ -590,7 +592,8 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * Return: The nvme command status if a response was received or -1 * with errno set otherwise. */ -int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap); +int nvme_identify_primary_ctrl(int fd, __u16 cntid, + struct nvme_primary_ctrl_cap *cap); /** * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list @@ -609,7 +612,8 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list); +int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, + struct nvme_secondary_ctrl_list *list); /** * nvme_identify_ns_granularity() - Retrieves namespace granularity @@ -783,7 +787,8 @@ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); * @len: Length of provided user buffer to hold the log data in bytes * @log: User address for log page data */ -int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void *log); +int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, + void *log); /** * nvme_get_log_endurance_group() - @@ -801,7 +806,8 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log); +int nvme_get_log_endurance_group(int fd, __u16 endgid, + struct nvme_endurance_group_log *log); /** * nvme_get_log_predictable_lat_nvmset() - @@ -938,18 +944,36 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, /** * nvme_set_features_arbitration() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result); /** * nvme_set_features_power_mgmt() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); /** * nvme_set_features_lba_range() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); @@ -965,6 +989,12 @@ enum nvme_feat_tmpthresh_thsel { /** * nvme_set_features_temp_thresh() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, @@ -972,6 +1002,12 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, /** * nvme_set_features_err_recovery() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); @@ -979,18 +1015,36 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, /** * nvme_set_features_volatile_wc() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result); /** * nvme_set_features_irq_coalesce() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result); /** * nvme_set_features_irq_config() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); @@ -998,6 +1052,12 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, /** * nvme_set_features_write_atomic() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); @@ -1024,6 +1084,12 @@ enum nvme_features_async_event_config_flags { /** * nvme_set_features_async_event() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); @@ -1031,6 +1097,12 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, /** * nvme_set_features_auto_pst() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, @@ -1038,12 +1110,24 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, /** * nvme_set_features_timestamp() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @timestamp: The current timestamp value to assign to this this feature + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); /** * nvme_set_features_hctm() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); @@ -1056,12 +1140,24 @@ int nvme_admin_set_features_nopsc(int fd, bool noppme, bool save, /** * nvme_set_features_rrl() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result); /** * nvme_set_features_plm_config() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, @@ -1077,6 +1173,12 @@ enum nvme_feat_plm_window_select { /** * nvme_set_features_plm_window() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result); @@ -1084,6 +1186,12 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, /** * nvme_set_features_lba_sts_interval() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); @@ -1091,26 +1199,48 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, /** * nvme_set_features_host_behavior() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data); /** * nvme_set_features_sanitize() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); /** * nvme_set_features_endurance_evt_cfg() - - * @fd: + * @fd: File descriptor of nvme device * @endgid: * @egwarn: Flags to enable warning, see &enum nvme_eg_critical_warning_flags + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result); /** * nvme_set_features_sw_progress() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); @@ -1118,6 +1248,12 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, /** * nvme_set_features_host_id() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); @@ -1132,11 +1268,23 @@ enum nvme_feat_resv_notify_flags { /** * nvme_set_features_resv_mask() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); /** * nvme_set_features_resv_persist() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); @@ -1156,6 +1304,12 @@ enum nvme_feat_nswpcfg_state { /** * nvme_set_features_write_protect() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); @@ -1181,18 +1335,36 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, /** * nvme_get_features_arbitration() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_power_mgmt() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_lba_range() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, @@ -1200,92 +1372,188 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_temp_thresh() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_err_recovery() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_volatile_wc() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_num_queues() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_irq_coalesce() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_irq_config() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result); /** * nvme_get_features_write_atomic() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_async_event() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_auto_pst() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result); /** * nvme_get_features_host_mem_buf() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_timestamp() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts); /** * nvme_get_features_kato() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_hctm() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_nopsc() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_rrl() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_plm_config() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, @@ -1293,18 +1561,36 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_plm_window() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result); /** * nvme_get_features_lba_sts_interval() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_host_behavior() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, @@ -1312,42 +1598,85 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_sanitize() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_endurance_event_cfg() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result); /** * nvme_get_features_sw_progress() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_host_id() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid); /** * nvme_get_features_resv_mask() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_resv_persist() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_write_protect() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, @@ -1798,7 +2127,7 @@ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, __u32 *result); /** - * DOC: NVMe IO command enums + * DOC: NVMe IO command */ /** @@ -1905,7 +2234,7 @@ enum nvme_io_dsm_flags { /** * nvme_read() - Submit an nvme user read command * @fd: File descriptor of nvme device - * @nsid: + * @nsid: Namespace ID * @slba: Starting logical block * @nblocks: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. @@ -1936,7 +2265,7 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, /** * nvme_write() - Submit an nvme user write command * @fd: File descriptor of nvme device - * @nsid: + * @nsid: Namespace ID * @slba: Starting logical block * @nblocks: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. @@ -1969,7 +2298,7 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, /** * nvme_compare() - Submit an nvme user compare command * @fd: File descriptor of nvme device - * @nsid: + * @nsid: Namespace ID * @slba: Starting logical block * @nblocks: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. diff --git a/lib/nvme/fabrics.c b/src/nvme/fabrics.c similarity index 99% rename from lib/nvme/fabrics.c rename to src/nvme/fabrics.c index c1119df0..56e97fca 100644 --- a/lib/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -248,7 +248,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) { - return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISC, true, len, log); + return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, len, log); } int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, diff --git a/lib/nvme/fabrics.h b/src/nvme/fabrics.h similarity index 100% rename from lib/nvme/fabrics.h rename to src/nvme/fabrics.h diff --git a/lib/nvme/filters.c b/src/nvme/filters.c similarity index 100% rename from lib/nvme/filters.c rename to src/nvme/filters.c diff --git a/lib/nvme/filters.h b/src/nvme/filters.h similarity index 100% rename from lib/nvme/filters.h rename to src/nvme/filters.h diff --git a/lib/nvme/ioctl.c b/src/nvme/ioctl.c similarity index 99% rename from lib/nvme/ioctl.c rename to src/nvme/ioctl.c index ca59e096..1120438c 100644 --- a/lib/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -608,7 +608,7 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_DISC, NVME_NSID_NONE, offset, + return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, len, log); } diff --git a/lib/nvme/ioctl.h b/src/nvme/ioctl.h similarity index 100% rename from lib/nvme/ioctl.h rename to src/nvme/ioctl.h diff --git a/lib/nvme/private.h b/src/nvme/private.h similarity index 100% rename from lib/nvme/private.h rename to src/nvme/private.h diff --git a/lib/nvme/tree.c b/src/nvme/tree.c similarity index 100% rename from lib/nvme/tree.c rename to src/nvme/tree.c diff --git a/lib/nvme/tree.h b/src/nvme/tree.h similarity index 77% rename from lib/nvme/tree.h rename to src/nvme/tree.h index b5f53856..0156a071 100644 --- a/lib/nvme/tree.h +++ b/src/nvme/tree.h @@ -9,88 +9,185 @@ #include "ioctl.h" #include "util.h" -extern const char *nvme_ctrl_sysfs_dir; -extern const char *nvme_subsys_sysfs_dir; - typedef struct nvme_ns *nvme_ns_t; typedef struct nvme_path *nvme_path_t; typedef struct nvme_ctrl *nvme_ctrl_t; typedef struct nvme_subsystem *nvme_subsystem_t; typedef struct nvme_root *nvme_root_t; +/** + * nvme_first_subsystem() - + */ nvme_subsystem_t nvme_first_subsystem(nvme_root_t r); + +/** + * nvme_next_subsystem() - + */ nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s); +/** + * nvme_ctrl_first_ns() - + */ nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c); + +/** + * nvme_ctrl_next_ns() - + */ nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n); +/** + * nvme_ctrl_first_path() - + */ nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c); + +/** + * nvme_ctrl_next_path() - + */ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p); +/** + * nvme_subsystem_first_ctrl() - + */ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); + +/** + * nvme_subsystem_next_ctrl() - + */ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); +/** + * nvme_subsystem_first_ns() - + */ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); + +/** + * nvme_subsystem_next_ns() - + */ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); +/** + * () + */ #define nvme_for_each_subsystem_safe(r, s, _s) \ for (s = nvme_first_subsystem(r), \ _s = nvme_next_subsystem(r, s); \ s != NULL; \ s = _s, _s = nvme_next_subsystem(r, s)) +/** + * () + */ #define nvme_for_each_subsystem(r, s) \ for (s = nvme_first_subsystem(r); s != NULL; \ s = nvme_next_subsystem(r, s)) +/** + * () + */ #define nvme_subsystem_for_each_ctrl_safe(s, c, _c) \ for (c = nvme_subsystem_first_ctrl(s), \ _c = nvme_subsystem_next_ctrl(s, c); \ c != NULL; \ c = _c, _c = nvme_subsystem_next_ctrl(s, c)) +/** + * () + */ #define nvme_subsystem_for_each_ctrl(s, c) \ for (c = nvme_subsystem_first_ctrl(s); c != NULL; \ c = nvme_subsystem_next_ctrl(s, c)) +/** + * () + */ #define nvme_ctrl_for_each_ns_safe(c, n, _n) \ for (n = nvme_ctrl_first_ns(c), \ _n = nvme_ctrl_next_ns(c, n); \ n != NULL; \ n = _n, _n = nvme_ctrl_next_ns(c, n)) +/** + * () + */ #define nvme_ctrl_for_each_ns(c, n) \ for (n = nvme_ctrl_first_ns(c); n != NULL; \ n = nvme_ctrl_next_ns(c, n)) +/** + * () + */ #define nvme_ctrl_for_each_path_safe(c, p, _p) \ for (p = nvme_ctrl_first_path(c), \ _p = nvme_ctrl_next_path(c, p); \ p != NULL; \ p = _p, _p = nvme_ctrl_next_path(c, p)) +/** + * () + */ #define nvme_ctrl_for_each_path(c, p) \ for (p = nvme_ctrl_first_path(c); p != NULL; \ p = nvme_ctrl_next_path(c, p)) +/** + * () + */ #define nvme_subsystem_for_each_ns_safe(s, n, _n) \ for (n = nvme_subsystem_first_ns(s), \ _n = nvme_subsystem_next_ns(s, n); \ n != NULL; \ n = _n, _n = nvme_subsystem_next_ns(s, n)) +/** + * () + */ #define nvme_subsystem_for_each_ns(s, n) \ for (n = nvme_subsystem_first_ns(s); n != NULL; \ n = nvme_subsystem_next_ns(s, n)) +/** + * nvme_ns_get_fd() - + */ int nvme_ns_get_fd(nvme_ns_t n); + +/** + * nvme_ns_get_nsid() - + */ int nvme_ns_get_nsid(nvme_ns_t n); + +/** + * nvme_ns_get_lba_size() - + */ int nvme_ns_get_lba_size(nvme_ns_t n); + +/** + * nvme_ns_get_lba_count() - + */ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); + +/** + * nvme_ns_get_lba_util() - + */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); + +/** + * char () - + */ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); + +/** + * char () - + */ const char *nvme_ns_get_name(nvme_ns_t n); + +/** + * nvme_ns_get_subsystem() - + */ nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); + +/** + * nvme_ns_get_ctrl() - + */ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); /** @@ -133,50 +230,171 @@ int nvme_ns_flush(nvme_ns_t n); */ int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); +/** + * char () - + */ const char *nvme_path_get_name(nvme_path_t p); + +/** + * char () - + */ const char *nvme_path_get_sysfs_dir(nvme_path_t p); + +/** + * char () - + */ const char *nvme_path_get_ana_state(nvme_path_t p); + +/** + * nvme_path_get_subsystem() - + */ nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p); + +/** + * nvme_path_get_ns() - + */ nvme_ns_t nvme_path_get_ns(nvme_path_t p); int nvme_ctrl_get_fd(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_name(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_model(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_state(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_serial(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); +/** + * nvme_ctrl_get_subsystem() - + */ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); +/** + * nvme_ctrl_identify() - + */ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); +/** + * nvme_ctrl_disconnect() - + */ int nvme_ctrl_disconnect(nvme_ctrl_t c); +/** + * nvme_scan_ctrl() - + */ nvme_ctrl_t nvme_scan_ctrl(const char *name); +/** + * nvme_free_ctrl() - + */ void nvme_free_ctrl(struct nvme_ctrl *c); +/** + * nvme_unlink_ctrl() - + */ void nvme_unlink_ctrl(struct nvme_ctrl *c); +/** + * char () - + */ const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); +/** + * char () - + */ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); +/** + * char () - + */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); + +/** + * nvme_scan_filter() - + */ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f); +/** + * nvme_scan() - + */ nvme_root_t nvme_scan(); + +/** + * nvme_refresh_topology() - + */ void nvme_refresh_topology(nvme_root_t r); + +/** + * nvme_reset_topology() - + */ void nvme_reset_topology(nvme_root_t r); + +/** + * nvme_free_tree() - + */ void nvme_free_tree(nvme_root_t r); +/** + * *() - + */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); + +/** + * *() - + */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); + +/** + * *() - + */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); + +/** + * *() - + */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); +extern const char *nvme_ctrl_sysfs_dir; +extern const char *nvme_subsys_sysfs_dir; #endif /* _LIBNVME_TREE_H */ diff --git a/lib/nvme/types.h b/src/nvme/types.h similarity index 95% rename from lib/nvme/types.h rename to src/nvme/types.h index 17d68512..ebb01c75 100644 --- a/lib/nvme/types.h +++ b/src/nvme/types.h @@ -2060,24 +2060,82 @@ struct nvme_host_mem_buf_desc { }; /** - * enum - - */ -enum { - NVME_AER_ERROR = 0, - NVME_AER_SMART = 1, - NVME_AER_NOTICE = 2, - NVME_AER_CSS = 6, - NVME_AER_VS = 7, -}; - -/** - * enum - - */ -enum { - NVME_AER_NOTICE_NS_CHANGED = 0x00, - NVME_AER_NOTICE_FW_ACT_STARTING = 0x01, - NVME_AER_NOTICE_ANA = 0x03, - NVME_AER_NOTICE_DISC_CHANGED = 0xf0, + * enum nvme_ae_type - + * @NVME_AER_ERROR: + * @NVME_AER_SMART: + * @NVME_AER_NOTICE: + * @NVME_AER_CSS: + * @NVME_AER_VS: + */ +enum nvme_ae_type { + NVME_AER_ERROR = 0, + NVME_AER_SMART = 1, + NVME_AER_NOTICE = 2, + NVME_AER_CSS = 6, + NVME_AER_VS = 7, +}; +/** + * enum nvme_ae_info_error - + * @NVME_AER_ERROR_INVALID_DB_REG: + * @NVME_AER_ERROR_INVALID_DB_VAL: + * @NVME_AER_ERROR_DIAG_FAILURE: + * @NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR: + * @NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR: + * @NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR: + */ +enum nvme_ae_info_error { + NVME_AER_ERROR_INVALID_DB_REG = 0x00, + NVME_AER_ERROR_INVALID_DB_VAL = 0x01, + NVME_AER_ERROR_DIAG_FAILURE = 0x02, + NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR = 0x03, + NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR = 0x04, + NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR = 0x05, +}; + +/** + * enum nvme_ae_info_smart - + * @NVME_AER_SMART_SUBSYSTEM_RELIABILITY: + * @NVME_AER_SMART_TEMPERATURE_THRESHOLD: + * @NVME_AER_SMART_SPARE_THRESHOLD: + */ +enum nvme_ae_info_smart { + NVME_AER_SMART_SUBSYSTEM_RELIABILITY = 0x00, + NVME_AER_SMART_TEMPERATURE_THRESHOLD = 0x01, + NVME_AER_SMART_SPARE_THRESHOLD = 0x02, +}; + +/** + * enum nvme_ae_info_css_nvm - + * @NVME_AER_CSS_NVM_RESERVATION: + * @NVME_AER_CSS_NVM_SANITIZE_COMPLETED: + * @NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC: + */ +enum nvme_ae_info_css_nvm { + NVME_AER_CSS_NVM_RESERVATION = 0x00, + NVME_AER_CSS_NVM_SANITIZE_COMPLETED = 0x01, + NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC = 0x02, +}; + +/** + * enum nvme_ae_info_notice - + * @NVME_AER_NOTICE_NS_CHANGED: + * @NVME_AER_NOTICE_FW_ACT_STARTING: + * @NVME_AER_NOTICE_TELEMETRY: + * @NVME_AER_NOTICE_ANA: + * @NVME_AER_NOTICE_PL_EVENT: + * @NVME_AER_NOTICE_LBA_STATUS_ALERT: + * @NVME_AER_NOTICE_EG_EVENT: + * @NVME_AER_NOTICE_DISC_CHANGED: + */ +enum nvme_ae_info_notice { + NVME_AER_NOTICE_NS_CHANGED = 0x00, + NVME_AER_NOTICE_FW_ACT_STARTING = 0x01, + NVME_AER_NOTICE_TELEMETRY = 0x02, + NVME_AER_NOTICE_ANA = 0x03, + NVME_AER_NOTICE_PL_EVENT = 0x04, + NVME_AER_NOTICE_LBA_STATUS_ALERT = 0x05, + NVME_AER_NOTICE_EG_EVENT = 0x06, + NVME_AER_NOTICE_DISC_CHANGED = 0xf0, }; /** diff --git a/lib/nvme/util.c b/src/nvme/util.c similarity index 100% rename from lib/nvme/util.c rename to src/nvme/util.c diff --git a/lib/nvme/util.h b/src/nvme/util.h similarity index 100% rename from lib/nvme/util.h rename to src/nvme/util.h diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..b21e4643 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,22 @@ +CFLAGS ?= -g -O2 +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ + +include ../Makefile.quiet + +ifneq ($(MAKECMDGOALS),clean) +include ../config-host.mak +endif + +all_targets += test + +all: $(all_targets) + +%: %.c + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + +test_srs := test.c + +test_objs := $(patsubst %.c,%.ol,$(test_srcs)) + +clean: + @rm -f $(all_targets) $(test_objs)