Mutually exclusive with ``--allow-storage-class-list``.
**File format:** One name per line. Lines starting with or containing ``#``
-are treated as comments. Whitespace is ignored.
+are treated as comments. Whitespace is ignored. The file must contain at least
+one valid name; an empty or all-comment file is rejected.
Skipped Objects
break;
case URGENT_MSG_RESTART:
if (!d_ctl.dedup_exec) {
- // Decode optional filter (may not be present for older senders)
+ // Decode optional filter
{
bool has_filter = false;
- try {
- ceph::decode(has_filter, bl_iter);
- if (has_filter) {
- decode(d_filter, bl_iter);
- ldpp_dout(dpp, 5) << __func__ << "::RESTART with filter" << dendl;
- }
- else {
- d_filter = dedup_filter_t{};
- }
- } catch (buffer::error&) {
- // older sender without filter - reset to no-filter
+ ceph::decode(has_filter, bl_iter);
+ if (has_filter) {
+ decode(d_filter, bl_iter);
+ ldpp_dout(dpp, 5) << __func__ << "::RESTART with filter" << dendl;
+ }
+ else {
d_filter = dedup_filter_t{};
}
}
{
std::ifstream f(path);
if (!f.is_open()) {
- ldpp_dout(dpp, 1) << __func__ << ":: failed to open filter file: " << path << dendl;
+ ldpp_dout(dpp, 1) << __func__ << "::Failed to open filter file: " << path << dendl;
return -ENOENT;
}
}
}
+ if (name_set.empty()) {
+ // we should have at least one valid filter
+ ldpp_dout(dpp, 1) << __func__ << "::No valid filter in file: " << path << dendl;
+ return -ENODATA;
+ }
+
return 0;
}
// main section
{
Formatter::ObjectSection main(*f, "main");
- f->dump_unsigned("Num Work-Shards", num_shards);
+ if (num_shards) {
+ f->dump_unsigned("Num Work-Shards", num_shards);
+ }
f->dump_unsigned("Ingress Objs count", this->ingress_obj);
f->dump_unsigned("Accum byte size Ingress Objs", this->ingress_obj_bytes);
f->dump_unsigned("Egress Records count", this->egress_records);
this->ingress_skip_too_small_bytes);
}
- if (this->ingress_skip_filtered_bucket && num_shards) {
- // buckets are scanned once per worker-shard
- f->dump_unsigned("Ingress skip: filtered bucket",
- this->ingress_skip_filtered_bucket/num_shards);
+ if (this->ingress_skip_filtered_bucket) {
+ auto skip_filtered_count = this->ingress_skip_filtered_bucket;
+ if (num_shards) {
+ // buckets are scanned once per worker-shard
+ skip_filtered_count /= num_shards;
+ }
+ f->dump_unsigned("Ingress skip: filtered bucket", skip_filtered_count);
}
if (this->ingress_skip_filtered_storage_class) {
f->dump_unsigned("Ingress skipped filtered storage class, num objects skipped",
std::ostream& operator<<(std::ostream &out, const worker_stats_t &s)
{
JSONFormatter formatter(false);
- s.dump(&formatter, 1);
+ s.dump(&formatter);
std::stringstream sstream;
formatter.flush(sstream);
out << sstream.str();
struct worker_stats_t {
worker_stats_t& operator +=(const worker_stats_t& other);
- void dump(Formatter *f, unsigned num_shards) const;
+ void dump(Formatter *f, unsigned num_shards = 0) const;
uint64_t ingress_obj = 0;
uint64_t ingress_obj_bytes = 0;
result = admin(['dedup', 'estimate', '--allow-bucket-list',
'/nonexistent/bucket_list.txt'])
assert result[1] != 0, "Expected failure for non-existent filter file"
+
+ # 3. Empty file
+ empty_file = OUT_DIR + "empty_buckets.txt"
+ with open(empty_file, "w") as f:
+ pass
+
+ result = admin(['dedup', 'estimate', '--allow-bucket-list', empty_file])
+ assert result[1] != 0, "Expected failure for empty filter file"
+
+ result = admin(['dedup', 'estimate', '--deny-bucket-list', empty_file])
+ assert result[1] != 0, "Expected failure for empty filter file"
finally:
cleanup_local()
prepare_test()
try:
# 1. Mutual exclusivity: --allow-storage-class-list and --deny-storage-class-list together.
- allow_file = OUT_DIR + "allow_storage_classs.txt"
- deny_file = OUT_DIR + "deny_storage_classs.txt"
+ allow_file = OUT_DIR + "allow_storage_class.txt"
+ deny_file = OUT_DIR + "deny_storage_class.txt"
write_filter_list_file(allow_file, ['STORAGECLASS1'])
write_filter_list_file(deny_file, ['STORAGECLASS2'])
result = admin(['dedup', 'estimate',
result = admin(['dedup', 'estimate', '--allow-storage-class-list',
'/nonexistent/storage_class_list.txt'])
assert result[1] != 0, "Expected failure for non-existent filter file"
+
+ # 3. Empty file
+ empty_file = OUT_DIR + "empty_storage_class.txt"
+ with open(empty_file, "w") as f:
+ pass
+
+ result = admin(['dedup', 'estimate', '--allow-storage-class-list', empty_file])
+ assert result[1] != 0, "Expected failure for empty filter file"
+
+ result = admin(['dedup', 'estimate', '--deny-storage-class-list', empty_file])
+ assert result[1] != 0, "Expected failure for empty filter file"
finally:
cleanup_local()
"""
prepare_test()
config=default_config
- filter_file = OUT_DIR + "deny_storage_classs.txt"
+ filter_file = OUT_DIR + "deny_storage_class.txt"
bucket_name = gen_bucket_name()
conn=get_single_connection()
files=[]