Skip to content

Commit 719e24c

Browse files
committed
tool: expose cutmark settings on the command line
1 parent 9add46d commit 719e24c

File tree

1 file changed

+116
-5
lines changed

1 file changed

+116
-5
lines changed

src/casync-tool.c

+116-5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ static bool arg_uid_shift_apply = false;
7373
static bool arg_mkdir = true;
7474
static CaDigestType arg_digest = CA_DIGEST_DEFAULT;
7575
static CaCompressionType arg_compression = CA_COMPRESSION_DEFAULT;
76+
static CaCutmark *arg_cutmarks = NULL;
77+
static size_t arg_n_cutmarks = 0;
78+
static bool arg_auto_cutmarks = true;
79+
static uint64_t arg_cutmark_delta_max = 0;
7680

7781
static void help(void) {
7882
printf("%1$s [OPTIONS...] make [ARCHIVE|ARCHIVE_INDEX|BLOB_INDEX] [PATH]\n"
@@ -99,6 +103,9 @@ static void help(void) {
99103
" --chunk-size=[MIN:]AVG[:MAX]\n"
100104
" The minimal/average/maximum number of bytes in a\n"
101105
" chunk\n"
106+
" --cutmark=CUTMARK Specify a cutmark\n"
107+
" --cutmark-delta-max=BYTES\n"
108+
" Maximum bytes to shift cut due to cutmark\n"
102109
" --digest=DIGEST Pick digest algorithm (sha512-256 or sha256)\n"
103110
" --compression=COMPRESSION\n"
104111
" Pick compression algorithm (zstd, xz or gzip)\n"
@@ -347,6 +354,8 @@ static int parse_argv(int argc, char *argv[]) {
347354
ARG_DIGEST,
348355
ARG_COMPRESSION,
349356
ARG_VERSION,
357+
ARG_CUTMARK,
358+
ARG_CUTMARK_DELTA_MAX,
350359
};
351360

352361
static const struct option options[] = {
@@ -380,6 +389,8 @@ static int parse_argv(int argc, char *argv[]) {
380389
{ "mkdir", required_argument, NULL, ARG_MKDIR },
381390
{ "digest", required_argument, NULL, ARG_DIGEST },
382391
{ "compression", required_argument, NULL, ARG_COMPRESSION },
392+
{ "cutmark", required_argument, NULL, ARG_CUTMARK },
393+
{ "cutmark-delta-max", required_argument, NULL, ARG_CUTMARK_DELTA_MAX },
383394
{}
384395
};
385396

@@ -684,6 +695,47 @@ static int parse_argv(int argc, char *argv[]) {
684695
break;
685696
}
686697

698+
case ARG_CUTMARK:
699+
r = parse_boolean(optarg);
700+
if (r < 0) {
701+
CaCutmark *n;
702+
703+
n = reallocarray(arg_cutmarks, sizeof(CaCutmark), arg_n_cutmarks + 1);
704+
if (!n)
705+
return log_oom();
706+
707+
arg_cutmarks = n;
708+
709+
r = ca_cutmark_parse(arg_cutmarks + arg_n_cutmarks, optarg);
710+
if (r < 0)
711+
return log_error_errno(r, "Failed to parse cutmark specification: %m");
712+
713+
arg_n_cutmarks++;
714+
arg_auto_cutmarks = false;
715+
} else {
716+
arg_auto_cutmarks = r;
717+
718+
arg_cutmarks = mfree(arg_cutmarks);
719+
arg_n_cutmarks = 0;
720+
}
721+
722+
break;
723+
724+
case ARG_CUTMARK_DELTA_MAX: {
725+
uint64_t u;
726+
727+
r = parse_size(optarg, &u);
728+
if (r < 0)
729+
return log_error_errno(r, "Failed to parse cutmark delta: %s", optarg);
730+
if (u == 0) {
731+
log_error("Cutmark delta cannot be zero.");
732+
return -EINVAL;
733+
}
734+
735+
arg_cutmark_delta_max = u;
736+
break;
737+
}
738+
687739
case '?':
688740
return -EINVAL;
689741

@@ -810,8 +862,10 @@ static int load_feature_flags(CaSync *s, uint64_t default_with_flags) {
810862
return 0;
811863
}
812864

813-
static int load_chunk_size(CaSync *s) {
865+
static int load_chunk_size(CaSync *s, bool is_catar) {
814866
uint64_t cavg, cmin, cmax;
867+
const CaCutmark *cutmarks;
868+
size_t n_cutmarks;
815869
int r;
816870

817871
if (arg_chunk_size_avg != 0) {
@@ -832,6 +886,22 @@ static int load_chunk_size(CaSync *s) {
832886
return log_error_errno(r, "Failed to set maximum chunk size to %zu: %m", arg_chunk_size_max);
833887
}
834888

889+
if (arg_auto_cutmarks && is_catar) {
890+
r = ca_sync_set_cutmarks_catar(s);
891+
if (r < 0)
892+
return log_error_errno(r, "Failed to set automatic cutmarks: %m");
893+
} else {
894+
r = ca_sync_set_cutmarks(s, arg_cutmarks, arg_n_cutmarks);
895+
if (r < 0)
896+
return log_error_errno(r, "Failed to set manual cutmarks: %m");
897+
}
898+
899+
if (arg_cutmark_delta_max != 0) {
900+
r = ca_sync_set_cutmark_delta_max(s, arg_cutmark_delta_max);
901+
if (r < 0)
902+
return log_error_errno(r, "Failed to set cutmark delta: %m");
903+
}
904+
835905
if (!arg_verbose)
836906
return 1;
837907

@@ -848,6 +918,31 @@ static int load_chunk_size(CaSync *s) {
848918
return log_error_errno(r, "Failed to read maximum chunk size: %m");
849919

850920
log_info("Selected chunk sizes: min=%" PRIu64 "..avg=%" PRIu64 "..max=%" PRIu64, cmin, cavg, cmax);
921+
922+
r = ca_sync_get_cutmarks(s, &cutmarks, &n_cutmarks);
923+
if (r < 0)
924+
return log_error_errno(r, "Failed to acquire cutmarks: %m");
925+
926+
if (n_cutmarks == 0)
927+
log_info("No cutmarks defined.");
928+
else {
929+
uint64_t delta;
930+
size_t i;
931+
932+
for (i = 0; i < n_cutmarks; i++)
933+
log_info("Cutmark: %016" PRIx64 "/%016" PRIx64 "%c%"PRIu64,
934+
cutmarks[i].value,
935+
cutmarks[i].mask,
936+
cutmarks[i].delta < 0 ? '-' : '+',
937+
(uint64_t) (cutmarks[i].delta < 0 ? -cutmarks[i].delta : cutmarks[i].delta));
938+
939+
r = ca_sync_get_cutmark_delta_max(s, &delta);
940+
if (r < 0)
941+
return log_error_errno(r, "Failed to determine cutmark delta: %m");
942+
943+
log_info("Maximum cutmark delta: %" PRIu64, delta);
944+
}
945+
851946
return 1;
852947
}
853948

@@ -904,7 +999,9 @@ static int verbose_print_path(CaSync *s, const char *verb) {
904999

9051000
static int verbose_print_done_make(CaSync *s) {
9061001
uint64_t n_chunks = UINT64_MAX, size = UINT64_MAX, n_reused = UINT64_MAX, covering,
907-
n_cache_hits = UINT64_MAX, n_cache_misses = UINT64_MAX, n_cache_invalidated = UINT64_MAX, n_cache_added = UINT64_MAX;
1002+
n_cache_hits = UINT64_MAX, n_cache_misses = UINT64_MAX, n_cache_invalidated = UINT64_MAX, n_cache_added = UINT64_MAX,
1003+
n_cutmarks_applied = UINT64_MAX;
1004+
int64_t cutmark_delta_sum = INT64_MAX;
9081005
char buffer[FORMAT_BYTES_MAX];
9091006
int r;
9101007

@@ -989,6 +1086,19 @@ static int verbose_print_done_make(CaSync *s) {
9891086
if (n_cache_hits != UINT64_MAX && n_cache_misses != UINT64_MAX && n_cache_invalidated != UINT64_MAX && n_cache_added != UINT64_MAX)
9901087
log_info("Cache hits: %" PRIu64 ", misses: %" PRIu64 ", invalidated: %" PRIu64 ", added: %" PRIu64, n_cache_hits, n_cache_misses, n_cache_invalidated, n_cache_added);
9911088

1089+
r = ca_sync_current_cutmarks_applied(s, &n_cutmarks_applied);
1090+
if (r < 0 && r != -ENODATA)
1091+
return log_error_errno(r, "Failed to read number of cutmarks: %m");
1092+
if (n_cutmarks_applied != UINT64_MAX)
1093+
log_info("Cutmarks applied: %"PRIu64, n_cutmarks_applied);
1094+
1095+
r = ca_sync_current_cutmark_delta_sum(s, &cutmark_delta_sum);
1096+
if (r < 0 && r != -ENODATA)
1097+
return log_error_errno(r, "Failed to read cutmark delta: %m");
1098+
if (cutmark_delta_sum != INT64_MAX)
1099+
log_info("Average cutmark delta for all chunks: %0.1f",
1100+
n_chunks > 0 ? (double) cutmark_delta_sum / n_chunks : 0.0);
1101+
9921102
return 1;
9931103
}
9941104

@@ -1314,7 +1424,7 @@ static int verb_make(int argc, char *argv[]) {
13141424
if (!s)
13151425
return log_oom();
13161426

1317-
r = load_chunk_size(s);
1427+
r = load_chunk_size(s, IN_SET(operation, MAKE_ARCHIVE, MAKE_ARCHIVE_INDEX));
13181428
if (r < 0)
13191429
return r;
13201430

@@ -2242,7 +2352,7 @@ static int verb_list(int argc, char *argv[]) {
22422352
if (!s)
22432353
return log_oom();
22442354

2245-
r = load_chunk_size(s);
2355+
r = load_chunk_size(s, true);
22462356
if (r < 0)
22472357
return r;
22482358

@@ -2549,7 +2659,7 @@ static int verb_digest(int argc, char *argv[]) {
25492659
if (!s)
25502660
return log_oom();
25512661

2552-
r = load_chunk_size(s);
2662+
r = load_chunk_size(s, IN_SET(operation, DIGEST_ARCHIVE, DIGEST_ARCHIVE_INDEX, DIGEST_DIRECTORY));
25532663
if (r < 0)
25542664
return r;
25552665

@@ -4013,6 +4123,7 @@ int main(int argc, char *argv[]) {
40134123
free(arg_cache);
40144124
strv_free(arg_extra_stores);
40154125
strv_free(arg_seeds);
4126+
free(arg_cutmarks);
40164127

40174128
/* fprintf(stderr, PID_FMT ": exiting with error code: %m", getpid()); */
40184129

0 commit comments

Comments
 (0)