Message ID | 20210422084612.26374-1-heiko.thiery@gmail.com |
---|---|
State | New |
Headers | show |
Series | lib/fs: fix issue when {name, open}_to_handle_at() is not implemented | expand |
Hi, > With commit d5e6ee0dac64b64e the usage of functions name_to_handle_at() and > open_by_handle_at() are introduced. But these function are not available > e.g. in uclibc-ng < 1.0.35. To have a backward compatibility check for the > availability in the configure script and in case of absence do a direct > syscall. LGTM, thanks for implementing it. I'd consider to check only one of the functions (very unlikely only one will be supported). > Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com> > --- > configure | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/fs.c | 25 ++++++++++++++++++++++++ > 2 files changed, 83 insertions(+) > diff --git a/configure b/configure > index 2c363d3b..f1be9977 100755 > --- a/configure > +++ b/configure > @@ -202,6 +202,58 @@ EOF > rm -f $TMPDIR/setnstest.c $TMPDIR/setnstest > } > +check_name_to_handle_at() > +{ > + nit: empty line. > + cat >$TMPDIR/name_to_handle_at_test.c <<EOF It's interesting it does not require _GNU_SOURCE ? (IMHO this is normally required for all glibc, musl, uclibc and binder): #define _GNU_SOURCE > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +int main(int argc, char **argv) > +{ > + struct file_handle *fhp; > + int mount_id, flags, dirfd; > + char *pathname; > + name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags); > + return 0; > +} > +EOF > + > + if $CC -I$INCLUDE -o $TMPDIR/name_to_handle_at_test $TMPDIR/name_to_handle_at_test.c >/dev/null 2>&1; then > + echo "IP_CONFIG_NAME_TO_HANDLE_AT:=y" >>$CONFIG > + echo "yes" > + echo "CFLAGS += -DHAVE_NAME_TO_HANDLE_AT" >>$CONFIG > + else > + echo "no" > + fi > + rm -f $TMPDIR/name_to_handle_at_test.c $TMPDIR/name_to_handle_at_test > +} > + > +check_open_by_handle_at() > +{ > + nit: empty line. > + cat >$TMPDIR/open_by_handle_at_test.c <<EOF > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +int main(int argc, char **argv) > +{ > + struct file_handle *fhp; > + int mount_fd; > + open_by_handle_at(mount_fd, fhp, O_RDONLY); > + return 0; > +} > +EOF > + if $CC -I$INCLUDE -o $TMPDIR/open_by_handle_at_test $TMPDIR/open_by_handle_at_test.c >/dev/null 2>&1; then > + echo "IP_CONFIG_OPEN_BY_HANDLE_AT:=y" >>$CONFIG > + echo "yes" > + echo "CFLAGS += -DHAVE_OPEN_BY_HANDLE_AT" >>$CONFIG > + else > + echo "no" > + fi > + rm -f $TMPDIR/open_by_handle_at_test.c $TMPDIR/open_by_handle_at_test > +} > + > check_ipset() > { > cat >$TMPDIR/ipsettest.c <<EOF > @@ -492,6 +544,12 @@ fi > echo -n "libc has setns: " > check_setns > +echo -n "libc has name_to_handle_at: " > +check_name_to_handle_at > + > +echo -n "libc has open_by_handle_at: " > +check_open_by_handle_at > + > echo -n "SELinux support: " > check_selinux > diff --git a/lib/fs.c b/lib/fs.c > index ee0b130b..c561d85b 100644 > --- a/lib/fs.c > +++ b/lib/fs.c > @@ -30,6 +30,31 @@ > /* if not already mounted cgroup2 is mounted here for iproute2's use */ > #define MNT_CGRP2_PATH "/var/run/cgroup2" > + > +#if (!defined HAVE_NAME_TO_HANDLE_AT && !defined HAVE_OPEN_BY_HANDLE_AT) > +struct file_handle { > + unsigned handle_bytes; > + int handle_type; > + unsigned char f_handle[]; > +}; > +#endif > + > +#ifndef HAVE_NAME_TO_HANDLE_AT > +int name_to_handle_at(int dirfd, const char *pathname, > + struct file_handle *handle, int *mount_id, int flags) > +{ > + return syscall(name_to_handle_at, 5, dirfd, pathname, handle, > + mount_id, flags); > +} > +#endif > + > +#ifndef HAVE_OPEN_BY_HANDLE_AT > +int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags) > +{ > + return syscall(open_by_handle_at, 3, mount_fd, handle, flags); > +} > +#endif > + > /* return mount path of first occurrence of given fstype */ > static char *find_fs_mount(const char *fs_to_find) > {
diff --git a/configure b/configure index 2c363d3b..f1be9977 100755 --- a/configure +++ b/configure @@ -202,6 +202,58 @@ EOF rm -f $TMPDIR/setnstest.c $TMPDIR/setnstest } +check_name_to_handle_at() +{ + + cat >$TMPDIR/name_to_handle_at_test.c <<EOF +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +int main(int argc, char **argv) +{ + struct file_handle *fhp; + int mount_id, flags, dirfd; + char *pathname; + name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags); + return 0; +} +EOF + + if $CC -I$INCLUDE -o $TMPDIR/name_to_handle_at_test $TMPDIR/name_to_handle_at_test.c >/dev/null 2>&1; then + echo "IP_CONFIG_NAME_TO_HANDLE_AT:=y" >>$CONFIG + echo "yes" + echo "CFLAGS += -DHAVE_NAME_TO_HANDLE_AT" >>$CONFIG + else + echo "no" + fi + rm -f $TMPDIR/name_to_handle_at_test.c $TMPDIR/name_to_handle_at_test +} + +check_open_by_handle_at() +{ + + cat >$TMPDIR/open_by_handle_at_test.c <<EOF +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +int main(int argc, char **argv) +{ + struct file_handle *fhp; + int mount_fd; + open_by_handle_at(mount_fd, fhp, O_RDONLY); + return 0; +} +EOF + if $CC -I$INCLUDE -o $TMPDIR/open_by_handle_at_test $TMPDIR/open_by_handle_at_test.c >/dev/null 2>&1; then + echo "IP_CONFIG_OPEN_BY_HANDLE_AT:=y" >>$CONFIG + echo "yes" + echo "CFLAGS += -DHAVE_OPEN_BY_HANDLE_AT" >>$CONFIG + else + echo "no" + fi + rm -f $TMPDIR/open_by_handle_at_test.c $TMPDIR/open_by_handle_at_test +} + check_ipset() { cat >$TMPDIR/ipsettest.c <<EOF @@ -492,6 +544,12 @@ fi echo -n "libc has setns: " check_setns +echo -n "libc has name_to_handle_at: " +check_name_to_handle_at + +echo -n "libc has open_by_handle_at: " +check_open_by_handle_at + echo -n "SELinux support: " check_selinux diff --git a/lib/fs.c b/lib/fs.c index ee0b130b..c561d85b 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -30,6 +30,31 @@ /* if not already mounted cgroup2 is mounted here for iproute2's use */ #define MNT_CGRP2_PATH "/var/run/cgroup2" + +#if (!defined HAVE_NAME_TO_HANDLE_AT && !defined HAVE_OPEN_BY_HANDLE_AT) +struct file_handle { + unsigned handle_bytes; + int handle_type; + unsigned char f_handle[]; +}; +#endif + +#ifndef HAVE_NAME_TO_HANDLE_AT +int name_to_handle_at(int dirfd, const char *pathname, + struct file_handle *handle, int *mount_id, int flags) +{ + return syscall(name_to_handle_at, 5, dirfd, pathname, handle, + mount_id, flags); +} +#endif + +#ifndef HAVE_OPEN_BY_HANDLE_AT +int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags) +{ + return syscall(open_by_handle_at, 3, mount_fd, handle, flags); +} +#endif + /* return mount path of first occurrence of given fstype */ static char *find_fs_mount(const char *fs_to_find) {
With commit d5e6ee0dac64b64e the usage of functions name_to_handle_at() and open_by_handle_at() are introduced. But these function are not available e.g. in uclibc-ng < 1.0.35. To have a backward compatibility check for the availability in the configure script and in case of absence do a direct syscall. Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com> --- configure | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/fs.c | 25 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+)