Skip to content

Commit bcabc9f

Browse files
authored
Merge pull request #7186 from chu11/flux_dump_fsck_cleanup
flux-dump/flux-fsck misc cleanup
2 parents 893c23e + e611d21 commit bcabc9f

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

src/cmd/builtin/dump.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,11 @@ static void dump_valref (struct archive *ar,
169169
const void *data;
170170
size_t len;
171171

172-
/* We need the total size before we start writing archive data,
173-
* so make a first pass, saving the data for writing later.
172+
/* Load all data comprising the valref before starting the archive
173+
* entry. This is because the total size of the value must
174+
* calculated and written before any data, and any load errors
175+
* must be detected so the whole entry can be skipped if
176+
* --ignore-failed-read.
174177
*/
175178
/* N.B. first attempt was to save the futures in an array, but ran into:
176179
* flux: ev_epoll.c:134: epoll_modify: Assertion `("libev: I/O watcher
@@ -188,7 +191,7 @@ static void dump_valref (struct archive *ar,
188191
treeobj_get_blobref (treeobj, i),
189192
content_flags))
190193
|| flux_future_get (f, (const void **)&msg) < 0
191-
|| flux_response_decode_raw (msg, NULL, &data, &len) < 0) {
194+
|| flux_response_decode_raw (msg, NULL, NULL, &len) < 0) {
192195
read_error ("%s: missing blobref %d: %s",
193196
path,
194197
i,

src/cmd/builtin/fsck.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "src/common/libutil/blobref.h"
2626
#include "src/common/libcontent/content.h"
2727
#include "src/common/libczmqcontainers/czmq_containers.h"
28+
#include "ccan/ptrint/ptrint.h"
2829
#include "ccan/str/str.h"
2930

3031
#include "builtin.h"
@@ -121,24 +122,24 @@ static void valref_validate_continuation (flux_future_t *f, void *arg)
121122
struct fsck_valref_data *fvd = arg;
122123

123124
if (flux_rpc_get (f, NULL) < 0) {
124-
int *index = flux_future_aux_get (f, "index");
125+
int index = ptr2int (flux_future_aux_get (f, "index"));
125126
if (fvd->ctx->verbose) {
126127
if (errno == ENOENT)
127128
errmsg (fvd->ctx,
128129
"%s: missing blobref index=%d",
129130
fvd->path,
130-
(*index));
131+
index);
131132
else
132133
errmsg (fvd->ctx,
133134
"%s: error retrieving blobref index=%d: %s",
134135
fvd->path,
135-
(*index),
136+
index,
136137
future_strerror (f, errno));
137138
}
138139
fvd->errorcount++;
139140
fvd->errnum = errno; /* we'll report the last errno */
140141
if (fvd->ctx->repair && errno == ENOENT)
141-
save_missing_ref_index (fvd, *index);
142+
save_missing_ref_index (fvd, index);
142143
}
143144
fvd->in_flight--;
144145

@@ -159,7 +160,6 @@ static void valref_validate (struct fsck_valref_data *fvd)
159160
ssize_t hash_size;
160161
const char *blobref;
161162
flux_future_t *f;
162-
int *indexp;
163163

164164
blobref = treeobj_get_blobref (fvd->treeobj, fvd->index);
165165

@@ -170,10 +170,7 @@ static void valref_validate (struct fsck_valref_data *fvd)
170170
log_err_exit ("failed to validate valref blob");
171171
if (flux_future_then (f, -1, valref_validate_continuation, fvd) < 0)
172172
log_err_exit ("cannot validate valref blob");
173-
if (!(indexp = (int *)malloc (sizeof (int))))
174-
log_err_exit ("cannot allocate index memory");
175-
(*indexp) = fvd->index;
176-
if (flux_future_aux_set (f, "index", indexp, free) < 0)
173+
if (flux_future_aux_set (f, "index", int2ptr (fvd->index), NULL) < 0)
177174
log_err_exit ("could not save index value");
178175
}
179176

