/* * Lookup uname/gname from uid/gid, return NULL if no match. */ static const char * lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable, int (*lookup_fn)(struct cpio *, const char **, id_t), id_t id) { char asnum[16]; struct name_cache *cache; const char *name; int slot; if (*name_cache_variable == NULL) { *name_cache_variable = malloc(sizeof(struct name_cache)); if (*name_cache_variable == NULL) lafe_errc(1, ENOMEM, "No more memory"); memset(*name_cache_variable, 0, sizeof(struct name_cache)); (*name_cache_variable)->size = name_cache_size; } cache = *name_cache_variable; cache->probes++; slot = id % cache->size; if (cache->cache[slot].name != NULL) { if (cache->cache[slot].id == id) { cache->hits++; return (cache->cache[slot].name); } free(cache->cache[slot].name); cache->cache[slot].name = NULL; } if (lookup_fn(cpio, &name, id) == 0) { if (name == NULL || name[0] == '\0') { /* If lookup failed, format it as a number. */ snprintf(asnum, sizeof(asnum), "%u", (unsigned)id); name = asnum; } cache->cache[slot].name = strdup(name); if (cache->cache[slot].name != NULL) { cache->cache[slot].id = id; return (cache->cache[slot].name); } /* * Conveniently, NULL marks an empty slot, so * if the strdup() fails, we've just failed to * cache it. No recovery necessary. */ } return (NULL); }
static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table, struct cYAML **show_rc, struct cYAML **err_rc) { struct cYAML *tree, *item = NULL, *head, *child; cmd_handler_t cb; char err_str[LNET_MAX_STR_LEN]; int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR; tree = cYAML_build_tree(f, NULL, 0, err_rc); if (tree == NULL) return LUSTRE_CFG_RC_BAD_PARAM; child = tree->cy_child; while (child != NULL) { cb = lookup_fn(child->cy_string, table); if (cb == NULL) { snprintf(err_str, sizeof(err_str), "\"call back for '%s' not found\"", child->cy_string); cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1, "yaml", "helper", err_str, err_rc); goto out; } if (cYAML_is_sequence(child)) { while ((head = cYAML_get_next_seq_item(child, &item)) != NULL) { rc = cb(head, show_rc, err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) return_rc = rc; } } else { rc = cb(child, show_rc, err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) return_rc = rc; } item = NULL; child = child->cy_next; } out: cYAML_free_tree(tree); return return_rc; }