]> git.apps.os.sepia.ceph.com Git - ceph-client.git/commitdiff
cephsan logger: WIP
authorAlex Markuze <amarkuze@redhat.com>
Sun, 16 Mar 2025 16:29:21 +0000 (16:29 +0000)
committerAlex Markuze <amarkuze@redhat.com>
Sun, 16 Mar 2025 16:29:21 +0000 (16:29 +0000)
include/linux/ceph/ceph_san_logger.h [new file with mode: 0644]
net/ceph/ceph_san_batch.c
net/ceph/ceph_san_logger.c [new file with mode: 0644]

diff --git a/include/linux/ceph/ceph_san_logger.h b/include/linux/ceph/ceph_san_logger.h
new file mode 100644 (file)
index 0000000..d45c353
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef CEPH_SAN_LOGGER_H
+#define CEPH_SAN_LOGGER_H
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/ceph/ceph_san_batch.h>
+#include <linux/ceph/ceph_san_pagefrag.h>
+
+/* Maximum length of a log entry buffer */
+#define CEPH_SAN_LOG_MAX_LEN 256
+
+/* Log entry structure */
+struct ceph_san_log_entry {
+    u64 ts;                     /* Timestamp (jiffies) */
+    unsigned int line;          /* Line number */
+    unsigned int len;           /* Length of the message */
+    const char *file;          /* Source file */
+    char buffer[0];            /* Flexible array for inline buffer */
+};
+
+/* TLS context structure */
+struct ceph_san_tls_ctx {
+    char comm[TASK_COMM_LEN];   /* Task command name */
+    pid_t pid;                  /* Process ID */
+    struct task_struct *task;    /* Pointer to task struct */
+    struct cephsan_pagefrag pf; /* Pagefrag for this context */
+    struct list_head list;      /* For global list of contexts */
+};
+
+/* Global logger state */
+struct ceph_san_logger {
+    struct list_head contexts;   /* List of all TLS contexts */
+    spinlock_t lock;            /* Protects contexts list */
+    struct ceph_san_batch alloc_batch;  /* Batch for allocating new entries */
+    struct ceph_san_batch log_batch;    /* Batch for storing log entries */
+};
+
+/* Initialize the logging system */
+int ceph_san_logger_init(void);
+
+/* Clean up the logging system */
+void ceph_san_logger_cleanup(void);
+
+/* Log a message */
+void ceph_san_log(const char *file, unsigned int line, const char *fmt, ...);
+
+/* Get current TLS context, creating if necessary */
+struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void);
+
+/* Helper macro for logging */
+#define CEPH_SAN_LOG(fmt, ...) \
+    ceph_san_log(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
+
+#endif /* CEPH_SAN_LOGGER_H */ 
\ No newline at end of file
index 1f9cb5cd3fb68b0c7a2d84d65a51f58d9dfbe630..2b8987ec8cd63776876b3a3cd099b6347d929e14 100644 (file)
@@ -244,6 +244,7 @@ EXPORT_SYMBOL(ceph_san_batch_get);
  * @batch: Batch to put element into
  * @element: Element to put back
  */
+ //TOOD this shit needs a rewrite
 void ceph_san_batch_put(struct ceph_san_batch *batch, void *element)
 {
     struct ceph_san_cpu_magazine *cpu_mag;
@@ -268,6 +269,7 @@ void ceph_san_batch_put(struct ceph_san_batch *batch, void *element)
 
         if (!cpu_mag->mag) {
             /* If we can't get a magazine, free the element */
+            pr_err("Failed to allocate magazine for batch put\n");
             batch->free_element(element);
             return;
         }
diff --git a/net/ceph/ceph_san_logger.c b/net/ceph/ceph_san_logger.c
new file mode 100644 (file)
index 0000000..7e8cba2
--- /dev/null
@@ -0,0 +1,182 @@
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ceph/ceph_san_logger.h>
+
+/* Global logger instance */
+static struct ceph_san_logger g_logger;
+
+static void *alloc_tls_ctx(void)
+{
+    struct ceph_san_tls_ctx *ctx;
+    ctx = kmem_cache_alloc(g_logger.alloc_batch.magazine_cache, GFP_KERNEL);
+    if (!ctx)
+        return NULL;
+
+    /* Initialize pagefrag */
+    memset(&ctx->pf, 0, sizeof(ctx->pf));
+    if (cephsan_pagefrag_init(&ctx->pf)) {
+        kmem_cache_free(g_logger.alloc_batch.magazine_cache, ctx);
+        return NULL;
+    }
+    return ctx;
+}
+
+static void free_tls_ctx(void *ptr)
+{
+    struct ceph_san_tls_ctx *ctx = ptr;
+    cephsan_pagefrag_deinit(&ctx->pf);
+    kmem_cache_free(g_logger.alloc_batch.magazine_cache, ctx);
+}
+
+/* Release function for TLS storage */
+static void ceph_san_tls_release(void *ptr)
+{
+    struct ceph_san_tls_ctx *ctx = ptr;
+
+    if (!ctx)
+        return;
+
+    /* Add context to log batch */
+    ceph_san_batch_put(&g_logger.log_batch, ctx);
+
+    current->tls.state = NULL;
+}
+
+/**
+ * ceph_san_get_tls_ctx - Get or create TLS context for current task
+ *
+ * Returns pointer to TLS context or NULL on error
+ */
+struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void)
+{
+    struct ceph_san_tls_ctx *ctx;
+
+    ctx = current->tls.state;
+    if (ctx)
+        return ctx;
+
+    /* Try to get context from batch first */
+    ctx = ceph_san_batch_get(&g_logger.alloc_batch);
+    if (!ctx) {
+        /* Create new context if batch is empty */
+        ctx = alloc_tls_ctx();
+        if (!ctx)
+            return NULL;
+        /* Add to global list */
+        spin_lock(&g_logger.lock);
+        list_add(&ctx->list, &g_logger.contexts);
+        spin_unlock(&g_logger.lock);
+    }
+
+    /* Set up TLS */
+    current->tls.state = ctx;
+    current->tls.release = ceph_san_tls_release;
+
+    return ctx;
+}
+EXPORT_SYMBOL(ceph_san_get_tls_ctx);
+
+/**
+ * ceph_san_log - Log a message
+ * @file: Source file name
+ * @line: Line number
+ * @fmt: Format string
+ *
+ * Logs a message to the current TLS context's log buffer
+ */
+void ceph_san_log(const char *file, unsigned int line, const char *fmt, ...)
+{
+    /* Format the message into local buffer first */
+    char buf[256];
+    struct ceph_san_tls_ctx *ctx;
+    struct ceph_san_log_entry *entry;
+    va_list args;
+    int len;
+
+    ctx = ceph_san_get_tls_ctx();
+    if (!ctx)
+        return;
+
+    va_start(args, fmt);
+    len = vsnprintf(buf, sizeof(buf), fmt, args);
+    va_end(args);
+
+    /* Allocate entry from pagefrag */
+    u64 alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1);
+    if (!alloc)
+        return;
+    entry = cephsan_pagefrag_get_ptr(&ctx->pf, alloc);
+
+    /* Copy to entry buffer */
+    memcpy(entry->buffer, buf, len + 1);
+    entry->buffer[len] = '\0';
+
+    /* Fill in entry details */
+    entry->ts = jiffies;
+    entry->line = line;
+    entry->file = file;
+    entry->len = len;
+}
+EXPORT_SYMBOL(ceph_san_log);
+
+/**
+ * ceph_san_logger_init - Initialize the logging system
+ *
+ * Returns 0 on success, negative error code on failure
+ */
+int ceph_san_logger_init(void)
+{
+    int ret;
+
+    /* Initialize global state */
+    INIT_LIST_HEAD(&g_logger.contexts);
+    spin_lock_init(&g_logger.lock);
+
+    /* Initialize allocation batch */
+    ret = ceph_san_batch_init(&g_logger.alloc_batch,
+                             alloc_tls_ctx,
+                             free_tls_ctx);
+    if (ret)
+        return ret;
+
+    /* Initialize log batch */
+    ret = ceph_san_batch_init(&g_logger.log_batch,
+                             NULL,
+                             NULL);
+    if (ret)
+        goto cleanup_alloc;
+
+    return 0;
+
+cleanup_alloc:
+    ceph_san_batch_cleanup(&g_logger.alloc_batch);
+    return ret;
+}
+EXPORT_SYMBOL(ceph_san_logger_init);
+
+/**
+ * ceph_san_logger_cleanup - Clean up the logging system
+ */
+void ceph_san_logger_cleanup(void)
+{
+    struct ceph_san_tls_ctx *ctx, *tmp;
+
+    /* Clean up all TLS contexts */
+    spin_lock(&g_logger.lock);
+    list_for_each_entry_safe(ctx, tmp, &g_logger.contexts, list) {
+        list_del(&ctx->list);
+        cephsan_pagefrag_deinit(&ctx->pf);
+        kfree(ctx);
+    }
+    spin_unlock(&g_logger.lock);
+
+    /* Clean up batches */
+    ceph_san_batch_cleanup(&g_logger.alloc_batch);
+    ceph_san_batch_cleanup(&g_logger.log_batch);
+}
+EXPORT_SYMBOL(ceph_san_logger_cleanup);
\ No newline at end of file