@@ -73,6 +73,10 @@ static bool arg_uid_shift_apply = false;
73
73
static bool arg_mkdir = true;
74
74
static CaDigestType arg_digest = CA_DIGEST_DEFAULT ;
75
75
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 ;
76
80
77
81
static void help (void ) {
78
82
printf ("%1$s [OPTIONS...] make [ARCHIVE|ARCHIVE_INDEX|BLOB_INDEX] [PATH]\n"
@@ -99,6 +103,9 @@ static void help(void) {
99
103
" --chunk-size=[MIN:]AVG[:MAX]\n"
100
104
" The minimal/average/maximum number of bytes in a\n"
101
105
" 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"
102
109
" --digest=DIGEST Pick digest algorithm (sha512-256 or sha256)\n"
103
110
" --compression=COMPRESSION\n"
104
111
" Pick compression algorithm (zstd, xz or gzip)\n"
@@ -347,6 +354,8 @@ static int parse_argv(int argc, char *argv[]) {
347
354
ARG_DIGEST ,
348
355
ARG_COMPRESSION ,
349
356
ARG_VERSION ,
357
+ ARG_CUTMARK ,
358
+ ARG_CUTMARK_DELTA_MAX ,
350
359
};
351
360
352
361
static const struct option options [] = {
@@ -380,6 +389,8 @@ static int parse_argv(int argc, char *argv[]) {
380
389
{ "mkdir" , required_argument , NULL , ARG_MKDIR },
381
390
{ "digest" , required_argument , NULL , ARG_DIGEST },
382
391
{ "compression" , required_argument , NULL , ARG_COMPRESSION },
392
+ { "cutmark" , required_argument , NULL , ARG_CUTMARK },
393
+ { "cutmark-delta-max" , required_argument , NULL , ARG_CUTMARK_DELTA_MAX },
383
394
{}
384
395
};
385
396
@@ -684,6 +695,47 @@ static int parse_argv(int argc, char *argv[]) {
684
695
break ;
685
696
}
686
697
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
+
687
739
case '?' :
688
740
return - EINVAL ;
689
741
@@ -810,8 +862,10 @@ static int load_feature_flags(CaSync *s, uint64_t default_with_flags) {
810
862
return 0 ;
811
863
}
812
864
813
- static int load_chunk_size (CaSync * s ) {
865
+ static int load_chunk_size (CaSync * s , bool is_catar ) {
814
866
uint64_t cavg , cmin , cmax ;
867
+ const CaCutmark * cutmarks ;
868
+ size_t n_cutmarks ;
815
869
int r ;
816
870
817
871
if (arg_chunk_size_avg != 0 ) {
@@ -832,6 +886,22 @@ static int load_chunk_size(CaSync *s) {
832
886
return log_error_errno (r , "Failed to set maximum chunk size to %zu: %m" , arg_chunk_size_max );
833
887
}
834
888
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
+
835
905
if (!arg_verbose )
836
906
return 1 ;
837
907
@@ -848,6 +918,31 @@ static int load_chunk_size(CaSync *s) {
848
918
return log_error_errno (r , "Failed to read maximum chunk size: %m" );
849
919
850
920
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
+
851
946
return 1 ;
852
947
}
853
948
@@ -904,7 +999,9 @@ static int verbose_print_path(CaSync *s, const char *verb) {
904
999
905
1000
static int verbose_print_done_make (CaSync * s ) {
906
1001
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 ;
908
1005
char buffer [FORMAT_BYTES_MAX ];
909
1006
int r ;
910
1007
@@ -989,6 +1086,19 @@ static int verbose_print_done_make(CaSync *s) {
989
1086
if (n_cache_hits != UINT64_MAX && n_cache_misses != UINT64_MAX && n_cache_invalidated != UINT64_MAX && n_cache_added != UINT64_MAX )
990
1087
log_info ("Cache hits: %" PRIu64 ", misses: %" PRIu64 ", invalidated: %" PRIu64 ", added: %" PRIu64 , n_cache_hits , n_cache_misses , n_cache_invalidated , n_cache_added );
991
1088
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
+
992
1102
return 1 ;
993
1103
}
994
1104
@@ -1314,7 +1424,7 @@ static int verb_make(int argc, char *argv[]) {
1314
1424
if (!s )
1315
1425
return log_oom ();
1316
1426
1317
- r = load_chunk_size (s );
1427
+ r = load_chunk_size (s , IN_SET ( operation , MAKE_ARCHIVE , MAKE_ARCHIVE_INDEX ) );
1318
1428
if (r < 0 )
1319
1429
return r ;
1320
1430
@@ -2242,7 +2352,7 @@ static int verb_list(int argc, char *argv[]) {
2242
2352
if (!s )
2243
2353
return log_oom ();
2244
2354
2245
- r = load_chunk_size (s );
2355
+ r = load_chunk_size (s , true );
2246
2356
if (r < 0 )
2247
2357
return r ;
2248
2358
@@ -2549,7 +2659,7 @@ static int verb_digest(int argc, char *argv[]) {
2549
2659
if (!s )
2550
2660
return log_oom ();
2551
2661
2552
- r = load_chunk_size (s );
2662
+ r = load_chunk_size (s , IN_SET ( operation , DIGEST_ARCHIVE , DIGEST_ARCHIVE_INDEX , DIGEST_DIRECTORY ) );
2553
2663
if (r < 0 )
2554
2664
return r ;
2555
2665
@@ -4013,6 +4123,7 @@ int main(int argc, char *argv[]) {
4013
4123
free (arg_cache );
4014
4124
strv_free (arg_extra_stores );
4015
4125
strv_free (arg_seeds );
4126
+ free (arg_cutmarks );
4016
4127
4017
4128
/* fprintf(stderr, PID_FMT ": exiting with error code: %m", getpid()); */
4018
4129
0 commit comments