diff --git a/src/modules/kvs/kvs.h b/src/modules/kvs/kvs.h index 30c83dff663b..aca622e5994a 100644 --- a/src/modules/kvs/kvs.h +++ b/src/modules/kvs/kvs.h @@ -48,6 +48,11 @@ int kvs_get_symlink (flux_t h, const char *key, char **valp); */ int kvs_get_treeobj (flux_t h, const char *key, char **treeobj); +/* Like kvs_get() but lookup is relative to 'treeobj'. + */ +int kvs_getat (flux_t h, const char *treeobj, + const char *key, char **json_str); + /* kvs_watch* is like kvs_get* except the registered callback is called * to set the value. It will be called immediately to set the initial * value and again each time the value changes. diff --git a/src/modules/kvs/libkvs.c b/src/modules/kvs/libkvs.c index 14627a22211d..77b547ecf8cb 100644 --- a/src/modules/kvs/libkvs.c +++ b/src/modules/kvs/libkvs.c @@ -380,6 +380,29 @@ int kvs_get (flux_t h, const char *key, char **val) return 0; } +int kvs_getat (flux_t h, const char *treeobj, + const char *key, char **val) +{ + JSON v = NULL; + JSON dirent = NULL; + + if (!treeobj || !key || !(dirent = Jfromstr (treeobj)) + || dirent_validate (dirent) < 0) { + errno = EINVAL; + goto error; + } + if (getobj (h, dirent, key, 0, &v) < 0) + goto error; + if (val) + *val = xstrdup (Jtostr (v)); + Jput (dirent); + return 0; +error: + Jput (v); + Jput (dirent); + return -1; +} + /* deprecated */ int kvs_get_obj (flux_t h, const char *key, JSON *val) {