blobcli: refactoring and cleanup
Some refactoring around functions that need to load the blobstore as a first step was done as general cleanup. Function names were also updated for consistency, some comments cleaned up and #defines added for clarity. Change-Id: I71550b6664a8ec78aca1b304891de3f6154b616d Signed-off-by: Paul Luse <paul.e.luse@intel.com> Reviewed-on: https://review.gerrithub.io/380834 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
c5e63c71ff
commit
866f15b3ac
@ -43,16 +43,17 @@
|
|||||||
#include "spdk/string.h"
|
#include "spdk/string.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is not a public header file, but the CLI does expose
|
* The following is not a public header file, but the CLI does expose
|
||||||
* some internals of blobstore for dev/debug puposes so we
|
* some internals of blobstore for dev/debug puposes so we
|
||||||
* include it here.
|
* include it here.
|
||||||
*/
|
*/
|
||||||
#include "../lib/blob/blobstore.h"
|
#include "../lib/blob/blobstore.h"
|
||||||
static void cli_start(void *arg1, void *arg2);
|
static void cli_start(void *arg1, void *arg2);
|
||||||
static bool cli_shell(void *arg1, void *arg2);
|
|
||||||
|
|
||||||
static const char *program_name = "blobcli";
|
static const char *program_name = "blobcli";
|
||||||
|
/* default name for .conf file, any name can be used however with -c switch */
|
||||||
static const char *program_conf = "blobcli.conf";
|
static const char *program_conf = "blobcli.conf";
|
||||||
|
/* default name for the first NVMe device, this needs to match what is in th conf */
|
||||||
static const char *bdev_name = "Nvme0n1";
|
static const char *bdev_name = "Nvme0n1";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -82,9 +83,12 @@ enum cli_action_type {
|
|||||||
CLI_SHELL_EXIT,
|
CLI_SHELL_EXIT,
|
||||||
CLI_HELP
|
CLI_HELP
|
||||||
};
|
};
|
||||||
#define BUFSIZE 255
|
|
||||||
|
|
||||||
|
#define BUFSIZE 255
|
||||||
#define MAX_ARGS 6
|
#define MAX_ARGS 6
|
||||||
|
#define ALIGN_4K 4096
|
||||||
|
#define STARTING_PAGE 0
|
||||||
|
#define NUM_PAGES 1
|
||||||
/*
|
/*
|
||||||
* The CLI uses the SPDK app framework so is async and callback driven. A
|
* The CLI uses the SPDK app framework so is async and callback driven. A
|
||||||
* pointer to this structure is passed to SPDK calls and returned in the
|
* pointer to this structure is passed to SPDK calls and returned in the
|
||||||
@ -112,7 +116,6 @@ struct cli_context_t {
|
|||||||
const char *bdev_name;
|
const char *bdev_name;
|
||||||
int rc;
|
int rc;
|
||||||
int num_clusters;
|
int num_clusters;
|
||||||
void (*next_func)(void *arg1, struct spdk_blob_store *bs, int bserrno);
|
|
||||||
enum cli_mode_type cli_mode;
|
enum cli_mode_type cli_mode;
|
||||||
const char *config_file;
|
const char *config_file;
|
||||||
int argc;
|
int argc;
|
||||||
@ -244,7 +247,7 @@ close_cb(void *arg1, int bserrno)
|
|||||||
* Callback function for sync'ing metadata.
|
* Callback function for sync'ing metadata.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
sync_complete(void *arg1, int bserrno)
|
sync_cb(void *arg1, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
|
|
||||||
@ -262,7 +265,7 @@ sync_complete(void *arg1, int bserrno)
|
|||||||
* Callback function for opening a blob after creating.
|
* Callback function for opening a blob after creating.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
open_now_resize(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
open_now_resize_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = cb_arg;
|
struct cli_context_t *cli_context = cb_arg;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -291,7 +294,7 @@ open_now_resize(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
* Always a good idea to sync after MD changes or the changes
|
* Always a good idea to sync after MD changes or the changes
|
||||||
* may be lost if things aren't closed cleanly.
|
* may be lost if things aren't closed cleanly.
|
||||||
*/
|
*/
|
||||||
spdk_bs_md_sync_blob(cli_context->blob, sync_complete,
|
spdk_bs_md_sync_blob(cli_context->blob, sync_cb,
|
||||||
cli_context);
|
cli_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +302,7 @@ open_now_resize(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
* Callback function for creating a blob.
|
* Callback function for creating a blob.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
blob_create_complete(void *arg1, spdk_blob_id blobid, int bserrno)
|
blob_create_cb(void *arg1, spdk_blob_id blobid, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
|
|
||||||
@ -314,14 +317,14 @@ blob_create_complete(void *arg1, spdk_blob_id blobid, int bserrno)
|
|||||||
|
|
||||||
/* We have to open the blob before we can do things like resize. */
|
/* We have to open the blob before we can do things like resize. */
|
||||||
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
||||||
open_now_resize, cli_context);
|
open_now_resize_cb, cli_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for get_super where we'll continue on to show blobstore info.
|
* Callback for get_super where we'll continue on to show blobstore info.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
show_bs(void *arg1, spdk_blob_id blobid, int bserrno)
|
show_bs_cb(void *arg1, spdk_blob_id blobid, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
@ -352,8 +355,7 @@ show_bs(void *arg1, spdk_blob_id blobid, int bserrno)
|
|||||||
printf("\tsuper blob ID: none assigned\n");
|
printf("\tsuper blob ID: none assigned\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
val = spdk_bs_get_page_size(cli_context->bs);
|
printf("\tpage size: %" PRIu64 "\n", cli_context->page_size);
|
||||||
printf("\tpage size: %" PRIu64 "\n", val);
|
|
||||||
|
|
||||||
val = spdk_bs_get_cluster_size(cli_context->bs);
|
val = spdk_bs_get_cluster_size(cli_context->bs);
|
||||||
printf("\tcluster size: %" PRIu64 "\n", val);
|
printf("\tcluster size: %" PRIu64 "\n", val);
|
||||||
@ -374,43 +376,6 @@ show_bs(void *arg1, spdk_blob_id blobid, int bserrno)
|
|||||||
unload_bs(cli_context, "", 0);
|
unload_bs(cli_context, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Load callback where we'll get the super blobid next.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
get_super_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
if (bserrno) {
|
|
||||||
unload_bs(cli_context, "Error in load blob callback",
|
|
||||||
bserrno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cli_context->bs = bs;
|
|
||||||
|
|
||||||
spdk_bs_get_super(cli_context->bs, show_bs, cli_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback for load bs where we'll continue on to create a blob.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
create_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
if (bserrno) {
|
|
||||||
unload_bs(cli_context, "Error in load callback",
|
|
||||||
bserrno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cli_context->bs = bs;
|
|
||||||
|
|
||||||
spdk_bs_md_create_blob(cli_context->bs, blob_create_complete,
|
|
||||||
cli_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show detailed info about a particular blob.
|
* Show detailed info about a particular blob.
|
||||||
*/
|
*/
|
||||||
@ -421,7 +386,7 @@ show_blob(struct cli_context_t *cli_context)
|
|||||||
struct spdk_xattr_names *names;
|
struct spdk_xattr_names *names;
|
||||||
const void *value;
|
const void *value;
|
||||||
size_t value_len;
|
size_t value_len;
|
||||||
char data[256];
|
char data[BUFSIZE];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
printf("Blob Public Info:\n");
|
printf("Blob Public Info:\n");
|
||||||
@ -486,7 +451,7 @@ show_blob(struct cli_context_t *cli_context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for getting the first blob.
|
* Callback for getting the first blob, shared with simple blob listing as well.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
blob_iter_cb(void *arg1, struct spdk_blob *blob, int bserrno)
|
blob_iter_cb(void *arg1, struct spdk_blob *blob, int bserrno)
|
||||||
@ -505,7 +470,7 @@ blob_iter_cb(void *arg1, struct spdk_blob *blob, int bserrno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cli_context->action == CLI_LIST_BLOBS) {
|
if (cli_context->action == CLI_LIST_BLOBS) {
|
||||||
/* just listing blobs */
|
printf("\nList BLOBS:\n");
|
||||||
printf("Found blob with ID# %" PRIu64 "\n",
|
printf("Found blob with ID# %" PRIu64 "\n",
|
||||||
spdk_blob_get_id(blob));
|
spdk_blob_get_id(blob));
|
||||||
} else if (spdk_blob_get_id(blob) == cli_context->blobid) {
|
} else if (spdk_blob_get_id(blob) == cli_context->blobid) {
|
||||||
@ -523,28 +488,6 @@ blob_iter_cb(void *arg1, struct spdk_blob *blob, int bserrno)
|
|||||||
cli_context);
|
cli_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback for load bs where we'll continue on to list all blobs.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
list_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
if (bserrno) {
|
|
||||||
unload_bs(cli_context, "Error in load callback",
|
|
||||||
bserrno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cli_context->bs = bs;
|
|
||||||
|
|
||||||
if (cli_context->action == CLI_LIST_BLOBS) {
|
|
||||||
printf("\nList BLOBS:\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
spdk_bs_md_iter_first(cli_context->bs, blob_iter_cb, cli_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for setting the super blob ID.
|
* Callback for setting the super blob ID.
|
||||||
*/
|
*/
|
||||||
@ -563,30 +506,11 @@ set_super_cb(void *arg1, int bserrno)
|
|||||||
unload_bs(cli_context, "", 0);
|
unload_bs(cli_context, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback for load bs where we'll continue on to set the super blob.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
set_super_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
if (bserrno) {
|
|
||||||
unload_bs(cli_context, "Error in load callback",
|
|
||||||
bserrno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cli_context->bs = bs;
|
|
||||||
|
|
||||||
spdk_bs_set_super(cli_context->bs, cli_context->superid,
|
|
||||||
set_super_cb, cli_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for set_xattr_open where we set or delete xattrs.
|
* Callback for set_xattr_open where we set or delete xattrs.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
set_xattr(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
set_xattr_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = cb_arg;
|
struct cli_context_t *cli_context = cb_arg;
|
||||||
|
|
||||||
@ -609,34 +533,14 @@ set_xattr(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
printf("Xattr has been removed.\n");
|
printf("Xattr has been removed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_bs_md_sync_blob(cli_context->blob, sync_complete,
|
spdk_bs_md_sync_blob(cli_context->blob, sync_cb, cli_context);
|
||||||
cli_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback for load bs where we'll continue on to set/del an xattr.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
xattr_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
if (bserrno) {
|
|
||||||
unload_bs(cli_context, "Error in load callback",
|
|
||||||
bserrno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cli_context->bs = bs;
|
|
||||||
|
|
||||||
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
|
||||||
set_xattr, cli_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback function for reading a blob for dumping to a file.
|
* Callback function for reading a blob for dumping to a file.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
read_dump_complete(void *arg1, int bserrno)
|
read_dump_cb(void *arg1, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
uint64_t bytes_written;
|
uint64_t bytes_written;
|
||||||
@ -648,7 +552,7 @@ read_dump_complete(void *arg1, int bserrno)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_written = fwrite(cli_context->buff, 1, cli_context->page_size,
|
bytes_written = fwrite(cli_context->buff, NUM_PAGES, cli_context->page_size,
|
||||||
cli_context->fp);
|
cli_context->fp);
|
||||||
if (bytes_written != cli_context->page_size) {
|
if (bytes_written != cli_context->page_size) {
|
||||||
fclose(cli_context->fp);
|
fclose(cli_context->fp);
|
||||||
@ -662,7 +566,7 @@ read_dump_complete(void *arg1, int bserrno)
|
|||||||
/* perform another read */
|
/* perform another read */
|
||||||
spdk_bs_io_read_blob(cli_context->blob, cli_context->channel,
|
spdk_bs_io_read_blob(cli_context->blob, cli_context->channel,
|
||||||
cli_context->buff, cli_context->page_count,
|
cli_context->buff, cli_context->page_count,
|
||||||
1, read_dump_complete, cli_context);
|
NUM_PAGES, read_dump_cb, cli_context);
|
||||||
} else {
|
} else {
|
||||||
/* done reading */
|
/* done reading */
|
||||||
printf("\nFile write complete.\n");
|
printf("\nFile write complete.\n");
|
||||||
@ -676,7 +580,7 @@ read_dump_complete(void *arg1, int bserrno)
|
|||||||
* Callback for write completion on the import of a file to a blob.
|
* Callback for write completion on the import of a file to a blob.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
write_imp_complete(void *arg1, int bserrno)
|
write_imp_cb(void *arg1, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
uint64_t bytes_read;
|
uint64_t bytes_read;
|
||||||
@ -698,8 +602,7 @@ write_imp_complete(void *arg1, int bserrno)
|
|||||||
/* if this read is < 1 page, fill with 0s */
|
/* if this read is < 1 page, fill with 0s */
|
||||||
if (bytes_read < cli_context->page_size) {
|
if (bytes_read < cli_context->page_size) {
|
||||||
uint8_t *offset = cli_context->buff + bytes_read;
|
uint8_t *offset = cli_context->buff + bytes_read;
|
||||||
memset(offset, 0,
|
memset(offset, 0, cli_context->page_size - bytes_read);
|
||||||
cli_context->page_size - bytes_read);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -712,13 +615,12 @@ write_imp_complete(void *arg1, int bserrno)
|
|||||||
printf(".");
|
printf(".");
|
||||||
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
||||||
cli_context->buff, cli_context->page_count,
|
cli_context->buff, cli_context->page_count,
|
||||||
1, write_imp_complete, cli_context);
|
NUM_PAGES, write_imp_cb, cli_context);
|
||||||
} else {
|
} else {
|
||||||
/* done writing */
|
/* done writing */
|
||||||
printf("\nBlob import complete.\n");
|
printf("\nBlob import complete.\n");
|
||||||
fclose(cli_context->fp);
|
fclose(cli_context->fp);
|
||||||
spdk_bs_md_close_blob(&cli_context->blob, close_cb,
|
spdk_bs_md_close_blob(&cli_context->blob, close_cb, cli_context);
|
||||||
cli_context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,7 +631,7 @@ write_imp_complete(void *arg1, int bserrno)
|
|||||||
* contents first and then 0 out the rest of the blob.
|
* contents first and then 0 out the rest of the blob.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dmpimp_open_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
dump_imp_open_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = cb_arg;
|
struct cli_context_t *cli_context = cb_arg;
|
||||||
|
|
||||||
@ -739,20 +641,13 @@ dmpimp_open_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cli_context->blob = blob;
|
cli_context->blob = blob;
|
||||||
cli_context->page_size = spdk_bs_get_page_size(cli_context->bs);
|
|
||||||
cli_context->channel = spdk_bs_alloc_io_channel(cli_context->bs);
|
|
||||||
if (cli_context->channel == NULL) {
|
|
||||||
unload_bs(cli_context, "Error in allocating channel",
|
|
||||||
-ENOMEM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'll transfer just one page at a time to keep the buffer
|
* We'll transfer just one page at a time to keep the buffer
|
||||||
* small. This could be bigger of course.
|
* small. This could be bigger of course.
|
||||||
*/
|
*/
|
||||||
cli_context->buff = spdk_dma_malloc(cli_context->page_size,
|
cli_context->buff = spdk_dma_malloc(cli_context->page_size,
|
||||||
0x1000, NULL);
|
ALIGN_4K, NULL);
|
||||||
if (cli_context->buff == NULL) {
|
if (cli_context->buff == NULL) {
|
||||||
unload_bs(cli_context, "Error in allocating memory",
|
unload_bs(cli_context, "Error in allocating memory",
|
||||||
-ENOMEM);
|
-ENOMEM);
|
||||||
@ -767,7 +662,7 @@ dmpimp_open_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
/* read a page of data from the blob */
|
/* read a page of data from the blob */
|
||||||
spdk_bs_io_read_blob(cli_context->blob, cli_context->channel,
|
spdk_bs_io_read_blob(cli_context->blob, cli_context->channel,
|
||||||
cli_context->buff, cli_context->page_count,
|
cli_context->buff, cli_context->page_count,
|
||||||
1, read_dump_complete, cli_context);
|
NUM_PAGES, read_dump_cb, cli_context);
|
||||||
} else {
|
} else {
|
||||||
cli_context->fp = fopen(cli_context->file, "r");
|
cli_context->fp = fopen(cli_context->file, "r");
|
||||||
|
|
||||||
@ -775,7 +670,7 @@ dmpimp_open_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
fseek(cli_context->fp, 0L, SEEK_END);
|
fseek(cli_context->fp, 0L, SEEK_END);
|
||||||
cli_context->filesize = ftell(cli_context->fp);
|
cli_context->filesize = ftell(cli_context->fp);
|
||||||
rewind(cli_context->fp);
|
rewind(cli_context->fp);
|
||||||
cli_context->bytes_so_far = fread(cli_context->buff, 1,
|
cli_context->bytes_so_far = fread(cli_context->buff, NUM_PAGES,
|
||||||
cli_context->page_size,
|
cli_context->page_size,
|
||||||
cli_context->fp);
|
cli_context->fp);
|
||||||
|
|
||||||
@ -790,35 +685,15 @@ dmpimp_open_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
|
|
||||||
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
||||||
cli_context->buff, cli_context->page_count,
|
cli_context->buff, cli_context->page_count,
|
||||||
1, write_imp_complete, cli_context);
|
NUM_PAGES, write_imp_cb, cli_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback for load bs where we'll continue on dump a blob to a file or
|
|
||||||
* import a file to a blob.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
dmpimp_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
if (bserrno) {
|
|
||||||
unload_bs(cli_context, "Error in load callback",
|
|
||||||
bserrno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cli_context->bs = bs;
|
|
||||||
|
|
||||||
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
|
||||||
dmpimp_open_cb, cli_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback function for writing a specific pattern to page 0.
|
* Callback function for writing a specific pattern to page 0.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
write_complete(void *arg1, int bserrno)
|
write_cb(void *arg1, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
|
|
||||||
@ -831,7 +706,7 @@ write_complete(void *arg1, int bserrno)
|
|||||||
if (++cli_context->page_count < cli_context->blob_pages) {
|
if (++cli_context->page_count < cli_context->blob_pages) {
|
||||||
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
||||||
cli_context->buff, cli_context->page_count,
|
cli_context->buff, cli_context->page_count,
|
||||||
1, write_complete, cli_context);
|
NUM_PAGES, write_cb, cli_context);
|
||||||
} else {
|
} else {
|
||||||
/* done writing */
|
/* done writing */
|
||||||
printf("\nBlob fill complete.\n");
|
printf("\nBlob fill complete.\n");
|
||||||
@ -842,23 +717,24 @@ write_complete(void *arg1, int bserrno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* function to fill a blob with a value.
|
* Callback function to fill a blob with a value, callback from open.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fill_blob(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
fill_blob_cb(void *arg1, struct spdk_blob *blob, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = cb_arg;
|
struct cli_context_t *cli_context = arg1;
|
||||||
|
|
||||||
if (bserrno) {
|
if (bserrno) {
|
||||||
unload_bs(cli_context, "Error in blob open callback",
|
unload_bs(cli_context, "Error in open callback",
|
||||||
bserrno);
|
bserrno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cli_context->blob = blob;
|
cli_context->blob = blob;
|
||||||
cli_context->page_count = 0;
|
cli_context->page_count = 0;
|
||||||
cli_context->blob_pages = spdk_blob_get_num_pages(cli_context->blob);
|
cli_context->blob_pages = spdk_blob_get_num_pages(cli_context->blob);
|
||||||
cli_context->buff = spdk_dma_malloc(cli_context->page_size,
|
cli_context->buff = spdk_dma_malloc(cli_context->page_size,
|
||||||
0x1000, NULL);
|
ALIGN_4K, NULL);
|
||||||
if (cli_context->buff == NULL) {
|
if (cli_context->buff == NULL) {
|
||||||
unload_bs(cli_context, "Error in allocating memory",
|
unload_bs(cli_context, "Error in allocating memory",
|
||||||
-ENOMEM);
|
-ENOMEM);
|
||||||
@ -870,14 +746,16 @@ fill_blob(void *cb_arg, struct spdk_blob *blob, int bserrno)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
spdk_bs_io_write_blob(cli_context->blob, cli_context->channel,
|
||||||
cli_context->buff,
|
cli_context->buff,
|
||||||
0, 1, write_complete, cli_context);
|
STARTING_PAGE, NUM_PAGES, write_cb, cli_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for load bs where we'll continue on to fill a blob.
|
* Multiple actions require us to open the bs first so here we use
|
||||||
|
* a common callback to set a bunch of values and then move on to
|
||||||
|
* the next step saved off via function pointer.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fill_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
load_bs_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = arg1;
|
struct cli_context_t *cli_context = arg1;
|
||||||
|
|
||||||
@ -886,6 +764,7 @@ fill_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|||||||
bserrno);
|
bserrno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cli_context->bs = bs;
|
cli_context->bs = bs;
|
||||||
cli_context->page_size = spdk_bs_get_page_size(cli_context->bs);
|
cli_context->page_size = spdk_bs_get_page_size(cli_context->bs);
|
||||||
cli_context->channel = spdk_bs_alloc_io_channel(cli_context->bs);
|
cli_context->channel = spdk_bs_alloc_io_channel(cli_context->bs);
|
||||||
@ -895,13 +774,47 @@ fill_load_cb(void *arg1, struct spdk_blob_store *bs, int bserrno)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
switch (cli_context->action) {
|
||||||
fill_blob, cli_context);
|
case CLI_SET_SUPER:
|
||||||
|
spdk_bs_set_super(cli_context->bs, cli_context->superid,
|
||||||
|
set_super_cb, cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_SHOW_BS:
|
||||||
|
spdk_bs_get_super(cli_context->bs, show_bs_cb, cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_CREATE_BLOB:
|
||||||
|
spdk_bs_md_create_blob(cli_context->bs, blob_create_cb,
|
||||||
|
cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_SET_XATTR:
|
||||||
|
case CLI_REM_XATTR:
|
||||||
|
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
||||||
|
set_xattr_cb, cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_SHOW_BLOB:
|
||||||
|
case CLI_LIST_BLOBS:
|
||||||
|
spdk_bs_md_iter_first(cli_context->bs, blob_iter_cb, cli_context);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLI_DUMP:
|
||||||
|
case CLI_IMPORT:
|
||||||
|
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
||||||
|
dump_imp_open_cb, cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_FILL:
|
||||||
|
spdk_bs_md_open_blob(cli_context->bs, cli_context->blobid,
|
||||||
|
fill_blob_cb, cli_context);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* should never get here */
|
||||||
|
spdk_app_stop(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Multiple actions require us to open the bs first. A function pointer
|
* Load the blobstore.
|
||||||
* setup earlier will direct the callback accordingly.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
load_bs(struct cli_context_t *cli_context)
|
load_bs(struct cli_context_t *cli_context)
|
||||||
@ -923,7 +836,7 @@ load_bs(struct cli_context_t *cli_context)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_bs_load(bs_dev, NULL, cli_context->next_func, cli_context);
|
spdk_bs_load(bs_dev, NULL, load_bs_cb, cli_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -960,8 +873,8 @@ list_bdevs(struct cli_context_t *cli_context)
|
|||||||
* Callback function for initializing a blob.
|
* Callback function for initializing a blob.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
bs_init_complete(void *cb_arg, struct spdk_blob_store *bs,
|
bs_init_cb(void *cb_arg, struct spdk_blob_store *bs,
|
||||||
int bserrno)
|
int bserrno)
|
||||||
{
|
{
|
||||||
struct cli_context_t *cli_context = cb_arg;
|
struct cli_context_t *cli_context = cb_arg;
|
||||||
|
|
||||||
@ -990,7 +903,7 @@ init_bs(struct cli_context_t *cli_context)
|
|||||||
spdk_app_stop(-1);
|
spdk_app_stop(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Blobstore using bdev Product Name: %s\n",
|
printf("Init blobstore using bdev Product Name: %s\n",
|
||||||
spdk_bdev_get_product_name(bdev));
|
spdk_bdev_get_product_name(bdev));
|
||||||
|
|
||||||
cli_context->bs_dev = spdk_bdev_create_bs_dev(bdev, NULL, NULL);
|
cli_context->bs_dev = spdk_bdev_create_bs_dev(bdev, NULL, NULL);
|
||||||
@ -1000,92 +913,10 @@ init_bs(struct cli_context_t *cli_context)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_bs_init(cli_context->bs_dev, NULL, bs_init_complete,
|
spdk_bs_init(cli_context->bs_dev, NULL, bs_init_cb,
|
||||||
cli_context);
|
cli_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the function we pass into the SPDK framework that gets
|
|
||||||
* called first.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
cli_start(void *arg1, void *arg2)
|
|
||||||
{
|
|
||||||
struct cli_context_t *cli_context = arg1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The initial cmd line options are parsed once before this function is
|
|
||||||
* called so if there is no action, we're in shell mode and will loop
|
|
||||||
* here until a a valid option is parsed and returned.
|
|
||||||
*/
|
|
||||||
if (cli_context->action == CLI_NONE) {
|
|
||||||
while (cli_shell(cli_context, NULL) == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decide what to do next based on cmd line parsing that
|
|
||||||
* happened earlier, in many cases we setup a function pointer
|
|
||||||
* to be used as a callback following a generic action like
|
|
||||||
* loading the blobstore.
|
|
||||||
*/
|
|
||||||
switch (cli_context->action) {
|
|
||||||
case CLI_SET_SUPER:
|
|
||||||
cli_context->next_func = &set_super_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_SHOW_BS:
|
|
||||||
cli_context->next_func = &get_super_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_CREATE_BLOB:
|
|
||||||
cli_context->next_func = &create_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_SET_XATTR:
|
|
||||||
case CLI_REM_XATTR:
|
|
||||||
cli_context->next_func = &xattr_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_SHOW_BLOB:
|
|
||||||
case CLI_LIST_BLOBS:
|
|
||||||
cli_context->next_func = &list_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_DUMP:
|
|
||||||
case CLI_IMPORT:
|
|
||||||
cli_context->next_func = &dmpimp_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_FILL:
|
|
||||||
cli_context->next_func = &fill_load_cb;
|
|
||||||
load_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_INIT_BS:
|
|
||||||
init_bs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_LIST_BDEVS:
|
|
||||||
list_bdevs(cli_context);
|
|
||||||
break;
|
|
||||||
case CLI_SHELL_EXIT:
|
|
||||||
/*
|
|
||||||
* Because shell mode reuses cmd mode functions, the blobstore
|
|
||||||
* is loaded/unloaded with every action so we just need to
|
|
||||||
* stop the framework. For this app there's no need to optimize
|
|
||||||
* and keep the blobstore open while the app is in shell mode.
|
|
||||||
*/
|
|
||||||
spdk_app_stop(0);
|
|
||||||
break;
|
|
||||||
case CLI_HELP:
|
|
||||||
print_cmds("");
|
|
||||||
unload_complete(cli_context, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* should never get here */
|
|
||||||
spdk_app_stop(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common cmd/option parser for command and shell modes.
|
* Common cmd/option parser for command and shell modes.
|
||||||
*/
|
*/
|
||||||
@ -1231,11 +1062,13 @@ cmd_parser(int argc, char **argv, struct cli_context_t *cli_context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* a few options require some extra paramters */
|
/* a few options require some extra paramters */
|
||||||
if (cli_context->action == CLI_SET_XATTR ||
|
if (cli_context->action == CLI_SET_XATTR) {
|
||||||
cli_context->action == CLI_REM_XATTR) {
|
|
||||||
snprintf(cli_context->key, BUFSIZE, "%s", argv[3]);
|
snprintf(cli_context->key, BUFSIZE, "%s", argv[3]);
|
||||||
snprintf(cli_context->value, BUFSIZE, "%s", argv[4]);
|
snprintf(cli_context->value, BUFSIZE, "%s", argv[4]);
|
||||||
}
|
}
|
||||||
|
if (cli_context->action == CLI_REM_XATTR) {
|
||||||
|
snprintf(cli_context->key, BUFSIZE, "%s", argv[3]);
|
||||||
|
}
|
||||||
|
|
||||||
if (cli_context->action == CLI_DUMP ||
|
if (cli_context->action == CLI_DUMP ||
|
||||||
cli_context->action == CLI_IMPORT) {
|
cli_context->action == CLI_IMPORT) {
|
||||||
@ -1300,6 +1133,63 @@ cli_shell(void *arg1, void *arg2)
|
|||||||
return cmd_chosen;
|
return cmd_chosen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the function we pass into the SPDK framework that gets
|
||||||
|
* called first.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
cli_start(void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
struct cli_context_t *cli_context = arg1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The initial cmd line options are parsed once before this function is
|
||||||
|
* called so if there is no action, we're in shell mode and will loop
|
||||||
|
* here until a a valid option is parsed and returned.
|
||||||
|
*/
|
||||||
|
if (cli_context->action == CLI_NONE) {
|
||||||
|
while (cli_shell(cli_context, NULL) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decide what to do next based on cmd line parsing. */
|
||||||
|
switch (cli_context->action) {
|
||||||
|
case CLI_SET_SUPER:
|
||||||
|
case CLI_SHOW_BS:
|
||||||
|
case CLI_CREATE_BLOB:
|
||||||
|
case CLI_SET_XATTR:
|
||||||
|
case CLI_REM_XATTR:
|
||||||
|
case CLI_SHOW_BLOB:
|
||||||
|
case CLI_LIST_BLOBS:
|
||||||
|
case CLI_DUMP:
|
||||||
|
case CLI_IMPORT:
|
||||||
|
case CLI_FILL:
|
||||||
|
load_bs(cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_INIT_BS:
|
||||||
|
init_bs(cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_LIST_BDEVS:
|
||||||
|
list_bdevs(cli_context);
|
||||||
|
break;
|
||||||
|
case CLI_SHELL_EXIT:
|
||||||
|
/*
|
||||||
|
* Because shell mode reuses cmd mode functions, the blobstore
|
||||||
|
* is loaded/unloaded with every action so we just need to
|
||||||
|
* stop the framework. For this app there's no need to optimize
|
||||||
|
* and keep the blobstore open while the app is in shell mode.
|
||||||
|
*/
|
||||||
|
spdk_app_stop(0);
|
||||||
|
break;
|
||||||
|
case CLI_HELP:
|
||||||
|
print_cmds("");
|
||||||
|
unload_complete(cli_context, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* should never get here */
|
||||||
|
spdk_app_stop(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
|
Loading…
Reference in New Issue
Block a user