Skip to content

Commit e16efd2

Browse files
authored
incremental: fix data raw crash and improve incremental update (#163)
* raw: avoid crash on unexpected value * tools: incremental: support protected slave authentication
1 parent 1007a31 commit e16efd2

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

libzdb/data.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ data_raw_t data_raw_get_real(int fd, off_t offset) {
325325
return raw;
326326
}
327327

328+
// default flag raw into error mode
329+
raw.error = DATA_RAW_UNEXPECTED;
330+
328331
// moving to the header offset
329332
lseek(fd, offset, SEEK_SET);
330333

@@ -375,6 +378,9 @@ data_raw_t data_raw_get_real(int fd, off_t offset) {
375378
// this validate return object to be valid
376379
raw.payload.length = raw.header.datalength;
377380

381+
// reset raw error flag, everything is fine
382+
raw.error = 0;
383+
378384
return raw;
379385
}
380386

libzdb/data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676

7777
typedef enum data_error_t {
7878
DATA_RAW_EOF = 1,
79+
DATA_RAW_UNEXPECTED = 2,
7980

8081
} data_error_t;
8182

tools/incremental-update/incremental.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55

66
class ZDBIncremental:
77
def __init__(self, master, mport, slave, sport):
8-
self.minfo = {"host": master, "port": mport}
9-
self.sinfo = {"host": slave, "port": sport}
8+
minfo = {"host": master, "port": mport, "namespace": "default", "name": "master"}
9+
sinfo = {"host": slave, "port": sport, "namespace": "default", "name": "slave"}
1010

1111
self.master = redis.Redis(host=master, port=mport)
12+
self.master.__data = minfo
13+
1214
self.slave = redis.Redis(host=slave, port=sport)
15+
self.slave.__data = sinfo
1316

1417
# disable defaults callbacks
1518
for target in [self.master, self.slave]:
@@ -19,15 +22,21 @@ def __init__(self, master, mport, slave, sport):
1922
target.set_response_callback("AUTH", bytes)
2023

2124
def authenticate(self, target, password):
22-
print(f"[+] authenticating")
25+
print(f"[+] authenticating: {target.__data['name']}")
2326

2427
request = target.execute_command("AUTH", "SECURE", "CHALLENGE")
2528
challenge = request.decode('utf-8')
2629

2730
encoded = f"{challenge}:{password}"
2831
response = hashlib.sha1(encoded.encode("utf-8")).hexdigest()
2932

33+
# authenticate
3034
status = target.execute_command("AUTH", "SECURE", response)
35+
if status != b"OK":
36+
return False
37+
38+
# authenticate on namespace as well
39+
status = target.execute_command("SELECT", target.__data["namespace"], password)
3140

3241
return status == b"OK"
3342

@@ -56,22 +65,20 @@ def sync(self, master, slave):
5665

5766

5867
def run(self):
59-
namespace = "default"
60-
61-
print(f"[+] master host: {self.minfo['host']}, port: {self.minfo['port']}")
62-
print(f"[+] slave host: {self.sinfo['host']}, port: {self.sinfo['port']}")
63-
print(f"[+] syncing namespace: {namespace}")
68+
print(f"[+] master host: {self.master.__data['host']}, port: {self.master.__data['port']}")
69+
print(f"[+] slave host: {self.slave.__data['host']}, port: {self.slave.__data['port']}")
70+
print(f"[+] syncing namespaces: {self.master.__data['namespace']} -> {self.slave.__data['namespace']}")
6471

6572
while True:
6673
master = {}
6774
slave = {}
6875

69-
nsmaster = self.master.execute_command("NSINFO", namespace)
76+
nsmaster = self.master.execute_command("NSINFO", self.master.__data['namespace'])
7077
master['dataid'] = int(nsmaster['data_current_id'])
7178
master['offset'] = int(nsmaster['data_current_offset'])
7279
master['size'] = int(nsmaster['data_size_bytes'])
7380

74-
nsslave = self.slave.execute_command("NSINFO", namespace)
81+
nsslave = self.slave.execute_command("NSINFO", self.slave.__data['namespace'])
7582
slave['dataid'] = int(nsslave['data_current_id'])
7683
slave['offset'] = int(nsslave['data_current_offset'])
7784
slave['size'] = int(nsslave['data_size_bytes'])
@@ -99,5 +106,6 @@ def run(self):
99106

100107
if __name__ == '__main__':
101108
incremental = ZDBIncremental("hub.grid.tf", 9900, "127.0.0.1", 9900)
102-
# incremental.authenticate(incremental.master, "set-password-here")
109+
incremental.authenticate(incremental.master, "master-password")
110+
incremental.authenticate(incremental.slave, "slave-password")
103111
incremental.run()

zdbd/commands_system.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ static int command_data_raw(redis_client_t *client) {
275275
return 1;
276276
}
277277

278+
if(raw.error == DATA_RAW_UNEXPECTED) {
279+
zdb_log("[-] command: data: raw: unexpected error, skipping\n");
280+
redis_hardsend(client, "-Unexpected Internal Error");
281+
return 1;
282+
}
283+
278284
if(raw.header.datalength == 0 || raw.header.datalength != raw.payload.length) {
279285
if((raw.header.flags & DATA_ENTRY_DELETED) == 0) {
280286
// something went wrong when fetching data from file

0 commit comments

Comments
 (0)