@@ -453,8 +450,7 @@ static void fsck_dirref (struct fsck_ctx *ctx,
453450
warn (ctx, "%s unlinked due to missing blobref", path);
454451
ctx->unlink_dir_count++;
455452
}
456-
flux_future_destroy (f);
457-
return;
453+
goto cleanup;
458454
}
459455
if (!(treeobj_deref = treeobj_decodeb (buf, buflen))) {
460456
errmsg (ctx, "%s: could not decode directory", path);

t/t2807-dump-cmd.t

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ test_expect_success 'load kvs and create some kvs content' '
4949
flux kvs put --no-merge x=$(cat x.val) &&
5050
flux kvs link --target-namespace=smurf otherthing z &&
5151
flux kvs put --no-merge w= &&
52-
flux kvs put --no-merge --append w=foo
52+
flux kvs put --no-merge --append w=foo &&
53+
flux kvs put --no-merge --append w=bar
5354
'
5455
test_expect_success 'unload kvs' '
5556
flux module remove kvs
@@ -81,16 +82,16 @@ test_expect_success 'unload content-sqlite' '
8182
# (1) rootdir 5th version (z is contained in root)
8283
# (1) rootdir 6th version (w probably contained in root)
8384
# (3) rootdir 7th version ('w' empty blobref + append to 'w')
84-
# Total: 12 blobs
85+
# (2) rootdir 8th version (append to 'w')
86+
# Total: 14 blobs
8587
#
8688
test_expect_success 'count blobs representing those five keys' '
87-
echo 12 >blobcount.exp &&
89+
echo 14 >blobcount.exp &&
8890
countblobs >blobcount.out &&
8991
test_cmp blobcount.exp blobcount.out
9092
'
91-
test_expect_success 'remove backing file and load content-sqlite' '
92-
rm -f content.sqlite &&
93-
flux module load content-sqlite
93+
test_expect_success 'load content-sqlite and truncate old file to start fresh' '
94+
flux module load content-sqlite truncate
9495
'
9596
test_expect_success 'restore content' '
9697
flux restore --checkpoint foo.tar
@@ -111,7 +112,8 @@ test_expect_success 'unload content-sqlite' '
111112
'
112113

113114
# Intermediate rootdir versions are not preserved across dump/restore.
114-
# Expect a blobcount of 4: rootdir 5th version + 'a' + 'b' + 'x',
115+
# Expect a blobcount of 4: rootdir 8th version + 'a' + 'b' + 'x',
116+
# N.B. 'w' is now contained in the root
115117
#
116118
test_expect_success 'count blobs after restore'\'s' implicit garbage collection' '
117119
echo 4 >blobcount2.exp &&
@@ -129,7 +131,7 @@ test_expect_success 'verify that exact KVS content was restored' '
129131
test $(flux kvs get x) = $(cat x.val) &&
130132
test $(flux kvs readlink y) = "linkedthing" &&
131133
test $(flux kvs readlink z) = "smurf::otherthing" &&
132-
test $(flux kvs get w) = "foo"
134+
test $(flux kvs get w) = "foobar"
133135
'
134136
test_expect_success 'now restore to key and verify content' '
135137
flux restore -v --key zz foo.tar &&
@@ -255,6 +257,44 @@ test_expect_success UTF8_LOCALE 'restore UTF-8 dump' '
255257
flux kvs get ƒuzzybunny)
256258
'
257259

260+
# Cover value with a very large number of appends
261+
262+
test_expect_success LONGTEST 'load content-sqlite and truncate old file to start fresh' '
263+
flux module load content-sqlite truncate
264+
'
265+
# N.B. from 1000 to 3000 instead of 0 to 2000, easier to debug errors
266+
# using fold(1) (i.e. all numbers same width)
267+
test_expect_success LONGTEST 'load kvs and create some kvs content' '
268+
flux module load kvs &&
269+
for i in `seq 1000 3000`; do
270+
flux kvs put --append bigval=${i}
271+
done &&
272+
flux kvs get bigval > bigval.exp
273+
'
274+
test_expect_success LONGTEST 'unload kvs' '
275+
flux module remove kvs
276+
'
277+
test_expect_success LONGTEST 'dump default=kvs-primary checkpoint' '
278+
flux dump --checkpoint bigval.tar
279+
'
280+
test_expect_success LONGTEST 'reload content-sqlite, truncate old file to start fresh' '
281+
flux module reload content-sqlite truncate
282+
'
283+
test_expect_success LONGTEST 'restore content' '
284+
flux restore --checkpoint bigval.tar
285+
'
286+
test_expect_success LONGTEST 'load kvs and check bigval value' '
287+
flux module load kvs &&
288+
flux kvs get bigval > bigval.out &&
289+
test_cmp bigval.out bigval.exp
290+
'
291+
test_expect_success LONGTEST 'unload kvs' '
292+
flux module remove kvs
293+
'
294+
test_expect_success LONGTEST 'unload content-sqlite' '
295+
flux module remove content-sqlite
296+
'
297+
258298
# Cover --size-limit
259299

260300
test_expect_success 'create bigdump.tar with a 12M blob in it' '

0 commit comments

Comments
 (0)