json: fix parsing json problems when json config is invalid.
Add parsing json as invalid cases: 1.json content that not enclosed in {}, it should be parsed as invalid, e.g. "abc":"not encloesed in {}" 2.json content that 'subsystems' not associate with array, it will report error and return failure, e.g. {"subsystems":"123"} 3.handle other invalid json formats, report and return failure, e.g. duplicate keys. Added `spdk_json_find` API return errcode: EPROTOTYPE - json not enclosed in {}. json config with content: 1."not enclosed in {}" 2."'subsystems' not be an array" 3."duplicate key in json" and some other invaild cases will be regarded as invalid json config, and will fail to start app. Fixes #2599 Signed-off-by: tongkunkun <tongkunkun_yewu@cmss.chinamobile.com> Change-Id: I02574c9acd7671e336d4c589ebbff8ed21eb3681 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13754 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: GangCao <gang.cao@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
19518dfb47
commit
bb432b4eea
11
CHANGELOG.md
11
CHANGELOG.md
@ -2,6 +2,17 @@
|
||||
|
||||
## v22.09: (Upcoming Release)
|
||||
|
||||
### json
|
||||
|
||||
Added `spdk_json_find` API return errcode: EPROTOTYPE - json not enclosed in {}.
|
||||
`spdk_json_find` now returns -EPROTOTYPE instead of -ENOENT if the object parameter
|
||||
does not point to a JSON object (i.e. is not enclosed with {}).
|
||||
|
||||
### init
|
||||
|
||||
`spdk_subsystem_init_from_json_config` now fails if the JSON configuration file is not
|
||||
an object with an array named "subsystems".
|
||||
|
||||
### bdev
|
||||
|
||||
New RPCs `bdev_xnvme_create` and `bdev_xnvme_delete` were added to support the xNVMe bdev.
|
||||
|
@ -266,6 +266,7 @@ int spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char
|
||||
* -EINVAL - json object is invalid
|
||||
* -ENOENT - key not found
|
||||
* -EDOM - key exists but value type mismatch.
|
||||
* -EPROTOTYPE - json not enclosed in {}.
|
||||
*/
|
||||
int spdk_json_find(struct spdk_json_val *object, const char *key_name, struct spdk_json_val **key,
|
||||
struct spdk_json_val **val, enum spdk_json_val_type type);
|
||||
|
@ -566,14 +566,26 @@ spdk_subsystem_init_from_json_config(const char *json_config_file, const char *r
|
||||
|
||||
/* Capture subsystems array */
|
||||
rc = spdk_json_find_array(ctx->values, "subsystems", NULL, &ctx->subsystems);
|
||||
if (rc) {
|
||||
SPDK_WARNLOG("No 'subsystems' key JSON configuration file.\n");
|
||||
} else {
|
||||
switch (rc) {
|
||||
case 0:
|
||||
/* Get first subsystem */
|
||||
ctx->subsystems_it = spdk_json_array_first(ctx->subsystems);
|
||||
if (ctx->subsystems_it == NULL) {
|
||||
SPDK_NOTICELOG("'subsystems' configuration is empty\n");
|
||||
}
|
||||
break;
|
||||
case -EPROTOTYPE:
|
||||
SPDK_ERRLOG("Invalid JSON configuration: not enclosed in {}.\n");
|
||||
goto fail;
|
||||
case -ENOENT:
|
||||
SPDK_WARNLOG("No 'subsystems' key JSON configuration file.\n");
|
||||
break;
|
||||
case -EDOM:
|
||||
SPDK_ERRLOG("Invalid JSON configuration: 'subsystems' should be an array.\n");
|
||||
goto fail;
|
||||
default:
|
||||
SPDK_ERRLOG("Failed to parse JSON configuration.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* If rpc_addr is not an Unix socket use default address as prefix. */
|
||||
|
@ -530,11 +530,17 @@ spdk_json_find(struct spdk_json_val *object, const char *key_name, struct spdk_j
|
||||
{
|
||||
struct spdk_json_val *_key = NULL;
|
||||
struct spdk_json_val *_val = NULL;
|
||||
struct spdk_json_val *it;
|
||||
struct spdk_json_val *it_first, *it;
|
||||
|
||||
assert(object != NULL);
|
||||
|
||||
for (it = json_first(object, SPDK_JSON_VAL_ARRAY_BEGIN | SPDK_JSON_VAL_OBJECT_BEGIN);
|
||||
it_first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
|
||||
if (!it_first) {
|
||||
SPDK_JSON_DEBUG("Not enclosed in {}\n");
|
||||
return -EPROTOTYPE;
|
||||
}
|
||||
|
||||
for (it = it_first;
|
||||
it != NULL;
|
||||
it = spdk_json_next(it)) {
|
||||
if (it->type != SPDK_JSON_VAL_NAME) {
|
||||
@ -553,7 +559,7 @@ spdk_json_find(struct spdk_json_val *object, const char *key_name, struct spdk_j
|
||||
_key = it;
|
||||
_val = json_value(_key);
|
||||
|
||||
if (type != SPDK_JSON_VAL_INVALID && (_val->type & type) == 0) {
|
||||
if (type != SPDK_JSON_VAL_ANY && (_val->type & type) == 0) {
|
||||
SPDK_JSON_DEBUG("key '%s' type is %#x but expected one of %#x\n", key_name, _val->type, type);
|
||||
return -EDOM;
|
||||
}
|
||||
|
@ -7,6 +7,9 @@ source $testdir/nbd_common.sh
|
||||
|
||||
rpc_py=rpc_cmd
|
||||
conf_file="$testdir/bdev.json"
|
||||
nonenclosed_conf_file="$testdir/nonenclosed.json"
|
||||
nonarray_conf_file="$testdir/nonarray.json"
|
||||
|
||||
# Make sure the configuration is clean
|
||||
: > "$conf_file"
|
||||
|
||||
@ -566,6 +569,12 @@ trap "cleanup" SIGINT SIGTERM EXIT
|
||||
run_test "bdev_verify" $testdir/bdevperf/bdevperf --json "$conf_file" -q 128 -o 4096 -w verify -t 5 -C -m 0x3 "$env_ctx"
|
||||
run_test "bdev_write_zeroes" $testdir/bdevperf/bdevperf --json "$conf_file" -q 128 -o 4096 -w write_zeroes -t 1 "$env_ctx"
|
||||
|
||||
# test json config not enclosed with {}
|
||||
run_test "bdev_json_nonenclosed" $testdir/bdevperf/bdevperf --json "$nonenclosed_conf_file" -q 128 -o 4096 -w write_zeroes -t 1 "$env_ctx" || true
|
||||
|
||||
# test json config "subsystems" not with array
|
||||
run_test "bdev_json_nonarray" $testdir/bdevperf/bdevperf --json "$nonarray_conf_file" -q 128 -o 4096 -w write_zeroes -t 1 "$env_ctx" || true
|
||||
|
||||
if [[ $test_type == bdev ]]; then
|
||||
run_test "bdev_qos" qos_test_suite "$env_ctx"
|
||||
run_test "bdev_qd_sampling" qd_sampling_test_suite "$env_ctx"
|
||||
|
1
test/bdev/nonarray.json
Normal file
1
test/bdev/nonarray.json
Normal file
@ -0,0 +1 @@
|
||||
{"subsystems": "test non array"}
|
1
test/bdev/nonenclosed.json
Normal file
1
test/bdev/nonenclosed.json
Normal file
@ -0,0 +1 @@
|
||||
"subsystems" : "test nonenclosed json"
|
Loading…
Reference in New Issue
Block a user