Introduce image names and metadata storage in etcd
Each inode has: image name, parent inode number & pool, size and readonly flag Snapshots are created by switching image name to a different inode number while using the older inode as parent.
This commit is contained in:
+71
-29
@@ -6,17 +6,17 @@
|
||||
// Random write:
|
||||
//
|
||||
// fio -thread -ioengine=./libfio_cluster.so -name=test -bs=4k -direct=1 -fsync=16 -iodepth=16 -rw=randwrite \
|
||||
// -etcd=127.0.0.1:2379 [-etcd_prefix=/vitastor] -pool=1 -inode=1 -size=1000M
|
||||
// -etcd=127.0.0.1:2379 [-etcd_prefix=/vitastor] (-image=testimg | -pool=1 -inode=1 -size=1000M)
|
||||
//
|
||||
// Linear write:
|
||||
//
|
||||
// fio -thread -ioengine=./libfio_cluster.so -name=test -bs=128k -direct=1 -fsync=32 -iodepth=32 -rw=write \
|
||||
// -etcd=127.0.0.1:2379 [-etcd_prefix=/vitastor] -pool=1 -inode=1 -size=1000M
|
||||
// -etcd=127.0.0.1:2379 [-etcd_prefix=/vitastor] -image=testimg
|
||||
//
|
||||
// Random read (run with -iodepth=32 or -iodepth=1):
|
||||
//
|
||||
// fio -thread -ioengine=./libfio_cluster.so -name=test -bs=4k -direct=1 -iodepth=32 -rw=randread \
|
||||
// -etcd=127.0.0.1:2379 [-etcd_prefix=/vitastor] -pool=1 -inode=1 -size=1000M
|
||||
// -etcd=127.0.0.1:2379 [-etcd_prefix=/vitastor] -image=testimg
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -35,6 +35,7 @@ struct sec_data
|
||||
ring_loop_t *ringloop = NULL;
|
||||
epoll_manager_t *epmgr = NULL;
|
||||
cluster_client_t *cli = NULL;
|
||||
inode_watch_t *watch = NULL;
|
||||
bool last_sync = false;
|
||||
/* The list of completed io_u structs. */
|
||||
std::vector<io_u*> completed;
|
||||
@@ -47,6 +48,7 @@ struct sec_options
|
||||
int __pad;
|
||||
char *etcd_host = NULL;
|
||||
char *etcd_prefix = NULL;
|
||||
char *image = NULL;
|
||||
uint64_t pool = 0;
|
||||
uint64_t inode = 0;
|
||||
int cluster_log = 0;
|
||||
@@ -64,7 +66,7 @@ static struct fio_option options[] = {
|
||||
.group = FIO_OPT_G_FILENAME,
|
||||
},
|
||||
{
|
||||
.name = "etcd",
|
||||
.name = "etcd_prefix",
|
||||
.lname = "etcd key prefix",
|
||||
.type = FIO_OPT_STR_STORE,
|
||||
.off1 = offsetof(struct sec_options, etcd_prefix),
|
||||
@@ -72,6 +74,15 @@ static struct fio_option options[] = {
|
||||
.category = FIO_OPT_C_ENGINE,
|
||||
.group = FIO_OPT_G_FILENAME,
|
||||
},
|
||||
{
|
||||
.name = "image",
|
||||
.lname = "Vitastor image name",
|
||||
.type = FIO_OPT_STR_STORE,
|
||||
.off1 = offsetof(struct sec_options, image),
|
||||
.help = "Vitastor image name to run tests on",
|
||||
.category = FIO_OPT_C_ENGINE,
|
||||
.group = FIO_OPT_G_FILENAME,
|
||||
},
|
||||
{
|
||||
.name = "pool",
|
||||
.lname = "pool number for the inode",
|
||||
@@ -86,7 +97,7 @@ static struct fio_option options[] = {
|
||||
.lname = "inode to run tests on",
|
||||
.type = FIO_OPT_INT,
|
||||
.off1 = offsetof(struct sec_options, inode),
|
||||
.help = "inode to run tests on (1 by default)",
|
||||
.help = "inode number to run tests on",
|
||||
.category = FIO_OPT_C_ENGINE,
|
||||
.group = FIO_OPT_G_FILENAME,
|
||||
},
|
||||
@@ -141,6 +152,51 @@ static int sec_setup(struct thread_data *td)
|
||||
td->o.open_files++;
|
||||
}
|
||||
|
||||
json11::Json cfg = json11::Json::object {
|
||||
{ "etcd_address", std::string(o->etcd_host) },
|
||||
{ "etcd_prefix", std::string(o->etcd_prefix ? o->etcd_prefix : "/vitastor") },
|
||||
{ "log_level", o->cluster_log },
|
||||
};
|
||||
|
||||
if (!o->image)
|
||||
{
|
||||
if (!(o->inode & ((1l << (64-POOL_ID_BITS)) - 1)))
|
||||
{
|
||||
td_verror(td, EINVAL, "inode number is missing");
|
||||
return 1;
|
||||
}
|
||||
if (o->pool)
|
||||
{
|
||||
o->inode = (o->inode & ((1l << (64-POOL_ID_BITS)) - 1)) | (o->pool << (64-POOL_ID_BITS));
|
||||
}
|
||||
if (!(o->inode >> (64-POOL_ID_BITS)))
|
||||
{
|
||||
td_verror(td, EINVAL, "pool is missing");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
o->inode = 0;
|
||||
}
|
||||
bsd->ringloop = new ring_loop_t(512);
|
||||
bsd->epmgr = new epoll_manager_t(bsd->ringloop);
|
||||
bsd->cli = new cluster_client_t(bsd->ringloop, bsd->epmgr->tfd, cfg);
|
||||
if (o->image)
|
||||
{
|
||||
while (!bsd->cli->is_ready())
|
||||
{
|
||||
bsd->ringloop->loop();
|
||||
if (bsd->cli->is_ready())
|
||||
break;
|
||||
bsd->ringloop->wait();
|
||||
}
|
||||
bsd->watch = bsd->cli->st_cli.watch_inode(std::string(o->image));
|
||||
td->files[0]->real_file_size = bsd->watch->cfg.size;
|
||||
}
|
||||
|
||||
bsd->trace = o->trace ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -149,6 +205,10 @@ static void sec_cleanup(struct thread_data *td)
|
||||
sec_data *bsd = (sec_data*)td->io_ops_data;
|
||||
if (bsd)
|
||||
{
|
||||
if (bsd->watch)
|
||||
{
|
||||
bsd->cli->st_cli.close_watch(bsd->watch);
|
||||
}
|
||||
delete bsd->cli;
|
||||
delete bsd->epmgr;
|
||||
delete bsd->ringloop;
|
||||
@@ -159,28 +219,6 @@ static void sec_cleanup(struct thread_data *td)
|
||||
/* Connect to the server from each thread. */
|
||||
static int sec_init(struct thread_data *td)
|
||||
{
|
||||
sec_options *o = (sec_options*)td->eo;
|
||||
sec_data *bsd = (sec_data*)td->io_ops_data;
|
||||
|
||||
json11::Json cfg = json11::Json::object {
|
||||
{ "etcd_address", std::string(o->etcd_host) },
|
||||
{ "etcd_prefix", std::string(o->etcd_prefix ? o->etcd_prefix : "/vitastor") },
|
||||
{ "log_level", o->cluster_log },
|
||||
};
|
||||
|
||||
if (o->pool)
|
||||
o->inode = (o->inode & ((1l << (64-POOL_ID_BITS)) - 1)) | (o->pool << (64-POOL_ID_BITS));
|
||||
if (!(o->inode >> (64-POOL_ID_BITS)))
|
||||
{
|
||||
td_verror(td, EINVAL, "pool is missing");
|
||||
return 1;
|
||||
}
|
||||
bsd->ringloop = new ring_loop_t(512);
|
||||
bsd->epmgr = new epoll_manager_t(bsd->ringloop);
|
||||
bsd->cli = new cluster_client_t(bsd->ringloop, bsd->epmgr->tfd, cfg);
|
||||
|
||||
bsd->trace = o->trace ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -200,19 +238,23 @@ static enum fio_q_status sec_queue(struct thread_data *td, struct io_u *io)
|
||||
io->engine_data = bsd;
|
||||
cluster_op_t *op = new cluster_op_t;
|
||||
|
||||
op->inode = opt->image ? bsd->watch->cfg.num : opt->inode;
|
||||
switch (io->ddir)
|
||||
{
|
||||
case DDIR_READ:
|
||||
op->opcode = OSD_OP_READ;
|
||||
op->inode = opt->inode;
|
||||
op->offset = io->offset;
|
||||
op->len = io->xfer_buflen;
|
||||
op->iov.push_back(io->xfer_buf, io->xfer_buflen);
|
||||
bsd->last_sync = false;
|
||||
break;
|
||||
case DDIR_WRITE:
|
||||
if (opt->image && bsd->watch->cfg.readonly)
|
||||
{
|
||||
io->error = EROFS;
|
||||
return FIO_Q_COMPLETED;
|
||||
}
|
||||
op->opcode = OSD_OP_WRITE;
|
||||
op->inode = opt->inode;
|
||||
op->offset = io->offset;
|
||||
op->len = io->xfer_buflen;
|
||||
op->iov.push_back(io->xfer_buf, io->xfer_buflen);
|
||||
|
||||
Reference in New Issue
Block a user