#include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <endian.h>
#include "common.h"
#include "output.h"
#include "transform.h"
#include "libpmempool.h"
struct pmempool_transform_context {
unsigned flags;
char *poolset_file_src;
char *poolset_file_dst;
};
static const struct pmempool_transform_context pmempool_transform_default = {
.flags = 0,
.poolset_file_src = NULL,
.poolset_file_dst = NULL,
};
static const char *help_str =
"Modify internal structure of a poolset\n"
"\n"
"Common options:\n"
" -d, --dry-run do not apply changes, only check for viability of"
" transformation\n"
" -v, --verbose increase verbosity level\n"
" -h, --help display this help and exit\n"
"\n"
"For complete documentation see %s-transform(1) manual page.\n"
;
static const struct option long_options[] = {
{"dry-run", no_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0 },
};
static void
print_usage(char *appname)
{
printf("usage: %s transform [<options>] <poolset_file_src>"
" <poolset_file_dst>\n", appname);
}
static void
print_version(char *appname)
{
printf("%s %s\n", appname, SRCVERSION);
}
void
pmempool_transform_help(char *appname)
{
print_usage(appname);
print_version(appname);
printf(help_str, appname);
}
static int
pmempool_transform_parse_args(struct pmempool_transform_context *ctx,
char *appname, int argc, char *argv[])
{
int opt;
while ((opt = getopt_long(argc, argv, "dhv",
long_options, NULL)) != -1) {
switch (opt) {
case 'd':
ctx->flags = PMEMPOOL_DRY_RUN;
break;
case 'h':
pmempool_transform_help(appname);
exit(EXIT_SUCCESS);
case 'v':
out_set_vlevel(1);
break;
default:
print_usage(appname);
exit(EXIT_FAILURE);
}
}
if (optind + 1 < argc) {
ctx->poolset_file_src = argv[optind];
ctx->poolset_file_dst = argv[optind + 1];
} else {
print_usage(appname);
exit(EXIT_FAILURE);
}
return 0;
}
int
pmempool_transform_func(char *appname, int argc, char *argv[])
{
int ret;
struct pmempool_transform_context ctx = pmempool_transform_default;
if ((ret = pmempool_transform_parse_args(&ctx, appname, argc, argv)))
return ret;
ret = pmempool_transform(ctx.poolset_file_src, ctx.poolset_file_dst,
ctx.flags);
if (ret) {
if (errno)
outv_err("%s\n", strerror(errno));
outv_err("failed to transform %s -> %s: %s\n",
ctx.poolset_file_src, ctx.poolset_file_dst,
pmempool_errormsg());
return -1;
} else {
outv(1, "%s -> %s: transformed\n", ctx.poolset_file_src,
ctx.poolset_file_dst);
return 0;
}
}