Skip to content

Commit 40b8c19

Browse files
authored
Merge pull request #148 from threefoldtech/development-v2-rscan-hotfix
libzdb: fix invalid RSCAN on sequential database
2 parents 4965161 + c0bbc0c commit 40b8c19

File tree

6 files changed

+34
-5
lines changed

6 files changed

+34
-5
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ This mode is not possible if you don't have any data/index already available.
188188
- `NSINFO <namespace>`
189189
- `NSLIST`
190190
- `NSSET <namespace> <property> <value>`
191+
- `NSJUMP`
191192
- `SELECT <namespace> [SECURE password]`
192193
- `DBSIZE`
193194
- `TIME`
@@ -367,6 +368,9 @@ denied with an error message (eg: `Namespace is temporarily locked`).
367368
`FREEZE` mode will deny any operation on the specific namespace, read, write, update, delete operations
368369
will be denied with an error message (eg: `Namespace is temporarily frozen`)
369370

371+
## NSJUMP
372+
Force closing current index and data files and open the next id.
373+
370374
## SELECT
371375
Change your current namespace. If the requested namespace is password-protected, you need
372376
to add the password as extra parameter. If the namespace is `public` but password protected,

libzdb/index.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void index_item_header_dump(index_item_t *item) {
2525
zdb_debug("[+] index: item dump: data fileid: %" PRIu32 "\n", item->dataid);
2626
zdb_debug("[+] index: item dump: data offset: %" PRIu32 "\n", item->offset);
2727
zdb_debug("[+] index: item dump: data length: %" PRIu32 "\n", item->length);
28-
zdb_debug("[+] index: item dump: previous : %" PRIx32 "\n", item->previous);
28+
zdb_debug("[+] index: item dump: previous : %" PRIu32 "\n", item->previous);
2929
zdb_debug("[+] index: item dump: flags : %" PRIu8 "\n", item->flags);
3030
zdb_debug("[+] index: item dump: timestamp : %" PRIu32 "\n", item->timestamp);
3131
zdb_debug("[+] index: item dump: parent id : %" PRIu32 "\n", item->parentid);

libzdb/index_scan.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,16 @@ void __ditry_seqmode_fix(index_item_t *source, off_t original) {
6060
if(zdb_rootsettings.mode != ZDB_MODE_SEQUENTIAL && zdb_rootsettings.mode != ZDB_MODE_DIRECT_KEY)
6161
return;
6262

63+
// hotfix
64+
return;
65+
6366
// compute previous offset
64-
// since sequential keys are hardcoded to be 4 bytes, we can easily
67+
// since sequential keys are hardcoded, we can easily
6568
// compute previous offset and ignoring value in the file
6669
//
6770
// this value were incorrect in some early version
6871
//
69-
source->previous = original - sizeof(index_item_t) - sizeof(uint32_t);
72+
source->previous = original - sizeof(index_item_t) - sizeof(seqid_t);
7073

7174
if(source->previous == sizeof(index_header_t))
7275
source->previous = 1;
@@ -76,12 +79,14 @@ void __ditry_seqmode_fix(index_item_t *source, off_t original) {
7679
static index_scan_t index_previous_header_real(index_scan_t scan) {
7780
index_item_t source;
7881

82+
#if 0
7983
// special dirty-fix case, please see __ditry_seqmode_fix function
8084
if(scan.target == 1) {
8185
// forcing last entry position
8286
scan.target = lseek(scan.fd, 0, SEEK_END);
8387
scan.target -= sizeof(index_item_t) + sizeof(uint32_t);
8488
}
89+
#endif
8590

8691
// if scan.target is not set yet, we don't know the expected
8792
// offset of the previous header, let's read the header
@@ -94,11 +99,12 @@ static index_scan_t index_previous_header_real(index_scan_t scan) {
9499
return index_scan_error(scan, INDEX_SCAN_UNEXPECTED);
95100
}
96101

97-
__ditry_seqmode_fix(&source, scan.original);
102+
// __ditry_seqmode_fix(&source, scan.original);
98103
index_item_header_dump(&source);
99104

100105
if(source.previous >= current) {
101106
zdb_debug("[+] index rscan: previous-header: previous offset (%u) in previous file\n", source.previous);
107+
scan.target = source.previous;
102108
return index_scan_error(scan, INDEX_SCAN_REQUEST_PREVIOUS);
103109
}
104110

@@ -117,11 +123,13 @@ static index_scan_t index_previous_header_real(index_scan_t scan) {
117123
return index_scan_error(scan, INDEX_SCAN_NO_MORE_DATA);
118124
}
119125

126+
#if 0
120127
// special dirty-fix case, please see __ditry_seqmode_fix function
121128
if(scan.target == 1) {
122129
scan.target = 0;
123130
return index_scan_error(scan, INDEX_SCAN_REQUEST_PREVIOUS);
124131
}
132+
#endif
125133

126134
// jumping to previous object
127135
lseek(scan.fd, scan.target, SEEK_SET);
@@ -132,7 +140,7 @@ static index_scan_t index_previous_header_real(index_scan_t scan) {
132140
return index_scan_error(scan, INDEX_SCAN_UNEXPECTED);
133141
}
134142

135-
__ditry_seqmode_fix(&source, scan.target);
143+
// __ditry_seqmode_fix(&source, scan.target);
136144

137145
// checking if entry is deleted
138146
if(source.flags & INDEX_ENTRY_DELETED) {

zdbd/commands.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ static command_t commands_handlers[] = {
151151
{.command = "NSLIST", .handler = command_nslist}, // custom command to list namespaces
152152
{.command = "NSSET", .handler = command_nsset}, // custom command to edit namespace settings
153153
{.command = "NSINFO", .handler = command_nsinfo}, // custom command to get namespace information
154+
{.command = "NSJUMP", .handler = command_nsjump}, // custom command to force jumping to next index/data
154155
{.command = "SELECT", .handler = command_select}, // default SELECT (with pwd) namespace switch
155156
{.command = "RELOAD", .handler = command_reload}, // custom command to reload a namespace
156157
{.command = "FLUSH", .handler = command_flush}, // custom command to reset a namespace

zdbd/commands_namespace.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,21 @@ int command_nsset(redis_client_t *client) {
582582
return 0;
583583
}
584584

585+
int command_nsjump(redis_client_t *client) {
586+
// command restricted to admin only
587+
if(!command_admin_authorized(client))
588+
return 1;
589+
590+
zdbd_debug("[+] command: nsjump: forcing index and data jump\n");
591+
592+
size_t newid = index_jump_next(client->ns->index);
593+
data_jump_next(client->ns->data, newid);
594+
595+
redis_hardsend(client, "+OK");
596+
597+
return 0;
598+
}
599+
585600
int command_dbsize(redis_client_t *client) {
586601
char response[64];
587602

zdbd/commands_namespace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
int command_nslist(redis_client_t *client);
88
int command_nsinfo(redis_client_t *client);
99
int command_nsset(redis_client_t *client);
10+
int command_nsjump(redis_client_t *client);
1011
int command_dbsize(redis_client_t *client);
1112
int command_reload(redis_client_t *client);
1213
int command_flush(redis_client_t *client);

0 commit comments

Comments
 (0)