All of lore.kernel.org
 help / color / mirror / Atom feed
* Errors from basic open_by_handle operations
@ 2015-04-09 12:53 Mark Hills
  2015-04-09 13:09 ` Roger Willcocks
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Mark Hills @ 2015-04-09 12:53 UTC (permalink / raw)
  To: xfs

I am having troubles with elementary file handle functions in libhandle.

A basic open_by_handle is giving "Bad file descriptor".

But I am suspicious of a side effect; using path_to_fshandle earlier in 
the program changes these errors to "Operation not permitted".

Is there a basic mistake in my use of these calls, or a bug/unmaintained 
code?

I am on an XFS filesystem (otherwise the first call fails with 
'inappropriate ioctl'). The only documentation I can find is the man page; 
no mention about initialising the library, and I wasn't able to find any 
examples.

I'm on Scientific Linux 6.6 (like RedHat 6, kernel 2.6.32-504.1.3), and 
also tried updating to the latest xfsprogs from Git, with the same 
results.

Many thanks

-- 
Mark


$ ./test-xfs ~/scratch/tmp/xfs/file.c; echo $?
Handle 24 bytes: bd2c94ba959858e0000000870000000
readlink_by_handle: Bad file descriptor
open_by_handle: Bad file descriptor
0


$ ./test-xfs ~/scratch/tmp/xfs/file.c; echo $?
Handle 8 bytes: bd2c94ba959858
Handle 24 bytes: bd2c94ba959858e0000000870000000
readlink_by_handle: Operation not permitted
open_by_handle: Operation not permitted
0


/*
 * xfs file handle test
 *
 * compile with: gcc -o test-xfs test-xfs.c -lhandle -Wall
 */

#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <xfs/handle.h>

static void dump(FILE *f, void *m, size_t len)
{
	fprintf(f, "Handle %zu bytes: ", len);

	while (len--) {
		fprintf(f, "%hhx", *(unsigned char*)m);
		m++;
	}

	putchar('\n');
}

int main(int argc, char *argv[])
{
	int fd;
	char *pathname;
	void *hanp = NULL;
	size_t hlen;
	char buf[PATH_MAX];

	pathname = argv[1];

#if 0
	/*
	 * Switching this section on changes changes the
	 * errors from the later calls
	 */

	if (path_to_fshandle(pathname, &hanp, &hlen) == -1) {
		perror("path_to_fshandle");
		return -1;
	}

	dump(stderr, hanp, hlen);

	free_handle(hanp, hlen);
#endif

	if (path_to_handle(pathname, &hanp, &hlen) == -1) {
		perror("path_to_handle");
		return -1;
	}

	dump(stderr, hanp, hlen);

        /*
	 * The above calls were successful, but the next part always
	 * fails
	 */

	if (readlink_by_handle(hanp, hlen, buf, sizeof buf) == -1)
		perror("readlink_by_handle");
	else
		printf("Link: %s\n", buf);

	fd = open_by_handle(hanp, hlen, O_RDONLY);
	if (fd == -1) {
		perror("open_by_handle");
	} else {
		if (close(fd) == -1)
			abort();
	}

	free_handle(hanp, hlen);

	return 0;
}

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Errors from basic open_by_handle operations
  2015-04-09 12:53 Errors from basic open_by_handle operations Mark Hills
@ 2015-04-09 13:09 ` Roger Willcocks
  2015-04-09 13:36   ` Mark Hills
  2015-04-09 13:27 ` Dave Chinner
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Roger Willcocks @ 2015-04-09 13:09 UTC (permalink / raw)
  To: Mark Hills; +Cc: xfs

There's a small gotcha - the filesystem itself has to have been opened:

        void *xfs_handle = 0;
        size_t hlen  = 0;

        /* xfs library needs the filesystem to have been opened */

        if (path_to_fshandle(mountpoint, &xfs_handle, &hlen) < 0) {
                /* error */
                exit(4);
        }

        free(xfs_handle);


