add NtyCo as submodule & 搭建设计ebpf主从同步代码框架
This commit is contained in:
168
kvs_slave.c
168
kvs_slave.c
@@ -1,84 +1,110 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "server.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* 创建并监听用于接收快照的 TCP 监听 socket,成功返回 listen fd,失败返回 -1 */
|
||||
static int create_listen_socket(const char *ip, int port){
|
||||
|
||||
static int kvs_write_u8(uint8_t **pp, uint8_t v) {
|
||||
uint8_t *p = *pp;
|
||||
*p = v;
|
||||
*pp = p + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvs_write_u32(uint8_t **pp, uint32_t v) {
|
||||
uint8_t *p = *pp;
|
||||
uint32_t be = htonl(v);
|
||||
memcpy(p, &be, 4);
|
||||
*pp = p + 4;
|
||||
return 0;
|
||||
/* 主动连接 master 指定地址,用于控制面通信(SSYNC / SREADY),返回连接 fd 或 -1 */
|
||||
static int connect_master(const char *master_ip, int master_port){
|
||||
|
||||
}
|
||||
|
||||
static uint64_t kvs_get_log_tail_offset(void) {
|
||||
int fd = open("kvs_cmd_log.db", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
// 文件不存在:从 0 开始同步
|
||||
if (errno == ENOENT) return 0;
|
||||
// 其他错误:保守起见从 0 开始
|
||||
return 0;
|
||||
/* 通过控制连接向 master 发送 SSYNC 请求,声明本 slave 的快照接收地址 */
|
||||
static int send_ssync(int ctrl_fd, const char *listen_ip, int listen_port){
|
||||
|
||||
}
|
||||
|
||||
/* 接收并校验 master 对 SSYNC 的确认响应(如 +OK),成功返回 0 */
|
||||
static int recv_ssync_ok(int ctrl_fd){
|
||||
|
||||
}
|
||||
|
||||
/* 在快照监听 socket 上阻塞等待 master 的快照发送连接,返回已建立连接的 fd */
|
||||
static int accept_snapshot_conn(int listen_fd){
|
||||
|
||||
}
|
||||
|
||||
/* 从快照连接中接收完整快照数据并构建内存状态,确保快照已完全应用 */
|
||||
static int recv_and_apply_snapshot(int snapshot_fd){
|
||||
|
||||
}
|
||||
|
||||
/* 通过控制连接向 master 发送 SREADY 通知,表示快照已应用,slave 即将进入服务态 */
|
||||
int send_sready(int ctrl_fd){
|
||||
|
||||
}
|
||||
|
||||
|
||||
int slave_bootstrap(
|
||||
const char *listen_ip,
|
||||
int listen_port,
|
||||
const char *master_ip,
|
||||
int master_port
|
||||
) {
|
||||
int listen_fd = -1;
|
||||
int ctrl_fd = -1;
|
||||
int snap_fd = -1;
|
||||
|
||||
/* 1. 监听 snapshot port */
|
||||
listen_fd = create_listen_socket(listen_ip, listen_port);
|
||||
if (listen_fd < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
off_t end = lseek(fd, 0, SEEK_END);
|
||||
close(fd);
|
||||
/* 2. 连接 master, 发送 SSYNC */
|
||||
ctrl_fd = connect_master(master_ip, master_port);
|
||||
if (ctrl_fd < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (end < 0) return 0;
|
||||
return (uint64_t)end; // 指向 EOF(下一次写入的位置)
|
||||
}
|
||||
if (send_ssync(ctrl_fd, listen_ip, listen_port) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int try_connect_master(char *ip, int port){
|
||||
if (recv_ssync_ok(ctrl_fd) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
close(ctrl_fd);
|
||||
ctrl_fd = -1;
|
||||
|
||||
/* 3. accept snapshot 连接 */
|
||||
snap_fd = accept_snapshot_conn(listen_fd);
|
||||
if (snap_fd < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 4. 接收 snapshot */
|
||||
if (recv_and_apply_snapshot(snap_fd) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
close(snap_fd);
|
||||
snap_fd = -1;
|
||||
|
||||
|
||||
close(listen_fd);
|
||||
listen_fd = -1;
|
||||
|
||||
/* 5. 通知 master 快照传输完毕 */
|
||||
ctrl_fd = connect_master(master_ip, master_port);
|
||||
if (ctrl_fd >= 0) {
|
||||
send_sready(ctrl_fd);
|
||||
close(ctrl_fd);
|
||||
ctrl_fd = -1;
|
||||
}
|
||||
|
||||
/* 6. bootstrap complete */
|
||||
return 0;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(struct sockaddr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = inet_addr(ip);
|
||||
|
||||
int rt = 1;
|
||||
while(1){
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(fd < 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(0 == connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in))){
|
||||
// [OP KVS_CMD_PSYNC=15][ARGC 1][ARGLEN 4][ARG offset]
|
||||
|
||||
char buf[100];
|
||||
char *p = buf;
|
||||
|
||||
kvs_write_u8((uint8_t**)&p, 15);
|
||||
kvs_write_u8((uint8_t**)&p, 1);
|
||||
|
||||
uint64_t len = sizeof(uint64_t);
|
||||
kvs_write_u32((uint8_t**)&p, len);
|
||||
|
||||
uint64_t offset = kvs_get_log_tail_offset();
|
||||
memcpy(p, (void*)&offset, len);
|
||||
p += sizeof(offset);
|
||||
|
||||
send(fd, buf, p-buf, 0);
|
||||
recv(fd, buf, 100, 0);
|
||||
return fd;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
fail:
|
||||
if (snap_fd >= 0) close(snap_fd);
|
||||
if (ctrl_fd >= 0) close(ctrl_fd);
|
||||
if (listen_fd >= 0) close(listen_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user