diff --git a/ldms/src/decomp/static/decomp_static.c b/ldms/src/decomp/static/decomp_static.c index 63c2616a6..c8bcb3b02 100644 --- a/ldms/src/decomp/static/decomp_static.c +++ b/ldms/src/decomp/static/decomp_static.c @@ -111,8 +111,7 @@ mval_from_json(ldms_mval_t *v, dst.type = mtype; jtype = json_typeof(jent); - if ((jtype == JSON_STRING && mtype != LDMS_V_CHAR_ARRAY) || - (mtype == LDMS_V_CHAR_ARRAY && jtype != JSON_STRING)) { + if ((mtype == LDMS_V_CHAR_ARRAY && jtype != JSON_STRING)) { snprintf(err_buf, err_sz, "string type must have string value"); return EINVAL; } @@ -132,6 +131,13 @@ mval_from_json(ldms_mval_t *v, return EINVAL; } break; + case JSON_STRING: + if (mtype != LDMS_V_CHAR && mtype != LDMS_V_CHAR_ARRAY) { + snprintf(err_buf, err_sz, + "string value must have 'char' or 'char_array' type"); + return EINVAL; + } + break; default: snprintf(err_buf, err_sz, "Unsupported JSON value"); return EINVAL; @@ -289,6 +295,7 @@ typedef struct decomp_static_mid_rbn_s { enum ldms_value_type mtype; size_t array_len; enum ldms_value_type rec_mtype; + enum ldms_value_type le_mtype; #if 0 size_t mval_size; /* Size of this mval */ off_t mval_offset; /* Offset into mval memory for this column */ @@ -874,6 +881,7 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, col_mid->array_len = -1; col_mid->rec_mid = -EINVAL; col_mid->rec_mtype = LDMS_V_NONE; + col_mid->le_mtype = LDMS_V_NONE; src = cfg_col->src; @@ -915,11 +923,12 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, if (mid < 0) { /* This is a fill candidate, must have a type and if * an array a length */ - if (cfg_col->type == LDMS_V_NONE) { + if (!cfg_col->fill) { ldmsd_log(LDMSD_LERROR, "strgp '%s': col[src] '%s' does not exist in " - "the set and the 'type' is not specified.\n", - ctxt->strgp->obj.name, cfg_col->src); + "the set '%s' and the 'fill' is not specified.\n", + ctxt->strgp->obj.name, cfg_col->src, + ldms_set_name_get(ctxt->set)); rc = EINVAL; goto err; } @@ -940,7 +949,7 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, mtype = ldms_metric_type_get(ctxt->set, mid); mlen = ldms_metric_array_get_len(ctxt->set, mid); - assert(mlen >= 0); + ASSERT_RETURN((!ldms_type_is_array(mtype)) || mlen); if (LDMS_V_NONE < mtype && mtype <= LDMS_V_D64_ARRAY) { /* Primitives & array of primitives. We have mlen, mtype and @@ -966,7 +975,7 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, /* handling LIST */ lh = ldms_metric_get(ctxt->set, mid); le = ldms_list_first(ctxt->set, lh, &le_mtype, &mlen); - assert(mlen); + ASSERT_RETURN((!ldms_type_is_array(le_mtype)) || mlen); if (!le) { /* list empty. can't init yet */ ldmsd_log(LDMSD_LERROR, @@ -1004,7 +1013,7 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, goto err; } rec_mtype = ldms_record_metric_type_get(le, rec_mid, &mlen); - assert(mlen); + ASSERT_RETURN((!ldms_type_is_array(rec_mtype)) || mlen); goto commit; rec_array_routine: @@ -1028,7 +1037,7 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, goto err; } rec_mtype = ldms_record_metric_type_get(rec, rec_mid, &mlen); - assert(mlen); + ASSERT_RETURN((!ldms_type_is_array(rec_mtype)) || mlen); /* fall through to commit */ commit: @@ -1036,21 +1045,29 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, col_mid->mid = mid; col_mid->mtype = mtype; col_mid->array_len = mlen; - assert(mlen); + col_mid->le_mtype = le_mtype; if (rec_mid >= 0) { col_mid->rec_mid = rec_mid; col_mid->rec_mtype = rec_mtype; + ASSERT_RETURN((!ldms_type_is_array(rec_mtype)) || mlen); + } else { } /* commit to cfg_col */ - assert(mtype != LDMS_V_NONE); + ASSERT_RETURN(mtype != LDMS_V_NONE); if (cfg_col->type == LDMS_V_NONE) { - cfg_col->type = rec_mid>=0?rec_mtype:mtype; + if (rec_mid >= 0) + cfg_col->type = rec_mtype; + else if (mtype == LDMS_V_LIST) + cfg_col->type = le_mtype; + else + cfg_col->type = mtype; } if (0 == cfg_col->array_len) { - assert(mlen >= 0); cfg_col->array_len = mlen; + ASSERT_RETURN((!ldms_type_is_array(cfg_col->type)) || + cfg_col->array_len); } if (0 == cfg_col->mval_size) { cfg_col->mval_offset = ctxt->mval_offset; @@ -1065,7 +1082,7 @@ static int resolve_col(struct resolve_ctxt_s *ctxt, next: - assert(special || cfg_col->mval_size); + ASSERT_RETURN(special || cfg_col->mval_size); /* update row schema digest */ EVP_DigestUpdate(ctxt->evp_ctx, cfg_col->dst, strlen(cfg_col->dst)); EVP_DigestUpdate(ctxt->evp_ctx, &cfg_col->type, sizeof(cfg_col->type)); @@ -1193,7 +1210,7 @@ static void assign_value(ldmsd_col_t dst, ldmsd_col_t src) } switch (dst->type) { case LDMS_V_CHAR: - dst->mval->v_char = ldms_mval_as_s8(src->mval, src->type, 0); + dst->mval->v_char = ldms_mval_as_char(src->mval, src->type, 0); break; case LDMS_V_U8: dst->mval->v_u8 = ldms_mval_as_u8(src->mval, src->type, 0); @@ -1750,6 +1767,7 @@ static int decomp_static_decompose(ldmsd_strgp_t strgp, ldms_set_t set, const char *producer; const char *instance; int producer_len, instance_len; + union ldms_value zfill = {0}; /* zero value as default "fill" */ if (!TAILQ_EMPTY(row_list)) return EINVAL; @@ -1922,8 +1940,15 @@ static int decomp_static_decompose(ldmsd_strgp_t strgp, ldms_set_t set, col_mvals_fill: mcol->le = NULL; mcol->mval = cfg_row->cols[j].fill; - mcol->mtype = cfg_row->cols[j].type; - mcol->array_len = cfg_row->cols[j].fill_len; + if (mcol->mval) { + mcol->mtype = cfg_row->cols[j].type; + mcol->array_len = cfg_row->cols[j].fill_len; + } else { + /* no "fill" specified, use default "fill" */ + mcol->mval = &zfill; + mcol->array_len = 1; + mcol->mtype = cfg_row->cols[j].type; + } } make_row: /* make/expand rows according to col_mvals */ @@ -2037,8 +2062,14 @@ static int decomp_static_decompose(ldmsd_strgp_t strgp, ldms_set_t set, col_fill: mcol->mval = cfg_row->cols[j].fill; - mcol->array_len = row->cols[j].array_len; - mcol->mtype = cfg_row->cols[j].type; + if (mcol->mval) { + mcol->array_len = row->cols[j].array_len; + mcol->mtype = cfg_row->cols[j].type; + } else { + mcol->mval = &zfill; + mcol->array_len = 1; + mcol->mtype = cfg_row->cols[j].type; + } } if (cfg_row->op_present) {