Richard W.M. Jones
2022-Aug-17 21:37 UTC
[Libguestfs] [PATCH nbdkit 2/2] file: Allow a file descriptor to be passed to the plugin
On Wed, Aug 17, 2022 at 03:57:24PM -0500, Eric Blake wrote:> On Wed, Aug 17, 2022 at 04:38:11PM +0100, Richard W.M. Jones wrote: > > This allows you to pass in a file descriptor to the plugin, eg: > > > > $ exec 6<>/var/tmp/fedora-36.img > > $ ./nbdkit file fd=6 --run 'nbdinfo $uri' > > > > Note this was previously possible on most platforms using /dev/fd/<N>, > > but not all platforms that have file descriptors support this > > (although it is POSIX) and it seems better to make this explicit. > > The parenthetical feels odd here. /dev/fd/<N> is not POSIX; what IS a > POSIX feature is the ability to pass an open file descriptor by > inheritance.Will fix.> > @@ -202,6 +208,17 @@ file_config (const char *key, const char *value) > > if (!directory) > > return -1; > > } > > + else if (strcmp (key, "fd") == 0) { > > + if (mode != mode_none) goto wrong_mode; > > + mode = mode_filedesc; > > + assert (filedesc == -1); > > + if (nbdkit_parse_int ("fd", value, &filedesc) == -1) > > + return -1; > > + if (filedesc <= 2) { > > + nbdkit_error ("file descriptor must be >= 3"); > > Is it worth using STDERR_FILENO instead of open-coding 2? I'll be okay > if your answer is that this is one place where <unistd.h> has too much > indirection ;)Will fix.> > @@ -408,59 +436,69 @@ file_open (int readonly) > ... > > + case mode_filedesc: > > + h->fd = dup (filedesc); > > + if (h->fd == -1) { > > + nbdkit_error ("dup fd=%d: %m", filedesc); > > + free (h); > > + return NULL; > > + } > > + file = "<file descriptor>"; /* This is needed for error messages. */ > > + break; > > Is it worth trying to figure out if the FD has O_RDWR privileges and > set h->can_write accordingly, to match...Is that actually possible? ?fcntl (fd, F_GETFL) & O_WRONLY? should do it?> > default: abort (); > > } > > > > - h = malloc (sizeof *h); > > - if (h == NULL) { > > - nbdkit_error ("malloc: %m"); > > - if (dfd != -1) > > - close (dfd); > > - return NULL; > > - } > > - > > - flags = O_CLOEXEC|O_NOCTTY; > > - if (readonly) { > > - flags |= O_RDONLY; > > - h->can_write = false; > > - } > > - else { > > - flags |= O_RDWR; > > - h->can_write = true; > > - } > > - > > - h->fd = openat (dfd, file, flags); > > - if (h->fd == -1 && !readonly) { > > - nbdkit_debug ("open O_RDWR failed, falling back to read-only: %s: %m", > > - file); > > - flags = (flags & ~O_ACCMODE) | O_RDONLY; > > - h->fd = openat (dfd, file, flags); > > - h->can_write = false; > > - } > > ... what we do for normal files? > > Overall looks like a nice addition. > > ACK seriesI also want to add dirfd= similarly for directory FDs (seems better to be explicit rather than overloading fd= and distinguishing through stat?) Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Richard W.M. Jones
2022-Aug-17 21:56 UTC
[Libguestfs] [PATCH nbdkit 2/2] file: Allow a file descriptor to be passed to the plugin
On Wed, Aug 17, 2022 at 10:37:00PM +0100, Richard W.M. Jones wrote:> Is that actually possible? ?fcntl (fd, F_GETFL) & O_WRONLY? > should do it?So the answer is no as it's a kind of tri-state. I think this should work (untested)? r = fcntl (fd, F_GETFL); if (r == -1) ... r &= O_ACCMODE; if (r == O_RDONLY) h->can_write = false; There's also the case where r == O_WRONLY which the plugin (and NBD) cannot deal with. Not sure what to do about that - error? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org