diff --git a/attributes/maestro-core-yaml.h b/attributes/maestro-core-yaml.h index dc46894d03c480082599a401f98b5c459bc1b4e6..ad8278f6ded41ebdde8c25bfb78de3697e3020c0 100644 --- a/attributes/maestro-core-yaml.h +++ b/attributes/maestro-core-yaml.h @@ -295,11 +295,25 @@ unsigned char maestro_core_yaml[] = { 0x20, 0x2d, 0x31, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x55, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, - 0x20, 0x20, 0x23, 0x20, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x73, 0x0a, - 0x20, 0x20, 0x23, 0x20, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x23, 0x20, 0x28, 0x65, - 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, - 0x6f, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x79, 0x61, 0x6d, 0x6c, 0x29, - 0x0a, 0x0a + 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, + 0x6f, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x69, + 0x6e, 0x3d, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x3a, 0x20, 0x2d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, + 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, + 0x44, 0x4f, 0x2e, 0x20, 0x2d, 0x31, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x20, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x2f, 0x55, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x4c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x73, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x44, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x23, + 0x20, 0x28, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, 0x65, + 0x73, 0x74, 0x72, 0x6f, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x79, 0x61, + 0x6d, 0x6c, 0x29, 0x0a, 0x0a }; -const unsigned int maestro_core_yaml_len = 3614; +const unsigned int maestro_core_yaml_len = 3785; diff --git a/attributes/maestro-core.yaml b/attributes/maestro-core.yaml index 2b1531b495e51f9407ac010d063984958989c6e8..c497681afefbe7b90d32d88f9236cdc6f53973e8 100644 --- a/attributes/maestro-core.yaml +++ b/attributes/maestro-core.yaml @@ -112,6 +112,12 @@ maestro-attributes: default: -1 documentation: The total size of the CDO. -1 indicates Unknown/Unallocated. + - key: "cdo.scope.local-size" + type: int(min=-1) + required: False + default: -1 + documentation: The local size of the CDO. -1 indicates Unknown/Unallocated. + # Layouts # Distributions diff --git a/attributes/maestro-schema.c b/attributes/maestro-schema.c index 5232a0b3a588224ff777640425a6efa9b684b9c2..1dcda1d7c5fd3da687d33a1b757a34bdc5fa05fd 100644 --- a/attributes/maestro-schema.c +++ b/attributes/maestro-schema.c @@ -1002,6 +1002,7 @@ struct mstro_attribute_entry_ { * expected type of the attribute in the * appropriate schema */ size_t valsize; /**< allocated space for val */ + enum mstro_stp_val_kind kind; /**< schema type parser type of the value (saves lookups in original type declaration)*/ bool user_owned_val; /**< whether the val allocation is owned by the * user (if not we must free it eventually) */ /* FIXME: this is the place where serialized versions of the entry @@ -1030,6 +1031,40 @@ struct partial_key { }; +/* set valsize slot according to type */ +static inline +mstro_status +mstro_attribute_entry__set_size(struct mstro_attribute_entry_ *entry, + enum mstro_stp_val_kind kind) +{ + mstro_status status=MSTRO_OK; + switch(kind) { + case MSTRO_STP_BOOL: + entry->valsize = sizeof(bool); break; + case MSTRO_STP_UINT: + entry->valsize = sizeof(uint64_t); break; + case MSTRO_STP_INT: + entry->valsize = sizeof(int64_t); break; + case MSTRO_STP_FLOAT: + entry->valsize = sizeof(float); break; + case MSTRO_STP_DOUBLE: + entry->valsize = sizeof(double); break; + case MSTRO_STP_STR: + case MSTRO_STP_REGEX: + entry->valsize = strlen(entry->val)+1; + break; + case MSTRO_STP_BLOB: + entry->valsize = 0; /* FIXME: query a previously set key like 'strcat(fqkey,"_len")' ? */ + break; + case MSTRO_STP_TIMESTAMP: + entry->valsize = sizeof(mstro_timestamp); break; + + default: + ERR("Unexpected parsed type %d\n", kind); + status=MSTRO_UNIMPL; + } + return status; +} /* parse VAL and fill in *entry */ static inline @@ -1073,38 +1108,39 @@ mstro_attributes_parse_val(mstro_schema schema, bool need_regmatch = true; /* except for BLOB we need it */ size_t minlen =0, maxlen=val_len; /* might be changed for strings */ - switch(tdecl->parsed_type->kind) { + entry->kind = tdecl->parsed_type->kind; + s = mstro_attribute_entry__set_size(entry, entry->kind); + if(s!=MSTRO_OK) { + ERR("Failed to set entry value size\n"); + goto BAILOUT; + } + + switch(entry->kind) { case MSTRO_STP_BOOL: { - entry->valsize = sizeof(bool); err = regcomp(&(regex[0]), "1|0|On|Off|True|False",REG_ICASE|REG_NOSUB|REG_EXTENDED); break; } case MSTRO_STP_UINT: { - entry->valsize = sizeof(uint64_t); err = regcomp(&(regex[0]), "[+]?[[:blank:]]*[0-9]+",REG_EXTENDED|REG_NOSUB); WARN("Not checking numeric bounds on types\n"); break; } case MSTRO_STP_INT: { - entry->valsize = sizeof(int64_t); err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]+",REG_EXTENDED|REG_NOSUB); WARN("Not checking numeric bounds on types\n"); break; } case MSTRO_STP_FLOAT: { - entry->valsize = sizeof(float); err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?",REG_EXTENDED); WARN("Not checking numeric bounds on types\n"); break; } case MSTRO_STP_DOUBLE: { - entry->valsize = sizeof(double); err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?",REG_EXTENDED); WARN("Not checking numeric bounds on types\n"); break; } case MSTRO_STP_STR: { - entry->valsize = sizeof(char)*(val_len+1); minlen = tdecl->parsed_type->str_minlen; maxlen = tdecl->parsed_type->str_maxlen; char *re; @@ -1129,20 +1165,17 @@ mstro_attributes_parse_val(mstro_schema schema, break; } case MSTRO_STP_REGEX: - entry->valsize = sizeof(char)*(val_len+1); for(size_t i=0; i<num_re; i++) { err |= regcomp(&(regex[i]), tdecl->parsed_type->regex_patterns[i], REG_EXTENDED|REG_NOSUB| (tdecl->parsed_type->regex_ignorecase ? REG_ICASE : 0)); } break; case MSTRO_STP_BLOB: - entry->valsize = sizeof(char)*(val_len); need_regmatch = false; minlen = tdecl->parsed_type->blob_minlen; maxlen = tdecl->parsed_type->blob_maxlen; break; case MSTRO_STP_TIMESTAMP: - entry->valsize = sizeof(mstro_timestamp); err = regcomp(&(regex[0]), RFC3339_PATTERN, REG_EXTENDED); break; @@ -1153,6 +1186,7 @@ mstro_attributes_parse_val(mstro_schema schema, if(err) { ERR("Failed to construct regex\n"); // regerror ... + goto BAILOUT; } if(! (minlen<=val_len && val_len <=maxlen)) { ERR("Argument |%s| (len %zu, strlen %zu) not within length bounds for type: min=%zu, max=%zu\n", @@ -1189,7 +1223,7 @@ mstro_attributes_parse_val(mstro_schema schema, } if(s==MSTRO_OK) { - switch(tdecl->parsed_type->kind) { + switch(entry->kind) { case MSTRO_STP_BOOL: { /* we are alredy checked by regex above */ switch(tolower(val[0])) { @@ -1252,7 +1286,8 @@ BAILOUT: static inline mstro_status -mstro_attribute_entry_create(mstro_symbol sym, struct mstro_attribute_entry_ **result) +mstro_attribute_entry_create(mstro_symbol sym, + struct mstro_attribute_entry_ **result) { if(sym==NULL) return MSTRO_INVARG; @@ -1266,6 +1301,7 @@ mstro_attribute_entry_create(mstro_symbol sym, struct mstro_attribute_entry_ **r (*result)->key = sym; (*result)->val = NULL; (*result)->valsize = 0; + (*result)->kind = MSTRO_STP_ERROR; (*result)->user_owned_val = false; (*result)->serialized_yaml = NULL; mstro__pool__aval__init(& ((*result)->serialized_pb)); @@ -1488,7 +1524,7 @@ mstro_attributes__parse_helper(yaml_parser_t parser, if(status!=MSTRO_OK) goto BAILOUT; } - + status = mstro_attributes_parse_val(schema, decl, val, val_len, entry); if(status!=MSTRO_OK) { ERR("Failed to parse |%s| as value for attribute |%s|\n", @@ -1742,6 +1778,90 @@ mstro_attribute_dict_dispose(mstro_attribute_dict dict) return status; } +/* find default for KEY in DICT's schema(ta) and create a fresh entry + * for it. If entry already exist, replaces the current value by the + * default. */ +static inline +mstro_status +mstro_attribute_dict__insert_default(mstro_attribute_dict dict, + mstro_symbol key) +{ + struct mstro_attribute_entry_ *entry=NULL; + bool must_insert=false; + mstro_status status = MSTRO_OK; + + HASH_FIND(hh, dict->dict, &key, sizeof(mstro_symbol), entry); + if(!entry) { + status = mstro_attribute_entry_create(key, &entry); + if(status!=MSTRO_OK) { + ERR("Cannot allocate default entry\n"); + goto BAILOUT; + } + must_insert=true; + status = mstro_attribute_entry__set_size(entry, entry->kind); + if(status!=MSTRO_OK) { + goto BAILOUT; + } + entry->val = NULL; + } + + mstro_schema_attribute attr=NULL; + status = mstro_schema_lookup_attribute(dict->schema, mstro_symbol_name(key), &attr); + if(status!=MSTRO_OK) { + ERR("Cannot find attribute in schema !? (should not happen here)\n"); + goto BAILOUT; + } + mstro_schema_type tdecl; + status = mstro_schema_lookup_type(dict->schema, attr->typespec, &tdecl); + if(status!=MSTRO_OK) { + goto BAILOUT; + } + assert(entry->kind = tdecl->parsed_type->kind); + + /* duplicate; if user-supplied: allocate freshly */ + if(entry->user_owned_val) + entry->val=NULL; + if(entry->val==NULL) { + /* either a fresh entry record, or we killed user value in this slot */ + entry->val = malloc(entry->valsize); + if(entry->val==NULL) { + status=MSTRO_NOMEM; + goto BAILOUT; + } + } + + switch(entry->kind) { + case MSTRO_STP_BOOL: + case MSTRO_STP_UINT: + case MSTRO_STP_INT: + case MSTRO_STP_FLOAT: + case MSTRO_STP_DOUBLE: + case MSTRO_STP_STR: + case MSTRO_STP_REGEX: + case MSTRO_STP_BLOB: + case MSTRO_STP_TIMESTAMP: + memcpy(entry->val, attr->defaultval, entry->valsize); + break; + default: + free(entry->val); + entry->val = NULL; + ERR("Unhandled STP kind %d\n", entry->kind); + status=MSTRO_UNIMPL; + goto BAILOUT; + } + + if(must_insert) { + HASH_ADD(hh, dict->dict, key, sizeof(mstro_symbol), entry); + } +BAILOUT: + if(status!=MSTRO_OK) + if(must_insert) + mstro_attribute_entry_dispose(entry); + + return status; +} + + mstro_status mstro_attribute_dict_get(mstro_attribute_dict dict, const char *key, @@ -1791,82 +1911,51 @@ mstro_attribute_dict_get(mstro_attribute_dict dict, HASH_FIND(hh, dict->dict, &sym, sizeof(mstro_symbol), entry); if(entry==NULL) { - DEBUG("Key |%s| found, but no value in attribute dictionary at %p\n", fqkey, dict); - /* FIXME: maybe dynamically find and insert default value from - dict->schema for it? That would avoid requiring users to - handle defaults and could be more efficient for large schemata - with lots of defaults. */ - if(valtype) - *valtype=MSTRO_CDO_ATTR_VALUE_INVALID; - status=MSTRO_NOENT; - goto BAILOUT; - } else { - /* return value */ - if(entry_p) - *entry_p = entry; - if(val_p) - *val_p = entry->val; - if(valtype) { - mstro_schema_attribute attr; - mstro_schema_type tdecl; - status = mstro_schema_lookup_attribute(dict->schema, fqkey, &attr); - if(status!=MSTRO_OK) { - if(status==MSTRO_NOENT) { - ERR("Invalid attribute |%s| (not in schema %s V%zu) (but had key in dict!?)\n", - fqkey, mstro_schema_name(dict->schema), mstro_schema_version(dict->schema)); - goto BAILOUT; - } else { - ERR("Lookup of attribute |%s| in schema failed: %d (%s)\n", - fqkey, status, mstro_status_description(status)); - goto BAILOUT; - } - } - - /* got attribute info */ - status = mstro_schema_lookup_type(dict->schema, attr->typespec, &tdecl); - if(status!=MSTRO_OK) { - ERR("Failed to find type declaration for type |%s| (attribute |%s|)\n", - attr->typespec, fqkey); - goto BAILOUT; - } else { - DEBUG("Found type declaration for type |%s| (attribute |%s|)\n", attr->typespec, fqkey); - } - if(!tdecl->parsed_type) { - ERR("Type not parsed yet, should not happen\n"); + DEBUG("Key |%s| found, but no value in attribute dictionary at %p, fetching default\n", fqkey, dict); + + status = mstro_attribute_dict__insert_default(dict, sym); + if(status!=MSTRO_OK) { + ERR("Failed to insert default value for attribute %s\n", fqkey); + goto BAILOUT; + } + } + + /* return value */ + if(entry_p) + *entry_p = entry; + if(val_p) + *val_p = entry->val; + if(valtype) { + switch(entry->kind) { + case MSTRO_STP_BOOL: + *valtype = MSTRO_CDO_ATTR_VALUE_bool; + break; + case MSTRO_STP_UINT: + *valtype = MSTRO_CDO_ATTR_VALUE_uint64; + break; + case MSTRO_STP_INT: + *valtype = MSTRO_CDO_ATTR_VALUE_int64; + break; + case MSTRO_STP_FLOAT: + *valtype = MSTRO_CDO_ATTR_VALUE_float; + break; + case MSTRO_STP_DOUBLE: + *valtype = MSTRO_CDO_ATTR_VALUE_double; + break; + case MSTRO_STP_STR: + case MSTRO_STP_REGEX: + *valtype = MSTRO_CDO_ATTR_VALUE_cstring; + break; + case MSTRO_STP_BLOB: + *valtype = MSTRO_CDO_ATTR_VALUE_blob; + break; + case MSTRO_STP_TIMESTAMP: + *valtype = MSTRO_CDO_ATTR_VALUE_timestamp; + break; + default: + ERR("Unhandled MSTRO_STP attribute type %d\n", entry->kind); status=MSTRO_UNIMPL; goto BAILOUT; - } - switch(tdecl->parsed_type->kind) { - case MSTRO_STP_BOOL: - *valtype = MSTRO_CDO_ATTR_VALUE_bool; - break; - case MSTRO_STP_UINT: - *valtype = MSTRO_CDO_ATTR_VALUE_uint64; - break; - case MSTRO_STP_INT: - *valtype = MSTRO_CDO_ATTR_VALUE_int64; - break; - case MSTRO_STP_FLOAT: - *valtype = MSTRO_CDO_ATTR_VALUE_float; - break; - case MSTRO_STP_DOUBLE: - *valtype = MSTRO_CDO_ATTR_VALUE_double; - break; - case MSTRO_STP_STR: - case MSTRO_STP_REGEX: - *valtype = MSTRO_CDO_ATTR_VALUE_cstring; - break; - case MSTRO_STP_BLOB: - *valtype = MSTRO_CDO_ATTR_VALUE_blob; - break; - case MSTRO_STP_TIMESTAMP: - *valtype = MSTRO_CDO_ATTR_VALUE_timestamp; - break; - default: - ERR("Unhandled MSTRO_STP attribute type %d\n", tdecl->parsed_type->kind); - status=MSTRO_UNIMPL; - goto BAILOUT; - } } } status=MSTRO_OK; @@ -1877,7 +1966,8 @@ BAILOUT: return status; } - + + mstro_status mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key, @@ -1956,38 +2046,11 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key, status = mstro_attribute_entry_create(decl->key_symbol, &entry); if(status!=MSTRO_OK) goto BAILOUT; - - /* FIXME: setting the val size should be part of the default init for entry */ - /* FIXME: entry should have the tdecl->parsed_type-> kind as a slot in it. */ - - /* all built-ins recognized by built-in regexps for now */ - - switch(tdecl->parsed_type->kind) { - case MSTRO_STP_BOOL: - entry->valsize = sizeof(bool); break; - case MSTRO_STP_UINT: - entry->valsize = sizeof(uint64_t); break; - case MSTRO_STP_INT: - entry->valsize = sizeof(int64_t); break; - case MSTRO_STP_FLOAT: - entry->valsize = sizeof(float); break; - case MSTRO_STP_DOUBLE: - entry->valsize = sizeof(double); break; - case MSTRO_STP_STR: - case MSTRO_STP_REGEX: - assert(valtype==MSTRO_CDO_ATTR_VALUE_INVALID||valtype==MSTRO_CDO_ATTR_VALUE_cstring); - entry->valsize = strlen(val)+1; - break; - case MSTRO_STP_BLOB: - entry->valsize = 0; /* FIXME: query a previously set key like 'strcat(fqkey,"_len")' ? */ - break; - case MSTRO_STP_TIMESTAMP: - entry->valsize = sizeof(mstro_timestamp); break; - - default: - ERR("Unexpected parsed type %d\n", tdecl->parsed_type->kind); - s=MSTRO_UNIMPL; - } + + entry->kind = tdecl->parsed_type->kind; + status = mstro_attribute_entry__set_size(entry, entry->kind); + if(status!=MSTRO_OK) + goto BAILOUT; HASH_ADD(hh, dict->dict, key, sizeof(mstro_symbol), entry); } @@ -1995,37 +2058,8 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key, /* some lax type checking */ if(valtype) { /* try some sanity checking */ - mstro_schema_attribute attr; - mstro_schema_type tdecl; - status = mstro_schema_lookup_attribute(dict->schema, fqkey, &attr); - if(status!=MSTRO_OK) { - if(status==MSTRO_NOENT) { - ERR("Invalid attribute |%s| (not in schema %s V%zu) (but had key in dict!?)\n", - fqkey, mstro_schema_name(dict->schema), mstro_schema_version(dict->schema)); - goto BAILOUT; - } else { - ERR("Lookup of attribute |%s| in schema failed: %d (%s)\n", - fqkey, status, mstro_status_description(status)); - goto BAILOUT; - } - } - - /* got attribute info */ - status = mstro_schema_lookup_type(dict->schema, attr->typespec, &tdecl); - if(status!=MSTRO_OK) { - ERR("Failed to find type declaration for type |%s| (attribute |%s|)\n", - attr->typespec, fqkey); - goto BAILOUT; - } else { - DEBUG("Found type declaration for type |%s| (attribute |%s|)\n", attr->typespec, fqkey); - } - if(!tdecl->parsed_type) { - ERR("Type not parsed yet, should not happen\n"); - status=MSTRO_UNIMPL; - goto BAILOUT; - } status = MSTRO_OK; - switch(tdecl->parsed_type->kind) { + switch(entry->kind) { case MSTRO_STP_BOOL: if(valtype!=MSTRO_CDO_ATTR_VALUE_bool) status = MSTRO_INVARG; @@ -2060,7 +2094,7 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key, status = MSTRO_INVARG; break; default: - ERR("Unhandled MSTRO_STP attribute type %d\n", tdecl->parsed_type->kind); + ERR("Unhandled MSTRO_STP attribute type %d\n", entry->kind); status=MSTRO_UNIMPL; } if(status!=MSTRO_OK) diff --git a/include/maestro/i_cdo.h b/include/maestro/i_cdo.h index b125087c5aeb0afe8aa953dffbf9d9f7b9ea5450..55c7b5793253d9c2fda6347802d4dd6a14e5bcc8 100644 --- a/include/maestro/i_cdo.h +++ b/include/maestro/i_cdo.h @@ -155,7 +155,7 @@ mstro_cdo_state_describe(mstro_cdo_state s); #define BYTE_ASCII_NUL sizeof(char) -#define MSTRO_CDO_ATTR_NAMESPACE_DEFAULT ".maestro.core.cdo" +#define MSTRO_CDO_ATTR_NAMESPACE_DEFAULT ".maestro.core.cdo." /**@defgroup MSTRO_Internal Internal Maestro Core API **@{ diff --git a/maestro/attributes.c b/maestro/attributes.c index 575062d0c9f55c6790593f08fc32aef5ea34ed43..1a7a6c7ca8e2b666dc6b236b3c3cbd9a0b55c6ad 100644 --- a/maestro/attributes.c +++ b/maestro/attributes.c @@ -137,23 +137,26 @@ mstro_cdo_attribute_get(mstro_cdo cdo, const char* key, return MSTRO_INVARG; if(val_p==NULL) return MSTRO_INVOUT; - /* FIXME Absolute path supported only for default namespace yet */ - if ( strncmp (key,MSTRO_CDO_ATTR_NAMESPACE_DEFAULT, strlen(MSTRO_CDO_ATTR_NAMESPACE_DEFAULT)) - && !strncmp (key,MSTRO_CDO_ATTR_NAMESPACE_DEFAULT, 1)) { - ERR("get attribute on CDO \"%s\" failed because absolute path supported only for default namespace yet", cdo->name); - return MSTRO_INVARG; - } - - mstro_status status; - void* tmp; - status = mstro_cdo_attr_table__lookup(cdo,key,type,&tmp); - if (MSTRO_OK != status) - return status; - - *val_p = tmp; + const char *fqkey=key; + char *tmpkey = NULL; + if(key[0]!='.') { + tmpkey = malloc(strlen(cdo->current_namespace)+strlen(key)+1); + if(tmpkey==NULL) { + ERR("Cannot allocate fully qualified key name\n"); + return MSTRO_NOMEM; + } + strcpy(tmpkey, cdo->current_namespace); + strcat(tmpkey, key); + fqkey=tmpkey; + } - return MSTRO_OK; + mstro_status status + = mstro_attribute_dict_get(cdo->attributes, fqkey, + type, val_p, NULL); + if(tmpkey) + free(tmpkey); + return status; } mstro_status diff --git a/maestro/cdo.c b/maestro/cdo.c index 9ddebf5ae363fb355db69bc3b6d19f405a7f5d66..1debc883a3a70edd6ce86bbe58c9eed5b929786b 100644 --- a/maestro/cdo.c +++ b/maestro/cdo.c @@ -128,14 +128,25 @@ mstro_cdo mstro_cdo__alloc(void) { mstro_cdo res = malloc(sizeof(struct mstro_cdo_)); + if(res==NULL) { + ERR("Cannot allocate a CDO\n"); + abort(); + } /* we need to zero out the hash-table relevant parts. For simplicity we zero everything */ memset(res, 0, sizeof(struct mstro_cdo_)); /* initialize parts that need special handling */ atomic_init(&(res->state), MSTRO_CDO_STATE_INVALID); - /* add attributes space */ - mstro_status s = mstro_attribute_dict_set_defaults(g_mstro_core_schema_instance, - false, - &(res->attributes)); + + /* add attribute and default namespace */ + res->current_namespace = strdup(MSTRO_CDO_ATTR_NAMESPACE_DEFAULT); + if (res->current_namespace == NULL) { + ERR("Cannot allocate for default CDO namespace\n"); + free(res); + abort(); + } + mstro_status s = mstro_attribute_dict_set_defaults( + g_mstro_core_schema_instance, false, &(res->attributes)); + if(s!=MSTRO_OK) { ERR("Cannot create CDO, aborting\n"); abort(); @@ -340,18 +351,10 @@ mstro_cdo_declare(const char *name, (*result)->mamba_array = NULL; (*result)->raw_ptr = NULL; - /* generate default attributes yaml string */ + /* Ensuire default attributes */ s = mstro_cdo_attribute_set_default(*result); if (s != MSTRO_OK) return s; - - /* TODO initialize default namespace*/ - (*result)->current_namespace = strdup(MSTRO_CDO_ATTR_NAMESPACE_DEFAULT); - if ((*result)->current_namespace == NULL) { - ERR("Cannot allocate for default CDO namespace\n"); - mstro_cdo__free(result); - return MSTRO_NOMEM; - } WITH_CDO_ID_STR(idstr,&(*result)->id, INFO("Declared CDO `%s', (local ID: %s)\n", @@ -603,13 +606,14 @@ mstro_cdo_offer(mstro_cdo cdo) mstro_cdo_block_until(cdo, MSTRO_CDO_STATE_OFFERED, "OFFERED"); { - void* val; + const void* val; enum mstro_cdo_attr_value_type type; - status = mstro_cdo_attr_table__lookup( - cdo, - /* FIXME: should use the well-defined one FQAN */ - "local_size", - &type, &val); + status = mstro_cdo_attribute_get(cdo, MSTRO_ATTR_CORE_CDO_SCOPE_LOCAL_SIZE, + NULL, &val); + if(status!=MSTRO_OK) { + ERR("CDO has no local-size\n"); + return MSTRO_FAIL; + } status = mstro_stats_add_counter(MSTRO_STATS_CAT_POOL, MSTRO_STATS_L_BYTES_POOLED,