Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145541851
D27136.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D27136.diff
View Options
Index: head/sys/compat/linprocfs/linprocfs.c
===================================================================
--- head/sys/compat/linprocfs/linprocfs.c
+++ head/sys/compat/linprocfs/linprocfs.c
@@ -403,24 +403,85 @@
}
#endif /* __i386__ || __amd64__ */
+static const char *path_slash_sys = "/sys";
+static const char *fstype_sysfs = "sysfs";
+
+static int
+_mtab_helper(const struct pfs_node *pn, const struct statfs *sp,
+ const char **mntfrom, const char **mntto, const char **fstype)
+{
+ /* determine device name */
+ *mntfrom = sp->f_mntfromname;
+
+ /* determine mount point */
+ *mntto = sp->f_mntonname;
+
+ /* determine fs type */
+ *fstype = sp->f_fstypename;
+ if (strcmp(*fstype, pn->pn_info->pi_name) == 0)
+ *mntfrom = *fstype = "proc";
+ else if (strcmp(*fstype, "procfs") == 0)
+ return (ECANCELED);
+
+ if (strcmp(*fstype, "autofs") == 0) {
+ /*
+ * FreeBSD uses eg "map -hosts", whereas Linux
+ * expects just "-hosts".
+ */
+ if (strncmp(*mntfrom, "map ", 4) == 0)
+ *mntfrom += 4;
+ }
+
+ if (strcmp(*fstype, "linsysfs") == 0) {
+ *mntfrom = path_slash_sys;
+ *fstype = fstype_sysfs;
+ } else {
+ /* For Linux msdosfs is called vfat */
+ if (strcmp(*fstype, "msdosfs") == 0)
+ *fstype = "vfat";
+ }
+ return (0);
+}
+
+static void
+_sbuf_mntoptions_helper(struct sbuf *sb, uint64_t f_flags)
+{
+ sbuf_cat(sb, (f_flags & MNT_RDONLY) ? "ro" : "rw");
+#define ADD_OPTION(opt, name) \
+ if (f_flags & (opt)) sbuf_cat(sb, "," name);
+ ADD_OPTION(MNT_SYNCHRONOUS, "sync");
+ ADD_OPTION(MNT_NOEXEC, "noexec");
+ ADD_OPTION(MNT_NOSUID, "nosuid");
+ ADD_OPTION(MNT_UNION, "union");
+ ADD_OPTION(MNT_ASYNC, "async");
+ ADD_OPTION(MNT_SUIDDIR, "suiddir");
+ ADD_OPTION(MNT_NOSYMFOLLOW, "nosymfollow");
+ ADD_OPTION(MNT_NOATIME, "noatime");
+#undef ADD_OPTION
+}
+
/*
- * Filler function for proc/mtab
+ * Filler function for proc/mtab and proc/<pid>/mounts.
*
- * This file 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
*/
static int
linprocfs_domtab(PFS_FILL_ARGS)
{
struct nameidata nd;
- const char *lep;
- char *dlep, *flep, *mntto, *mntfrom, *fstype;
+ const char *lep, *mntto, *mntfrom, *fstype;
+ char *dlep, *flep;
size_t lep_len;
int error;
struct statfs *buf, *sp;
size_t count;
/* resolve symlinks etc. in the emulation tree prefix */
+ /*
+ * Ideally, this would use the current chroot rather than some
+ * hardcoded path.
+ */
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, td);
flep = NULL;
error = namei(&nd);
@@ -442,55 +503,112 @@
}
for (sp = buf; count > 0; sp++, count--) {
- /* determine device name */
- mntfrom = sp->f_mntfromname;
+ error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype);
+ if (error != 0) {
+ MPASS(error == ECANCELED);
+ continue;
+ }
/* determine mount point */
- mntto = sp->f_mntonname;
if (strncmp(mntto, lep, lep_len) == 0 && mntto[lep_len] == '/')
mntto += lep_len;
- /* determine fs type */
- fstype = sp->f_fstypename;
- if (strcmp(fstype, pn->pn_info->pi_name) == 0)
- mntfrom = fstype = "proc";
- else if (strcmp(fstype, "procfs") == 0)
- continue;
+ sbuf_printf(sb, "%s %s %s ", mntfrom, mntto, fstype);
+ _sbuf_mntoptions_helper(sb, sp->f_flags);
+ /* a real Linux mtab will also show NFS options */
+ sbuf_printf(sb, " 0 0\n");
+ }
- if (strcmp(fstype, "autofs") == 0) {
- /*
- * FreeBSD uses eg "map -hosts", whereas Linux
- * expects just "-hosts".
- */
- if (strncmp(mntfrom, "map ", 4) == 0)
- mntfrom += 4;
- }
+ free(buf, M_TEMP);
+ free(flep, M_TEMP);
+ return (error);
+}
- if (strcmp(fstype, "linsysfs") == 0) {
- sbuf_printf(sb, "/sys %s sysfs %s", mntto,
- sp->f_flags & MNT_RDONLY ? "ro" : "rw");
- } else {
- /* For Linux msdosfs is called vfat */
- if (strcmp(fstype, "msdosfs") == 0)
- fstype = "vfat";
- sbuf_printf(sb, "%s %s %s %s", mntfrom, mntto, fstype,
- sp->f_flags & MNT_RDONLY ? "ro" : "rw");
+static int
+linprocfs_doprocmountinfo(PFS_FILL_ARGS)
+{
+ struct nameidata nd;
+ const char *mntfrom, *mntto, *fstype;
+ const char *lep;
+ char *dlep, *flep;
+ struct statfs *buf, *sp;
+ size_t count, lep_len;
+ int error;
+
+ /*
+ * Ideally, this would use the current chroot rather than some
+ * hardcoded path.
+ */
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, td);
+ flep = NULL;
+ error = namei(&nd);
+ lep = linux_emul_path;
+ if (error == 0) {
+ if (vn_fullpath(nd.ni_vp, &dlep, &flep) == 0)
+ lep = dlep;
+ vrele(nd.ni_vp);
+ }
+ lep_len = strlen(lep);
+
+ buf = NULL;
+ error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count,
+ UIO_SYSSPACE, MNT_WAIT);
+ if (error != 0)
+ goto out;
+
+ for (sp = buf; count > 0; sp++, count--) {
+ error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype);
+ if (error != 0) {
+ MPASS(error == ECANCELED);
+ continue;
}
-#define ADD_OPTION(opt, name) \
- if (sp->f_flags & (opt)) sbuf_printf(sb, "," name);
- ADD_OPTION(MNT_SYNCHRONOUS, "sync");
- ADD_OPTION(MNT_NOEXEC, "noexec");
- ADD_OPTION(MNT_NOSUID, "nosuid");
- ADD_OPTION(MNT_UNION, "union");
- ADD_OPTION(MNT_ASYNC, "async");
- ADD_OPTION(MNT_SUIDDIR, "suiddir");
- ADD_OPTION(MNT_NOSYMFOLLOW, "nosymfollow");
- ADD_OPTION(MNT_NOATIME, "noatime");
-#undef ADD_OPTION
- /* a real Linux mtab will also show NFS options */
- sbuf_printf(sb, " 0 0\n");
+
+ if (strncmp(mntto, lep, lep_len) == 0 && mntto[lep_len] == '/')
+ mntto += lep_len;
+#if 0
+ /*
+ * If the prefix is a chroot, and this mountpoint is not under
+ * the prefix, we should skip it. Leave it for now for
+ * consistency with procmtab above.
+ */
+ else
+ continue;
+#endif
+
+ /*
+ * (1) mount id
+ *
+ * (2) parent mount id -- we don't have this cheaply, so
+ * provide a dummy value
+ *
+ * (3) major:minor -- ditto
+ *
+ * (4) root filesystem mount -- probably a namespaces thing
+ *
+ * (5) mountto path
+ */
+ sbuf_printf(sb, "%u 0 0:0 / %s ",
+ sp->f_fsid.val[0] ^ sp->f_fsid.val[1], mntto);
+ /* (6) mount options */
+ _sbuf_mntoptions_helper(sb, sp->f_flags);
+ /*
+ * (7) zero or more optional fields -- again, namespace related
+ *
+ * (8) End of variable length fields separator ("-")
+ *
+ * (9) fstype
+ *
+ * (10) mount from
+ *
+ * (11) "superblock" options -- like (6), but different
+ * semantics in Linux
+ */
+ sbuf_printf(sb, " - %s %s %s\n", fstype, mntfrom,
+ (sp->f_flags & MNT_RDONLY) ? "ro" : "rw");
}
+ error = 0;
+out:
free(buf, M_TEMP);
free(flep, M_TEMP);
return (error);
@@ -1889,6 +2007,8 @@
NULL, NULL, NULL, PFS_RD | PFS_AUTODRAIN);
pfs_create_file(dir, "mem", &linprocfs_doprocmem,
procfs_attr_rw, &procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
+ pfs_create_file(dir, "mountinfo", &linprocfs_doprocmountinfo,
+ NULL, NULL, NULL, PFS_RD);
pfs_create_file(dir, "mounts", &linprocfs_domtab,
NULL, NULL, NULL, PFS_RD);
pfs_create_link(dir, "root", &linprocfs_doprocroot,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 22, 5:32 AM (9 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28932909
Default Alt Text
D27136.diff (6 KB)
Attached To
Mode
D27136: linprocfs(5): Add rudimentary /proc/<pid>/mountinfo
Attached
Detach File
Event Timeline
Log In to Comment