diff options
author | ambrisko <ambrisko@FreeBSD.org> | 2009-03-26 17:14:22 +0000 |
---|---|---|
committer | ambrisko <ambrisko@FreeBSD.org> | 2009-03-26 17:14:22 +0000 |
commit | ac334eb30e7fc51d608733da4eef1ad1f9360aee (patch) | |
tree | c9846c9d840f38d40234dc55f72ed1de2e7af370 /sys/compat | |
parent | 6164bdbd68ca59de5e16e2802028373e5beeb6f5 (diff) | |
download | FreeBSD-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.c | 72 | ||||
-rw-r--r-- | sys/compat/linux/linux_file.c | 9 |
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); |