Upload New File

This commit is contained in:
wang bojing
2024-08-10 14:25:43 +00:00
parent 13016eacd6
commit f216f73dda

869
success-case/zvfs.c Normal file
View File

@@ -0,0 +1,869 @@
#include <stdio.h>
#include <spdk/event.h>
#include <spdk/blob.h>
#include <spdk/bdev.h>
#include <spdk/env.h>
#include <spdk/blob_bdev.h>
#include <unistd.h>
#include <sys/syscall.h>
#define FILENAME_LENGTH 1024
typedef struct zfs_ctx_s {
struct spdk_bs_dev *bsdev;
struct spdk_blob_store *bs;
spdk_blob_id blobid;
struct spdk_blob *blob;
struct spdk_io_channel *channel;
uint8_t *write_buff;
uint8_t *read_buff;
uint64_t io_unit_size;
bool finished;
} zfs_ctx_t;
typedef struct zvfs_file_s {
char filename[FILENAME_LENGTH];
struct spdk_blob *blob;
spdk_blob_id blobid;
struct zvfs_s *fs;
uint8_t *write_buff; //
uint8_t *read_buff; //
bool finished;
} zvfs_file_t;
typedef struct zvfs_file_operation_s {
int (*open)(void);
int (*write)(void);
int (*read)(void);
int (*close)(void);
} zvfs_file_operation_t;
typedef struct zvfs_s {
struct spdk_bs_dev *bsdev;
struct spdk_blob_store *bs;
struct spdk_io_channel *channel;
uint64_t io_unit_size;
bool finished;
} zvfs_t;
typedef struct zvfs_operation_s {
int (*load)(zvfs_t *fs);
int (*unload)(zvfs_t *fs);
} zvfs_operation_t;
struct spdk_thread *global_thread;
zvfs_t *fs;
static void zvfs_spdk_bdev_complete(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
void *event_ctx) {
printf("blobstore create success\n");
}
static void zvfs_spdk_bs_unload_complete(void *arg, int bserrno) {
zvfs_t *ctx = arg;
#if 0
if (ctx->read_buff) {
spdk_free(ctx->read_buff);
ctx->read_buff = NULL;
}
if (ctx->write_buff) {
spdk_free(ctx->write_buff);
ctx->write_buff = NULL;
}
#endif
ctx->finished = true;
}
static void zvfs_spdk_bs_destroy_complete(void *arg, int bserrno) {
zvfs_t *ctx = arg;
if (ctx->bs) {
if (ctx->channel) {
spdk_bs_free_io_channel(ctx->channel);
}
spdk_bs_unload(ctx->bs, zvfs_spdk_bs_unload_complete, ctx);
}
}
static void zvfs_spdk_blob_close_complete(void *arg, int bserrno) {
zvfs_file_t *file = arg;
#if 1
if (file->read_buff) {
spdk_free(file->read_buff);
file->read_buff = NULL;
}
if (file->write_buff) {
spdk_free(file->write_buff);
file->write_buff = NULL;
}
#endif
file->finished = true;
}
static void zvfs_spdk_blob_read_complete(void *arg, int bserrno) {
zvfs_file_t *file = arg;
//SPDK_NOTICELOG("read : %s\n", file->read_buff);
#if 0
int match_res = memcmp(file->write_buff, file->read_buff,
file->fs->io_unit_size);
if (!match_res) {
SPDK_NOTICELOG("read SUCCESS and data matches!\n");
}
#endif
file->finished = true;
}
static void zvfs_spdk_blob_write_complete(void *arg, int bserrno) {
zvfs_file_t *file = arg;
file->finished = true;
//SPDK_NOTICELOG("ctx->finished = true\n");
}
static void zvfs_spdk_blob_sync_complete(void *arg, int bserrno) {
zvfs_file_t *file = arg;
#if 1
file->write_buff = spdk_malloc(file->fs->io_unit_size, 0x1000, NULL,
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (file->write_buff == NULL) {
return ;
}
file->read_buff = spdk_malloc(file->fs->io_unit_size, 0x1000, NULL,
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (file->read_buff == NULL) {
return ;
}
#endif
file->finished = true;
//SPDK_NOTICELOG("ctx->finished = true\n");
}
static void zvfs_spdk_bdev_resize_blob_complete(void *arg, int bserrno) {
zvfs_file_t *file = arg;
spdk_blob_sync_md(file->blob, zvfs_spdk_blob_sync_complete, file);
}
static void zvfs_spdk_bdev_open_blob_complete(void *arg, struct spdk_blob *blb, int bserrno) {
zvfs_file_t *file = arg;
file->blob = blb;
uint64_t numfreed = spdk_bs_free_cluster_count(file->fs->bs);
//SPDK_NOTICELOG("numfreed: %"PRIu64"\n", numfreed);
spdk_blob_resize(blb, numfreed, zvfs_spdk_bdev_resize_blob_complete, file);
}
// create
// open
static void zvfs_spdk_bdev_create_blob_complete(void *arg, spdk_blob_id blobid, int bserrno) {
//SPDK_NOTICELOG("spdk_blob_id: %"PRIu64"\n", blobid);
zvfs_file_t *file = arg;
file->blobid = blobid;
#if 1
spdk_bs_open_blob(file->fs->bs, blobid, zvfs_spdk_bdev_open_blob_complete, file);
#endif
}
static void zvfs_spdk_bdev_init_complete(void *arg, struct spdk_blob_store *bs,
int bserrno) {
zvfs_t *ctx = arg;
ctx->bs = bs;
ctx->io_unit_size = spdk_bs_get_io_unit_size(bs);
#if 1
ctx->channel = spdk_bs_alloc_io_channel(ctx->bs);
if (ctx->channel == NULL) {
return ;
}
#endif
//SPDK_NOTICELOG("io_unit_size --> %" PRIu64 "\n", ctx->io_unit_size);
ctx->finished = true;
}
// zvfs
static void zvfs_do_load(void *arg) {
zvfs_t *ctx = arg;
struct spdk_bs_dev *bsdev = NULL;
const char * bdev_name = "Malloc0";
int res = spdk_bdev_create_bs_dev_ext(bdev_name, zvfs_spdk_bdev_complete, NULL, &bsdev);
if (res != 0) {
spdk_app_stop(-1);
return ;
}
ctx->bsdev = bsdev;
spdk_bs_init(bsdev, NULL, zvfs_spdk_bdev_init_complete, ctx);
return ;
}
// unload
static void zvfs_do_unload(void *arg) {
zvfs_t *ctx = arg;
//spdk_bs_delete_blob(ctx->bs, ctx->blobid, zvfs_spdk_bs_delete_complete, ctx);
spdk_bs_destroy(ctx->bs, zvfs_spdk_bs_destroy_complete, ctx);
return ;
}
/// zvfs file api
//
static const int POLLER_MAX_TIME = 100000;
static bool poller(struct spdk_thread *thread, spdk_msg_fn start_fn, void *ctx, bool *finished) {
spdk_thread_send_msg(thread, start_fn, ctx);
int poller_count = 0;
do {
spdk_thread_poll(thread, 0, 0);
poller_count ++;
} while (!(*finished) && poller_count < POLLER_MAX_TIME);
if (!(*finished) && poller_count >= POLLER_MAX_TIME) { //timeout
return false;
}
return true;
}
///
static void zvfs_do_open(void *arg) {
zvfs_file_t *ctx = arg;
#if 0
spdk_bs_open_blob(ctx->fs->bs, ctx->blobid, zvfs_spdk_bdev_open_blob_complete, ctx);
#else
spdk_bs_create_blob(ctx->fs->bs, zvfs_spdk_bdev_create_blob_complete, ctx);
#endif
return ;
}
static void zvfs_do_write(void *arg) {
zvfs_file_t *file = arg;
#if 0
ctx->write_buff = spdk_malloc(ctx->io_unit_size, 0x1000, NULL,
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (ctx->write_buff == NULL) {
return ;
}
memset(ctx->write_buff, 'K', ctx->io_unit_size);
ctx->write_buff[ctx->io_unit_size-1] = '\0';
#endif
spdk_blob_io_write(file->blob, file->fs->channel, file->write_buff, 0, 1, zvfs_spdk_blob_write_complete, file);
return ;
}
static void zvfs_do_read(void *arg) {
zvfs_file_t *file = arg;
#if 0
ctx->read_buff = spdk_malloc(ctx->io_unit_size, 0x1000, NULL,
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (ctx->read_buff == NULL) {
return ;
}
#endif
spdk_blob_io_read(file->blob, file->fs->channel, file->read_buff, 0, 1, zvfs_spdk_blob_read_complete, file);
return ;
}
static void zvfs_do_close(void *arg) {
zvfs_file_t *file = arg;
spdk_blob_close(file->blob, zvfs_spdk_blob_close_complete, file);
return ;
}
// errno
// 1.
// strerr
//
//// zvfs_file_open
static int zvfs_file_open(zvfs_file_t *file) {
file->finished = false;
if (!poller(global_thread, zvfs_do_open, file, &file->finished)) {
return -1;
}
return 0;
}
static int zvfs_file_close(zvfs_file_t *file) {
file->finished = false;
if (!poller(global_thread, zvfs_do_close, file, &file->finished)) {
return -1;
}
return 0;
}
static int zvfs_file_write(zvfs_file_t *file, const void *buf, size_t size) {
file->finished = false;
memcpy(file->write_buff, buf, size); //
if (!poller(global_thread, zvfs_do_write, file, &file->finished)) {
return -1;
}
return 0;
}
static int zvfs_file_read(zvfs_file_t *file, void *buf, size_t size) {
file->finished = false;
if (!poller(global_thread, zvfs_do_read, file, &file->finished)) {
return -1;
}
memcpy(buf, file->read_buff, size);
return 0;
}
//// zvfs
static int zvfs_load(zvfs_t *fs) {
fs->finished = false;
if (!poller(global_thread, zvfs_do_load, fs, &fs->finished)) {
return -1;
}
return 0;
}
static int zvfs_unload(zvfs_t *fs) {
fs->finished = false;
if (!poller(global_thread, zvfs_do_unload, fs, &fs->finished)) {
return -1;
}
return 0;
}
// fd
#define MAX_FD_COUNT 1024
#define DEFAULT_FD_NUM 3
static unsigned char fd_table[MAX_FD_COUNT / 8] = {0};
zvfs_file_t *files[MAX_FD_COUNT] = {0};
static int get_fd_frombitmap(void) {
int fd = DEFAULT_FD_NUM;
for ( ;fd < MAX_FD_COUNT;fd ++) {
if ((fd_table[fd/8] & (0x1 << (fd % 8))) == 0) {
fd_table[fd/8] |= (0x1 << (fd % 8));
return fd;
}
}
return -1;
}
static int set_fd_frombitmap(int fd) {
if (fd >= MAX_FD_COUNT) return -1;
fd_table[fd/8] &= ~(0x1 << (fd % 8));
return 0;
}
static int zvfs_open(const char *filename, int flag) {
zvfs_file_t *file = (zvfs_file_t*)malloc(sizeof(zvfs_file_t));
if (file == NULL) return -1;
int fd = get_fd_frombitmap();
file->fs = fs;
files[fd] = file;
zvfs_file_open(file);
return fd;
}
static int zvfs_write(int fd,const void *buf, size_t count) {
zvfs_file_t *file = files[fd];
zvfs_file_write(file, buf, count);
return 0;
}
static int zvfs_read(int fd, void *buf, size_t count) {
zvfs_file_t *file = files[fd];
zvfs_file_read(file, buf, count);
return strlen(buf);
}
static int zvfs_close(int fd) {
zvfs_file_t *file = files[fd];
zvfs_file_close(file);
set_fd_frombitmap(fd);
free(file);
return 0;
}
/// hook
#if 0
typedef int (*open_t)(const char *pathname, int flags);
open_t open_f = NULL;
typedef ssize_t (*write_t)(int fd, const void *buf, size_t n);
write_t write_f = NULL;
typedef ssize_t (*read_t)(int fd, void *buf, size_t n);
read_t read_f = NULL;
typedef int (*close_t)(int fd);
close_t close_f;
int zvfs_initilize = false;
static int zvfs_setup(void);
int open(const char *pathname, int flags, ...) {
int ret = 0;
ret = syscall(__NR_open, pathname, flags);
return ret;
}
ssize_t write(int fd, const void *buf, size_t n) {
int ret = 0;
ret = syscall(__NR_write, buf, n);
return ret;
}
ssize_t read(int fd, void *buf, size_t n) {
int ret = 0;
ret = syscall(__NR_read, buf, n);
return ret;
}
int close (int fd) {
int ret = 0;
ret = syscall(__NR_close, fd);
return ret;
}
#else
#include <dlfcn.h>
#define DEBUG_ENABLE 1
#if DEBUG_ENABLE
#define dblog(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define dblog(fmt, ...)
#endif
typedef int (*open_t)(const char *pathname, int flags);
open_t open_f = NULL;
typedef ssize_t (*write_t)(int fd, const void *buf, size_t n);
write_t write_f = NULL;
typedef ssize_t (*read_t)(int fd, void *buf, size_t n);
read_t read_f = NULL;
typedef int (*close_t)(int fd);
close_t close_f = NULL;
int open(const char *pathname, int flags, ...) {
if (!open_f) {
open_f = dlsym(RTLD_NEXT, "open");
}
dblog("open.. %s\n", pathname);
return open_f(pathname, flags);
}
ssize_t read(int fd, void *buf, size_t count) {
ssize_t ret;
if (!read_f) {
read_f = dlsym(RTLD_NEXT, "read");
}
ret = read_f(fd, buf, count);
dblog("read.. : %ld, %ld\n", ret, count);
return ret;
}
ssize_t write(int fd, const void *buf, size_t count) {
if (!write_f) {
write_f = dlsym(RTLD_NEXT, "write");
}
dblog("write.. : %ld\n", count);
return write_f(fd, buf, count);
}
int close(int fd) {
if (!close_f) {
close_f = dlsym(RTLD_NEXT, "close");
}
dblog("close..\n");
return close_f(fd);
}
#endif
#if 1
static const char *json_file = "/home/king/share/spdk/examples/mysql/hello_blob.json";
static void json_app_load_done(int rc, void *ctx) {
bool *done = ctx;
*done = true;
// SPDK_NOTICELOG("json_app_load_done\n");
}
static void zvfs_json_load_fn(void *arg) {
spdk_subsystem_init_from_json_config(json_file, SPDK_DEFAULT_RPC_ADDR,
json_app_load_done, arg, true);
}
static int zvfs_env_setup(void) {
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
if (spdk_env_init(&opts) != 0) {
return -1;
}
spdk_log_set_print_level(SPDK_LOG_NOTICE);
spdk_log_set_level(SPDK_LOG_NOTICE);
spdk_log_open(NULL);
spdk_thread_lib_init(NULL, 0);
global_thread = spdk_thread_create("global", NULL);
spdk_set_thread(global_thread);
bool done = false;
poller(global_thread, zvfs_json_load_fn, &done, &done);
return 0;
}
// blob --> json
static int zvfs_setup(void) {
zvfs_env_setup();
zvfs_t *ctx = calloc(1, sizeof(zvfs_t));
zvfs_load(ctx);
fs = ctx;
return 0;
}
#if 0
int main(int argc, char *argv[]) {
printf("zvfs_env_setup111\n");
#if 0
zvfs_env_setup();
// load --> bs_init, blob_create, blob_open, blob_resize
zfs_ctx_t *ctx = calloc(1, sizeof(zfs_ctx_t));
ctx->finished = false;
poller(global_thread, zvfs_do_load, ctx, &ctx->finished);
// open
ctx->finished = false;
poller(global_thread, zvfs_do_open, ctx, &ctx->finished);
// write
ctx->finished = false;
poller(global_thread, zvfs_do_write, ctx, &ctx->finished);
// read
ctx->finished = false;
poller(global_thread, zvfs_do_read, ctx, &ctx->finished);
// close
ctx->finished = false;
poller(global_thread, zvfs_do_close, ctx, &ctx->finished);
// unload
ctx->finished = false;
poller(global_thread, zvfs_do_unload, ctx, &ctx->finished);
#elif 0
zvfs_env_setup();
zvfs_t *ctx = calloc(1, sizeof(zvfs_t));
zvfs_load(ctx);
fs = ctx;
zvfs_file_t *file = calloc(1, sizeof(zvfs_file_t));
file->fs = ctx;
zvfs_file_open(file);
char *buffer = "zvoice.king";
zvfs_file_write(file, buffer, strlen(buffer));
char rbuffer[1024] = {0};
zvfs_file_read(file, rbuffer, 1024);
printf("rbuffer: %s\n", rbuffer);
zvfs_file_close(file);
zvfs_unload(ctx);
#elif 0
zvfs_t *ctx = calloc(1, sizeof(zvfs_t));
zvfs_load(ctx);
fs = ctx;
int fd = zvfs_open("king.txt", 0x666);
char *buffer = "zvoice.king";
zvfs_write(fd, buffer, strlen(buffer));
char rbuffer[1024] = {0};
zvfs_read(fd, rbuffer, 1024);
printf("rbuffer: %s\n", rbuffer);
zvfs_close(fd);
zvfs_unload(ctx);
#else
printf("zvfs_env_setup\n");
//zvfs_t *ctx = calloc(1, sizeof(zvfs_t));
//zvfs_load(ctx);
//fs = ctx;
printf("zvfs_load\n");
int fd = open("/home/king/share/spdk/examples/mysql/a.txt", O_RDWR | O_CREAT);
printf("fd: %d, %s\n", fd, strerror(errno));
char *buffer = "zvoice.king";
int ret = write(fd, buffer, strlen(buffer));
lseek(fd, 0, SEEK_SET);
char rbuffer[1024] = {0};
ret = read(fd, rbuffer, 1024);
printf("ret : %d, rbuffer: %s\n", ret, rbuffer);
close(fd);
//zvfs_unload(fs);
return 0;
#endif
}
#endif
#elif 0
int main() {
int fd = open("./a.txt", RW);
char *buffer = "zvoice.king";
write(fd, buffer, strlen(buffer));
char rbuffer[1024] = {0};
read(fd, rbuffer, 1024);
close(fd);
}
#else
int main(int argc, char *argv[]) {
if (argc < 2) {
return -1;
}
struct spdk_app_opts opts= {0};
spdk_app_opts_init(&opts, sizeof(opts));
opts.name = "zvfs";
opts.json_config_file = argv[1];
printf("spdk_set_thread --> \n");
zfs_ctx_t *ctx = calloc(1, sizeof(zfs_ctx_t));
spdk_app_start(&opts, zvfs_entry, ctx);
spdk_app_fini();
free(ctx);
return 0;
}
#endif