Compare commits

..

10 Commits

Author SHA1 Message Date
a1f8ac4ecf Run tests with writeback?
All checks were successful
Test / test_rebalance_verify (push) Successful in 1m32s
Test / test_rebalance_verify_imm (push) Successful in 1m34s
Test / test_root_node (push) Successful in 8s
Test / test_rebalance_verify_ec (push) Successful in 1m40s
Test / test_rebalance_verify_ec_imm (push) Successful in 1m42s
Test / test_write_no_same (push) Successful in 7s
Test / test_switch_primary (push) Successful in 31s
Test / test_write (push) Successful in 30s
Test / test_write_xor (push) Successful in 34s
Test / test_osd_tags (push) Successful in 9s
Test / test_enospc (push) Successful in 9s
Test / test_enospc_imm (push) Successful in 10s
Test / test_enospc_xor (push) Successful in 13s
Test / test_enospc_imm_xor (push) Successful in 13s
Test / test_scrub (push) Successful in 13s
Test / test_scrub_zero_osd_2 (push) Successful in 11s
Test / test_scrub_xor (push) Successful in 14s
Test / test_scrub_pg_size_3 (push) Successful in 14s
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 15s
Test / test_scrub_ec (push) Successful in 13s
Test / test_nfs (push) Successful in 10s
Test / test_heal_pg_size_2 (push) Successful in 2m14s
Test / test_heal_ec (push) Successful in 2m19s
Test / test_heal_antietcd (push) Successful in 2m19s
Test / test_heal_csum_32k_dmj (push) Successful in 2m18s
Test / test_heal_csum_32k_dj (push) Successful in 2m21s
Test / test_heal_csum_32k (push) Successful in 2m18s
Test / test_heal_csum_4k_dmj (push) Successful in 2m17s
Test / test_heal_csum_4k_dj (push) Successful in 2m19s
Test / test_heal_csum_4k (push) Successful in 2m8s
2024-07-22 20:06:32 +03:00
3acf3a867d Try to catch hang bug
All checks were successful
Test / test_rebalance_verify (push) Successful in 1m27s
Test / test_root_node (push) Successful in 7s
Test / test_rebalance_verify_imm (push) Successful in 1m29s
Test / test_rebalance_verify_ec (push) Successful in 1m38s
Test / test_rebalance_verify_ec_imm (push) Successful in 1m37s
Test / test_write_no_same (push) Successful in 7s
Test / test_switch_primary (push) Successful in 32s
Test / test_write (push) Successful in 31s
Test / test_write_xor (push) Successful in 36s
Test / test_osd_tags (push) Successful in 7s
Test / test_enospc (push) Successful in 10s
Test / test_enospc_xor (push) Successful in 13s
Test / test_enospc_imm (push) Successful in 11s
Test / test_enospc_imm_xor (push) Successful in 13s
Test / test_scrub (push) Successful in 12s
Test / test_scrub_zero_osd_2 (push) Successful in 14s
Test / test_scrub_xor (push) Successful in 14s
Test / test_scrub_pg_size_3 (push) Successful in 14s
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 15s
Test / test_scrub_ec (push) Successful in 14s
Test / test_nfs (push) Successful in 12s
Test / test_heal_pg_size_2 (push) Successful in 2m15s
Test / test_heal_ec (push) Successful in 2m16s
Test / test_heal_antietcd (push) Successful in 2m17s
Test / test_heal_csum_32k_dmj (push) Successful in 2m20s
Test / test_heal_csum_32k_dj (push) Successful in 2m18s
Test / test_heal_csum_32k (push) Successful in 2m18s
Test / test_heal_csum_4k_dmj (push) Successful in 2m20s
Test / test_heal_csum_4k_dj (push) Successful in 2m20s
Test / test_heal_csum_4k (push) Successful in 2m15s
2024-07-22 13:28:58 +03:00
8635e0af24 Always continue operations to not miss resuming after the lack of PG primary
Some checks failed
Test / test_rebalance_verify (push) Successful in 1m27s
Test / test_rebalance_verify_imm (push) Successful in 1m28s
Test / test_root_node (push) Successful in 7s
Test / test_rebalance_verify_ec (push) Successful in 1m34s
Test / test_rebalance_verify_ec_imm (push) Successful in 1m35s
Test / test_write_no_same (push) Successful in 8s
Test / test_switch_primary (push) Successful in 31s
Test / test_write (push) Successful in 30s
Test / test_write_xor (push) Successful in 33s
Test / test_osd_tags (push) Successful in 7s
Test / test_enospc (push) Successful in 10s
Test / test_enospc_imm (push) Successful in 8s
Test / test_enospc_xor (push) Successful in 11s
Test / test_enospc_imm_xor (push) Successful in 13s
Test / test_scrub (push) Successful in 12s
Test / test_scrub_zero_osd_2 (push) Successful in 12s
Test / test_scrub_xor (push) Successful in 14s
Test / test_scrub_pg_size_3 (push) Successful in 15s
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 16s
Test / test_nfs (push) Successful in 10s
Test / test_scrub_ec (push) Successful in 14s
Test / test_heal_pg_size_2 (push) Successful in 2m16s
Test / test_heal_ec (push) Successful in 2m17s
Test / test_heal_csum_4k_dj (push) Successful in 2m18s
Test / test_heal_csum_4k (push) Successful in 2m18s
Test / test_heal_csum_4k_dmj (push) Successful in 2m18s
Test / test_heal_csum_32k_dmj (push) Successful in 2m16s
Test / test_heal_csum_32k_dj (push) Successful in 2m19s
Test / test_heal_antietcd (push) Failing after 10m9s
Test / test_heal_csum_32k (push) Successful in 2m16s
Should fix spurious client hangs during PG primary switchover
2024-07-22 00:27:35 +03:00
da73d5f45a Add downgrade docs
Some checks failed
Test / test_rebalance_verify (push) Successful in 1m25s
Test / test_rebalance_verify_imm (push) Successful in 1m26s
Test / test_root_node (push) Successful in 7s
Test / test_rebalance_verify_ec (push) Successful in 1m33s
Test / test_rebalance_verify_ec_imm (push) Successful in 1m34s
Test / test_switch_primary (push) Successful in 31s
Test / test_write_no_same (push) Successful in 9s
Test / test_write (push) Successful in 30s
Test / test_write_xor (push) Successful in 34s
Test / test_osd_tags (push) Successful in 7s
Test / test_enospc (push) Successful in 10s
Test / test_enospc_xor (push) Successful in 13s
Test / test_enospc_imm (push) Successful in 12s
Test / test_enospc_imm_xor (push) Successful in 12s
Test / test_scrub (push) Successful in 15s
Test / test_scrub_zero_osd_2 (push) Successful in 14s
Test / test_scrub_xor (push) Successful in 12s
Test / test_scrub_pg_size_3 (push) Successful in 13s
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 14s
Test / test_nfs (push) Successful in 10s
Test / test_scrub_ec (push) Successful in 13s
Test / test_heal_csum_4k_dj (push) Successful in 2m15s
Test / test_heal_csum_4k (push) Successful in 2m12s
Test / test_heal_pg_size_2 (push) Successful in 2m15s
Test / test_heal_antietcd (push) Successful in 2m16s
Test / test_heal_csum_32k_dmj (push) Successful in 2m15s
Test / test_heal_csum_32k_dj (push) Successful in 2m19s
Test / test_heal_csum_32k (push) Successful in 2m16s
Test / test_heal_csum_4k_dmj (push) Failing after 10m13s
Test / test_heal_ec (push) Failing after 10m8s
2024-07-21 13:35:20 +03:00
88bbe16ac3 Support seamless upgrade to new PG config and stats etcd key names
All checks were successful
Test / test_rebalance_verify (push) Successful in 1m21s
Test / test_rebalance_verify_imm (push) Successful in 1m23s
Test / test_root_node (push) Successful in 7s
Test / test_rebalance_verify_ec (push) Successful in 1m31s
Test / test_rebalance_verify_ec_imm (push) Successful in 1m28s
Test / test_write_no_same (push) Successful in 8s
Test / test_switch_primary (push) Successful in 31s
Test / test_write (push) Successful in 30s
Test / test_write_xor (push) Successful in 34s
Test / test_heal_pg_size_2 (push) Successful in 2m17s
Test / test_heal_ec (push) Successful in 2m16s
Test / test_heal_antietcd (push) Successful in 2m17s
Test / test_heal_csum_32k_dmj (push) Successful in 2m16s
Test / test_heal_csum_32k_dj (push) Successful in 2m18s
Test / test_heal_csum_32k (push) Successful in 2m20s
Test / test_heal_csum_4k_dmj (push) Successful in 2m19s
Test / test_osd_tags (push) Successful in 9s
Test / test_heal_csum_4k_dj (push) Successful in 2m16s
Test / test_enospc (push) Successful in 10s
Test / test_enospc_xor (push) Successful in 14s
Test / test_enospc_imm (push) Successful in 12s
Test / test_enospc_imm_xor (push) Successful in 14s
Test / test_scrub_zero_osd_2 (push) Successful in 12s
Test / test_scrub (push) Successful in 15s
Test / test_scrub_xor (push) Successful in 13s
Test / test_scrub_pg_size_3 (push) Successful in 16s
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 14s
Test / test_scrub_ec (push) Successful in 13s
Test / test_nfs (push) Successful in 11s
Test / test_heal_csum_4k (push) Successful in 2m17s
2024-07-21 02:07:00 +03:00
85ba14319a Use separate watch revisions for different watchers 2024-07-21 02:07:00 +03:00
5a56912d5e Run tests in CI in memory (in tmpfs) 2024-07-21 02:06:25 +03:00
edc2f4eb97 Report OSD version in /osd/state/ and /osd/stats/ (for the future) 2024-07-20 02:19:41 +03:00
ba806ff1ba Rename VERSION define to VITASTOR_VERSION 2024-07-20 02:19:41 +03:00
3d925c37cd Rename /config/pgs to /pg/config and /pg/stats/* to /pgstats/* 2024-07-20 02:19:39 +03:00
11 changed files with 109 additions and 230 deletions

View File

@@ -17,10 +17,10 @@ To enable Vitastor support in Proxmox Virtual Environment (6.4-8.1 are supported
- Restart pvedaemon: `systemctl restart pvedaemon`
`/etc/pve/storage.cfg` example (the only required option is vitastor_pool, all others
are listed below with their default values; `vitastor_ssd` is Proxmox storage pool id):
are listed below with their default values):
```
vitastor: vitastor_ssd
vitastor: vitastor
# pool to put new images into
vitastor_pool testpool
# path to the configuration file

View File

@@ -16,10 +16,10 @@
- Перезапустите демон Proxmox: `systemctl restart pvedaemon`
Пример `/etc/pve/storage.cfg` (единственная обязательная опция - vitastor_pool, все остальные
перечислены внизу для понимания значений по умолчанию; `vitastor_ssd` - имя хранилища в Proxmox):
перечислены внизу для понимания значений по умолчанию):
```
vitastor: vitastor_ssd
vitastor: vitastor
# Пул, в который будут помещаться образы дисков
vitastor_pool testpool
# Путь к файлу конфигурации

View File

@@ -307,7 +307,7 @@ OSD PARENT UP SIZE USED% TAGS WEIGHT BLOCK BITMAP
`vitastor-cli modify-osd [--tags tag1,tag2,...] [--reweight <number>] [--noout true/false] <osd_number>`
Set OSD reweight, tags or noout flag. See detail description in [OSD config documentation](../config/pool.en.md#osd-settings).
Set OSD reweight, tags or noout flag. See detail description in [OSD config documentation](../config.pool.en.md#osd-settings).
## pg-list

View File

@@ -324,7 +324,7 @@ OSD PARENT UP SIZE USED% TAGS WEIGHT BLOCK BITMAP
`vitastor-cli modify-osd [--tags tag1,tag2,...] [--reweight <number>] [--noout true/false] <osd_number>`
Установить вес OSD, теги или флаг noout. Смотрите подробное описание в [документации настроек OSD](../config/pool.ru.md#настройки-osd).
Установить вес OSD, теги или флаг noout. Смотрите подробное описание в [документации настроек OSD](../config.pool.ru.md#настройки-osd).
## pg-list

View File

@@ -24,7 +24,7 @@ NAN_MODULE_INIT(InitAddon)
tpl = Nan::New<v8::FunctionTemplate>(NodeVitastorImage::Create);
tpl->SetClassName(Nan::New("Image").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->InstanceTemplate()->SetInternalFieldCount(2);
Nan::SetPrototypeMethod(tpl, "read", NodeVitastorImage::Read);
Nan::SetPrototypeMethod(tpl, "write", NodeVitastorImage::Write);
@@ -67,7 +67,7 @@ NAN_MODULE_INIT(InitAddon)
tpl = Nan::New<v8::FunctionTemplate>(NodeVitastorKVListing::Create);
tpl->SetClassName(Nan::New("KVListing").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->InstanceTemplate()->SetInternalFieldCount(2);
Nan::SetPrototypeMethod(tpl, "next", NodeVitastorKVListing::Next);
Nan::SetPrototypeMethod(tpl, "close", NodeVitastorKVListing::Close);

View File

@@ -10,11 +10,10 @@
'<!(node -e "require(\'nan\')")'
],
'cflags': [
'<!(pkg-config --cflags vitastor) -g'
'<!(pkg-config --cflags vitastor)'
],
'libraries': [
'<!(pkg-config --libs vitastor)',
'-lvitastor_kv'
'<!(pkg-config --libs vitastor)'
]
}
]

View File

@@ -18,15 +18,12 @@
class NodeVitastorRequest: public Nan::AsyncResource
{
public:
NodeVitastorRequest(NodeVitastor *cli, v8::Local<v8::Function> cb): Nan::AsyncResource("NodeVitastorRequest")
NodeVitastorRequest(v8::Local<v8::Function> cb): Nan::AsyncResource("NodeVitastorRequest")
{
this->cli = cli;
callback.Reset(cb);
}
iovec iov;
std::vector<iovec> iov_list;
NodeVitastor *cli = NULL;
NodeVitastorImage *img = NULL;
int op = 0;
uint64_t offset = 0, len = 0, version = 0;
@@ -46,7 +43,6 @@ NodeVitastor::NodeVitastor(): Nan::ObjectWrap()
NodeVitastor::~NodeVitastor()
{
TRACE("NodeVitastor: destructor");
uv_poll_stop(&poll_watcher);
vitastor_c_destroy(c);
c = NULL;
@@ -78,10 +74,9 @@ NAN_METHOD(NodeVitastor::Create)
if (res >= 0)
{
cli->eventfd = res;
res = uv_poll_init(uv_default_loop(), &cli->poll_watcher, cli->eventfd);
res = uv_poll_init_socket(uv_default_loop(), &cli->poll_watcher, cli->eventfd);
if (res >= 0)
res = uv_poll_start(&cli->poll_watcher, UV_READABLE, on_io_readable);
on_io_readable(&cli->poll_watcher, 0, UV_READABLE);
}
if (res < 0)
{
@@ -102,28 +97,12 @@ void NodeVitastor::on_io_readable(uv_poll_t* handle, int status, int revents)
if (revents & UV_READABLE)
{
NodeVitastor* self = (NodeVitastor*)handle->data;
{
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_uring_handle_events(self->c);
}
self->run_postponed();
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_uring_handle_events(self->c);
}
}
void NodeVitastor::run_postponed()
{
std::vector<std::function<void()>> callbacks;
{
std::unique_lock<std::mutex> lock(mu);
callbacks.swap(postponed);
}
for (auto & cb: callbacks)
{
cb();
}
}
NodeVitastorRequest* NodeVitastor::get_read_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
static NodeVitastorRequest* getReadRequest(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
{
uint64_t offset = Nan::To<int64_t>(info[argpos+0]).FromJust();
uint64_t len = Nan::To<int64_t>(info[argpos+1]).FromJust();
@@ -134,7 +113,7 @@ NodeVitastorRequest* NodeVitastor::get_read_request(const Nan::FunctionCallbackI
return NULL;
}
v8::Local<v8::Function> callback = info[argpos+2].As<v8::Function>();
auto req = new NodeVitastorRequest(this, callback);
auto req = new NodeVitastorRequest(callback);
req->offset = offset;
req->len = len;
@@ -153,21 +132,19 @@ NAN_METHOD(NodeVitastor::Read)
uint64_t pool = Nan::To<int64_t>(info[0]).FromJust();
uint64_t inode = Nan::To<int64_t>(info[1]).FromJust();
auto req = self->get_read_request(info, 2);
auto req = getReadRequest(info, 2);
self->Ref();
{
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_read(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, &req->iov, 1, postpone_read_finish, req);
}
self->run_postponed();
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_read(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, &req->iov, 1, on_read_finish, req);
}
NodeVitastorRequest* NodeVitastor::get_write_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
static NodeVitastorRequest* getWriteRequest(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
{
uint64_t offset = Nan::To<int64_t>(info[argpos+0]).FromJust();
const auto & bufarg = info[argpos+1];
char *buf = node::Buffer::Data(info[argpos+1]);
uint64_t len = node::Buffer::Length(info[argpos+1]);
uint64_t version = 0;
if (!info[argpos+2].IsEmpty() && info[argpos+2]->IsObject())
{
auto key = Nan::New<v8::String>("version").ToLocalChecked();
@@ -179,36 +156,17 @@ NodeVitastorRequest* NodeVitastor::get_write_request(const Nan::FunctionCallback
}
v8::Local<v8::Function> callback = info[argpos+2].As<v8::Function>();
auto req = new NodeVitastorRequest(this, callback);
auto req = new NodeVitastorRequest(callback);
req->offset = offset;
req->len = len;
req->version = version;
if (bufarg->IsArray())
{
auto buffers = bufarg.As<v8::Array>();
req->len = 0;
for (uint32_t i = 0; i < buffers->Length(); i++)
{
auto buffer_obj = Nan::Get(buffers, i).ToLocalChecked();
char *buf = node::Buffer::Data(buffer_obj);
uint64_t len = node::Buffer::Length(buffer_obj);
req->iov_list.push_back({ .iov_base = buf, .iov_len = len });
req->len += len;
}
}
else
{
char *buf = node::Buffer::Data(bufarg);
uint64_t len = node::Buffer::Length(bufarg);
req->iov = { .iov_base = buf, .iov_len = len };
req->len = len;
}
req->iov = { .iov_base = buf, .iov_len = req->len };
return req;
}
// write(pool, inode, offset, buf: Buffer | Buffer[], { version }?, callback(err))
// write(pool, inode, offset, buffer, { version }?, callback(err))
NAN_METHOD(NodeVitastor::Write)
{
TRACE("NodeVitastor::Write");
@@ -218,17 +176,10 @@ NAN_METHOD(NodeVitastor::Write)
uint64_t pool = Nan::To<int64_t>(info[0]).FromJust();
uint64_t inode = Nan::To<int64_t>(info[1]).FromJust();
auto req = self->get_write_request(info, 2);
auto req = getWriteRequest(info, 2);
self->Ref();
{
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_write(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, req->version,
req->iov_list.size() ? req->iov_list.data() : &req->iov,
req->iov_list.size() ? req->iov_list.size() : 1,
postpone_write_finish, req);
}
self->run_postponed();
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_write(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, req->version, &req->iov, 1, on_write_finish, req);
}
// sync(callback(err))
@@ -239,14 +190,10 @@ NAN_METHOD(NodeVitastor::Sync)
NodeVitastor* self = Nan::ObjectWrap::Unwrap<NodeVitastor>(info.This());
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
auto req = new NodeVitastorRequest(self, callback);
auto req = new NodeVitastorRequest(callback);
self->Ref();
{
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_sync(self->c, postpone_write_finish, req);
}
self->run_postponed();
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_sync(self->c, on_write_finish, req);
}
// read_bitmap(pool, inode, offset, len, with_parents, callback(err, bitmap_buffer))
@@ -262,14 +209,9 @@ NAN_METHOD(NodeVitastor::ReadBitmap)
uint64_t len = Nan::To<int64_t>(info[3]).FromJust();
bool with_parents = Nan::To<bool>(info[4]).FromJust();
v8::Local<v8::Function> callback = info[5].As<v8::Function>();
auto req = new NodeVitastorRequest(self, callback);
self->Ref();
{
std::unique_lock<std::mutex> lock(self->mu);
vitastor_c_read_bitmap(self->c, ((pool << (64-POOL_ID_BITS)) | inode), offset, len, with_parents, postpone_read_bitmap_finish, req);
}
self->run_postponed();
auto req = new NodeVitastorRequest(callback);
vitastor_c_read_bitmap(self->c, ((pool << (64-POOL_ID_BITS)) | inode), offset, len, with_parents, on_read_bitmap_finish, req);
}
static void on_error(NodeVitastorRequest *req, Nan::Callback & nanCallback, long retval)
@@ -285,7 +227,6 @@ static void on_error(NodeVitastorRequest *req, Nan::Callback & nanCallback, long
void NodeVitastor::on_read_finish(void *opaque, long retval, uint64_t version)
{
TRACE("NodeVitastor::on_read_finish");
Nan::HandleScope scope;
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
Nan::Callback nanCallback(Nan::New(req->callback));
@@ -307,24 +248,20 @@ void NodeVitastor::on_read_finish(void *opaque, long retval, uint64_t version)
args[2] = v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), version);
nanCallback.Call(3, args, req);
}
req->cli->Unref();
delete req;
}
void NodeVitastor::on_write_finish(void *opaque, long retval)
{
TRACE("NodeVitastor::on_write_finish");
Nan::HandleScope scope;
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
Nan::Callback nanCallback(Nan::New(req->callback));
on_error(req, nanCallback, retval);
req->cli->Unref();
delete req;
}
void NodeVitastor::on_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap)
{
TRACE("NodeVitastor::on_read_bitmap_finish");
Nan::HandleScope scope;
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
Nan::Callback nanCallback(Nan::New(req->callback));
@@ -339,28 +276,9 @@ void NodeVitastor::on_read_bitmap_finish(void *opaque, long retval, uint8_t *bit
args[1] = Nan::NewBuffer((char*)bitmap, (retval+7)/8).ToLocalChecked();
nanCallback.Call(2, args, req);
}
req->cli->Unref();
delete req;
}
void NodeVitastor::postpone_read_finish(void *opaque, long retval, uint64_t version)
{
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
req->cli->postponed.push_back([=]() { on_read_finish(opaque, retval, version); });
}
void NodeVitastor::postpone_write_finish(void *opaque, long retval)
{
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
req->cli->postponed.push_back([=]() { on_write_finish(opaque, retval); });
}
void NodeVitastor::postpone_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap)
{
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
req->cli->postponed.push_back([=]() { on_read_bitmap_finish(opaque, retval, bitmap); });
}
//NAN_METHOD(NodeVitastor::Destroy)
//{
// TRACE("NodeVitastor::Destroy");
@@ -379,8 +297,6 @@ NAN_METHOD(NodeVitastorImage::Create)
NodeVitastor *cli = Nan::ObjectWrap::Unwrap<NodeVitastor>(parent);
NodeVitastorImage *img = new NodeVitastorImage();
img->Wrap(info.This());
img->cli = cli;
img->name = name;
@@ -389,6 +305,7 @@ NAN_METHOD(NodeVitastorImage::Create)
std::unique_lock<std::mutex> lock(cli->mu);
vitastor_c_watch_inode(cli->c, (char*)img->name.c_str(), on_watch_start, img);
img->Wrap(info.This());
info.GetReturnValue().Set(info.This());
}
@@ -409,7 +326,7 @@ NAN_METHOD(NodeVitastorImage::Read)
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
auto req = img->cli->get_read_request(info, 0);
auto req = getReadRequest(info, 0);
req->img = img;
req->op = NODE_VITASTOR_READ;
@@ -423,7 +340,7 @@ NAN_METHOD(NodeVitastorImage::Write)
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
auto req = img->cli->get_write_request(info, 0);
auto req = getWriteRequest(info, 0);
req->img = img;
req->op = NODE_VITASTOR_WRITE;
@@ -437,7 +354,7 @@ NAN_METHOD(NodeVitastorImage::Sync)
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
auto req = new NodeVitastorRequest(img->cli, callback);
auto req = new NodeVitastorRequest(callback);
req->img = img;
req->op = NODE_VITASTOR_SYNC;
@@ -456,7 +373,7 @@ NAN_METHOD(NodeVitastorImage::ReadBitmap)
bool with_parents = Nan::To<bool>(info[2]).FromJust();
v8::Local<v8::Function> callback = info[3].As<v8::Function>();
auto req = new NodeVitastorRequest(img->cli, callback);
auto req = new NodeVitastorRequest(callback);
req->img = img;
req->op = NODE_VITASTOR_READ_BITMAP;
req->offset = offset;
@@ -468,12 +385,12 @@ NAN_METHOD(NodeVitastorImage::ReadBitmap)
NAN_METHOD(NodeVitastorImage::GetInfo)
{
TRACE("NodeVitastorImage::GetInfo");
TRACE("NodeVitastorImage::Sync");
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
auto req = new NodeVitastorRequest(img->cli, callback);
auto req = new NodeVitastorRequest(callback);
req->img = img;
req->op = NODE_VITASTOR_GET_INFO;
@@ -495,52 +412,75 @@ void NodeVitastorImage::exec_or_wait(NodeVitastorRequest *req)
void NodeVitastorImage::exec_request(NodeVitastorRequest *req)
{
std::unique_lock<std::mutex> lock(cli->mu);
if (req->op == NODE_VITASTOR_READ)
{
cli->Ref();
std::unique_lock<std::mutex> lock(cli->mu);
uint64_t ino = vitastor_c_inode_get_num(watch);
vitastor_c_read(cli->c, ino, req->offset, req->len, &req->iov, 1, NodeVitastor::postpone_read_finish, req);
vitastor_c_read(cli->c, ino, req->offset, req->len, &req->iov, 1, NodeVitastor::on_read_finish, req);
}
else if (req->op == NODE_VITASTOR_WRITE)
{
cli->Ref();
std::unique_lock<std::mutex> lock(cli->mu);
uint64_t ino = vitastor_c_inode_get_num(watch);
vitastor_c_write(cli->c, ino, req->offset, req->len, req->version,
req->iov_list.size() ? req->iov_list.data() : &req->iov,
req->iov_list.size() ? req->iov_list.size() : 1,
NodeVitastor::postpone_write_finish, req);
vitastor_c_write(cli->c, ino, req->offset, req->len, req->version, &req->iov, 1, NodeVitastor::on_write_finish, req);
}
else if (req->op == NODE_VITASTOR_SYNC)
{
cli->Ref();
std::unique_lock<std::mutex> lock(cli->mu);
uint64_t ino = vitastor_c_inode_get_num(watch);
uint32_t imm = vitastor_c_inode_get_immediate_commit(cli->c, ino);
if (imm != IMMEDIATE_ALL)
{
vitastor_c_sync(cli->c, NodeVitastor::postpone_write_finish, req);
vitastor_c_sync(cli->c, NodeVitastor::on_write_finish, req);
}
else
{
NodeVitastor::postpone_write_finish(req, 0);
NodeVitastor::on_write_finish(req, 0);
}
}
else if (req->op == NODE_VITASTOR_READ_BITMAP)
{
cli->Ref();
std::unique_lock<std::mutex> lock(cli->mu);
uint64_t ino = vitastor_c_inode_get_num(watch);
vitastor_c_read_bitmap(cli->c, ino, req->offset, req->len, req->with_parents, NodeVitastor::postpone_read_bitmap_finish, req);
vitastor_c_read_bitmap(cli->c, ino, req->offset, req->len, req->with_parents, NodeVitastor::on_read_bitmap_finish, req);
}
else if (req->op == NODE_VITASTOR_GET_INFO)
{
v8::Local<v8::Object> res = Nan::New<v8::Object>();
fill_info(res);
uint64_t size = vitastor_c_inode_get_size(watch);
uint64_t num = vitastor_c_inode_get_num(watch);
uint32_t block_size = vitastor_c_inode_get_block_size(cli->c, num);
uint32_t bitmap_granularity = vitastor_c_inode_get_bitmap_granularity(cli->c, num);
int readonly = vitastor_c_inode_get_readonly(watch);
uint32_t immediate_commit = vitastor_c_inode_get_immediate_commit(cli->c, num);
uint64_t parent_id = vitastor_c_inode_get_parent_id(watch);
char *meta = vitastor_c_inode_get_meta(watch);
uint64_t mod_revision = vitastor_c_inode_get_mod_revision(watch);
Nan::HandleScope scope;
v8::Local<v8::Object> res = Nan::New<v8::Object>();
Nan::Set(res, Nan::New<v8::String>("pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(num)));
Nan::Set(res, Nan::New<v8::String>("inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(num)));
if (size < ((uint64_t)1<<53))
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), Nan::New<v8::Number>(size));
else
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), size));
if (parent_id)
{
Nan::Set(res, Nan::New<v8::String>("parent_pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(parent_id)));
Nan::Set(res, Nan::New<v8::String>("parent_inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(parent_id)));
}
Nan::Set(res, Nan::New<v8::String>("readonly").ToLocalChecked(), Nan::New((bool)readonly));
if (meta)
{
Nan::JSON nanJSON;
Nan::Set(res, Nan::New<v8::String>("meta").ToLocalChecked(), nanJSON.Parse(Nan::New<v8::String>(meta).ToLocalChecked()).ToLocalChecked());
}
if (mod_revision < ((uint64_t)1<<53))
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), Nan::New<v8::Number>(mod_revision));
else
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), mod_revision));
Nan::Set(res, Nan::New<v8::String>("block_size").ToLocalChecked(), Nan::New(block_size));
Nan::Set(res, Nan::New<v8::String>("bitmap_granularity").ToLocalChecked(), Nan::New(bitmap_granularity));
Nan::Set(res, Nan::New<v8::String>("immediate_commit").ToLocalChecked(), Nan::New(immediate_commit));
Nan::Callback nanCallback(Nan::New(req->callback));
v8::Local<v8::Value> args[1];
args[0] = res;
@@ -548,46 +488,6 @@ void NodeVitastorImage::exec_request(NodeVitastorRequest *req)
delete req;
}
cli->run_postponed();
}
void NodeVitastorImage::fill_info(v8::Local<v8::Object> & res)
{
std::unique_lock<std::mutex> lock(cli->mu);
uint64_t size = vitastor_c_inode_get_size(watch);
uint64_t num = vitastor_c_inode_get_num(watch);
uint32_t block_size = vitastor_c_inode_get_block_size(cli->c, num);
uint32_t bitmap_granularity = vitastor_c_inode_get_bitmap_granularity(cli->c, num);
int readonly = vitastor_c_inode_get_readonly(watch);
uint32_t immediate_commit = vitastor_c_inode_get_immediate_commit(cli->c, num);
uint64_t parent_id = vitastor_c_inode_get_parent_id(watch);
char *meta = vitastor_c_inode_get_meta(watch);
uint64_t mod_revision = vitastor_c_inode_get_mod_revision(watch);
Nan::Set(res, Nan::New<v8::String>("pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(num)));
Nan::Set(res, Nan::New<v8::String>("inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(num)));
if (size < ((uint64_t)1<<53))
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), Nan::New<v8::Number>(size));
else
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), size));
if (parent_id)
{
Nan::Set(res, Nan::New<v8::String>("parent_pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(parent_id)));
Nan::Set(res, Nan::New<v8::String>("parent_inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(parent_id)));
}
Nan::Set(res, Nan::New<v8::String>("readonly").ToLocalChecked(), Nan::New((bool)readonly));
if (meta)
{
Nan::JSON nanJSON;
Nan::Set(res, Nan::New<v8::String>("meta").ToLocalChecked(), nanJSON.Parse(Nan::New<v8::String>(meta).ToLocalChecked()).ToLocalChecked());
}
if (mod_revision < ((uint64_t)1<<53))
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), Nan::New<v8::Number>(mod_revision));
else
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), mod_revision));
Nan::Set(res, Nan::New<v8::String>("block_size").ToLocalChecked(), Nan::New(block_size));
Nan::Set(res, Nan::New<v8::String>("bitmap_granularity").ToLocalChecked(), Nan::New(bitmap_granularity));
Nan::Set(res, Nan::New<v8::String>("immediate_commit").ToLocalChecked(), Nan::New(immediate_commit));
}
void NodeVitastorImage::on_watch_start(void *opaque, long retval)
@@ -608,8 +508,6 @@ void NodeVitastorImage::on_watch_start(void *opaque, long retval)
// NodeVitastorKV
//////////////////////////////////////////////////
Nan::Persistent<v8::Function> NodeVitastorKV::listing_class;
// constructor(node_vitastor)
NAN_METHOD(NodeVitastorKV::Create)
{
@@ -626,26 +524,24 @@ NAN_METHOD(NodeVitastorKV::Create)
}
kv->Wrap(info.This());
cli->Ref();
info.GetReturnValue().Set(info.This());
}
NodeVitastorKV::~NodeVitastorKV()
{
delete dbw;
cli->Unref();
}
// open(pool_id, inode_num, { ...config }, callback(err))
// open(inode_id, { ...config }, callback(err))
NAN_METHOD(NodeVitastorKV::Open)
{
TRACE("NodeVitastorKV::Open");
NodeVitastorKV* kv = Nan::ObjectWrap::Unwrap<NodeVitastorKV>(info.This());
uint64_t inode_id = INODE_WITH_POOL(Nan::To<int64_t>(info[0]).FromJust(), Nan::To<int64_t>(info[1]).FromJust());
uint64_t inode_id = Nan::To<int64_t>(info[0]).FromJust();
v8::Local<v8::Object> jsParams = info[2].As<v8::Object>();
v8::Local<v8::Object> jsParams = info[1].As<v8::Object>();
v8::Local<v8::Array> keys = Nan::GetOwnPropertyNames(jsParams).ToLocalChecked();
std::map<std::string, std::string> cfg;
for (uint32_t i = 0; i < keys->Length(); i++)
@@ -654,8 +550,8 @@ NAN_METHOD(NodeVitastorKV::Open)
cfg[std::string(*Nan::Utf8String(key))] = std::string(*Nan::Utf8String(Nan::Get(jsParams, key).ToLocalChecked()));
}
v8::Local<v8::Function> callback = info[3].As<v8::Function>();
auto req = new NodeVitastorRequest(kv->cli, callback);
v8::Local<v8::Function> callback = info[2].As<v8::Function>();
auto req = new NodeVitastorRequest(callback);
kv->Ref();
kv->dbw->open(inode_id, cfg, [kv, req](int res)
@@ -678,7 +574,7 @@ NAN_METHOD(NodeVitastorKV::Close)
NodeVitastorKV* kv = Nan::ObjectWrap::Unwrap<NodeVitastorKV>(info.This());
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
auto req = new NodeVitastorRequest(kv->cli, callback);
auto req = new NodeVitastorRequest(callback);
kv->Ref();
kv->dbw->close([kv, req]()
@@ -731,7 +627,7 @@ void NodeVitastorKV::get_impl(const Nan::FunctionCallbackInfo<v8::Value> & info,
std::string key(*Nan::Utf8String(info[0].As<v8::String>()));
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
auto req = new NodeVitastorRequest(kv->cli, callback);
auto req = new NodeVitastorRequest(callback);
kv->Ref();
kv->dbw->get(key, [kv, req](int res, const std::string & value)
@@ -788,13 +684,13 @@ NAN_METHOD(NodeVitastorKV::Set)
std::string value(*Nan::Utf8String(info[1].As<v8::String>()));
v8::Local<v8::Function> callback = info[2].As<v8::Function>();
NodeVitastorRequest *req = new NodeVitastorRequest(kv->cli, callback), *cas_req = NULL;
NodeVitastorRequest *req = new NodeVitastorRequest(callback), *cas_req = NULL;
std::function<bool(int, const std::string &)> cas_cb;
if (info.Length() > 3 && info[3]->IsObject())
{
v8::Local<v8::Function> cas_callback = info[3].As<v8::Function>();
cas_req = new NodeVitastorRequest(kv->cli, cas_callback);
cas_req = new NodeVitastorRequest(cas_callback);
cas_cb = make_cas_callback(cas_req);
}
@@ -824,13 +720,13 @@ NAN_METHOD(NodeVitastorKV::Del)
std::string key(*Nan::Utf8String(info[0].As<v8::String>()));
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
NodeVitastorRequest *req = new NodeVitastorRequest(kv->cli, callback), *cas_req = NULL;
NodeVitastorRequest *req = new NodeVitastorRequest(callback), *cas_req = NULL;
std::function<bool(int, const std::string &)> cas_cb;
if (info.Length() > 2 && info[2]->IsObject())
{
v8::Local<v8::Function> cas_callback = info[2].As<v8::Function>();
cas_req = new NodeVitastorRequest(kv->cli, cas_callback);
cas_req = new NodeVitastorRequest(cas_callback);
cas_cb = make_cas_callback(cas_req);
}
@@ -866,15 +762,6 @@ NAN_METHOD(NodeVitastorKV::List)
info.GetReturnValue().Set(Nan::NewInstance(cons, narg, args).ToLocalChecked());
}
/*NAN_METHOD(NodeVitastorKV::Destroy)
{
TRACE("NodeVitastorKV::Destroy");
NodeVitastorKV* kv = Nan::ObjectWrap::Unwrap<NodeVitastorKV>(info.This());
std::unique_lock<std::mutex> lock(self->mu);
if (!kv->dead)
kv->Unref();
}*/
//////////////////////////////////////////////////
// NodeVitastorKVListing
//////////////////////////////////////////////////
@@ -902,7 +789,6 @@ NAN_METHOD(NodeVitastorKVListing::Create)
}
list->Wrap(info.This());
kv->Ref();
info.GetReturnValue().Set(info.This());
}
@@ -914,7 +800,6 @@ NodeVitastorKVListing::~NodeVitastorKVListing()
kv->dbw->list_close(handle);
handle = NULL;
}
kv->Unref();
}
// next(callback(err, value))
@@ -925,7 +810,7 @@ NAN_METHOD(NodeVitastorKVListing::Next)
NodeVitastorKVListing* list = Nan::ObjectWrap::Unwrap<NodeVitastorKVListing>(info.This());
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
auto req = new NodeVitastorRequest(list->kv->cli, callback);
auto req = new NodeVitastorRequest(callback);
if (!list->handle)
{
// Already closed

View File

@@ -19,7 +19,7 @@ public:
static NAN_METHOD(Create);
// read(pool, inode, offset, len, callback(err, buffer, version))
static NAN_METHOD(Read);
// write(pool, inode, offset, buf: Buffer | Buffer[], { version }?, callback(err))
// write(pool, inode, offset, buffer, { version }?, callback(err))
static NAN_METHOD(Write);
// sync(callback(err))
static NAN_METHOD(Sync);
@@ -36,7 +36,6 @@ private:
uv_poll_t poll_watcher;
// FIXME: Is it really needed?
std::mutex mu;
std::vector<std::function<void()>> postponed;
NodeVitastor();
@@ -45,14 +44,6 @@ private:
static void on_write_finish(void *opaque, long retval);
static void on_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap);
void run_postponed();
static void postpone_read_finish(void *opaque, long retval, uint64_t version);
static void postpone_write_finish(void *opaque, long retval);
static void postpone_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap);
NodeVitastorRequest* get_read_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos);
NodeVitastorRequest* get_write_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos);
friend class NodeVitastorImage;
friend class NodeVitastorKV;
friend class NodeVitastorKVListing;
@@ -65,7 +56,7 @@ public:
static NAN_METHOD(Create);
// read(offset, len, callback(err, buffer, version))
static NAN_METHOD(Read);
// write(offset, buf: Buffer | Buffer[], { version }?, callback(err))
// write(offset, buffer, { version }?, callback(err))
static NAN_METHOD(Write);
// sync(callback(err))
static NAN_METHOD(Sync);
@@ -83,10 +74,11 @@ private:
std::vector<NodeVitastorRequest*> on_init;
Nan::Persistent<v8::Object> cliObj;
NodeVitastorImage();
static void on_watch_start(void *opaque, long retval);
void exec_request(NodeVitastorRequest *req);
void exec_or_wait(NodeVitastorRequest *req);
void fill_info(v8::Local<v8::Object> & res);
};
class NodeVitastorKV: public Nan::ObjectWrap
@@ -94,7 +86,7 @@ class NodeVitastorKV: public Nan::ObjectWrap
public:
// constructor(node_vitastor)
static NAN_METHOD(Create);
// open(pool_id, inode_num, { ...config }, callback(err))
// open(inode_id, { ...config }, callback(err))
static NAN_METHOD(Open);
// set_config({ ...config })
static NAN_METHOD(SetConfig);
@@ -121,6 +113,8 @@ private:
NodeVitastor *cli = NULL;
vitastorkv_dbw_t *dbw = NULL;
NodeVitastorKV();
static void get_impl(const Nan::FunctionCallbackInfo<v8::Value> & info, bool allow_cache);
friend class NodeVitastorKVListing;
@@ -141,6 +135,8 @@ public:
private:
NodeVitastorKV *kv = NULL;
void *handle = NULL;
NodeVitastorKVListing();
};
#endif

