summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorambrisko <ambrisko@FreeBSD.org>2009-03-26 17:14:22 +0000
committerambrisko <ambrisko@FreeBSD.org>2009-03-26 17:14:22 +0000
commitac334eb30e7fc51d608733da4eef1ad1f9360aee (patch)
treec9846c9d840f38d40234dc55f72ed1de2e7af370 /sys/compat
parent6164bdbd68ca59de5e16e2802028373e5beeb6f5 (diff)
downloadFreeBSD-src-ac334eb30e7fc51d608733da4eef1ad1f9360aee.zip
FreeBSD-src-ac334eb30e7fc51d608733da4eef1ad1f9360aee.tar.gz
Add stuff to support upcoming BMC/IPMI flashing of newer Dell machine
via the Linux tool. - Add Linux shim to ipmi(4) - Create a partitions file to linprocfs to make Linux fdisk see disks. This file is dynamic so we can see disks come and go. - Convert msdosfs to vfat in mtab since Linux uses that for msdosfs. - In the Linux mount path convert vfat passed in to msdosfs so Linux mount works on FreeBSD. Note that tasting works so that if da0 is a msdos file system /compat/linux/bin/mount /dev/da0 /mnt works. - fix a 64it bug for l_off_t. Grabing sh, mount, fdisk, df from Linux, creating a symlink of mtab to /compat/linux/etc/mtab and then some careful unpacking of the Linux bmc update tool and hacking makes it work on newer Dell boxes. Note, probably if you can't figure out how to do this, then you probably shouldn't be doing it :-)
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linprocfs/linprocfs.c72
-rw-r--r--sys/compat/linux/linux_file.c9
2 files changed, 81 insertions, 0 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 5cc1f7d..52f6e94 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vmmeter.h>
#include <sys/vnode.h>
#include <sys/vimage.h>
+#include <sys/bus.h>
#include <net/if.h>
#include <net/route.h>
@@ -90,6 +91,9 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
+#include <geom/geom.h>
+#include <geom/geom_int.h>
+
#if defined(__i386__) || defined(__amd64__)
#include <machine/cputypes.h>
#include <machine/md_var.h>
@@ -359,6 +363,9 @@ linprocfs_domtab(PFS_FILL_ARGS)
sbuf_printf(sb, "/sys %s sysfs %s", mntto,
mp->mnt_stat.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,
mp->mnt_stat.f_flags & MNT_RDONLY ? "ro" : "rw");
}
@@ -383,6 +390,69 @@ linprocfs_domtab(PFS_FILL_ARGS)
}
/*
+ * Filler function for proc/partitions
+ *
+ */
+static int
+linprocfs_dopartitions(PFS_FILL_ARGS)
+{
+ struct g_class *cp;
+ struct g_geom *gp;
+ struct g_provider *pp;
+ struct nameidata nd;
+ const char *lep;
+ char *dlep, *flep;
+ size_t lep_len;
+ int error;
+ int major, minor;
+
+ /* resolve symlinks etc. in the emulation tree prefix */
+ NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, linux_emul_path, td);
+ flep = NULL;
+ error = namei(&nd);
+ lep = linux_emul_path;
+ if (error == 0) {
+ if (vn_fullpath(td, nd.ni_vp, &dlep, &flep) == 0)
+ lep = dlep;
+ vrele(nd.ni_vp);
+ VFS_UNLOCK_GIANT(NDHASGIANT(&nd));
+ }
+ lep_len = strlen(lep);
+
+ g_topology_lock();
+ error = 0;
+ sbuf_printf(sb, "major minor #blocks name rio rmerge rsect "
+ "ruse wio wmerge wsect wuse running use aveq\n");
+
+ LIST_FOREACH(cp, &g_classes, class) {
+ if (strcmp(cp->name, "DISK") == 0 ||
+ strcmp(cp->name, "PART") == 0)
+ LIST_FOREACH(gp, &cp->geom, geom) {
+ LIST_FOREACH(pp, &gp->provider, provider) {
+ if (linux_driver_get_major_minor(
+ pp->name, &major, &minor) != 0) {
+ major = 0;
+ minor = 0;
+ }
+ sbuf_printf(sb, "%d %d %lld %s "
+ "%d %d %d %d %d "
+ "%d %d %d %d %d %d\n",
+ major, minor,
+ (long long)pp->mediasize, pp->name,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0);
+ }
+ }
+ }
+ g_topology_unlock();
+
+ if (flep != NULL)
+ free(flep, M_TEMP);
+ return (error);
+}
+
+
+/*
* Filler function for proc/stat
*/
static int
@@ -1206,6 +1276,8 @@ linprocfs_init(PFS_INIT_ARGS)
NULL, NULL, NULL, PFS_RD);
pfs_create_file(root, "mtab", &linprocfs_domtab,
NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(root, "partitions", &linprocfs_dopartitions,
+ NULL, NULL, NULL, PFS_RD);
pfs_create_link(root, "self", &procfs_docurproc,
NULL, NULL, NULL, 0);
pfs_create_file(root, "stat", &linprocfs_dostat,
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index b368429..54ab6a2 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -1109,6 +1109,9 @@ linux_mount(struct thread *td, struct linux_mount_args *args)
} else if (strcmp(fstypename, "proc") == 0) {
strcpy(fstypename, "linprocfs");
fsdata = NULL;
+ } else if (strcmp(fstypename, "vfat") == 0) {
+ strcpy(fstypename, "msdosfs");
+ fsdata = NULL;
} else {
return (ENODEV);
}
@@ -1135,6 +1138,12 @@ linux_mount(struct thread *td, struct linux_mount_args *args)
"fstype", fstypename,
"fspath", mntonname,
NULL);
+ } else if (strcmp(fstypename, "msdosfs") == 0) {
+ error = kernel_vmount(fsflags,
+ "fstype", fstypename,
+ "fspath", mntonname,
+ "from", mntfromname,
+ NULL);
} else
error = EOPNOTSUPP;
return (error);
OpenPOWER on IntegriCloud