forkables: About hardlink creation and NTFS transaction in rename()

Corinna Vinschen corinna-cygwin@cygwin.com
Wed Nov 30 12:17:00 GMT 2016


On Nov 29 14:47, Michael Haubenwallner wrote:
> On 11/21/2016 04:19 PM, Michael Haubenwallner wrote:
> > Hi Corinna,
> > 
> > now working with the cygfork patches (hardlinks to retain forkability
> > beyond exe/dll update): when creating the forkable hardlink using the
> > earlier opened file handle I may get STATUS_TRANSACTION_NOT_ACTIVE.
> > 
> > It turns out that when loaded 'some.dll' was readonly, then
> > rename("new/some.dll", "some.dll") uses an NTFS-transaction to drop
> > the readonly attribute, breaking the subsequent hardlink creation
> > of "/var/run/cygfork/.../soname.dll" via the original file handle.
> 
> It turns out that when NTFS transactions are involved with the dll,
> creating a hardlink requires the FILE_WRITE_ATTRIBUTES access.
> 
> Strange enough, this also applies when the file handle used to create
> the hardlink is opened _after_ the rename transaction has finished.
> 
> On the other hand, opening the file handle with FILE_WRITE_ATTRIBUTES
> access _before_ the rename(), the transactional unlink_nt fails with
> STATUS_TRANSACTIONAL_CONFLICT.

I wonder how Microsoft implemented NTFS transactions.  Something
seems a little bit off here.

> > Now I can see these options:
> > * As using NTFS transactions seems not to be recommended any more,
> >   might we drop the NTFS transaction from rename() and _unlink_nt ()?
> > * Or do I need to create an NTFS-transaction in dll_list::alloc()
> >   when opening the original dll file handle?
> 
> some more now:
> 
> * Just for creating the hardlink open the file by id, determined
>   in dll_list::alloc(), with immediately closing the file handle.
>   However, I've not managed yet to open a file by id...

  You need a handle to some file on the same file system to identify
  the file system.  Let's say the handle is called vol_hdl.  Then:

  path_conv pc ("my.dll");
  OBJECT_ATTRIBUTES attr;
  IO_STATUS_BLOCK io;
  NTSTATUS status;

  LARGE_INTEGER &file_id = pc.fai ()->InternalInformation.IndexNumber;
  UNICODE_STRING ufid = { sizeof file_id, sizeof file_id, (PWSTR) &file_id };
  InitializeObjectAttributes (&attr, &ufid, pc.objcaseinsensitive (),
			      vol_hdl, NULL);
  status = NtOpenFile (&hdl, access, &attr, &io, share_flags, options);


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-developers/attachments/20161130/42317500/attachment.sig>


More information about the Cygwin-developers mailing list