2626import static org .apache .hadoop .fs .viewfs .Constants .CONFIG_VIEWFS_MOUNT_LINKS_AS_SYMLINKS_DEFAULT ;
2727import static org .apache .hadoop .fs .viewfs .Constants .PERMISSION_555 ;
2828
29+ import java .util .function .Function ;
2930import java .io .FileNotFoundException ;
3031import java .io .IOException ;
3132import java .net .URI ;
3233import java .net .URISyntaxException ;
34+ import java .security .PrivilegedExceptionAction ;
3335import java .util .ArrayList ;
3436import java .util .Arrays ;
3537import java .util .Collection ;
@@ -302,7 +304,7 @@ public void initialize(final URI theUri, final Configuration conf)
302304 enableInnerCache = config .getBoolean (CONFIG_VIEWFS_ENABLE_INNER_CACHE ,
303305 CONFIG_VIEWFS_ENABLE_INNER_CACHE_DEFAULT );
304306 FsGetter fsGetter = fsGetter ();
305- final InnerCache innerCache = new InnerCache (fsGetter );
307+ cache = new InnerCache (fsGetter );
306308 // Now build client side view (i.e. client side mount table) from config.
307309 final String authority = theUri .getAuthority ();
308310 String tableName = authority ;
@@ -318,15 +320,32 @@ public void initialize(final URI theUri, final Configuration conf)
318320 fsState = new InodeTree <FileSystem >(conf , tableName , myUri ,
319321 initingUriAsFallbackOnNoMounts ) {
320322 @ Override
321- protected FileSystem getTargetFileSystem (final URI uri )
322- throws URISyntaxException , IOException {
323- FileSystem fs ;
324- if (enableInnerCache ) {
325- fs = innerCache .get (uri , config );
326- } else {
327- fs = fsGetter .get (uri , config );
328- }
329- return new ChRootedFileSystem (fs , uri );
323+ protected Function <URI , FileSystem > initAndGetTargetFs () {
324+ return new Function <URI , FileSystem >() {
325+ @ Override
326+ public FileSystem apply (final URI uri ) {
327+ FileSystem fs ;
328+ try {
329+ fs = ugi .doAs (new PrivilegedExceptionAction <FileSystem >() {
330+ @ Override
331+ public FileSystem run () throws IOException {
332+ if (enableInnerCache ) {
333+ synchronized (cache ) {
334+ return cache .get (uri , config );
335+ }
336+ } else {
337+ return fsGetter ().get (uri , config );
338+ }
339+ }
340+ });
341+ return new ChRootedFileSystem (fs , uri );
342+ } catch (IOException | InterruptedException ex ) {
343+ LOG .error ("Could not initialize the underlying FileSystem "
344+ + "object. Exception: " + ex .toString ());
345+ }
346+ return null ;
347+ }
348+ };
330349 }
331350
332351 @ Override
@@ -350,13 +369,6 @@ protected FileSystem getTargetFileSystem(final String settings,
350369 } catch (URISyntaxException e ) {
351370 throw new IOException ("URISyntax exception: " + theUri );
352371 }
353-
354- if (enableInnerCache ) {
355- // All fs instances are created and cached on startup. The cache is
356- // readonly after the initialize() so the concurrent access of the cache
357- // is safe.
358- cache = innerCache ;
359- }
360372 }
361373
362374 /**
@@ -388,7 +400,7 @@ public URI getUri() {
388400 @ Override
389401 public Path resolvePath (final Path f ) throws IOException {
390402 final InodeTree .ResolveResult <FileSystem > res ;
391- res = fsState .resolve (getUriPath (f ), true );
403+ res = fsState .resolve (getUriPath (f ), true );
392404 if (res .isInternalDir ()) {
393405 return f ;
394406 }
@@ -908,10 +920,35 @@ public void removeXAttr(Path path, String name) throws IOException {
908920 public void setVerifyChecksum (final boolean verifyChecksum ) {
909921 List <InodeTree .MountPoint <FileSystem >> mountPoints =
910922 fsState .getMountPoints ();
923+ Map <String , FileSystem > fsMap = initializeMountedFileSystems (mountPoints );
911924 for (InodeTree .MountPoint <FileSystem > mount : mountPoints ) {
912- mount .target . targetFileSystem .setVerifyChecksum (verifyChecksum );
925+ fsMap . get ( mount .src ) .setVerifyChecksum (verifyChecksum );
913926 }
914927 }
928+
929+ /**
930+ * Initialize the target filesystem for all mount points.
931+ * @param mountPoints The mount points
932+ * @return Mapping of mount point and the initialized target filesystems
933+ * @throws RuntimeException when the target file system cannot be initialized
934+ */
935+ private Map <String , FileSystem > initializeMountedFileSystems (
936+ List <InodeTree .MountPoint <FileSystem >> mountPoints ) {
937+ FileSystem fs = null ;
938+ Map <String , FileSystem > fsMap = new HashMap <>(mountPoints .size ());
939+ for (InodeTree .MountPoint <FileSystem > mount : mountPoints ) {
940+ try {
941+ fs = mount .target .getTargetFileSystem ();
942+ fsMap .put (mount .src , fs );
943+ } catch (IOException ex ) {
944+ String errMsg = "Not able to initialize FileSystem for mount path " +
945+ mount .src + " with exception " + ex ;
946+ LOG .error (errMsg );
947+ throw new RuntimeException (errMsg , ex );
948+ }
949+ }
950+ return fsMap ;
951+ }
915952
916953 @ Override
917954 public long getDefaultBlockSize () {
@@ -936,6 +973,9 @@ public long getDefaultBlockSize(Path f) {
936973 return res .targetFileSystem .getDefaultBlockSize (res .remainingPath );
937974 } catch (FileNotFoundException e ) {
938975 throw new NotInMountpointException (f , "getDefaultBlockSize" );
976+ } catch (IOException e ) {
977+ throw new RuntimeException ("Not able to initialize fs in "
978+ + " getDefaultBlockSize for path " + f + " with exception" , e );
939979 }
940980 }
941981
@@ -947,6 +987,9 @@ public short getDefaultReplication(Path f) {
947987 return res .targetFileSystem .getDefaultReplication (res .remainingPath );
948988 } catch (FileNotFoundException e ) {
949989 throw new NotInMountpointException (f , "getDefaultReplication" );
990+ } catch (IOException e ) {
991+ throw new RuntimeException ("Not able to initialize fs in "
992+ + " getDefaultReplication for path " + f + " with exception" , e );
950993 }
951994 }
952995
@@ -979,25 +1022,33 @@ public QuotaUsage getQuotaUsage(Path f) throws IOException {
9791022 public void setWriteChecksum (final boolean writeChecksum ) {
9801023 List <InodeTree .MountPoint <FileSystem >> mountPoints =
9811024 fsState .getMountPoints ();
1025+ Map <String , FileSystem > fsMap = initializeMountedFileSystems (mountPoints );
9821026 for (InodeTree .MountPoint <FileSystem > mount : mountPoints ) {
983- mount .target . targetFileSystem .setWriteChecksum (writeChecksum );
1027+ fsMap . get ( mount .src ) .setWriteChecksum (writeChecksum );
9841028 }
9851029 }
9861030
9871031 @ Override
9881032 public FileSystem [] getChildFileSystems () {
9891033 List <InodeTree .MountPoint <FileSystem >> mountPoints =
9901034 fsState .getMountPoints ();
1035+ Map <String , FileSystem > fsMap = initializeMountedFileSystems (mountPoints );
9911036 Set <FileSystem > children = new HashSet <FileSystem >();
9921037 for (InodeTree .MountPoint <FileSystem > mountPoint : mountPoints ) {
993- FileSystem targetFs = mountPoint .target . targetFileSystem ;
1038+ FileSystem targetFs = fsMap . get ( mountPoint .src ) ;
9941039 children .addAll (Arrays .asList (targetFs .getChildFileSystems ()));
9951040 }
9961041
997- if (fsState .isRootInternalDir () && fsState .getRootFallbackLink () != null ) {
998- children .addAll (Arrays .asList (
999- fsState .getRootFallbackLink ().targetFileSystem
1000- .getChildFileSystems ()));
1042+ try {
1043+ if (fsState .isRootInternalDir () &&
1044+ fsState .getRootFallbackLink () != null ) {
1045+ children .addAll (Arrays .asList (
1046+ fsState .getRootFallbackLink ().getTargetFileSystem ()
1047+ .getChildFileSystems ()));
1048+ }
1049+ } catch (IOException ex ) {
1050+ LOG .error ("Could not add child filesystems for source path "
1051+ + fsState .getRootFallbackLink ().fullPath + " with exception " + ex );
10011052 }
10021053 return children .toArray (new FileSystem []{});
10031054 }
0 commit comments