#include "kvstore.h" #include 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(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(&global_array, array_file); if(rc < 0){ printf("kvs_engine_array save error\n"); ret = -1; } #endif #if ENABLE_RBTREE rc = kvs_rbtree_save(&global_rbtree, rbtree_file); if(rc < 0){ printf("kvs_engine_rbtree save error\n"); ret = -1; } #endif #if ENABLE_HASH rc = kvs_hash_save(&global_hash, hash_file); if(rc < 0){ printf("kvs_engine_hash save error\n"); ret = -1; } #endif return ret; } void __create_snapshot_ok(const char* array_file, const char* rbtree_file, const char* hash_file){ } int kvs_create_snapshot_async(const char *ip, int port){ int pipefd[2]; // 用于子进程通知主进程 if (pipe(pipefd) == -1) { perror("pipe"); return -1; } pid_t pid = fork(); if (pid == -1) { perror("fork"); return -1; } if (pid == 0) { // 子进程 close(pipefd[0]); // 关闭读端 // 指定临时文件路径,避免覆盖 global_xxx_file char tmp_array[128]; // 可写缓冲区 char tmp_rbtree[128]; char tmp_hash[128]; snprintf(tmp_array, sizeof(tmp_array), "snapshot_array_%s.tmp", ip); snprintf(tmp_rbtree, sizeof(tmp_rbtree), "snapshot_rbtree_%s.tmp", ip); snprintf(tmp_hash, sizeof(tmp_hash), "snapshot_hash_%s.tmp", ip); int ret = kvs_create_snapshot(tmp_array, tmp_rbtree, tmp_hash); if (ret == 0) { // 成功:rename 到最终路径,或直接通知 write(pipefd[1], "OK", 2); // 通知主进程 } else { write(pipefd[1], "ERR", 3); } close(pipefd[1]); _exit(0); // 子进程退出 // hook point __create_snapshot_ok(tmp_array, tmp_rbtree, tmp_hash); } else { // 主进程 close(pipefd[1]); // 关闭写端 // 立即返回,继续处理其他请求(不阻塞) // 可以记录 pid,在别处 waitpid(pid, NULL, WNOHANG) 检查完成 // 或用信号:signal(SIGCHLD, handler); 在 handler 中 read(pipefd[0]) 检查 "OK" return 0; // SYNC 响应成功,主进程继续 } }