131 lines
3.4 KiB
C
131 lines
3.4 KiB
C
#include "kvstore.h"
|
|
#include "diskuring/diskuring.h"
|
|
#include <unistd.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
|
|
char global_oplog_file[256] = "kvs_oplog.default.db";
|
|
char global_array_file[256] = "kvs_array.default.db";
|
|
char global_rbtree_file[256] = "kvs_rbtree.default.db";
|
|
char global_hash_file[256] = "kvs_hash.default.db";
|
|
|
|
int kvs_create_snapshot(iouring_ctx_t *uring, const char* array_file, const char* rbtree_file, const char* hash_file){
|
|
int ret = 0;
|
|
int rc = 0;
|
|
#if ENABLE_ARRAY
|
|
rc = kvs_array_save(uring, &global_array, array_file);
|
|
if(rc < 0){
|
|
printf("kvs_engine_array save error\n");
|
|
ret = -1;
|
|
}
|
|
#endif
|
|
|
|
#if ENABLE_RBTREE
|
|
rc = kvs_rbtree_save(uring, &global_rbtree, rbtree_file);
|
|
if(rc < 0){
|
|
printf("kvs_engine_rbtree save error\n");
|
|
ret = -1;
|
|
}
|
|
#endif
|
|
|
|
#if ENABLE_HASH
|
|
rc = kvs_hash_save(uring, &global_hash, hash_file);
|
|
if(rc < 0){
|
|
printf("kvs_engine_hash save error\n");
|
|
ret = -1;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
void __complete_snapshot(const char *ip, int port, const char *array_file, const char *rbtree_file, const char *hash_file){
|
|
|
|
}
|
|
|
|
static int send_file_to_ipport(const char *ip, int port, const char *filename) {
|
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (sockfd < 0) { perror("socket"); return -1; }
|
|
|
|
struct sockaddr_in addr;
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_port = htons(port);
|
|
addr.sin_addr.s_addr = inet_addr(ip);
|
|
|
|
if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
|
perror("connect"); close(sockfd); return -1;
|
|
}
|
|
|
|
FILE *fp = fopen(filename, "rb");
|
|
if (!fp) { perror("fopen"); close(sockfd); return -1; }
|
|
|
|
char buf[4096];
|
|
size_t n;
|
|
|
|
while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
|
|
ssize_t written = 0;
|
|
while (written < n) {
|
|
ssize_t ret = write(sockfd, buf + written, n - written);
|
|
if (ret < 0) {
|
|
perror("write");
|
|
fclose(fp);
|
|
close(sockfd);
|
|
return -1;
|
|
}
|
|
written += ret;
|
|
}
|
|
}
|
|
|
|
if (ferror(fp)) {
|
|
perror("fread");
|
|
fclose(fp);
|
|
close(sockfd);
|
|
return -1;
|
|
}
|
|
|
|
fclose(fp);
|
|
shutdown(sockfd, SHUT_WR);
|
|
close(sockfd);
|
|
return 0;
|
|
}
|
|
|
|
int kvs_create_snapshot_async(const char *ip, int port){
|
|
pid_t pid = fork();
|
|
if (pid == -1) { perror("fork"); return -1; }
|
|
|
|
if (pid == 0) {
|
|
char tmp_array[128];
|
|
char tmp_rbtree[128];
|
|
char tmp_hash[128];
|
|
|
|
snprintf(tmp_array, sizeof(tmp_array), "data/snapshot_array_%s.tmp.db", ip);
|
|
snprintf(tmp_rbtree, sizeof(tmp_rbtree), "data/snapshot_rbtree_%s.tmp.db", ip);
|
|
snprintf(tmp_hash, sizeof(tmp_hash), "data/snapshot_hash_%s.tmp.db", ip);
|
|
|
|
iouring_ctx_t uring;
|
|
iouring_init(&uring, 256);
|
|
|
|
int ret = kvs_create_snapshot(&uring, tmp_array, tmp_rbtree, tmp_hash);
|
|
if (ret != 0) {
|
|
fprintf(stderr, "snapshot creation failed\n");
|
|
_exit(1);
|
|
}
|
|
|
|
// 发送快照到目标 IP:port
|
|
if (send_file_to_ipport(ip, port, tmp_array) != 0 ||
|
|
send_file_to_ipport(ip, port, tmp_rbtree) != 0 ||
|
|
send_file_to_ipport(ip, port, tmp_hash) != 0) {
|
|
fprintf(stderr, "snapshot send failed\n");
|
|
_exit(1);
|
|
}
|
|
|
|
// hook 通知 eBPF
|
|
__complete_snapshot(ip, port, tmp_array, tmp_rbtree, tmp_hash);
|
|
|
|
iouring_shutdown(&uring);
|
|
_exit(0);
|
|
} else {
|
|
|
|
return 0;
|
|
}
|
|
} |