On Sun, 26 Mar 2000, Jamie Lokier wrote:
> > That being the case, I'd rather that O_NONE just went away. I
> > am unconvinced of its worth anyway.
>
> Apparently it's used by fdformat and a few other small utils.
Presumably this is so that the floppy driver can check that nobody
expects to read or write the disk while a format is in progress?
If so, I accept the need for O_NONE.
> Well, nearly all the uses for O_DEFEROPEN seem to be the same as the
> uses of O_NONE. Being able to do safe fstat()s without opening the
> device, that sort of thing.
>
> The only difference is the current ioctl behaviour for O_NONE, and the
> fact that you can actually open an O_DEFEROPEN fd later.
But those features of O_DEFEROPEN are the only useful ones. Other
than posssibly in the future being able to say "give me a no-priv
fd to this object if I can read _or_ write it" I think that O_NONE
is useless for race-avoidance purposes.
Basically, I want it for things like tar. Currently, for files GNU
tar does:
lstat("./defines.h", {st_mode=S_IFREG|0664, st_size=318, ...}) = 0
open("./defines.h", O_RDONLY|O_LARGEFILE) = 6
read(6, "#define UTIL_LINUX_VERSION \"2.10"..., 318) = 318
fstat(6, {st_mode=S_IFREG|0664, st_size=318, ...}) = 0
close(6) = 0
which is fairly easily raceable if you make your directories big
enough. Make a link at the right time, and tar may well have
backed up /etc/shadow but thought that it was a file that you
owned.
This:
open(path, O_RDONLY|O_DEFEROPEN) = 6
fstat(6, ...) = 0
fcntl(6, F_REALLYOPEN) = 0
read(6, ..., N) = M
close(6) = 0
is safe (though we do need O_SYMLINK to complete the picture).
Does anyone know if/how *BSD deal with this? I can't find anything
but GNU tar under their cvsweb services.
> But your deferred open could be made properly generic: Define F_REOPEN
> to mean reopen this fd's object with new flags. It needn't be
> specific to O_DEFEROPEN, and probably has a few uses. (Like just
> being able to dup a file without sharing the file pointer and locks).
I'd rather that was an _fdopen(fd, opts) than an fcntl. But it does
look useful.
> For the fstat() and fs-specific ioctl() type of thing, the current
> ioctl behaviour for O_NONE isn't really right. For for fdformat it is
> right.
Yep.
> Your O_DEFEROPEN actually seems like the right thing in many cases,
> like when you want to open a device file prior to fstat(), and you
> don't really want to open the device.
Yep. I just don't understand your desire to combine the two.
> Neither the current O_NONE nor O_DEFEROPEN implement another useful
> case: provide an fd you can use fs-flag-setting ioctls on. E.g.
> that's why you can't do chattr +i /dev/*.
I think that this is a separate issue. Last time it was discussed,
the consensus seemed to be that dealing with flags via ioctl() is
horrible and should probably stop.
I think Linus wanted:
int fflags(int fd, flagset * set, flagset * get);
plus something like O_SYMLINK to allow flags on symlinks too. I
assume that it's waiting on some other VFS work.
> It would be nice to provide all the useful facilities in the simplest
> possible way. I think making O_NONE not open underlying devices but
> to permit fs ioctls which could in principle be filename based anyway,
> and F_REOPEN, gets very close to that. fdformat is solved by simply
> providing an alternate device to open -- it works for not rewinding
> tapes so there is a precedent.
I disagree. Some filesystems (network filesystems especially) will
need to have their own open routine called before flags are available.
My intent with O_DEFEROPEN was to permit a race-proof way to do what
could otherwise be done with pathnames. The other facilities that
you suggest seem useful but still essentially separate.
Matthew.