myxce/src/controller/main.c
Rongsong Shen b52fbef36d feat: wire persist_init/recover/start/stop into cluster lifecycle (P0-F)
- Add `persist_t persist` field to cluster_t (cluster_def.h includes persist.h)
- Add `workdir` and `name` fields to myconf_t; main.c passes them through
- cluster_init: call persist_set_workdir, persist_init, persist_recover after apiserver_init
- cluster_start: call persist_start (launches fsync thread + registers WAL hooks)
- cluster_fini: call persist_stop + persist_fini before delaymgr/vtaskmgr teardown
- persist_init: store cluster back-pointer (replaces (void)c stub)
- persist_start: register persist_job/queue/worker_hook_fun via xce_add_hook when cluster != NULL
- Add test_cluster_persist.c: compile-time struct check + config defaults + workdir path derivation
- Register test in controller_test.c and meson.build

All controller tests pass (1/1 OK, 50s).
2026-05-07 13:07:47 +00:00

120 lines
3.1 KiB
C

#include <argp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlog.h>
#include "myconf.h"
#include "utils.h"
extern int myapp_run(myconf_t*);
static char doc[] = "xce_controller";
static char args_doc[] = "";
const char* argp_program_version
= MK_VERSION("xce v0.0.1-", STR(VERSION_COMMIT_ID));
const char* argp_program_bug_address = BUG_EMAIL;
struct arguments {
char* myname;
char* logfile;
char* workdir;
int verbose;
};
static struct argp_option options[] = {
{ "workdir", 'w', "DIR", 0, "The work directory of xce controller" },
{ "logfile", 'l', "FILE", 0, "The full path of log file" },
{ "verbose", 'v', 0, 0, "Produce verbose logs" },
{ "myname", 'n', "STR", 0, "The name of controller" },
{ 0 }
};
static error_t parse_opt(int key, char* arg, struct argp_state* state)
{
struct arguments* arguments = state->input;
switch (key) {
case 'l':
arguments->logfile = arg;
break;
case 'v':
arguments->verbose++;
break;
case 'w':
arguments->workdir = arg;
break;
case 'n':
arguments->myname = arg;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = { options, parse_opt, args_doc, doc };
int main(int argc, char* argv[])
{
struct arguments arguments;
myconf_t myconf;
char* logfile = "/tmp/xce_controller.log";
char* loglevel = "info";
int logsize = 64 * 1024 * 1024;
int logcount = 10;
char conf_file[XCE_MAXPATH_LEN + 1];
char key_file[XCE_MAXPATH_LEN + 1];
char cert_file[XCE_MAXPATH_LEN + 1];
char myname[XCE_MAXNAME_LEN + 1];
memset(&arguments, 0x0, sizeof(arguments));
argp_parse(&argp, argc, argv, 0, 0, &arguments);
if (arguments.logfile != NULL) {
logfile = arguments.logfile;
}
if (arguments.verbose != 0) {
loglevel = verbose_to_loglevel(arguments.verbose);
}
mylog_init(logfile, loglevel, logsize, logcount);
if (arguments.workdir == NULL) {
INFO("no cluster work directory specified. The default work directory "
"`" DEFAULT_WORKDIR "' will be used.");
arguments.workdir = DEFAULT_WORKDIR;
}
if (arguments.myname == NULL) {
if (get_myname(myname, sizeof(myname) - 1) < 0) {
ERROR("get_myname");
return -1;
}
arguments.myname = myname;
}
INFO("My name is %s", myname);
memset(&conf_file, 0x0, sizeof(conf_file));
snprintf(conf_file, XCE_MAXPATH_LEN, "%s/%s/conf/current_config",
arguments.workdir, myname);
snprintf(key_file, XCE_MAXPATH_LEN, "%s/certs/xce.key", arguments.workdir);
snprintf(cert_file, XCE_MAXPATH_LEN, "%s/certs/xce.crt", arguments.workdir);
myconf.cluster_config = NULL;
myconf.conffile = conf_file;
myconf.certfile = cert_file;
myconf.keyfile = key_file;
myconf.workdir = arguments.workdir;
myconf.name = arguments.myname;
myapp_run(&myconf);
mylog_fini();
return 0;
}