Symlink to another IO manager

I have implemented a custom file system in an IO manager. This IO
manager is based on the example downloaded from the QNX FTP site. When
it is started it presents block devices in the /dev directory. Mount can
be used to attach the block devices to the prefix space…

The new file system supports symlinks. Symlinks that point to my prefix
space work fine. The question is what magic must be done to redirect a
request to a symlink that points to a different IO manager?

We are using the latest QNX 4.25 release.

Any hints on how to implement this would be greatly appreciated.

Ray Hausman wrote:

The new file system supports symlinks. Symlinks that point to my prefix
space work fine. The question is what magic must be done to redirect a
request to a symlink that points to a different IO manager?

Given that you must be doing an EMORE reply, the only other thing is to
make sure you always construct an absolute pathname in reply (ie starts
with ‘/’). This can involve some funky string manipulations and the
need to store for each device where it has been mounted
(qnx_prefix_attach). Generally the procedure is: for an absolute
symlink, create a path consisting of the link plus whatever is left of
the input path beyond the current symlink component; for a relative
synmlink, create a path consisting of your mountpoint plus the part of
the pathname that got you to the link plus the link itself plus whatever
is left of the input path beyond the current symlink component.

The path name part is working. Given an open message to my IO manager of
a path containing a symlink, the open resolves the symlink (as per your
procedure below) to a full path (including the node) of a directory or
file. If the directory or file is for me then I just deal with it. If
its not for me you suggest my reply to the open should be an EMORE.
How does this work?
Is the full path (which is for some other IO manager like FSYS)
communicated back to the client?

John Garvey wrote:

Ray Hausman wrote:

The new file system supports symlinks. Symlinks that point to my
prefix space work fine. The question is what magic must be done to
redirect a request to a symlink that points to a different IO manager?


Given that you must be doing an EMORE reply, the only other thing is to
make sure you always construct an absolute pathname in reply (ie starts
with ‘/’). This can involve some funky string manipulations and the
need to store for each device where it has been mounted
(qnx_prefix_attach). Generally the procedure is: for an absolute
symlink, create a path consisting of the link plus whatever is left of
the input path beyond the current symlink component; for a relative
synmlink, create a path consisting of your mountpoint plus the part of
the pathname that got you to the link plus the link itself plus whatever
is left of the input path beyond the current symlink component.

Ray Hausman wrote:

The path name part is working. Given an open message to my IO manager of
a path containing a symlink, the open resolves the symlink (as per your
procedure below) to a full path (including the node) of a directory or
file. If the directory or file is for me then I just deal with it. If
its not for me you suggest my reply to the open should be an EMORE.
How does this work?

Ah, that is the problem, you are not supposed to “just deal with it”
internally. You always bounce a symlink back to the pathmgr (since
the expanded link may be to another prefix - something has mounted over
the top of part of your pathname space or there is a ‘prefix -R’ in
effect - this is the power of having an central pathname manager). When
you encounter a symlink you produce a new absolute pathname based on the
rules I posted previously, and then EMORE this: the reply message is a
“struct _io_open”, the type field is EMORE, the rest is as per the
original IO_OPEN input, and the following path[] is the expanded symlink
(’\0’-terminated).

Is the full path (which is for some other IO manager like FSYS)
communicated back to the client?

Yes, always. If the resulting symlink is still within you, you’ll get
sent another IO_OPEN message with the expanded path; if it is for
someone else, they’ll get it; this process continues until there are no
more links (servers stop EMORE-ing the pathname).

Thanks very much. The piece I was missing was the EMORE-ing with “struct
_io_open” path set to the expanded full path. This technique makes
implementing symlinks easy.

John Garvey wrote:

Ray Hausman wrote:

The path name part is working. Given an open message to my IO manager
of a path containing a symlink, the open resolves the symlink (as per
your procedure below) to a full path (including the node) of a
directory or file. If the directory or file is for me then I just deal
with it. If its not for me you suggest my reply to the open should be
an EMORE.
How does this work?


Ah, that is the problem, you are not supposed to “just deal with it”
internally. You always bounce a symlink back to the pathmgr (since
the expanded link may be to another prefix - something has mounted over
the top of part of your pathname space or there is a ‘prefix -R’ in
effect - this is the power of having an central pathname manager). When
you encounter a symlink you produce a new absolute pathname based on the
rules I posted previously, and then EMORE this: the reply message is a
“struct _io_open”, the type field is EMORE, the rest is as per the
original IO_OPEN input, and the following path[] is the expanded symlink
(’\0’-terminated).

Is the full path (which is for some other IO manager like FSYS)
communicated back to the client?


Yes, always. If the resulting symlink is still within you, you’ll get
sent another IO_OPEN message with the expanded path; if it is for
someone else, they’ll get it; this process continues until there are no
more links (servers stop EMORE-ing the pathname).

Ray -

Contact me at dkrunnfusz@wideopenwest.com.

Thanks,
Dave