initial commit for release
This commit is contained in:
parent
159767e347
commit
745adb56cc
2
LICENSE
2
LICENSE
@ -58,7 +58,7 @@ APPENDIX: How to apply the Apache License to your work.
|
|||||||
|
|
||||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2024 JackrabbitLabs-Releases
|
Copyright 2024 Jackrabbit-Founders-LLC
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
88
README.md
88
README.md
@ -1,3 +1,87 @@
|
|||||||
# libmem-release
|
# Overview
|
||||||
|
|
||||||
|
Libmem is a C library for managing the state of memory blocks in a Linux
|
||||||
|
system. This library provides a user or orchestration application the ability
|
||||||
|
to online / offline individual memory blocks of the system or specific blocks
|
||||||
|
within a CXL region.
|
||||||
|
|
||||||
|
The library consists of a `libmem.h` header file and a `libmem.a` library archive.
|
||||||
|
The library also builds a CLI tool `mem` that allows the user user to
|
||||||
|
view and manipulate the state of system memory blocks from the command line.
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
To compile, the library requires the following libraries to be installed in
|
||||||
|
addition to typical packages to build C programs (e.g. `make`)
|
||||||
|
|
||||||
|
```
|
||||||
|
daxctl uuid cxl
|
||||||
|
```
|
||||||
|
|
||||||
|
The `uuid` library can be installed from the system package manager:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install uuid-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
The `daxctl` and `libcxl` libraries included with current Linux distributions are
|
||||||
|
typically too old to support the features needed. Consequently, the user is
|
||||||
|
required to build the current version of the `ndctl` project and install the
|
||||||
|
manually built `daxctl` and `cxl` libraries.
|
||||||
|
|
||||||
|
See [ndctl](https://github.com/pmem/ndctl) on build and installation
|
||||||
|
instructions.
|
||||||
|
|
||||||
|
# Build
|
||||||
|
|
||||||
|
To build simply type:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
To install to `/usr/local/*` locations type:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
# CLI Usage
|
||||||
|
|
||||||
|
The `mem` CLI tool can be used to display system memory block information:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mem show info
|
||||||
|
```
|
||||||
|
|
||||||
|
To display the state of memory blocks in the system:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mem list
|
||||||
|
```
|
||||||
|
|
||||||
|
To online system memory block 306
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mem block online 306
|
||||||
|
```
|
||||||
|
|
||||||
|
To offline a system memory block
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mem block offline 306
|
||||||
|
```
|
||||||
|
|
||||||
|
To online memory block 2 of a CXL region:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mem block online 2 region0
|
||||||
|
```
|
||||||
|
|
||||||
|
To offline memory block 2 of a CXL region:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mem block offline 2 region0
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Online and offline those memory blocks and regions
|
|
||||||
210
libmem.h
Normal file
210
libmem.h
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/**
|
||||||
|
* @file libmem.h
|
||||||
|
*
|
||||||
|
* @brief Header file for memory management library
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||||
|
*
|
||||||
|
* @date Jul 2024
|
||||||
|
* @author Barrett Edwards <code@jrlabs.io>
|
||||||
|
*
|
||||||
|
* Macro / Enumeration Prefixes (LM)
|
||||||
|
* PL - Memory Online Policies
|
||||||
|
* ST - State options
|
||||||
|
* ZN - Valid Zones bitfield enum
|
||||||
|
* ZM - Valid Zones bitfield masks
|
||||||
|
*/
|
||||||
|
#ifndef _LIBMEM_H
|
||||||
|
#define _LIBMEM_H
|
||||||
|
|
||||||
|
/* INCLUDES ==================================================================*/
|
||||||
|
|
||||||
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
|
#define mem_blk_foreach(ctx, blk) for (blk = mem_blk_get_first(ctx); blk != NULL; blk = mem_blk_get_next(blk))
|
||||||
|
|
||||||
|
/* ENUMERATIONS ==============================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumereation represeting log destinations
|
||||||
|
*/
|
||||||
|
enum LMLD
|
||||||
|
{
|
||||||
|
LMLD_STDIO = 0,
|
||||||
|
LMLD_SYSLOG = 1,
|
||||||
|
LMLD_NULL = 2,
|
||||||
|
LMLD_FILE = 3,
|
||||||
|
LMLD_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Auto Online Policy Options */
|
||||||
|
enum LMPL
|
||||||
|
{
|
||||||
|
LMPL_OFFLINE = 0,
|
||||||
|
LMPL_ONLINE = 1,
|
||||||
|
LMPL_KERNEL = 2,
|
||||||
|
LMPL_MOVABLE = 3,
|
||||||
|
LMPL_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* State options */
|
||||||
|
enum LMST
|
||||||
|
{
|
||||||
|
LMST_OFFLINE = 0,
|
||||||
|
LMST_ONLINE = 1,
|
||||||
|
LMST_GOING_OFFLINE = 2,
|
||||||
|
LMST_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Valid Zone options */
|
||||||
|
enum LMZN
|
||||||
|
{
|
||||||
|
LMZN_DMA = 0,
|
||||||
|
LMZN_DMA32 = 1,
|
||||||
|
LMZN_NORMAL = 2,
|
||||||
|
LMZN_MOVABLE = 3,
|
||||||
|
LMZN_NONE = 4,
|
||||||
|
LMZN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Bitfield masks for valid_zones */
|
||||||
|
#define LMZM_DMA (0x01)
|
||||||
|
#define LMZM_DMA32 (0x02)
|
||||||
|
#define LMZM_NORMAL (0x04)
|
||||||
|
#define LMZM_MOVABLE (0x08)
|
||||||
|
#define LMZM_NONE (0x10)
|
||||||
|
|
||||||
|
/* STRUCTS ===================================================================*/
|
||||||
|
|
||||||
|
struct mem_ctx;
|
||||||
|
struct mem_blk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Typedef for mem_set_log_fn()
|
||||||
|
*/
|
||||||
|
typedef void (*mem_log_fn)(struct mem_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args);
|
||||||
|
|
||||||
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
|
/* PROTOTYPES ================================================================*/
|
||||||
|
|
||||||
|
/* Library Instantiation */
|
||||||
|
int mem_new(struct mem_ctx **ctx);
|
||||||
|
struct mem_ctx * mem_ref(struct mem_ctx *ctx);
|
||||||
|
int mem_unref(struct mem_ctx *ctx);
|
||||||
|
|
||||||
|
/* Library Log Configuration */
|
||||||
|
int mem_log_get_priority(struct mem_ctx *ctx);
|
||||||
|
void mem_log_set_destination(struct mem_ctx *ctx, int dst, char *file);
|
||||||
|
void mem_log_set_fn(struct mem_ctx *ctx,
|
||||||
|
void (*mem_log_fn)(struct mem_ctx *ctx,
|
||||||
|
int priority,
|
||||||
|
const char *fn,
|
||||||
|
int line,
|
||||||
|
const char *format,
|
||||||
|
va_list args));
|
||||||
|
void mem_log_set_priority(struct mem_ctx *ctx, int priority);
|
||||||
|
|
||||||
|
/* Library Collections API - Get */
|
||||||
|
struct cxl_region * mem_get_region(struct mem_ctx *ctx, char *name);
|
||||||
|
struct cxl_memdev * mem_get_memdev(struct mem_ctx *ctx, char *name);
|
||||||
|
struct cxl_memdev ** mem_get_memdevs(struct mem_ctx *ctx);
|
||||||
|
struct cxl_region ** mem_get_regions(struct mem_ctx *ctx);
|
||||||
|
struct cxl_decoder * mem_get_root_decoder(struct mem_ctx *ctx);
|
||||||
|
int mem_num_memdevs(struct mem_ctx* ctx);
|
||||||
|
int mem_num_regions(struct mem_ctx* ctx);
|
||||||
|
|
||||||
|
/* Memory System API - Get */
|
||||||
|
int * mem_system_get_blocks(struct mem_ctx *ctx);
|
||||||
|
unsigned long long mem_system_get_blocksize(struct mem_ctx *ctx);
|
||||||
|
unsigned long long mem_system_get_capacity(struct mem_ctx *ctx);
|
||||||
|
unsigned long long mem_system_get_capacity_offline(struct mem_ctx *ctx);
|
||||||
|
unsigned long long mem_system_get_capacity_online(struct mem_ctx *ctx);
|
||||||
|
int mem_system_get_policy(struct mem_ctx *ctx);
|
||||||
|
int mem_system_num_blocks(struct mem_ctx *ctx);
|
||||||
|
int mem_system_num_blocks_online(struct mem_ctx *ctx);
|
||||||
|
int mem_system_num_blocks_offline(struct mem_ctx *ctx);
|
||||||
|
|
||||||
|
/* Memory System API - Actions */
|
||||||
|
int mem_system_set_policy(struct mem_ctx *ctx, int mode);
|
||||||
|
|
||||||
|
/* Memory Block API - Enumeration */
|
||||||
|
struct mem_blk * mem_blk_get_first(struct mem_ctx *ctx);
|
||||||
|
struct mem_blk * mem_blk_get_next(struct mem_blk *blk);
|
||||||
|
|
||||||
|
/* Memory Block API - Get */
|
||||||
|
int mem_blk_get_device(struct mem_blk *blk);
|
||||||
|
int mem_blk_get_id(struct mem_blk *blk);
|
||||||
|
int mem_blk_get_node(struct mem_blk *blk);
|
||||||
|
struct cxl_region * mem_blk_get_region(struct mem_blk *blk);
|
||||||
|
int mem_blk_get_state(struct mem_blk *blk);
|
||||||
|
unsigned long mem_blk_get_zones(struct mem_blk *blk);
|
||||||
|
int mem_blk_is_online(struct mem_blk *blk);
|
||||||
|
int mem_blk_is_removable(struct mem_blk *blk);
|
||||||
|
|
||||||
|
/* Memory Block API - Actions */
|
||||||
|
int mem_blk_offline(struct mem_blk *blk);
|
||||||
|
int mem_blk_online(struct mem_blk *blk);
|
||||||
|
int mem_blk_set_state(struct mem_blk *blk, int state);
|
||||||
|
|
||||||
|
/* Memory BlockID API - Get */
|
||||||
|
struct mem_blk * mem_blkid_get_blk(struct mem_ctx *ctx, int id);
|
||||||
|
int mem_blkid_get_device(struct mem_ctx *ctx, int id);
|
||||||
|
int mem_blkid_get_node(struct mem_ctx *ctx, int id);
|
||||||
|
int mem_blkid_get_state(struct mem_ctx *ctx, int id);
|
||||||
|
unsigned long mem_blkid_get_zones(struct mem_ctx *ctx, int id);
|
||||||
|
int mem_blkid_is_online(struct mem_ctx *ctx, int id);
|
||||||
|
int mem_blkid_is_removable(struct mem_ctx *ctx, int id);
|
||||||
|
|
||||||
|
/* Memory BlockID API - Actions */
|
||||||
|
int mem_blkid_offline(struct mem_ctx *ctx, int index);
|
||||||
|
int mem_blkid_online(struct mem_ctx *ctx, int index);
|
||||||
|
int mem_blkid_set_state(struct mem_ctx *ctx, int index, int state);
|
||||||
|
|
||||||
|
/* Memory Memdev API - Get */
|
||||||
|
int mem_memdev_get_interleave_granularity(struct mem_ctx *ctx, struct cxl_memdev *memdev);
|
||||||
|
int mem_memdev_is_available(struct mem_ctx *ctx, struct cxl_memdev *memdev);
|
||||||
|
|
||||||
|
/* Memory Region API - Get */
|
||||||
|
int mem_region_get_blk_state(struct mem_ctx *ctx, struct cxl_region *region, int offset);
|
||||||
|
int * mem_region_get_blocks(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
unsigned long long mem_region_get_capacity(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
unsigned long long mem_region_get_capacity_offline(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
unsigned long long mem_region_get_capacity_online(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
int mem_region_is_daxmode(struct mem_ctx *ctx, struct cxl_region* region);
|
||||||
|
int mem_region_is_rammode(struct mem_ctx *ctx, struct cxl_region* region);
|
||||||
|
int mem_region_num_blocks(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
int mem_region_num_blocks_offline(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
int mem_region_num_blocks_online(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
|
||||||
|
/* Memory Region API - Actions */
|
||||||
|
int mem_region_create(struct mem_ctx *ctx, int granularity, int num, struct cxl_memdev **memdevs);
|
||||||
|
int mem_region_delete(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
|
||||||
|
int mem_region_offline_blocks(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
int mem_region_online_blocks(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
int mem_region_set_blk_state(struct mem_ctx *ctx, struct cxl_region *region, int offset, int mode);
|
||||||
|
|
||||||
|
int mem_region_daxmode(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
int mem_region_rammode(struct mem_ctx *ctx, struct cxl_region *region);
|
||||||
|
|
||||||
|
/* Compare functions for qsort */
|
||||||
|
int mem_compare_ints(const void* a, const void* b);
|
||||||
|
int mem_compare_cxl_memdevs(const void* a, const void* b);
|
||||||
|
int mem_compare_cxl_regions(const void* a, const void* b);
|
||||||
|
|
||||||
|
/* Print Functions */
|
||||||
|
void mem_blk_print(struct mem_blk *blk);
|
||||||
|
|
||||||
|
/* String representations of enumerations */
|
||||||
|
const char * mem_lmpl(int policy);
|
||||||
|
const char * mem_lmst(int state);
|
||||||
|
const char * mem_lmzn(int zone);
|
||||||
|
|
||||||
|
/* Convert strings into enum values */
|
||||||
|
int mem_to_lmpl(char *policy);
|
||||||
|
int mem_to_lmst(char *state);
|
||||||
|
int mem_to_lmzn(char *zone);
|
||||||
|
|
||||||
|
#endif //ifndef _LIBMEM_H
|
||||||
|
|
||||||
196
log.c
Normal file
196
log.c
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* @file log.c
|
||||||
|
*
|
||||||
|
* @brief Code file for logging library
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||||
|
*
|
||||||
|
* @date Jul 2024
|
||||||
|
* @author Barrett Edwards <code@jrlabs.io>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ==================================================================*/
|
||||||
|
|
||||||
|
/* printf()
|
||||||
|
* fprintf()
|
||||||
|
* vfprintf()
|
||||||
|
* FILE
|
||||||
|
* stdout
|
||||||
|
* stderr
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* calloc()
|
||||||
|
* free()
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* getpid()
|
||||||
|
*/
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* clock_gettime()
|
||||||
|
*/
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/* va_start
|
||||||
|
* va_end
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* LOG_* Macros
|
||||||
|
*/
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
|
/* ENUMERATIONS ==============================================================*/
|
||||||
|
|
||||||
|
/* STRUCTS ===================================================================*/
|
||||||
|
|
||||||
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String representation of logging levels
|
||||||
|
*/
|
||||||
|
static const char *levels[] =
|
||||||
|
{
|
||||||
|
"EMERG",
|
||||||
|
"ALERT",
|
||||||
|
"CRIT",
|
||||||
|
"ERR",
|
||||||
|
"WARNING",
|
||||||
|
"NOTICE",
|
||||||
|
"INFO",
|
||||||
|
"DEBUG",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *log_destinations[] =
|
||||||
|
{
|
||||||
|
"STDIO",
|
||||||
|
"SYSLOG",
|
||||||
|
"NULL",
|
||||||
|
"FILE",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PROTOTYPES ================================================================*/
|
||||||
|
|
||||||
|
/* FUNCTIONS =================================================================*/
|
||||||
|
|
||||||
|
void log_to_syslog(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
vsyslog(priority, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_to_stdio(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (priority >= LOG_INFO)
|
||||||
|
fp = stdout;
|
||||||
|
else
|
||||||
|
fp = stderr;
|
||||||
|
|
||||||
|
if (ctx->timestamp)
|
||||||
|
{
|
||||||
|
// Get time for entry
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
|
||||||
|
// print the time first
|
||||||
|
fprintf(fp, "[%10ld.%09ld] [%d] %s - ", ts.tv_sec, ts.tv_nsec, getpid(), levels[priority]);
|
||||||
|
fprintf(fp, "%s: %s:%d ", ctx->owner, fn, ln);
|
||||||
|
}
|
||||||
|
|
||||||
|
vfprintf(fp, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_to_file(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
FILE *f = ctx->file;
|
||||||
|
|
||||||
|
if (ctx->timestamp)
|
||||||
|
{
|
||||||
|
// Get time for entry
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
|
||||||
|
// print the time first
|
||||||
|
fprintf(f, "[%10ld.%09ld] [%d] %s - ", ts.tv_sec, ts.tv_nsec, getpid(), levels[priority]);
|
||||||
|
fprintf(f, "%s: %s:%d ", ctx->owner, fn, ln);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the message
|
||||||
|
vfprintf(f, format, args);
|
||||||
|
|
||||||
|
// flush
|
||||||
|
fflush(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_submit(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
ctx->log_fn(ctx, priority, fn, ln, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct log_ctx *log_init(const char *owner, int dst, int priority, int timestamp, char *filepath)
|
||||||
|
{
|
||||||
|
struct log_ctx *l;
|
||||||
|
|
||||||
|
// Allocate memory for the log struct
|
||||||
|
l = calloc(1, sizeof(*l));
|
||||||
|
if (l == NULL)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
// Set values
|
||||||
|
l->owner = owner;
|
||||||
|
l->priority = priority;
|
||||||
|
l->timestamp = timestamp;
|
||||||
|
|
||||||
|
if (dst == LDST_SYSLOG)
|
||||||
|
l->log_fn = log_to_syslog;
|
||||||
|
else if (dst == LDST_NULL)
|
||||||
|
l->log_fn = log_to_null;
|
||||||
|
else if (dst == LDST_FILE & filepath != NULL)
|
||||||
|
{
|
||||||
|
l->file = fopen(filepath, "a");
|
||||||
|
l->log_fn = log_to_file;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
l->log_fn = log_to_stdio;
|
||||||
|
|
||||||
|
end:
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the memory used by struct log_ctx
|
||||||
|
*/
|
||||||
|
int log_free(struct log_ctx *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->file != NULL)
|
||||||
|
fclose(ctx->file);
|
||||||
|
|
||||||
|
if (ctx != NULL)
|
||||||
|
free(ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *log_priority_to_str(int priority)
|
||||||
|
{
|
||||||
|
if (priority < 0 || priority > LOG_DEBUG)
|
||||||
|
return NULL;
|
||||||
|
return levels[priority];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *log_dst_to_str(int dst)
|
||||||
|
{
|
||||||
|
if (dst < 0 || dst > LDST_MAX)
|
||||||
|
return NULL;
|
||||||
|
return log_destinations[dst];
|
||||||
|
}
|
||||||
95
log.h
Normal file
95
log.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/**
|
||||||
|
* @file log.h
|
||||||
|
*
|
||||||
|
* @brief Header file for logging library
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||||
|
*
|
||||||
|
* @date Jul 2024
|
||||||
|
* @author Barrett Edwards <code@jrlabs.io>
|
||||||
|
*
|
||||||
|
* Log levels for reference:
|
||||||
|
* LOG_EMERG 0 system is unusable
|
||||||
|
* LOG_ALERT 1 action must be taken immediately
|
||||||
|
* LOG_CRIT 2 critical conditions
|
||||||
|
* LOG_ERR 3 error conditions
|
||||||
|
* LOG_WARNING 4 warning conditions
|
||||||
|
* LOG_NOTICE 5 normal but significant condition
|
||||||
|
* LOG_INFO 6 informational
|
||||||
|
* LOG_DEBUG 7 debug-level messages
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LOG_H
|
||||||
|
#define _LOG_H
|
||||||
|
|
||||||
|
/* INCLUDES ==================================================================*/
|
||||||
|
|
||||||
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
|
#define dbg(x, arg...) log_dbg(x->log, ## arg)
|
||||||
|
#define info(x, arg...) log_info(x->log, ## arg)
|
||||||
|
#define notice(x, arg...) log_notice(x->log, ## arg)
|
||||||
|
#define warn(x, arg...) log_warn(x->log, ## arg)
|
||||||
|
#define err(x, arg...) log_err(x->log, ## arg)
|
||||||
|
|
||||||
|
#ifdef ENABLE_LOGGING
|
||||||
|
# define log_dbg(ctx, arg...) do { if ((ctx)->priority >= LOG_DEBUG) log_submit(ctx, LOG_DEBUG, __FUNCTION__, __LINE__, ## arg); } while(0)
|
||||||
|
# define log_info(ctx, arg...) do { if ((ctx)->priority >= LOG_INFO) log_submit(ctx, LOG_INFO, __FUNCTION__, __LINE__, ## arg); } while(0)
|
||||||
|
# define log_notice(ctx, arg...) do { if ((ctx)->priority >= LOG_NOTICE) log_submit(ctx, LOG_NOTICE, __FUNCTION__, __LINE__, ## arg); } while(0)
|
||||||
|
# define log_warn(ctx, arg...) do { if ((ctx)->priority >= LOG_WARNING) log_submit(ctx, LOG_WARNING, __FUNCTION__, __LINE__, ## arg); } while(0)
|
||||||
|
# define log_err(ctx, arg...) do { if ((ctx)->priority >= LOG_ERR) log_submit(ctx, LOG_ERR, __FUNCTION__, __LINE__, ## arg); } while(0)
|
||||||
|
#else
|
||||||
|
# define log_dbg(ctx, arg...) {}
|
||||||
|
# define log_info(ctx, arg...) {}
|
||||||
|
# define log_notice(ctx, arg...) {}
|
||||||
|
# define log_warn(ctx, arg...) {}
|
||||||
|
# define log_err(ctx, arg...) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ENUMERATIONS ==============================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumereation represeting log destinations to use
|
||||||
|
*/
|
||||||
|
enum LOG_DST
|
||||||
|
{
|
||||||
|
LDST_STDIO = 0,
|
||||||
|
LDST_SYSLOG = 1,
|
||||||
|
LDST_NULL = 2,
|
||||||
|
LDST_FILE = 3,
|
||||||
|
LDST_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* STRUCTS ===================================================================*/
|
||||||
|
|
||||||
|
struct log_ctx;
|
||||||
|
typedef void (*log_fn)(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args);
|
||||||
|
|
||||||
|
struct log_ctx
|
||||||
|
{
|
||||||
|
log_fn log_fn;
|
||||||
|
int timestamp;
|
||||||
|
int priority;
|
||||||
|
const char *owner;
|
||||||
|
FILE *file;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
|
/* PROTOTYPES ================================================================*/
|
||||||
|
|
||||||
|
struct log_ctx *log_init(const char *owner, int dst, int level, int timestamp, char *filepath);
|
||||||
|
void log_submit(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, ...);
|
||||||
|
int log_free(struct log_ctx *ctx);
|
||||||
|
|
||||||
|
/* Log functions */
|
||||||
|
void log_to_file(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args);
|
||||||
|
void log_to_stdio(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args);
|
||||||
|
void log_to_syslog(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args);
|
||||||
|
static inline void log_to_null(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args) {}
|
||||||
|
|
||||||
|
const char *log_priority_to_str(int priority);
|
||||||
|
const char *log_dst_to_str(int dst);
|
||||||
|
|
||||||
|
#endif //ifndef _LOG_H
|
||||||
|
|
||||||
247
options.h
Normal file
247
options.h
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
/**
|
||||||
|
* @file options.h
|
||||||
|
*
|
||||||
|
* @brief Header file for CLI options
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||||
|
*
|
||||||
|
* @date Jul 2024
|
||||||
|
* @author Barrett Edwards
|
||||||
|
*
|
||||||
|
* Macro / Enumeration Prefixes (CL)
|
||||||
|
* CLAP - CLI Options Parsers Enumeration (AP)
|
||||||
|
* CLCM - CLI Command Opcod (CM)
|
||||||
|
* CLMR - CLI Macros (MR)
|
||||||
|
* CLOP - CLI Option (CL)
|
||||||
|
* CLPC - Physical Port Control Opcodes (PC)
|
||||||
|
* CLPU - Port Unbind Mode Options (PU)
|
||||||
|
*
|
||||||
|
* Key mapping
|
||||||
|
* -o --offline Zone: offline
|
||||||
|
* -O --online online
|
||||||
|
* -a --all Perform operatiion on all objects
|
||||||
|
* -b --block Block id
|
||||||
|
* -d --device Memdev name
|
||||||
|
* -g --granularity Interleave Granularity
|
||||||
|
* -h --help Display Help
|
||||||
|
* -H --human Display numbers using K, M, G, T units
|
||||||
|
* -k --kernel Zone: kernel
|
||||||
|
* -m --movable Zone: Online movable
|
||||||
|
* -n --num Display the number of objects
|
||||||
|
* -r --region Region name
|
||||||
|
* -v --verbose Increase verbosity
|
||||||
|
*
|
||||||
|
* Non char key mapping
|
||||||
|
* 701 - usage
|
||||||
|
* 702 - version
|
||||||
|
* 703 - data
|
||||||
|
* 704 - infile
|
||||||
|
* 705 - outfile
|
||||||
|
* 706 - print-options
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OPTIONS_H
|
||||||
|
#define _OPTIONS_H
|
||||||
|
|
||||||
|
/* INCLUDES ==================================================================*/
|
||||||
|
|
||||||
|
/* __u8
|
||||||
|
*/
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI Macros (MR)
|
||||||
|
*
|
||||||
|
* These are values that don't belong in an enumeration
|
||||||
|
*/
|
||||||
|
#define CLMR_HELP_COLUMN 30
|
||||||
|
#define CLMR_MAX_HELP_WIDTH 100
|
||||||
|
#define CLMR_MAX_NAME_LEN 64
|
||||||
|
|
||||||
|
/* ENUMERATIONS ==============================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbosity Options (VO)
|
||||||
|
*/
|
||||||
|
enum _CLVO
|
||||||
|
{
|
||||||
|
CLVO_GENERAL = 0,
|
||||||
|
CLVO_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbosity Bitfield Index (VB)
|
||||||
|
*/
|
||||||
|
enum _CLVB
|
||||||
|
{
|
||||||
|
CLVB_GENERAL = (0x01 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI Options Parsers Enumeration (AP)
|
||||||
|
*
|
||||||
|
* This enumeration identifies each argp parser. It is used to print options
|
||||||
|
*/
|
||||||
|
enum _CLAP
|
||||||
|
{
|
||||||
|
CLAP_MAIN = 0,
|
||||||
|
|
||||||
|
CLAP_BLOCK ,
|
||||||
|
CLAP_LIST ,
|
||||||
|
CLAP_REGION ,
|
||||||
|
CLAP_SET ,
|
||||||
|
CLAP_SHOW ,
|
||||||
|
|
||||||
|
CLAP_SHOW_BLOCK ,
|
||||||
|
CLAP_SHOW_CAPACITY ,
|
||||||
|
CLAP_SHOW_DEVICE ,
|
||||||
|
CLAP_SHOW_NUM ,
|
||||||
|
CLAP_SHOW_REGION ,
|
||||||
|
CLAP_SHOW_SYSTEM ,
|
||||||
|
|
||||||
|
CLAP_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI Command Opcode (CM)
|
||||||
|
*/
|
||||||
|
enum _CLCM
|
||||||
|
{
|
||||||
|
CLCM_NULL = 0,
|
||||||
|
|
||||||
|
CLCM_INFO ,
|
||||||
|
CLCM_LIST ,
|
||||||
|
|
||||||
|
CLCM_BLOCK_ONLINE ,
|
||||||
|
CLCM_BLOCK_OFFLINE ,
|
||||||
|
|
||||||
|
CLCM_SET_BLOCK_STATE ,
|
||||||
|
CLCM_SET_REGION_BLOCK_STATE ,
|
||||||
|
CLCM_SET_SYSTEM_POLICY ,
|
||||||
|
|
||||||
|
CLCM_SHOW_REGIONS ,
|
||||||
|
CLCM_SHOW_BLOCKS ,
|
||||||
|
CLCM_SHOW_DEVICES ,
|
||||||
|
|
||||||
|
CLCM_SHOW_CAPACITY ,
|
||||||
|
|
||||||
|
CLCM_SHOW_NUM_BLOCKS ,
|
||||||
|
CLCM_SHOW_NUM_DEVICES ,
|
||||||
|
CLCM_SHOW_NUM_REGIONS ,
|
||||||
|
|
||||||
|
CLCM_SHOW_SYSTEM_BLOCKSIZE ,
|
||||||
|
CLCM_SHOW_SYSTEM_POLICY ,
|
||||||
|
|
||||||
|
CLCM_SHOW_BLK_ISONLINE ,
|
||||||
|
CLCM_SHOW_BLK_ISREMOVABLE ,
|
||||||
|
CLCM_SHOW_BLK_NODE ,
|
||||||
|
CLCM_SHOW_BLK_PHYSDEVICE ,
|
||||||
|
CLCM_SHOW_BLK_STATE ,
|
||||||
|
CLCM_SHOW_BLK_ZONES ,
|
||||||
|
|
||||||
|
CLCM_SHOW_REGION_ISENABLED ,
|
||||||
|
CLCM_SHOW_DEVICE_ISAVAILABLE ,
|
||||||
|
CLCM_SHOW_DEVICE_INTERLEAVE_GRANULARITY ,
|
||||||
|
|
||||||
|
CLCM_REGION_CREATE ,
|
||||||
|
CLCM_REGION_DAXMODE ,
|
||||||
|
CLCM_REGION_DELETE ,
|
||||||
|
CLCM_REGION_DISABLE ,
|
||||||
|
CLCM_REGION_ENABLE ,
|
||||||
|
CLCM_REGION_RAMMODE ,
|
||||||
|
|
||||||
|
CLCM_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI Option (OP)
|
||||||
|
*/
|
||||||
|
enum _CLOP
|
||||||
|
{
|
||||||
|
/* General CLI Options */
|
||||||
|
CLOP_VERBOSITY = 0, //!< Count <u32>
|
||||||
|
CLOP_PRNT_OPTS = 1, //!< Print Options Array when completed parsing <set>
|
||||||
|
CLOP_INFILE = 2, //!< Filename for input <str,buf,len>
|
||||||
|
CLOP_OUTFILE = 3, //!< Filename for output <str>
|
||||||
|
CLOP_NUM = 4, //!< Number of items <u8>
|
||||||
|
CLOP_ALL = 5, //!< Perform aciton on all of collection <set>
|
||||||
|
CLOP_LEN = 6, //!< Length of data parameter <len>
|
||||||
|
CLOP_LIMIT = 7, //!< Message Response Limit <u8>
|
||||||
|
CLOP_CMD = 8, //!< Command to RUN <val>
|
||||||
|
CLOP_DATA = 9, //!< Immediate Data for Write transaction <u32>
|
||||||
|
CLOP_HUMAN = 10, //!< Human readable values (K, M, G, T) <set>
|
||||||
|
|
||||||
|
CLOP_DEVICE = 11, //!< Device name <str>, <u32>
|
||||||
|
CLOP_REGION = 12, //!< Region name <str>, <u32>
|
||||||
|
CLOP_BLOCK = 13, //!< Block id <val>
|
||||||
|
CLOP_GRANULARITY = 14, //!< Memory Interleave Granularity <u32>
|
||||||
|
CLOP_ZONE = 15, //!< Memory Zone <u32> [CLZN]
|
||||||
|
CLOP_ONLINE = 16, //!< Online action <set>
|
||||||
|
CLOP_OFFLINE = 17, //!< Offline action <set>
|
||||||
|
CLOP_KERNEL = 18, //!< Online to kernel normal zone
|
||||||
|
CLOP_MOVABLE = 19, //!< Online to zone movable
|
||||||
|
|
||||||
|
CLOP_BLOCKS = 20, //!< Show Blocks <set>
|
||||||
|
CLOP_DEVICES = 21, //!< Show Devices <set>
|
||||||
|
CLOP_REGIONS = 22, //!< Show Regions <set>
|
||||||
|
|
||||||
|
CLOP_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Valid Zone options */
|
||||||
|
enum _CLZN
|
||||||
|
{
|
||||||
|
CLZN_DMA = 0,
|
||||||
|
CLZN_DMA32 = 1,
|
||||||
|
CLZN_NORMAL = 2,
|
||||||
|
CLZN_MOVABLE = 3,
|
||||||
|
CLZN_NONE = 4,
|
||||||
|
CLZN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* STRUCTS ===================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI Option Struct
|
||||||
|
*
|
||||||
|
* Each command line parameter is stored in one of these objects
|
||||||
|
*/
|
||||||
|
struct opt
|
||||||
|
{
|
||||||
|
int set; //!< Not set (0), set (1)
|
||||||
|
__u8 u8; //!< Unsigned char value
|
||||||
|
__u16 u16; //!< Unsigned long value
|
||||||
|
__u32 u32; //!< Unsigned long value
|
||||||
|
__u64 u64; //!< Unsigned long long value
|
||||||
|
__s32 val; //!< Generic signed value
|
||||||
|
__u64 num; //!< Number of items
|
||||||
|
__u64 len; //!< Data Buffer Length
|
||||||
|
char *str; //!< String value
|
||||||
|
__u8 *buf; //!< Data buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global varible to store parsed CLI options
|
||||||
|
*/
|
||||||
|
extern struct opt *opts;
|
||||||
|
|
||||||
|
/* PROTOTYPES ================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free allocated memory by option parsing proceedure
|
||||||
|
*
|
||||||
|
* @return 0 upon success. Non zero otherwise
|
||||||
|
*/
|
||||||
|
int options_free();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse command line options
|
||||||
|
*/
|
||||||
|
int options_parse(int argc, char *argv[]);
|
||||||
|
|
||||||
|
#endif //ifndef _OPTIONS_H
|
||||||
Loading…
Reference in New Issue
Block a user