1 2 Previous Next 18 Replies Latest reply on Jun 26, 2010 9:01 AM by Marko Strukelj

    VFS3 and symlinks

    Ales Justin Master
      Me:

      Symlinks also don't work with VFS3 -- see added SymlinkTestCase test.

      JohnB:

      I think the problem here is how the mounting is happening.  Your test is mounting the EARs/JARs using the canonical path.  So they are showing up in the VFS with the full non-symlinked path.  Then when you test the URL you are providing the path with a symlink.  It won't work is this mixed style as they are separate paths in the VFS.  If you mount the EAR given the symlinked path, the test works fine as the path is used in the VFS and you can then continue to use the symlinked path from then on.

      The question is....  Do we want to support the notion that they are always the same?   I don't think so.  I think if you provide the canonical path at mount time, that is what is mounted.  If you provide the path with a symlink, that is what is mounted.  Otherwise we would have to force it to the canonical path every time, or create mount the same filesystem at multiple mount points.

      Thoughts?

        • 1. Re: VFS3 and symlinks
          Ales Justin Master

          * https://jira.jboss.org/jira/browse/JBVFS-138

          The question is....  Do we want to support the notion that they are always the same?   I don't think so.  I think if you provide the canonical path at mount time, that is what is mounted.  If you provide the path with a symlink, that is what is mounted.  Otherwise we would have to force it to the canonical path every time, or create mount the same filesystem at multiple mount points.

          Afais, the fix is simple, simply try to convert every path in VFS::getChild(String path) to canonical path.

          I would just put a flag, which would be false by default, if we should really do this for every invocation.

           

          I hacked this already. :-)

          But if there is a better way to do this, or if I missed some use case, feel free to fix it.

          • 2. Re: VFS3 and symlinks
            David Lloyd Master
            Just want to say that if this is the correct fix, it should not be optional.  No point in allowing configurations which aren't valid.
            • 3. Re: VFS3 and symlinks
              Ales Justin Master
              Just want to say that if this is the correct fix, it should not be optional.

              I don't see any other way of fixing this -- force all paths to be canonical.

               

              But I would expect that this call is not cheap, asking the underlying FS for canonical path.

              And since 99% of users are not using symlinks (at least that's what I would expect), making this force optional makes sense.

              No point in allowing configurations which aren't valid.


              I don't get this.

               

              Unfortunately I think the problem is even bigger than just VFS::getChild.

              My guess is that even calls to VirtualFile::getChild are due to fail with symlinked path?

              • 4. Re: VFS3 and symlinks
                John Bailey Novice

                I agree that having it force canonical every time would be a bit expensive for something that will occur somewhat infrequently.  I have however seen symlinks used in large infrastructures in the past.

                 

                What I question is why we need to force it.  As long as all accesses to the file via URL use the same path (either symlinked or canonical), I don't think there is a problem.  The problem that existed in VFS2 with AS5 was specific to the way the URL was being manipulated when the VFS cache was creating permanent roots.  I don't think the same problem would exist in the current VFS3 setup.

                 

                What is being tested in the VFS symlink test does not seem like a real world test to me.  Since there would be no reason for someone to create the URL expecting the inner archive to be a valid path to use as it doesn't exist on the filesystem unless they are using the VFS.  I could only see them getting that URL through the VFS in some way and then manipulating it after.

                 

                The reason I fail to see this scenario happening in real life is there is an assumption someone is going to take a URL from a VirtualFile from within a zip filesystem and turn it into a File object to then get the canonical file.  This will already not work for zip filesystems as the initial File does not actually exist. on the real filesystem whether symlinked or not.  The other option is someone has to take a URL run through a process to convert it to a canonical URL and then use that for mounting, and then later on someone is going to ask for files using the symlinked URL.  I can't see any reason for symlinked URLs to just be magiced up later in the execution.

                 

                I am sure I am missing something, but it seems like as long as nothing within AS takes URLs and manipulates them to get the canonical URL we should be fine.  But maybe just to be sure we need to come up with some kind of solution.

                • 5. Re: VFS3 and symlinks
                  John Bailey Novice

                  Upon further thought I guess it could be possible for someone to feed the canonical File/URL in through the profileservice or admin console, which could then cause issues as it would not match the deployment URL.

                   

                  So maybe we need something.

                  • 6. Re: VFS3 and symlinks
                    Scott Stark Master
                    I don't expect that non-vfs urls to inner paths will be used by any interface as input. You will only upload the top-level deployment, not any of its internals.
                    • 7. Re: VFS3 and symlinks
                      Ales Justin Master

                      Upon further thought I guess it could be possible for someone to feed the canonical File/URL in through the profileservice or admin console, which could then cause issues as it would not match the deployment URL.

                       

                      So maybe we need something.

                      I might be too "paranoid" and I agree the test doesn't really show the real-life use case.

                      But like you said, we might need something or at least be ready if it turns out there is a valid need for this.


                      Another (extreme) scenario I have in mind is the following use case.

                      Let's say we already mounted stuff for canonical paths.

                      But a user doesn't know about the real path (as it's ugly, hard to remember, ...), but he does know the nice symlinks.

                      And he tries to use that one to navigate through his resources -- resulting in a failure, as we only know the canonical path.

                       

                      This one is quite ugly to get right, as we would probably always have to re-create the full path,

                      transform it into canonical, and only then get the child.

                      Doubt it's worth doing this -- ugly and slow code. No need to repeat some of the mistakes from VFS2. :-)

                      • 8. Re: VFS3 and symlinks
                        David Lloyd Master

                        One option could be to simply "punt", as the Perl guys say, and wait for Java 7 to solve this, which contains a much-improved filesystem API.  This would open up a lot of options, like being able to possibly install VFS as the "real" file handler, or at the very least, be able to identify and read symlinks so as to avoid the problem that way without the expensive canonicalization of every file name.

                         

                        Just a thought

                        • 9. Re: VFS3 and symlinks
                          John Bailey Novice

                          Another possible solution (that I have not proven or even finished thinking about) is to detect a symlinked path at mount time and mount in both the symlinked path and the canonical path.  You wouldn't really need to mount multiple filesystems, as it would really be the same filesystem mounted in multiple locations in the VFS.  This would allow either path to be used from that point forward and both paths would resolve to the same filesysem entries. There would be no need to perform excessive getCanonicalFile calls once the mount has occurred.

                           

                          Some things to think about:

                           

                          1.  This only works if the mount occurs from the symlinked path however

                          2.  It would need to make sure the canonical path is not currently mounted with another filesystem

                          3.  Unmounting would need to remove both

                           

                           

                          Just a thought.

                          • 10. Re: VFS3 and symlinks
                            John Bailey Novice

                            After discussing with Jason on IRC, it seems any behavior related to symbolic link support would really have to rely in the FileSystem instances.  The FileSystem instances may need to support symbolic links in different ways, or not at all.  Handling symbolic links in the VFS or VirtualFile classes would break certain functionality allowing FileSystems to be mounted at any path.

                             

                            Ex.

                              RealPath --> /real/path/to/archive.jar

                              SymLinkedPath --> /link/to/archive.jar  ('link' is symlink to /real/path)

                             

                            If you mount mount any FileSystem (maybe real, zip, assembled ...) at '/link' in the VFS, regardless of if it has anything to do with 'archive.jar', it would not be possible to get to  the contents of the FileSystem if you force paths to be canonical in the VFS or VirtualFile layer.  It would take the VFS path and convert it to the canonical path, and never get to the mounted FileSystem.  In essence, the FileSystem does not exist in the VFS.

                             

                            What would make sense is if you asked a RealFileSystem for a specific path and it does the JDK File based canonical path conversion automatically.  There may not necessarily be any other FileSystem that supports it, but there is nothing stopping a specific FileSystem from adding support.

                             

                            So I think it just makes sense to make sure we aren't switching between path types, and just leave it to the FileSystems to support it.

                            • 11. Re: VFS3 and symlinks
                              Jason Greene Master

                              johnbailey wrote:

                               

                              After discussing with Jason on IRC, it seems any behavior related to symbolic link support would really have to rely in the FileSystem instances.  The FileSystem instances may need to support symbolic links in different ways, or not at all.  Handling symbolic links in the VFS or VirtualFile classes would break certain functionality allowing FileSystems to be mounted at any path.

                               

                              Ex.

                                RealPath --> /real/path/to/archive.jar

                                SymLinkedPath --> /link/to/archive.jar  ('link' is symlink to /real/path)

                               

                              If you mount mount any FileSystem (maybe real, zip, assembled ...) at '/link' in the VFS, regardless of if it has anything to do with 'archive.jar', it would not be possible to get to  the contents of the FileSystem if you force paths to be canonical in the VFS or VirtualFile layer.  It would take the VFS path and convert it to the canonical path, and never get to the mounted FileSystem.  In essence, the FileSystem does not exist in the VFS.

                               

                              What would make sense is if you asked a RealFileSystem for a specific path and it does the JDK File based canonical path conversion automatically.  There may not necessarily be any other FileSystem that supports it, but there is nothing stopping a specific FileSystem from adding support.

                               

                              So I think it just makes sense to make sure we aren't switching between path types, and just leave it to the FileSystems to support it.

                              Where symlinks on vfs really break down is relative paths. If you have a symlink in a mount's root that points to "../sibling.jar", then it should refer to the parent of the mount in VFS. Unfortunately we don't know what a symlink points to since java doesn't know. If we could, however, read the link (say via an lstat call), it would be possible to canonicalize them correctly. We could bundle a JNI module that would allow for RealFileSystem to pull the link info, however, that would be a big effort for an uncommon feature. IMO we should wait to see if there is demand for it, and add it later.

                              • 12. Re: VFS3 and symlinks
                                Rainer Meier Newbie

                                I am facing the same problem here and this thread seems to describe the source of my problems but it also seems that people lost interest in the discussion. Does anybody know the status of these VFS3 issues? Any fix available?

                                 

                                Currently I am running a stand-alone JBoss instance installed at /opt/jboss/5.1.0/. We run an application which installs itself to /opt/app/4.0/server/app (the complete JBoss configuration is deployed there). So the instlalation package creates a symlink:

                                /opt/jboss/5.1.0/server/app -> /opt/app/current/server/app

                                 

                                Note: That /opt/app/current is a symlink on its own pointing to the current app version, currently current points to the 4.0 folder at the same level:

                                /opt/app/current -> 4.0

                                 

                                Then JBoss is launched with the "-c app" parameter.

                                 

                                After about 1 hour the tmp/vfs-nested.tmp/ folder is starting to grow until it fills up the whole disk (>100GB).

                                 

                                I've tried a couple of settings. For example I've tried to extend vfs.xml to include the canonical URLs as well:

                                 

                                 

                                {code:xml}

                                        <entry>

                                           <key>file:/opt/app/4.0/server/app/deploy</key>

                                           <value><inject  bean="VfsNamesExceptionHandler"/></value>

                                         </entry>

                                        <entry>

                                           <key>file:/opt/app/4.0/server/app/farm</key>

                                           <value><inject  bean="VfsNamesExceptionHandler"/></value>

                                         </entry>

                                        <entry>

                                           <key>file:/opt/app/current/server/app/deploy</key>

                                           <value><inject  bean="VfsNamesExceptionHandler"/></value>

                                         </entry>

                                        <entry>

                                           <key>file:/opt/app/current/server/app/farm</key>

                                           <value><inject  bean="VfsNamesExceptionHandler"/></value>

                                         </entry>

                                {code}

                                 

                                But it did not help at all.

                                 

                                I also tried to play with JBoss properties to have it pointing directly to the physical server configuration directory by appending

                                "-Djboss.server.base.dir='/opt/app/current/server/' -Djboss.server.base.url='file:/opt/app/current/server/'

                                to the sartup options. This makes JBoss read the configuration directly from /opt/app/current/server but still no go, tmp/vfs-nested.tmp/ is still growing after a while.

                                 

                                Does anybody have any hints what I have to configure to make VFS work as expected in this situation?

                                 

                                Copying the whole /opt/app/current/server/app folder to /opt/jboss/5.1.0/server/ works as expected, so it's not an application issue. However the package of this application will maintain the files at /opt/app and therefore a simple symlink would be much easier from maintenance point of view. If the whole application needs to be copied it will have to be duplicated after each package/patch installation.

                                • 13. Re: VFS3 and symlinks
                                  Ales Justin Master
                                  Does anybody have any hints what I have to configure to make VFS work as expected in this situation?

                                  You can update the AS5.1's VFS to 2.2.0.GA and use the -Djboss.vfs.forceCanonical=true.

                                  • 14. Re: VFS3 and symlinks
                                    Rainer Meier Newbie

                                    {quote}You can update the AS5.1's VFS to 2.2.0.GA and use the  -Djboss.vfs.forceCanonical=true.{quote}

                                     

                                    Thanks a lot for the hint.

                                    If I understand correctly this also means that I will have to insret canonical paths to vfs.xml like this:

                                     

                                    {code:xml}

                                    <entry>
                                      <key>file:/opt/app/4.0/server/app/deploy</key>
                                      <value><inject bean="VfsNamesExceptionHandler"/></value>
                                    </entry>

                                    <entry>
                                      <key>file:/opt/app/4.0/server/app/farm</key>
                                      <value><inject bean="VfsNamesExceptionHandler"/></value>
                                    </entry>
                                    {code}

                                     

                                    "Unfortunately" the app is also relocatable so providing absolute paths within vfs.xml is not a good idea during deployment since the app might also be installed at /opt/xy/app or /usr/local/app or somewhere else.

                                     

                                    I just tried to use the default notation in vfs.xml:

                                     

                                    {code:xml}

                                            <entry>

                                              <key>${jboss.server.home.url}deploy</key>

                                              <value><inject bean="VfsNamesExceptionHandler"/></value>

                                            </entry>

                                            <entry>

                                              <key>${jboss.server.home.url}farm</key>

                                              <value><inject bean="VfsNamesExceptionHandler"/></value>

                                            </entry>

                                    {code}

                                     

                                    But after 1 hour it started to grow again. So it seems that jboss.server.home.url is probably not expanded as a canonical path and therefore it does not match. Is this a bug or am I just misunderstanding the functionality here?

                                    1 2 Previous Next