# SPDX-License-Identifier: LGPL-2.1-or-later
+LIBNVME_1.10 {
+ global:
+ nvme_init_default_logging;
+};
+
LIBNVME_1.9 {
global:
nvme_ctrl_get_cntlid;
}
json_object_object_add(json_root, "hosts", host_array);
- ret = json_object_to_fd(fileno(r->fp), json_root, JSON_C_TO_STRING_PRETTY);
+ ret = json_object_to_fd(r->log.fd, json_root, JSON_C_TO_STRING_PRETTY);
if (ret < 0) {
nvme_msg(r, LOG_ERR, "Failed to write, %s\n",
json_util_get_last_err());
#define LOG_CLOCK CLOCK_MONOTONIC
#endif
-static nvme_root_t root;
+static struct nvme_log def_log = {
+ .fd = STDERR_FILENO,
+ .level = DEFAULT_LOGLEVEL,
+ .pid = false,
+ .timestamp = false,
+};
void __attribute__((format(printf, 4, 5)))
__nvme_msg(nvme_root_t r, int level,
const char *func, const char *format, ...)
{
- FILE *fp = stderr;
+ struct nvme_log *l;
va_list ap;
char pidbuf[16];
char timebuf[32];
_cleanup_free_ char *message = NULL;
int idx = 0;
- if (!r)
- r = root;
-
if (r)
- fp = r->fp;
+ l = &r->log;
+ else
+ l = &def_log;
- if (r && level > r->log_level)
- return;
- if (!r && level > DEFAULT_LOGLEVEL)
+ if (level > l->level)
return;
- if (r && r->log_timestamp) {
+ if (l->timestamp) {
struct timespec now;
clock_gettime(LOG_CLOCK, &now);
} else
*timebuf = '\0';
- if (r && r->log_pid) {
+ if (l->pid) {
snprintf(pidbuf, sizeof(pidbuf), "%ld", (long)getpid());
idx |= 1 << 1;
} else
message = NULL;
va_end(ap);
- fprintf(fp, "%s%s",
+ dprintf(l->fd, "%s%s",
header ? header : "<error>",
message ? message : "<error>");
}
void nvme_init_logging(nvme_root_t r, int lvl, bool log_pid, bool log_tstamp)
{
- r->log_level = lvl;
- r->log_pid = log_pid;
- r->log_timestamp = log_tstamp;
+ r->log.level = lvl;
+ r->log.pid = log_pid;
+ r->log.timestamp = log_tstamp;
}
int nvme_get_logging_level(nvme_root_t r, bool *log_pid, bool *log_tstamp)
{
- if (!r)
- r = root;
- if (!r)
- return DEFAULT_LOGLEVEL;
+ struct nvme_log *l;
+
+ if (r)
+ l = &r->log;
+ else
+ l = &def_log;
+
if (log_pid)
- *log_pid = r->log_pid;
+ *log_pid = l->pid;
if (log_tstamp)
- *log_tstamp = r->log_timestamp;
- return r->log_level;
+ *log_tstamp = l->timestamp;
+ return l->level;
+}
+
+void nvme_init_default_logging(FILE *fp, int level, bool log_pid, bool log_tstamp)
+{
+ def_log.fd = fileno(fp);
+ def_log.level = level;
+ def_log.pid = log_pid;
+ def_log.timestamp = log_tstamp;
}
void nvme_set_root(nvme_root_t r)
{
- root = r;
+ def_log.fd = r->log.fd;
+ def_log.level = r->log.level;
+ def_log.pid = r->log.pid;
+ def_log.timestamp = r->log.timestamp;
}
void nvme_set_debug(bool debug)
{
- root->log_level = debug ? LOG_DEBUG : DEFAULT_LOGLEVEL;
+ def_log.level = debug ? LOG_DEBUG : DEFAULT_LOGLEVEL;
}
bool nvme_get_debug(void)
{
- return root->log_level == LOG_DEBUG;
+ return def_log.level == LOG_DEBUG;
}
*/
void nvme_init_logging(nvme_root_t r, int lvl, bool log_pid, bool log_tstamp);
+/**
+ * nvme_init_default_logging() - Initialize default (fallback) logging
+ * @fp: File descriptor for logging messages
+ * @lvl: Logging level to set
+ * @log_pid: Boolean to enable logging of the PID
+ * @log_tstamp: Boolean to enable logging of the timestamp
+ *
+ * Sets the default logging settings for the library in case the root object
+ * is absent.
+ */
+void nvme_init_default_logging(FILE *fp, int lvl, bool log_pid, bool log_tstamp);
+
/**
* nvme_get_logging_level() - Get current logging level
* @r: nvme_root_t context
* will be set as well. This means the global root object is always pointing to
* the latest created root object. Note the first @nvme_free_tree call will reset
* the global root object.
+ *
+ * This function is deprecated. Use nvme_init_default_logging or/and
+ * nvme_init_logging instead.
*/
-void nvme_set_root(nvme_root_t r);
+void nvme_set_root(nvme_root_t r) __attribute__((deprecated));
/**
* nvme_set_debug - Set NVMe command debugging output
* @debug: true to enable or false to disable
*
- * Don't use it, it's debricated.
+ * This function is deprecated. Use nvme_init_default_logging instead.
*/
-void nvme_set_debug(bool debug);
+void nvme_set_debug(bool debug) __attribute__((deprecated));
/**
* nvme_get_debug - Get NVMe command debugging output
*
- * Don't use it, it's debricated.
+ * This function is deprecated. Use nvme_get_logging_level instead.
*
* Return: false if disabled or true if enabled.
*/
-bool nvme_get_debug(void);
+bool nvme_get_debug(void) __attribute__((deprecated));
#endif /* _LOG_H */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
+#include <unistd.h>
#include <ccan/array_size/array_size.h>
#include <ccan/endian/endian.h>
*/
nvme_root_t nvme_mi_create_root(FILE *fp, int log_level)
{
- struct nvme_root *r = calloc(1, sizeof(*r));
+ struct nvme_root *r;
+ int fd;
+ r = calloc(1, sizeof(*r));
if (!r) {
+ errno = ENOMEM;
return NULL;
}
- r->log_level = log_level;
- r->fp = stderr;
+
+ if (fp) {
+ fd = fileno(fp);
+ if (fd < 0) {
+ free(r);
+ return NULL;
+ }
+ } else
+ fd = STDERR_FILENO;
+
+ r->log.fd = fd;
+ r->log.level = log_level;
+
r->mi_probe_enabled = nvme_mi_probe_enabled_default();
- if (fp)
- r->fp = fp;
+
list_head_init(&r->hosts);
list_head_init(&r->endpoints);
+
return r;
}
bool trsvcid;
};
+struct nvme_log {
+ int fd;
+ int level;
+ bool pid;
+ bool timestamp;
+};
+
struct nvme_root {
char *config_file;
char *application;
struct list_head hosts;
struct list_head endpoints; /* MI endpoints */
- FILE *fp;
- int log_level;
- bool log_pid;
- bool log_timestamp;
+ struct nvme_log log;
bool modified;
bool mi_probe_enabled;
struct nvme_fabric_options *options;
nvme_root_t nvme_create_root(FILE *fp, int log_level)
{
- struct nvme_root *r = calloc(1, sizeof(*r));
+ struct nvme_root *r;
+ int fd;
+ r = calloc(1, sizeof(*r));
if (!r) {
errno = ENOMEM;
return NULL;
}
- r->log_level = log_level;
- r->fp = stderr;
- if (fp)
- r->fp = fp;
+
+ if (fp) {
+ fd = fileno(fp);
+ if (fd < 0) {
+ free(r);
+ return NULL;
+ }
+ } else
+ fd = STDERR_FILENO;
+
+ r->log.fd = fd;
+ r->log.level = log_level;
+
list_head_init(&r->hosts);
list_head_init(&r->endpoints);
- nvme_set_root(r);
+
return r;
}
free(r->config_file);
if (r->application)
free(r->application);
- nvme_set_root(NULL);
free(r);
}