Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linprocfs/linprocfs.c
Show First 20 Lines • Show All 520 Lines • ▼ Show 20 Lines | |||||
* Filler function for proc/mtab and proc/<pid>/mounts. | * Filler function for proc/mtab and proc/<pid>/mounts. | ||||
* | * | ||||
* /proc/mtab doesn't exist in Linux' procfs, but is included here so | * /proc/mtab doesn't exist in Linux' procfs, but is included here so | ||||
* users can symlink /compat/linux/etc/mtab to /proc/mtab | * users can symlink /compat/linux/etc/mtab to /proc/mtab | ||||
*/ | */ | ||||
static int | static int | ||||
linprocfs_domtab(PFS_FILL_ARGS) | linprocfs_domtab(PFS_FILL_ARGS) | ||||
{ | { | ||||
struct nameidata nd; | const char *mntto, *mntfrom, *fstype; | ||||
const char *lep, *mntto, *mntfrom, *fstype; | |||||
char *dlep, *flep; | char *dlep, *flep; | ||||
struct vnode *vp; | |||||
struct pwd *pwd; | |||||
size_t lep_len; | size_t lep_len; | ||||
int error; | int error; | ||||
struct statfs *buf, *sp; | struct statfs *buf, *sp; | ||||
size_t count; | size_t count; | ||||
/* resolve symlinks etc. in the emulation tree prefix */ | |||||
/* | /* | ||||
* Ideally, this would use the current chroot rather than some | * Resolve emulation tree prefix | ||||
* hardcoded path. | |||||
*/ | */ | ||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path); | |||||
flep = NULL; | flep = NULL; | ||||
error = namei(&nd); | pwd = pwd_hold(td); | ||||
lep = linux_emul_path; | vp = pwd->pwd_adir; | ||||
if (error == 0) { | error = vn_fullpath_global(vp, &dlep, &flep); | ||||
if (vn_fullpath(nd.ni_vp, &dlep, &flep) == 0) | pwd_drop(pwd); | ||||
lep = dlep; | if (error != 0) | ||||
vrele(nd.ni_vp); | return (error); | ||||
} | lep_len = strlen(dlep); | ||||
lep_len = strlen(lep); | |||||
buf = NULL; | buf = NULL; | ||||
error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count, | error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count, | ||||
UIO_SYSSPACE, MNT_WAIT); | UIO_SYSSPACE, MNT_WAIT); | ||||
if (error != 0) { | if (error != 0) { | ||||
free(buf, M_TEMP); | free(buf, M_TEMP); | ||||
free(flep, M_TEMP); | free(flep, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
for (sp = buf; count > 0; sp++, count--) { | for (sp = buf; count > 0; sp++, count--) { | ||||
error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype); | error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ECANCELED); | MPASS(error == ECANCELED); | ||||
continue; | continue; | ||||
} | } | ||||
/* determine mount point */ | /* determine mount point */ | ||||
if (strncmp(mntto, lep, lep_len) == 0 && mntto[lep_len] == '/') | if (strncmp(mntto, dlep, lep_len) == 0 && mntto[lep_len] == '/') | ||||
mntto += lep_len; | mntto += lep_len; | ||||
sbuf_printf(sb, "%s %s %s ", mntfrom, mntto, fstype); | sbuf_printf(sb, "%s %s %s ", mntfrom, mntto, fstype); | ||||
_sbuf_mntoptions_helper(sb, sp->f_flags); | _sbuf_mntoptions_helper(sb, sp->f_flags); | ||||
/* a real Linux mtab will also show NFS options */ | /* a real Linux mtab will also show NFS options */ | ||||
sbuf_printf(sb, " 0 0\n"); | sbuf_printf(sb, " 0 0\n"); | ||||
} | } | ||||
free(buf, M_TEMP); | free(buf, M_TEMP); | ||||
free(flep, M_TEMP); | free(flep, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
linprocfs_doprocmountinfo(PFS_FILL_ARGS) | linprocfs_doprocmountinfo(PFS_FILL_ARGS) | ||||
{ | { | ||||
struct nameidata nd; | |||||
const char *mntfrom, *mntto, *fstype; | const char *mntfrom, *mntto, *fstype; | ||||
const char *lep; | |||||
char *dlep, *flep; | char *dlep, *flep; | ||||
struct statfs *buf, *sp; | struct statfs *buf, *sp; | ||||
size_t count, lep_len; | size_t count, lep_len; | ||||
struct vnode *vp; | |||||
struct pwd *pwd; | |||||
int error; | int error; | ||||
/* | /* | ||||
* Ideally, this would use the current chroot rather than some | * Resolve emulation tree prefix | ||||
* hardcoded path. | |||||
*/ | */ | ||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path); | |||||
flep = NULL; | flep = NULL; | ||||
error = namei(&nd); | pwd = pwd_hold(td); | ||||
lep = linux_emul_path; | vp = pwd->pwd_adir; | ||||
if (error == 0) { | error = vn_fullpath_global(vp, &dlep, &flep); | ||||
if (vn_fullpath(nd.ni_vp, &dlep, &flep) == 0) | pwd_drop(pwd); | ||||
lep = dlep; | if (error != 0) | ||||
vrele(nd.ni_vp); | return (error); | ||||
} | lep_len = strlen(dlep); | ||||
lep_len = strlen(lep); | |||||
buf = NULL; | buf = NULL; | ||||
error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count, | error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count, | ||||
UIO_SYSSPACE, MNT_WAIT); | UIO_SYSSPACE, MNT_WAIT); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
for (sp = buf; count > 0; sp++, count--) { | for (sp = buf; count > 0; sp++, count--) { | ||||
error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype); | error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ECANCELED); | MPASS(error == ECANCELED); | ||||
continue; | continue; | ||||
} | } | ||||
if (strncmp(mntto, lep, lep_len) == 0 && mntto[lep_len] == '/') | if (strncmp(mntto, dlep, lep_len) == 0 && mntto[lep_len] == '/') | ||||
mntto += lep_len; | mntto += lep_len; | ||||
#if 0 | #if 0 | ||||
/* | /* | ||||
* If the prefix is a chroot, and this mountpoint is not under | * If the prefix is a chroot, and this mountpoint is not under | ||||
* the prefix, we should skip it. Leave it for now for | * the prefix, we should skip it. Leave it for now for | ||||
* consistency with procmtab above. | * consistency with procmtab above. | ||||
*/ | */ | ||||
else | else | ||||
▲ Show 20 Lines • Show All 1,656 Lines • Show Last 20 Lines |