Set cwd to '/' for the process executing insmod.

Ricardo has pointed out that under Solaris the cwd is set to '/'
during module load, while under Linux it is set to the callers cwd.
To handle this cleanly I've reworked the module *_init()/_exit()
macros so they call a *_setup()/_cleanup() function when any SPL
dependent module is loaded or unloaded.  This gives us a chance to
perform any needed modification of the process, in this case changing
the cwd.  It also handily provides a way to avoid creating wrapper
init()/exit() functions because the Solaris and Linux prototypes
differ slightly.  All dependent modules should now call the spl
helper macros spl_module_{init,exit}() instead of the native linux
versions.

Unfortunately, it appears that under Linux there has been no consistent
API in the kernel to set the cwd in a module.  Because of this I have
had to add more autoconf magic than I'd like.  However, what I have
done is correct and has been tested on RHEL5, SLES11, FC11, and CHAOS
kernels.

In addition, I have change the rootdir type from a 'void *' to the
correct 'vnode_t *' type.  And I've set rootdir to a non-NULL value.
This commit is contained in:
Brian Behlendorf
2009-10-01 16:06:15 -07:00
parent 0e77fc118e
commit 51a727e90f
10 changed files with 404 additions and 8 deletions
Vendored
+210
View File
@@ -21709,6 +21709,111 @@ _ACEOF
fi
rm -Rf build
echo "$as_me:$LINENO: checking whether symbol set_fs_pwd is exported" >&5
echo $ECHO_N "checking whether symbol set_fs_pwd is exported... $ECHO_C" >&6
grep -q -E '[[:space:]]set_fs_pwd[[:space:]]' \
$LINUX_OBJ/Module*.symvers 2>/dev/null
rc=$?
if test $rc -ne 0; then
export=0
for file in ; do
grep -q -E "EXPORT_SYMBOL.*(set_fs_pwd)" \
"$LINUX_OBJ/$file" 2>/dev/null
rc=$?
if test $rc -eq 0; then
export=1
break;
fi
done
if test $export -eq 0; then
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
else
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_SET_FS_PWD 1
_ACEOF
fi
else
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_SET_FS_PWD 1
_ACEOF
fi
echo "$as_me:$LINENO: checking whether set_fs_pwd() wants 2 args" >&5
echo $ECHO_N "checking whether set_fs_pwd() wants 2 args... $ECHO_C" >&6
cat >conftest.c <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/sched.h>
int
main (void)
{
set_fs_pwd(NULL, NULL);
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build
echo "obj-m := conftest.o" >build/Makefile
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_2ARGS_SET_FS_PWD 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -Rf build
@@ -24752,6 +24857,111 @@ _ACEOF
fi
rm -Rf build
echo "$as_me:$LINENO: checking whether symbol set_fs_pwd is exported" >&5
echo $ECHO_N "checking whether symbol set_fs_pwd is exported... $ECHO_C" >&6
grep -q -E '[[:space:]]set_fs_pwd[[:space:]]' \
$LINUX_OBJ/Module*.symvers 2>/dev/null
rc=$?
if test $rc -ne 0; then
export=0
for file in ; do
grep -q -E "EXPORT_SYMBOL.*(set_fs_pwd)" \
"$LINUX_OBJ/$file" 2>/dev/null
rc=$?
if test $rc -eq 0; then
export=1
break;
fi
done
if test $export -eq 0; then
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
else
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_SET_FS_PWD 1
_ACEOF
fi
else
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_SET_FS_PWD 1
_ACEOF
fi
echo "$as_me:$LINENO: checking whether set_fs_pwd() wants 2 args" >&5
echo $ECHO_N "checking whether set_fs_pwd() wants 2 args... $ECHO_C" >&6
cat >conftest.c <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/sched.h>
int
main (void)
{
set_fs_pwd(NULL, NULL);
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build
echo "obj-m := conftest.o" >build/Makefile
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_2ARGS_SET_FS_PWD 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -Rf build