Skip to content

Commit 9d6596b

Browse files
authored
Merge pull request #6818 from chu11/issue6814_flux_kvs_sync
flux-kvs: support sync command
2 parents 16f72c4 + bd045ea commit 9d6596b

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

doc/man1/flux-kvs.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SYNOPSIS
2121
| **flux** **kvs** **getroot**
2222
| **flux** **kvs** **version**
2323
| **flux** **kvs** **wait** *version*
24+
| **flux** **kvs** **sync**
2425
2526
| **flux** **kvs** **namespace** **create** [*-o owner*] *name...*
2627
| **flux** **kvs** **namespace** **remove** *name...*
@@ -435,6 +436,16 @@ Block until the KVS version reaches *version* or greater. A simple form
435436
of synchronization between peers is: node A puts a value, commits it,
436437
reads version, sends version to node B. Node B waits for version, gets value.
437438

439+
sync
440+
----
441+
442+
.. program:: flux kvs sync
443+
444+
Flush pending content and checkpoints to disk to ensure data persists
445+
across a Flux instance crash. This command is identical to the
446+
:command:`flux kvs put` :option:`--sync` option, but does not require
447+
any data to be written.
448+
438449
namespace create
439450
----------------
440451

src/cmd/flux-kvs.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ int cmd_move (optparse_t *p, int argc, char **argv);
4747
int cmd_dir (optparse_t *p, int argc, char **argv);
4848
int cmd_ls (optparse_t *p, int argc, char **argv);
4949
int cmd_getroot (optparse_t *p, int argc, char **argv);
50+
int cmd_sync (optparse_t *p, int argc, char **argv);
5051
int cmd_eventlog (optparse_t *p, int argc, char **argv);
5152

5253
static int get_window_width (optparse_t *p, int fd);
@@ -373,6 +374,13 @@ static struct optparse_subcommand subcommands[] = {
373374
0,
374375
getroot_opts
375376
},
377+
{ "sync",
378+
NULL,
379+
"sync content and checkpoint to disk",
380+
cmd_sync,
381+
0,
382+
NULL
383+
},
376384
{ "eventlog",
377385
NULL,
378386
"Manipulate a KVS eventlog",
@@ -1828,6 +1836,37 @@ int cmd_getroot (optparse_t *p, int argc, char **argv)
18281836
return (0);
18291837
}
18301838

1839+
/* We could call kvs_checkpoint_commit() for syncing, however we
1840+
* choose to go with FLUX_KVS_SYNC and an empty transaction. That way
1841+
* this "transaction" goes into the same queue as other KVS
1842+
* transactions and syncs after all previously submitted KVS
1843+
* transactions. In contrast, kvs_checkpoint_commit() operates
1844+
* outside of the KVS transaction queue.
1845+
*/
1846+
int cmd_sync (optparse_t *p, int argc, char **argv)
1847+
{
1848+
flux_t *h;
1849+
int optindex = optparse_option_index (p);
1850+
flux_kvs_txn_t *txn;
1851+
flux_future_t *f;
1852+
1853+
if (optindex != argc) {
1854+
optparse_print_usage (p);
1855+
exit (1);
1856+
}
1857+
if (!(h = flux_open (NULL, 0)))
1858+
log_err_exit ("flux_open");
1859+
if (!(txn = flux_kvs_txn_create ()))
1860+
log_err_exit ("flux_kvs_txn_create");
1861+
if (!(f = flux_kvs_commit (h, NULL, FLUX_KVS_SYNC, txn))
1862+
|| flux_future_get (f, NULL) < 0)
1863+
log_err_exit ("flux_kvs_commit");
1864+
flux_future_destroy (f);
1865+
flux_kvs_txn_destroy (txn);
1866+
flux_close (h);
1867+
return (0);
1868+
}
1869+
18311870
/* combine 'argv' elements into one space-separated string (caller must free).
18321871
* assumes 'argv' is NULL terminated.
18331872
*/

t/t1010-kvs-commit-sync.t

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test_expect_success 'kvs: no checkpoint of kvs-primary should exist yet' '
3333
test_must_fail checkpoint_get kvs-primary
3434
'
3535

36-
test_expect_success 'kvs: put some data to kvs and sync it' '
36+
test_expect_success 'kvs: put some data to kvs and sync it (flux kvs put)' '
3737
flux kvs put --blobref --sync c=3 > syncblob.out
3838
'
3939

@@ -46,6 +46,16 @@ test_expect_success 'kvs: checkpoint of kvs-primary should match rootref' '
4646
test_cmp syncblob.out checkpoint.out
4747
'
4848

49+
test_expect_success 'kvs: put some data to kvs and sync it (flux kvs sync)' '
50+
flux kvs put --blobref d=4 > syncblob2.out &&
51+
flux kvs sync
52+
'
53+
54+
test_expect_success 'kvs: checkpoint of kvs-primary should match rootref' '
55+
checkpoint_get kvs-primary | jq -r .value.rootref > checkpoint2.out &&
56+
test_cmp syncblob2.out checkpoint2.out
57+
'
58+
4959
test_expect_success 'kvs: sync fails against non-primary namespace' '
5060
flux kvs namespace create ${TESTNAMESPACE} &&
5161
flux kvs put --namespace=${TESTNAMESPACE} a=10 &&

t/t2816-fsck-cmd.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ test_expect_success 'create some kvs content' '
2929
'
3030
# N.B. startlog commands in rc scripts normally ensures a checkpoint
3131
# exists but we do this just to be extra sure
32-
test_expect_success 'call --sync to ensure we have checkpointed' '
33-
flux kvs put --sync dir.sync=foo
32+
test_expect_success 'call sync to ensure we have checkpointed' '
33+
flux kvs sync
3434
'
3535
test_expect_success 'save some treeobjs for later' '
3636
flux kvs get --treeobj dir.b > dirb.out &&

0 commit comments

Comments
 (0)