On Thu, 2015-04-09 at 13:53 +0100, Mark Hills wrote:
> I am having troubles with elementary file handle functions in libhandle.
> 
> A basic open_by_handle is giving "Bad file descriptor".
> 
> But I am suspicious of a side effect; using path_to_fshandle earlier in 
> the program changes these errors to "Operation not permitted".
> 
> Is there a basic mistake in my use of these calls, or a bug/unmaintained 
> code?
> 
> I am on an XFS filesystem (otherwise the first call fails with 
> 'inappropriate ioctl'). The only documentation I can find is the man page; 
> no mention about initialising the library, and I wasn't able to find any 
> examples.
> 
> I'm on Scientific Linux 6.6 (like RedHat 6, kernel 2.6.32-504.1.3), and 
> also tried updating to the latest xfsprogs from Git, with the same 
> results.
> 
> Many thanks
> 
-- 
Roger Willcocks <roger@filmlight.ltd.uk>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Errors from basic open_by_handle operations
  2015-04-09 12:53 Errors from basic open_by_handle operations Mark Hills
  2015-04-09 13:09 ` Roger Willcocks
@ 2015-04-09 13:27 ` Dave Chinner
  2015-04-09 13:31 ` [PATCH] libhandle: document the need for path_to_handle tinguely
  2015-04-09 14:09 ` Errors from basic open_by_handle operations Roger Willcocks
  3 siblings, 0 replies; 8+ messages in thread
From: Dave Chinner @ 2015-04-09 13:27 UTC (permalink / raw)
  To: Mark Hills; +Cc: xfs

On Thu, Apr 09, 2015 at 01:53:31PM +0100, Mark Hills wrote:
> I am having troubles with elementary file handle functions in libhandle.
> 
> A basic open_by_handle is giving "Bad file descriptor".
> 
> But I am suspicious of a side effect; using path_to_fshandle earlier in 
> the program changes these errors to "Operation not permitted".

EPERM. Root permissions are required to convert file handles back to
file descriptors, as the handle could have been passed to anyone and
open_by_handle has no directory based access/permission checks to
determine if the user actually has permission to access the inode
behind the filehandle.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] libhandle: document the need for path_to_handle
  2015-04-09 12:53 Errors from basic open_by_handle operations Mark Hills
  2015-04-09 13:09 ` Roger Willcocks
  2015-04-09 13:27 ` Dave Chinner
@ 2015-04-09 13:31 ` tinguely
  2015-04-13  0:25   ` Dave Chinner
  2015-04-09 14:09 ` Errors from basic open_by_handle operations Roger Willcocks
  3 siblings, 1 reply; 8+ messages in thread
From: tinguely @ 2015-04-09 13:31 UTC (permalink / raw)
  To: xfs

[-- Attachment #1: libhandle-doc-need-for-path_to_handle.patch --]
[-- Type: text/plain, Size: 2687 bytes --]

The handle ioctls require an open file descriptor to
the XFS mount directory. This file descriptor is found
and supplied in the libhandle code by matching the
entry added with a path_to_handle() call. Document
the requirement and supply a simple example.

Signed-off-by: Mark Tinguely <tinguely@sgi.com>

---
 man/man3/handle.3 |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

Index: b/man/man3/handle.3
===================================================================
--- a/man/man3/handle.3
+++ b/man/man3/handle.3
@@ -74,6 +74,12 @@ The
 function returns the handle for the filesystem in which the object given by the
 .I path
 argument resides.
+.I path
+must be the path to the mount point or
+.BR open_by_handle ()
+will return the
+.B ENOTDIR
+error.
 .PP
 The
 .BR fd_to_handle ()
@@ -95,7 +101,16 @@ The
 function opens a file descriptor for the object referenced by a handle.
 It is analogous and identical to
 .BR open (2)
-with the exception of accepting handles instead of path names.
+with the exception of accepting handles instead of path names. The returned
+file descriptor is opened to do invisible IO. Internally,
+.BR open_by_handle ()
+uses the mount point file descriptor that was saved by
+.BR path_to_fshandle ().
+Therefore,
+.BR path_to_fshandle ().
+must be called before calling
+.BR open_by_handle ().
+See below for an example.
 .PP
 The
 .BR readlink_by_handle ()
@@ -192,6 +207,59 @@ does not exist.
 .TP
 .B EPERM
 The caller does not have sufficient privileges.
+.SH EXAMPLE
+Example of
+.BR open_by_handle ().
+.PP
+.Vb 1
+\& main()
+.br
+\& {
+.br
+\&	int fd;
+.br
+\&	size_t hlen;
+.br
+\&	void *han;
+.br
+\&	size_t sz_int_used;
+.br
+\&	void *hdl_int_used;
+.br
+\&	char *mount_path = "/mnt/";
+.br
+\&	char *file = "file_to_open";
+.br
+\&	if (path_to_handle(file, &han, &hlen) < 0) {
+.br
+\&		perror("path-to-handle");
+.br
+\&		exit(1);
+.br
+\&	}
+.br
+\&	/*
+.br
+\&	 * path_to_fshandle saves an internal copy of the mount point's
+.br
+\&	 * (/mnt in this example) file descriptor. The open_by_handle call
+.br
+\&	 * looks up this internal file descriptor and uses it in the
+.br
+\&	 * xfsctl call to the kernel. Once path_to_fshandle is called,
+.br
+\&	 * this internal file descriptor remains open for the remaining
+.br
+\&	 * life of the application.
+.br
+\&	 */
+.br
+\&	path_to_fshandle(mount_path, &hdl_int_used, &sz_int_used);
+.br
+\&	fd = open_by_handle(han, hlen, O_RDWR);
+.br
+\&}
+.Ve
 .SH SEE ALSO
 .BR open (2),
 .BR readlink (2),


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Errors from basic open_by_handle operations
  2015-04-09 13:09 ` Roger Willcocks
@ 2015-04-09 13:36   ` Mark Hills
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Hills @ 2015-04-09 13:36 UTC (permalink / raw)
  To: Roger Willcocks; +Cc: xfs

On Thu, 9 Apr 2015, Roger Willcocks wrote:

> There's a small gotcha - the filesystem itself has to have been opened:
> 
>         void *xfs_handle = 0;
>         size_t hlen  = 0;
> 
>         /* xfs library needs the filesystem to have been opened */
> 
>         if (path_to_fshandle(mountpoint, &xfs_handle, &hlen) < 0) {
>                 /* error */
>                 exit(4);
>         }
> 
>         free(xfs_handle);

Thank you Roger, that moves me one step but not to success

Now I know "Operation not permitted" is the correct message I assume that 
use of XFS file handles requires root.

But even as root, I cannot open a file with O_RDONLY:

  $ sudo ./test-xfs ~/scratch/tmp/xfs/file.c ; echo $?
  Handle 8 bytes: bd2c94ba959858
  Handle 24 bytes: bd2c94ba959858e0000000870000000
  readlink_by_handle: Not a directory
  open_by_handle: Not a directory
  0

I am able to do open_by_handle(O_RDONLY) on a directory though:

  $ sudo ./test-xfs ~/scratch/tmp/xfs/directory ; echo $?
  Handle 8 bytes: bd2c94ba959858
  Handle 24 bytes: bd2c94ba959858e0000000880000000
  readlink_by_handle: Invalid argument
  0

and a readlink_by_handle on a symlink works:

  $ sudo ./test-xfs ~/scratch/tmp/xfs/link.c ; echo $?
  Handle 8 bytes: bd2c94ba959858
  Handle 24 bytes: bd2c94ba959858e0000000860000000
  Link: fortress.c
  open_by_handle: Operation not permitted
  0

Switching to O_RDWR does not succeed in opening a file either, and also 
stops the directory case.

It seems possible flags are getting mangled and are not what I think they 
mean. The docs state the call as analogous to open(); is the 'oflags' 
argument actually ready to accept O_RDONLY etc. or some other set of 
flags? Because it seems like I can't actually open a file here.

Many thanks

-- 
Mark

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Errors from basic open_by_handle operations
  2015-04-09 12:53 Errors from basic open_by_handle operations Mark Hills
                   ` (2 preceding siblings ...)
  2015-04-09 13:31 ` [PATCH] libhandle: document the need for path_to_handle tinguely
@ 2015-04-09 14:09 ` Roger Willcocks
  2015-04-09 14:34   ` Mark Hills
  3 siblings, 1 reply; 8+ messages in thread
From: Roger Willcocks @ 2015-04-09 14:09 UTC (permalink / raw)
  To: Mark Hills; +Cc: xfs

The code below works here on a CentOS 6.4 box ('test' is a file at the
root of the volume):

$ ./a.out
hlen = 24
fd = -1
$ sudo ./a.out
hlen = 24
fd = 4


/* g++ handle_test.cpp -lhandle */

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <xfs/handle.h>

int main(int argc, char *argv[])
{
  void *xfs_handle = 0;
  size_t hlen = 0;

  if (path_to_fshandle("/mnt/disk1", &xfs_handle, &hlen) < 0)
    exit(4);

  if (path_to_handle("/mnt/disk1/test", &xfs_handle, &hlen) < 0)
    exit(5);

  printf("hlen = %d\n", (int)hlen);

  int fd = open_by_handle(xfs_handle, hlen, O_RDWR);

  printf("fd = %d\n", fd);
  return 0;
}


On Thu, 2015-04-09 at 13:53 +0100, Mark Hills wrote:
> I am having troubles with elementary file handle functions in libhandle.
> 
> A basic open_by_handle is giving "Bad file descriptor".
> 
> But I am suspicious of a side effect; using path_to_fshandle earlier in 
> the program changes these errors to "Operation not permitted".
> 
> Is there a basic mistake in my use of these calls, or a bug/unmaintained 
> code?
> 
> I am on an XFS filesystem (otherwise the first call fails with 
> 'inappropriate ioctl'). The only documentation I can find is the man page; 
> no mention about initialising the library, and I wasn't able to find any 
> examples.
> 
> I'm on Scientific Linux 6.6 (like RedHat 6, kernel 2.6.32-504.1.3), and 
> also tried updating to the latest xfsprogs from Git, with the same 
> results.
> 
> Many thanks
> 
-- 
Roger Willcocks <roger@filmlight.ltd.uk>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Errors from basic open_by_handle operations
  2015-04-09 14:09 ` Errors from basic open_by_handle operations Roger Willcocks
@ 2015-04-09 14:34   ` Mark Hills
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Hills @ 2015-04-09 14:34 UTC (permalink / raw)
  To: Roger Willcocks; +Cc: xfs

On Thu, 9 Apr 2015, Roger Willcocks wrote:

> The code below works here on a CentOS 6.4 box ('test' is a file at the
> root of the volume):
> 
> $ ./a.out
> hlen = 24
> fd = -1
> $ sudo ./a.out
> hlen = 24
> fd = 4

Yup, and I can reproduce that here on my system, thanks.

It seems the subtlety is rooted here:

>   if (path_to_fshandle("/mnt/disk1", &xfs_handle, &hlen) < 0)
>     exit(4);
> 
>   if (path_to_handle("/mnt/disk1/test", &xfs_handle, &hlen) < 0)
>     exit(5);

This code is correct, and it looks like it's necessary to do 
path_to_fshandle on the file system root, otherwise it does not satisfy 
the precondition of open_by_handle().

So what I was doing:

  path_to_fshandle("/mnt/disk1/test-file" ... );
  ...
  path_to_handle("/mnt/disk1/test-file" ... );

even though it reports the expected success (and returns the right file 
handles), is not enough to allow open_by_handle() to work on a file.

It does leave me needing to have prior knowledge of the mounted filesystem 
root (or look it up); handle_to_fshandle() doesn't achieve the same.

Definitely some oddities here -- but now I have enough to get me started 
though I hope.

Thanks for all the help, and perhaps I can look at some patches to the man 
page as I go.

Thanks

-- 
Mark

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libhandle: document the need for path_to_handle
  2015-04-09 13:31 ` [PATCH] libhandle: document the need for path_to_handle tinguely
@ 2015-04-13  0:25   ` Dave Chinner
  0 siblings, 0 replies; 8+ messages in thread
From: Dave Chinner @ 2015-04-13  0:25 UTC (permalink / raw)
  To: tinguely; +Cc: xfs

On Thu, Apr 09, 2015 at 08:31:04AM -0500, tinguely@sgi.com wrote:
> The handle ioctls require an open file descriptor to
> the XFS mount directory. This file descriptor is found
> and supplied in the libhandle code by matching the
> entry added with a path_to_handle() call. Document
> the requirement and supply a simple example.
> 
> Signed-off-by: Mark Tinguely <tinguely@sgi.com>
> 
> ---
>  man/man3/handle.3 |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 69 insertions(+), 1 deletion(-)
> 
> Index: b/man/man3/handle.3
> ===================================================================
> --- a/man/man3/handle.3
> +++ b/man/man3/handle.3
> @@ -74,6 +74,12 @@ The
>  function returns the handle for the filesystem in which the object given by the
>  .I path
>  argument resides.
> +.I path
> +must be the path to the mount point or
> +.BR open_by_handle ()
> +will return the
> +.B ENOTDIR
> +error.

This is wrong. ENOTDIR is only returned by open_by_handle if the
cached fsfd is not a directory - it does not check if it's the root
of a mount point at all. i.e, filesystem root is /mnt/scratch:

$ ls -l /mnt/scratch
total 4
-rw-r--r--.   1 root root    0 Apr 13 09:57 foo
drwxr-xr-x. 102 root root 4096 Apr 11 01:49 quota_dir
$
$ sudo ./fhtest /mnt/scratch /mnt/scratch/foo
open_by_handle: Success
$ sudo ./fhtest /mnt/scratch/foo /mnt/scratch/foo
open_by_handle: Not a directory
$ sudo ./fhtest /mnt/scratch/quota_dir/ /mnt/scratch/foo
open_by_handle: Success

So, as long as the fs path points to a directory on the filesystem
in question, open_by_handle (and all the other handle functions)
works just fine.

>  .PP
>  The
>  .BR fd_to_handle ()
> @@ -95,7 +101,16 @@ The
>  function opens a file descriptor for the object referenced by a handle.
>  It is analogous and identical to
>  .BR open (2)
> -with the exception of accepting handles instead of path names.
> +with the exception of accepting handles instead of path names. The returned
> +file descriptor is opened to do invisible IO. Internally,

Invisible IO is not defined anywhere in the man page, and most
people will have no idea what it means. Either don't mention it, or
define it properly first. For simplicity, I'd just omit it.

> +.BR open_by_handle ()
> +uses the mount point file descriptor that was saved by
> +.BR path_to_fshandle ().
> +Therefore,
> +.BR path_to_fshandle ().
> +must be called before calling

I don't think you need to mention anything about internal
implemenation of libhandle, just that a call to path_to_fshandle()
is required first.

> +.BR open_by_handle ().
> +See below for an example.
>  .PP
>  The
>  .BR readlink_by_handle ()
> @@ -192,6 +207,59 @@ does not exist.
>  .TP
>  .B EPERM
>  The caller does not have sufficient privileges.
> +.SH EXAMPLE
> +Example of
> +.BR open_by_handle ().
> +.PP
> +.Vb 1
> +\& main()
> +.br
> +\& {
> +.br
> +\&	int fd;
> +.br
> +\&	size_t hlen;
> +.br
> +\&	void *han;
> +.br
> +\&	size_t sz_int_used;
> +.br
> +\&	void *hdl_int_used;
> +.br
> +\&	char *mount_path = "/mnt/";
> +.br
> +\&	char *file = "file_to_open";
> +.br
> +\&	if (path_to_handle(file, &han, &hlen) < 0) {
> +.br
> +\&		perror("path-to-handle");
> +.br
> +\&		exit(1);
> +.br
> +\&	}
> +.br
> +\&	/*
> +.br
> +\&	 * path_to_fshandle saves an internal copy of the mount point's
> +.br
> +\&	 * (/mnt in this example) file descriptor. The open_by_handle call
> +.br
> +\&	 * looks up this internal file descriptor and uses it in the
> +.br
> +\&	 * xfsctl call to the kernel. Once path_to_fshandle is called,
> +.br
> +\&	 * this internal file descriptor remains open for the remaining
> +.br
> +\&	 * life of the application.
> +.br
> +\&	 */

Again, this is internal implementation details, so isn't appropriate
for a man page documenting an API.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-04-13  0:25 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-09 12:53 Errors from basic open_by_handle operations Mark Hills
2015-04-09 13:09 ` Roger Willcocks
2015-04-09 13:36   ` Mark Hills
2015-04-09 13:27 ` Dave Chinner
2015-04-09 13:31 ` [PATCH] libhandle: document the need for path_to_handle tinguely
2015-04-13  0:25   ` Dave Chinner
2015-04-09 14:09 ` Errors from basic open_by_handle operations Roger Willcocks
2015-04-09 14:34   ` Mark Hills

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.