/** * Get id of root dir */ static int retrieve_root_id(entry_id_t * root_id) { int rc; rc = Path2Id(config.global_config.fs_path, root_id); if (rc) DisplayLog(LVL_MAJOR, FIND_TAG, "Can't access filesystem's root %s: %s", config.global_config.fs_path, strerror(-rc)); return rc; }
static inline int rebind_helper(const char *old_backend_path, const char *new_fs_path, const char *new_fid_str) { int rc; char rp[RBH_PATH_MAX]; char new_backend_path[RBH_PATH_MAX]; entry_id_t new_fid; char *tmp; /* full path required */ tmp = realpath(new_fs_path, NULL); if (tmp == NULL) { rc = -errno; DisplayLog(LVL_CRIT, LOGTAG, "Error in realpath(%s): %s", new_fs_path, strerror(-rc)); return rc; } if (strlen(tmp) >= RBH_PATH_MAX) { DisplayLog(LVL_CRIT, LOGTAG, "Path length is too long!"); return -ENAMETOOLONG; } /* safe because of previous check */ strcpy(rp, tmp); /* now can release tmp path */ free(tmp); if (new_fid_str) { int nb_read; /* parse fid */ if (new_fid_str[0] == '[') nb_read = sscanf(new_fid_str, "[" SFID "]", RFID(&new_fid)); else nb_read = sscanf(new_fid_str, SFID, RFID(&new_fid)); if (nb_read != FID_SCAN_CNT) { DisplayLog(LVL_CRIT, LOGTAG, "Unexpected format for fid %s", new_fid_str); return -EINVAL; } printf("Binding " DFID " to '%s'...\n", PFID(&new_fid), old_backend_path); } else { /* get fid for the given file */ rc = Path2Id(new_fs_path, &new_fid); if (rc) return rc; printf("Binding '%s' (" DFID ") to '%s'...\n", new_fs_path, PFID(&new_fid), old_backend_path); } /* build the new backend path for the entry */ rc = rbhext_rebind(rp, old_backend_path, new_backend_path, &new_fid); if (rc) { fprintf(stderr, "rebind failed for '%s': %s\n", rp, strerror(-rc)); return rc; } else { printf("'%s' successfully rebound to '%s'\n", rp, new_backend_path); return 0; } }
/** * List contents of the given id/path list */ static int list_contents(char ** id_list, int id_count) { wagon_t *ids; int i, rc; attr_set_t root_attrs; entry_id_t root_id; int is_id; rc = retrieve_root_id(&root_id); if (rc) return rc; ids = MemCalloc(id_count, sizeof(wagon_t)); if (!ids) return -ENOMEM; for (i = 0; i < id_count; i++) { is_id = TRUE; /* is it a path or fid? */ if (sscanf(id_list[i], SFID, RFID(&ids[i].id)) != FID_SCAN_CNT) { is_id = FALSE; /* take it as a path */ rc = Path2Id(id_list[i], &ids[i].id); if (!rc) { ids[i].fullname = id_list[i]; if (FINAL_SLASH(ids[i].fullname)) REMOVE_FINAL_SLASH(ids[i].fullname); } } else { #if _HAVE_FID /* Take it as an FID. */ char path[RBH_PATH_MAX]; rc = Lustre_GetFullPath( &ids[i].id, path, sizeof(path)); if (!rc) ids[i].fullname = strdup(path); #endif } if (rc) { DisplayLog(LVL_MAJOR, FIND_TAG, "Invalid parameter: %s: %s", id_list[i], strerror(-rc)); goto out; } if ((prog_options.bulk != force_nobulk) && (id_count == 1) && entry_id_equal(&ids[i].id, &root_id)) { /* the ID is FS root: use list_bulk instead */ DisplayLog(LVL_DEBUG, FIND_TAG, "Optimization: switching to bulk DB request mode"); mkfilters(FALSE); /* keep dirs */ MemFree(ids); return list_bulk(); } /* get root attrs to print it (if it matches program options) */ root_attrs.attr_mask = disp_mask | query_mask; rc = ListMgr_Get(&lmgr, &ids[i].id, &root_attrs); if (rc == 0) dircb(&ids[i], &root_attrs, 1, NULL); else { DisplayLog(LVL_VERB, FIND_TAG, "Notice: no attrs in DB for %s", id_list[i]); if (!is_id) { struct stat st; ATTR_MASK_SET(&root_attrs, fullpath); strcpy(ATTR(&root_attrs, fullpath), id_list[i]); if (lstat(ATTR(&root_attrs, fullpath ), &st) == 0) { PosixStat2EntryAttr(&st, &root_attrs, TRUE); ListMgr_GenerateFields( &root_attrs, disp_mask | query_mask); } } else if (entry_id_equal(&ids[i].id, &root_id)) { /* this is root id */ struct stat st; ATTR_MASK_SET(&root_attrs, fullpath); strcpy(ATTR(&root_attrs, fullpath), config.global_config.fs_path); if (lstat(ATTR(&root_attrs, fullpath ), &st) == 0) { PosixStat2EntryAttr(&st, &root_attrs, TRUE); ListMgr_GenerateFields( &root_attrs, disp_mask | query_mask); } } dircb(&ids[i], &root_attrs, 1, NULL); } rc = rbh_scrub(&lmgr, &ids[i], 1, disp_mask | query_mask, dircb, NULL); } out: /* ids have been processed, free them */ MemFree(ids); return rc; }
static inline int rebind_helper(const char *old_bk_id, const char *new_bk_id, const char *new_path, const char *new_fid_str) { int rc; attr_set_t old_attrs = ATTR_SET_INIT; attr_set_t new_attrs = ATTR_SET_INIT; entry_id_t new_fid; entry_id_t old_fid; bool old_fid_set = false; char *tmp; /* full path required */ tmp = realpath(new_path, NULL); if (tmp == NULL) { rc = -errno; DisplayLog(LVL_CRIT, LOGTAG, "Error in realpath(%s): %s", new_path, strerror(-rc)); return rc; } if (strlen(tmp) >= RBH_PATH_MAX) { DisplayLog(LVL_CRIT, LOGTAG, "Path length is too long!"); return -ENAMETOOLONG; } /* safe because of previous check */ strcpy(ATTR(&new_attrs, fullpath), tmp); ATTR_MASK_SET(&new_attrs, fullpath); strcpy(ATTR(&old_attrs, fullpath), tmp); ATTR_MASK_SET(&old_attrs, fullpath); /* now we can free tmp path */ free(tmp); if ((new_fid_str != NULL) && !EMPTY_STRING(new_fid_str)) rc = read_fid(new_fid_str, &new_fid); else /* get fid for the given file */ rc = Path2Id(new_path, &new_fid); if (rc) return rc; printf("Rebinding '%s' (" DFID ") from '%s' to '%s'...\n", new_path, PFID(&new_fid), old_bk_id, new_bk_id); /* parse old/new bk ids and set attr accordingly */ if (parse_bk_id(&old_attrs, old_bk_id, &old_fid, &old_fid_set)) return -EINVAL; if (parse_bk_id(&new_attrs, new_bk_id, &new_fid, NULL)) return -EINVAL; /* rebind is like undelete with 'already recovered = true' */ rc = smi->sm->undelete_func(smi, old_fid_set ? &old_fid : NULL, &old_attrs, &new_fid, &new_attrs, true); fprintf(stderr, "Rebind status for '%s': %s\n", ATTR(&new_attrs, fullpath), recov_status2str(rc)); if (rc == RS_NOBACKUP || rc == RS_ERROR) return -1; return 0; }