mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-02-03 18:49:28 -05:00
knotc: add 'conf-snapshot' command
This commit is contained in:
parent
1d16c453db
commit
69e24f4601
5 changed files with 86 additions and 0 deletions
|
|
@ -2271,6 +2271,42 @@ static int ctl_conf_modify(ctl_args_t *args, ctl_cmd_t cmd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ctl_conf_snapshot(ctl_args_t *args, ctl_cmd_t cmd)
|
||||
{
|
||||
assert(conf() != NULL);
|
||||
|
||||
int ret = KNOT_EOK;
|
||||
const char *output_path = args->data[KNOT_CTL_IDX_DATA];
|
||||
if (output_path == NULL || output_path[0] == '\0') {
|
||||
ret = KNOT_EINVAL;
|
||||
log_ctl_error("control, conf-snapshot (missing destination)");
|
||||
send_error(args, knot_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create confdb directory
|
||||
ret = make_dir(output_path, LMDB_DIR_MODE, true);
|
||||
if (ret != KNOT_EOK) {
|
||||
const char *err_str = knot_strerror(ret);
|
||||
log_ctl_error("control, conf-snapshot failed to create destination directory (%s)", err_str);
|
||||
send_error(args, err_str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Snapshot configuration database
|
||||
ret = knot_db_lmdb_clone(conf()->db, output_path);
|
||||
if (ret != KNOT_EOK) {
|
||||
const char *err_str = knot_strerror(ret);
|
||||
log_ctl_error("control, unable to store confdb (%s)", err_str);
|
||||
send_error(args, err_str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
log_ctl_info("control, current confdb snapshot were saved at '%s'", output_path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int (*fcn)(ctl_args_t *, ctl_cmd_t);
|
||||
|
|
@ -2322,6 +2358,7 @@ static const desc_t cmd_table[] = {
|
|||
[CTL_CONF_GET] = { "conf-get", ctl_conf_read },
|
||||
[CTL_CONF_SET] = { "conf-set", ctl_conf_modify },
|
||||
[CTL_CONF_UNSET] = { "conf-unset", ctl_conf_modify },
|
||||
[CTL_CONF_SNAPSHOT] = { "conf-snapshot", ctl_conf_snapshot },
|
||||
};
|
||||
|
||||
#define MAX_CTL_CODE (sizeof(cmd_table) / sizeof(desc_t) - 1)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ typedef enum {
|
|||
CTL_CONF_GET,
|
||||
CTL_CONF_SET,
|
||||
CTL_CONF_UNSET,
|
||||
CTL_CONF_SNAPSHOT,
|
||||
} ctl_cmd_t;
|
||||
|
||||
/*! Control command parameters. */
|
||||
|
|
|
|||
|
|
@ -559,6 +559,28 @@ const char *knot_db_lmdb_get_path(knot_db_t *db)
|
|||
}
|
||||
}
|
||||
|
||||
_public_
|
||||
int knot_db_lmdb_clone(knot_db_t *db, const char *path)
|
||||
{
|
||||
struct lmdb_env *env = db;
|
||||
// NOTE: Must be opened for copy
|
||||
if (env == NULL || env->env == NULL) {
|
||||
return KNOT_EACCES;
|
||||
}
|
||||
|
||||
int ret = make_dir(path, LMDB_DIR_MODE, true);
|
||||
if (ret != KNOT_EOK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mdb_env_copy(env->env, path);
|
||||
if (ret != KNOT_EOK) {
|
||||
return knot_map_errno_code(ret);
|
||||
}
|
||||
return KNOT_EOK;
|
||||
|
||||
}
|
||||
|
||||
_public_
|
||||
const knot_db_api_t *knot_db_lmdb_api(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,5 +69,6 @@ int knot_db_lmdb_iter_del(knot_db_iter_t *iter);
|
|||
size_t knot_db_lmdb_get_mapsize(knot_db_t *db);
|
||||
size_t knot_db_lmdb_get_usage(knot_db_t *db);
|
||||
const char *knot_db_lmdb_get_path(knot_db_t *db);
|
||||
int knot_db_lmdb_clone(knot_db_t *db, const char *path);
|
||||
|
||||
/*! @} */
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
#define CMD_CONF_GET "conf-get"
|
||||
#define CMD_CONF_SET "conf-set"
|
||||
#define CMD_CONF_UNSET "conf-unset"
|
||||
#define CMD_CONF_SNAPSHOT "conf-snapshot"
|
||||
|
||||
#define CTL_LOG_STR "failed to control"
|
||||
|
||||
|
|
@ -244,6 +245,7 @@ static void format_data(cmd_args_t *args, knot_ctl_type_t data_type,
|
|||
case CTL_RELOAD:
|
||||
case CTL_CONF_BEGIN:
|
||||
case CTL_CONF_ABORT:
|
||||
case CTL_CONF_SNAPSHOT:
|
||||
// Only error message is expected here.
|
||||
if (error != NULL) {
|
||||
printf("error: (%s)", error);
|
||||
|
|
@ -404,6 +406,7 @@ static void format_block(ctl_cmd_t cmd, bool failed, bool empty)
|
|||
case CTL_CONF_COMMIT:
|
||||
case CTL_CONF_ABORT:
|
||||
case CTL_CONF_SET:
|
||||
case CTL_CONF_SNAPSHOT:
|
||||
case CTL_CONF_UNSET:
|
||||
case CTL_ZONE_RELOAD:
|
||||
case CTL_ZONE_REFRESH:
|
||||
|
|
@ -1225,6 +1228,27 @@ static int cmd_conf_export(cmd_args_t *args)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int cmd_conf_snapshot(cmd_args_t *args)
|
||||
{
|
||||
int ret = check_args(args, 1, 1);
|
||||
if (ret != KNOT_EOK) {
|
||||
if (args->argv == 0) {
|
||||
log_error("conf-snapshot (missing argument)");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
knot_ctl_data_t data = {
|
||||
[KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd),
|
||||
[KNOT_CTL_IDX_FLAGS] = args->flags,
|
||||
[KNOT_CTL_IDX_DATA] = args->argv[0],
|
||||
};
|
||||
CTL_SEND_DATA
|
||||
CTL_SEND_BLOCK
|
||||
|
||||
return ctl_receive(args);
|
||||
}
|
||||
|
||||
static int cmd_conf_ctl(cmd_args_t *args)
|
||||
{
|
||||
// Check the number of arguments.
|
||||
|
|
@ -1321,6 +1345,7 @@ const cmd_desc_t cmd_table[] = {
|
|||
{ CMD_CONF_CHECK, cmd_conf_check, CTL_NONE, CMD_FREAD | CMD_FREQ_MOD },
|
||||
{ CMD_CONF_IMPORT, cmd_conf_import, CTL_NONE, CMD_FWRITE | CMD_FOPT_MOD },
|
||||
{ CMD_CONF_EXPORT, cmd_conf_export, CTL_NONE, CMD_FREAD | CMD_FOPT_MOD },
|
||||
{ CMD_CONF_SNAPSHOT, cmd_conf_snapshot, CTL_CONF_SNAPSHOT, CMD_FOPT_DATA },
|
||||
{ CMD_CONF_LIST, cmd_conf_ctl, CTL_CONF_LIST, CMD_FOPT_ITEM | CMD_FLIST_SCHEMA },
|
||||
{ CMD_CONF_READ, cmd_conf_ctl, CTL_CONF_READ, CMD_FOPT_ITEM },
|
||||
{ CMD_CONF_BEGIN, cmd_conf_ctl, CTL_CONF_BEGIN },
|
||||
|
|
|
|||
Loading…
Reference in a new issue