View File

@@ -1 +0,0 @@
module.exports = require('bindings')('addon.node');

View File

@@ -730,7 +730,7 @@ void etcd_state_client_t::clean_nonexistent_pgs()
{
if (!pg_cfg.state_exists)
{
if (this->log_level > 3 && (pg_cfg.cur_primary || pg_cfg.cur_state))
if (this->log_level > 3)
{
fprintf(stderr, "PG %u/%u primary OSD disappeared after reload, forgetting it\n", pool_item.first, pg_it->first);
}
@@ -740,7 +740,7 @@ void etcd_state_client_t::clean_nonexistent_pgs()
}
if (!pg_cfg.history_exists)
{
if (this->log_level > 3 && (pg_cfg.target_history.size() || pg_cfg.all_peers.size() || pg_cfg.epoch || pg_cfg.next_scrub))
if (this->log_level > 3)
{
fprintf(stderr, "PG %u/%u history disappeared after reload, forgetting it\n", pool_item.first, pg_it->first);
}

View File

@@ -30,10 +30,10 @@ wait_etcd
if [ "$IMMEDIATE_COMMIT" != "" ]; then
NO_SAME="--journal_no_same_sector_overwrites true --journal_sector_buffer_count 1024 --disable_data_fsync 1 --immediate_commit all --log_level 10 --etcd_stats_interval 5"
$ETCDCTL put /vitastor/config/global '{"recovery_queue_depth":1,"recovery_tune_util_low":1,"immediate_commit":"all","client_enable_writeback":true,"client_max_writeback_iodepth":32'$GLOBAL_CONFIG'}'
$ETCDCTL put /vitastor/config/global '{"recovery_queue_depth":1,"recovery_tune_util_low":1,"immediate_commit":"all","client_writeback_allowed":true,"client_enable_writeback":true,"client_max_writeback_iodepth":32'$GLOBAL_CONFIG'}'
else
NO_SAME="--journal_sector_buffer_count 1024 --log_level 10 --etcd_stats_interval 5 --min_flusher_count 16"
$ETCDCTL put /vitastor/config/global '{"recovery_queue_depth":1,"recovery_tune_util_low":1,"immediate_commit":"none","client_enable_writeback":true,"client_max_writeback_iodepth":32'$GLOBAL_CONFIG'}'
$ETCDCTL put /vitastor/config/global '{"recovery_queue_depth":1,"recovery_tune_util_low":1,"immediate_commit":"none","client_writeback_allowed":true,"client_enable_writeback":true,"client_max_writeback_iodepth":32'$GLOBAL_CONFIG'}'
fi
start_osd_on()