Skip to content

Unable to Copy/Create file on NFS share on macOS #72786

Closed

Description

@mikkeljohnsen

Description

dotnet on macOS is not able to copy files to a NFS share.

The NFS share is working perfectly from "Terminal" and "Finder", files can be created/copied and deleted all works.

But from a dotnet (Net6) application I get "UnauthorizedAccess", when writing. Read is working fine.

Reproduction Steps

Setup NFS share on Linux

/etc/exports

/files	*(fsid=1,crossmnt,rw,insecure,all_squash,async,no_subtree_check,anonuid=99,anongid=99)

Mount on macOS from Finder "nfs://servername/files" will mount on "/Volumes/files"

Terminal and Finder can read and write.

Expected behavior

Should be able to create directory and copy files

Actual behavior

Type: System.UnauthorizedAccessException
Message: Access to the path '/Volumes/files/p10001-20000/p13001-14000/p13101-13200/13156/70487.pdf' is denied.

   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Interop.CheckIo(Error error, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
   at System.IO.File.Create(String path)
   at OpenMedicus.IO.Files.CopyFileAsync(DbConnection conn, DbTransaction t, String sourceFile, String description, Int32 patientId, Int32 accountId, Boolean isHidden, IProgress`1 progress, Int32 count, Int32 index, CancellationToken token) in /XMedicus/libxcarefiles/Files.cs:line 180
   at OpenMedicus.IO.Files.CopyFileAsync(String[] files, String description, Int32 patientId, Int32 accountId, Boolean isHidden, IProgress`1 progress, CancellationToken token) in /XMedicus/libxcarefiles/Files.cs:line 109
   at OpenMedicus.IO.FileManager.CopyFileAsync(String[] files, String destpath, Int32 patientId, Int32 accountId, Boolean isHidden, IProgress`1 progress, CancellationToken token) in /XMedicus/libxcarefiles/Manager.cs:line 163
   at OpenMedicus.Journal.Summary.CopyFilesAsync(FileManager fm, List`1 files, Int32 episodeId, String desc, List`1 tags) in /XMedicus/components/summary/Summary.cs:line 800
   at OpenMedicus.Journal.Summary.AttachFilesAsync(List`1 files, String description) in /XMedicus/components/summary/Summary.cs:line 917

Regression?

Not sure if it has been working before. (On Mono it worked).

Known Workarounds

None

Configuration

dotnet version: 6.0.6
macOS: Catalina

Other information

No response

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Jul 25, 2022
  2. danmoseley commented on Jul 25, 2022

    @danmoseley
    Contributor

    Thanks for the report. It would be interesting to compare IO traces to when this is done successfully (eg in the shell). On Linux one would use strace. I don't have access to a Mac but I believe it has something similar called dtrace?

  3. jozkee commented on Jul 25, 2022

    @jozkee
    Member

    It works on my macbook using the three ways you mentioned (finder, terminal, and .NET app).

    This is my sudo exportfs -v on my Ubuntu NFS server:

    /srv/nfs4/home  <world>(rw,wdelay,crossmnt,insecure,root_squash,no_subtree_check,sec=sys,rw,insecure,root_squash,no_all_squash)
    /srv/nfs4       <world>(rw,wdelay,crossmnt,root_squash,no_subtree_check,fsid=0,sec=sys,rw,secure,root_squash,no_all_squash)
    

    I also did a chmod 777 /srv/nfs4/home to allow the the client to write to the shared folder.

    I'm not sure what might be different on your mac. Perhaps you could share the strace that @danmoseley mentioned (it's called dtruss on macos).

  4. added this to the Future milestone on Jul 25, 2022
  5. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Jul 25, 2022
  6. added
    untriagedNew issue has not been triaged by the area owner
    needs-author-actionAn issue or pull request that requires more info or actions from the author.
    on Jul 25, 2022
  7. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Jul 25, 2022
  8. mikkeljohnsen commented on Jul 26, 2022

    @mikkeljohnsen
    Author
    ...
    select(0x39, 0x7FFEECD066D0, 0x7FFEECD06650, 0x7FFEECD065D0, 0x7FFEECD06750)		 = 0 0
    select(0x39, 0x7FFEECD066D0, 0x7FFEECD06650, 0x7FFEECD065D0, 0x7FFEECD06750)		 = 0 0
    select(0x39, 0x7FFEECD066D0, 0x7FFEECD06650, 0x7FFEECD065D0, 0x7FFEECD06750)		 = 0 0
    select(0x39, 0x7FFEECD066D0, 0x7FFEECD06650, 0x7FFEECD065D0, 0x7FFEECD06750)		 = 0 0
    workq_kernreturn(0x100, 0x70000E82AB80, 0x1)		 = 0 -2
    bsdthread_ctl(0x100, 0x0, 0x21573)		 = 0 ?P???0
    bsdthread_ctl(0x100, 0x0, 0x0)		 = 0 0
    stat64("/Volumes/files/p10001-20000/p13001-14000/p13101-13200/13156/\0", 0x7FFEECD05960, 0x0)		 = 0 0
    open("/Users/anja/Downloads/BekraeftelseFraTDC.pdf\0", 0x1000000, 0x1B6)		 = 327 0
    fstat64(0x147, 0x7FFEECD05980, 0x0)		 = 0 0
    flock(0x147, 0x5, 0x0)		 = 0 0
    open("/Volumes/files/p10001-20000/p13001-14000/p13101-13200/13156/70493.pdf\0", 0x1000202, 0x1B6)		 = -1 1
    psynch_cvsignal(0x7FDD962B2278, 0x100, 0x0)		 = 257 0
    flock(0x147, 0x8, 0x0)		 = 0 0
    close(0x147)		 = 0 0
    sendto(0x67, 0x1835D5CB8, 0xE)		 = 14 0
    recvmsg(0x67, 0x7FFEECD00DF0, 0x0)		 = -1 35
    gettimeofday(0x7FFEECD007E8, 0x0, 0x0)		 = 0 0
    psynch_cvwait(0x7FDD962B2278, 0x100000100, 0x0)		 = 0 0
    gettimeofday(0x70000ED08A18, 0x0, 0x0)		 = 0 0
    kevent(0x68, 0x0, 0x0)		 = 2 0
    psynch_cvsignal(0x7FDD9680EA78, 0x1560000015700, 0x15500)		 = 257 0
    psynch_cvwait(0x7FDD9680EA78, 0x1560100015700, 0x15500)		 = 0 read0
    psynch_cvsignal(0x7FDD969A8278, 0x260000002700, 0x2600)		 = 257 0
    recvmsg(0x67, 0x7FFEECD00C80, 0x0)		 = 20 0
    dtrace: error on enabled probe ID 2252 (ID 167: syscall::write:return): invalid kernel access in action #12 at DIF offset 68
    dtrace: error on enabled probe ID 2252 (ID 167: syscall::write:return): invalid kernel access in action #12 at DIF offset 68
    psynch_cvwait(0x7FDD969A8278, 0x260100002700, 0x2600)		 = 0 0
    psynch_cvsignal(0x7FDD96217878, 0x310000003200, 0x3100)		 = 257 0
    psynch_cvsignal(0x7FDD958E1E78, 0x5E0000005F00, 0x5E00)		 = 257 0
    psynch_cvsignal(0x7FDD968D9478, 0x1F0000002000, 0x1F00)		 = 257 0
    dtrace: error on enabled probe ID 2252 (ID 167: syscall::write:return): invalid kernel access in action #12 at DIF offset 68
    psynch_cvwait(0x7FDD96217878, 0x310100003200, 0x3100)		 = 0 0
    psynch_cvwait(0x7FDD958E1E78, 0x5E0100005F00, 0x5E00)		 = 0 0
    psynch_cvwait(0x7FDD968D9478, 0x1F0100002000, 0x1F00)		 = 0 0
    ...
    
  9. ghost added
    needs-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration
    on Jul 26, 2022
  10. ghost removed
    needs-author-actionAn issue or pull request that requires more info or actions from the author.
    on Jul 26, 2022
  11. mikkeljohnsen commented on Jul 26, 2022

    @mikkeljohnsen
    Author

    @jozkee Could you try using this code:

    			var sourceUri = new Uri(sourceFile);
    			var destUri = new Uri(destFile);
    
    			byte[] buffer = new byte[BufferSize];
    
    			using (FileStream sourceStream = File.OpenRead(sourceUri.LocalPath))
    			{
    				using (FileStream destinationStream = File.Create(destUri.LocalPath))
    				{
    					long remaining = sourceStream.Length;
    
    					while (remaining > 0)
    					{
    						int read = await sourceStream.ReadAsync(buffer, 0, BufferSize, token);
    						if (token.IsCancellationRequested) return 0;
    
    						if (read <= 0)
    							throw new EndOfStreamException();
    
    						await destinationStream.WriteAsync(buffer, 0, read, token);
    						if (token.IsCancellationRequested) return 0;
    
    						remaining -= read;
    
    						total += read;
    
    						//progress?.Report(total);
    					}
    				}
    			}
    
  12. adamsitnik commented on Aug 17, 2022

    @adamsitnik
    Member

    But from a dotnet (Net6) application I get "UnauthorizedAccess", when writing. Read is working fine.

    I am 99% sure that it's #55256. The problem is that the fix was tested only on Linux (as there were no macOS bug reports). We need to implement proper file system detection for apple (#69852) and most likely backport the change to 7.0 and 6.0 (it should not be hard; we should be able to reuse the freebsd implementation)

  13. modified the milestones: Future, 8.0.0 on Aug 17, 2022
  14. added and removed
    needs-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration
    on Aug 17, 2022
  15. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Aug 24, 2022
  16. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Aug 25, 2022
  17. ghost locked as resolved and limited conversation to collaborators on Sep 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions