Skip to content

x/sys/unix: add name_to_handle_at and open_by_handle_at #30537

@dominikh

Description

@dominikh

I would like to add name_to_handle_at and open_by_handle_at to x/sys/unix for Linux, but I am not sure how to structure the functions and types.

Their canonical definitions are

int name_to_handle_at(int dirfd, const char *pathname, struct file_handle *handle, int *mount_id, int flags);
int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags);

struct file_handle {
  unsigned int  handle_bytes;   /* Size of f_handle [in, out] */
  int           handle_type;    /* Handle type [out] */
  unsigned char f_handle[0];    /* File identifier (sized by caller) [out] */
};

My issue is with the open-ended nature of file_handle. The name_to_handle_at syscall expects the user to allocate a file_handle of sufficient size (usually in a loop to determine the correct size) and to put its size in handle_bytes. And while the value of f_handle is opaque, the user may want to access it, for example to transmit it over the network.

I can imagine two possible ways of designing the API, and I am hoping for a third one.

The first option is to stick 1:1 to the C definitions. This would require use of unsafe.Pointer on the caller's side to convert the backing array into the appropriate type, as well as to access the value of f_handle. And due to #14440, the existence of the f_handle field is obscured. Furthermore, I am not sure how this interacts with the GC. If we back a 16 byte struct with an N bytes byte slice, can we be sure GC will never collect part of the memory?

The second option is to split the file_handle argument in two, one for the part of the struct that Go actually generates, and a byte slice for the f_handle, giving us the following:

func NameToHandleAt(..., handle *FileHandle, fHandle []byte, ...)

This, however, begs the question: who's responsibility is it to ensure that handle.Bytes and len(fHandle) match, and what do we do if they don't?

Is there a third option I'm missing?

/cc @ianlancetaylor @tklauser

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.OS-Linuxhelp wanted

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions