/** * @file utils/nfsref/lookup.c * @brief Examine junction metadata from a local file system object */ /* * Copyright 2011, 2018 Oracle. All rights reserved. * * This file is part of nfs-utils. * * nfs-utils is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2.0 as * published by the Free Software Foundation. * * nfs-utils is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License version 2.0 for more details. * * You should have received a copy of the GNU General Public License * version 2.0 along with nfs-utils. If not, see: * * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ #include #include #include #include #include #include "junction.h" #include "xlog.h" #include "nfsref.h" /** * Display help message for "lookup" subcommand * * @param progname NUL-terminated C string containing name of program * @return program exit status */ int nfsref_lookup_help(const char *progname) { fprintf(stderr, " \n"); fprintf(stderr, "Usage: %s [ -t type ] lookup \n\n", progname); fprintf(stderr, "Display the contents of the junction at " ". For NFS basic\n"); fprintf(stderr, "junctions, the local contents of the junction " "are displayed. For FedFS\n"); fprintf(stderr, "junctions, FSL records are retrieved from the " "NSDB and displayed.\n"); return EXIT_SUCCESS; } /** * Convert a boolean value into a displayable string constant * * @param value boolean value * @return NUL-terminated static constant C string */ static const char * nfsref_lookup_display_boolean(_Bool value) { return value ? "true" : "false"; } /** * Display a single NFS location * * @param fsloc pointer to an NFS location structure */ static void nfsref_lookup_display_nfs_location(struct nfs_fsloc *fsloc) { char *rootpath; if (nsdb_path_array_to_posix(fsloc->nfl_rootpath, &rootpath) == FEDFS_OK) { printf("%s:%s\n", fsloc->nfl_hostname, rootpath); free(rootpath); } else printf("%s: - Invalid root path -\n", fsloc->nfl_hostname); printf("\n"); printf("\tNFS port:\t%u\n", fsloc->nfl_hostport); printf("\tValid for:\t%d\n", fsloc->nfl_validfor); printf("\tCurrency:\t%d\n", fsloc->nfl_currency); printf("\tFlags:\t\tvarsub(%s)\n", nfsref_lookup_display_boolean(fsloc->nfl_flags.nfl_varsub)); printf("\tGenFlags:\twritable(%s), going(%s), split(%s)\n", nfsref_lookup_display_boolean(fsloc->nfl_genflags.nfl_writable), nfsref_lookup_display_boolean(fsloc->nfl_genflags.nfl_going), nfsref_lookup_display_boolean(fsloc->nfl_genflags.nfl_split)); printf("\tTransFlags:\trdma(%s)\n", nfsref_lookup_display_boolean(fsloc->nfl_transflags.nfl_rdma)); printf("\tClass:\t\tsimul(%u), handle(%u), fileid(%u)\n", fsloc->nfl_info.nfl_simul, fsloc->nfl_info.nfl_handle, fsloc->nfl_info.nfl_fileid); printf("\tClass:\t\twritever(%u), change(%u), readdir(%u)\n", fsloc->nfl_info.nfl_writever, fsloc->nfl_info.nfl_change, fsloc->nfl_info.nfl_readdir); printf("\tRead:\t\trank(%u), order(%u)\n", fsloc->nfl_info.nfl_readrank, fsloc->nfl_info.nfl_readorder); printf("\tWrite:\t\trank(%u), order(%u)\n", fsloc->nfl_info.nfl_writerank, fsloc->nfl_info.nfl_writeorder); printf("\n"); } /** * Display a list of NFS locations * * @param fslocs list of NFS locations to display */ static void nfsref_lookup_display_nfs_locations(struct nfs_fsloc *fslocs) { struct nfs_fsloc *fsloc; for (fsloc = fslocs; fsloc != NULL; fsloc = fsloc->nfl_next) nfsref_lookup_display_nfs_location(fsloc); } /** * List NFS locations in an nfs-basic junction * * @param junct_path NUL-terminated C string containing pathname of junction * @return program exit status */ static int nfsref_lookup_nfs_basic(const char *junct_path) { struct nfs_fsloc *fslocs = NULL; FedFsStatus retval; xlog(D_GENERAL, "%s: Looking up basic junction in %s", __func__, junct_path); retval = nfs_is_junction(junct_path); switch (retval) { case FEDFS_OK: break; case FEDFS_ERR_NOTJUNCT: xlog(L_ERROR, "%s is not an nfs-basic junction", junct_path); return EXIT_FAILURE; default: xlog(L_ERROR, "Failed to access %s: %s", junct_path, nsdb_display_fedfsstatus(retval)); return EXIT_FAILURE; } retval = nfs_get_locations(junct_path, &fslocs); if (retval != FEDFS_OK) { xlog(L_ERROR, "Failed to access %s: %s", junct_path, nsdb_display_fedfsstatus(retval)); return EXIT_FAILURE; } nfsref_lookup_display_nfs_locations(fslocs); nfs_free_locations(fslocs); return EXIT_SUCCESS; } /** * Resolve either a FedFS or NFS basic junction * * @param junct_path NUL-terminated C string containing pathname of junction * @return program exit status */ static int nfsref_lookup_unspecified(const char *junct_path) { FedFsStatus retval; retval = nfs_is_junction(junct_path); if (retval == FEDFS_OK) return nfsref_lookup_nfs_basic(junct_path); xlog(L_ERROR, "%s is not a junction", junct_path); return EXIT_FAILURE; } /** * Enumerate metadata of a junction * * @param type type of junction to add * @param junct_path NUL-terminated C string containing pathname of junction * @return program exit status */ int nfsref_lookup(enum nfsref_type type, const char *junct_path) { switch (type) { case NFSREF_TYPE_UNSPECIFIED: return nfsref_lookup_unspecified(junct_path); case NFSREF_TYPE_NFS_BASIC: return nfsref_lookup_nfs_basic(junct_path); default: xlog(L_ERROR, "Unrecognized junction type"); } return EXIT_FAILURE; }