[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 2/5] lib/devfs: Adapt imported devfs to Unikraft
Signed-off-by: Vlad-Andrei Badoiu <vlad_andrei.badoiu@xxxxxxxxxxxxxxx> --- lib/Config.uk | 1 + lib/Makefile.uk | 1 + lib/devfs/Config.uk | 10 ++ lib/devfs/Makefile.uk | 4 + lib/devfs/devfs.h | 2 +- lib/devfs/devfs_vnops.c | 123 +++++++++++++------ lib/devfs/device.c | 239 +++++++++---------------------------- lib/devfs/include/device.h | 15 +-- 8 files changed, 167 insertions(+), 228 deletions(-) create mode 100644 lib/devfs/Config.uk create mode 100644 lib/devfs/Makefile.uk diff --git a/lib/Config.uk b/lib/Config.uk index 553d4c6b..ea8b06a3 100644 --- a/lib/Config.uk +++ b/lib/Config.uk @@ -40,6 +40,7 @@ source "lib/ukschedcoop/Config.uk" source "lib/fdt/Config.uk" source "lib/vfscore/Config.uk" source "lib/ramfs/Config.uk" +source "lib/devfs/Config.uk" source "lib/uklock/Config.uk" source "lib/ukmpi/Config.uk" source "lib/ukswrand/Config.uk" diff --git a/lib/Makefile.uk b/lib/Makefile.uk index 54a957de..97fdf7b2 100644 --- a/lib/Makefile.uk +++ b/lib/Makefile.uk @@ -18,6 +18,7 @@ $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukschedcoop)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/fdt)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/vfscore)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ramfs)) +$(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/devfs)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/uklock)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukmpi)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukbus)) diff --git a/lib/devfs/Config.uk b/lib/devfs/Config.uk new file mode 100644 index 00000000..e38a616e --- /dev/null +++ b/lib/devfs/Config.uk @@ -0,0 +1,10 @@ +config LIBDEVFS + bool "devfs: devfs file system" + default n + depends on LIBVFSCORE +if LIBDEVFS + config LIBDEVFS_USE_RAMFS + bool "Use ramfs as root" + default n + select LIBRAMFS +endif diff --git a/lib/devfs/Makefile.uk b/lib/devfs/Makefile.uk new file mode 100644 index 00000000..f33187f3 --- /dev/null +++ b/lib/devfs/Makefile.uk @@ -0,0 +1,4 @@ +$(eval $(call addlib_s,libdevfs,$(CONFIG_LIBDEVFS))) + +LIBDEVFS_SRCS-y += $(LIBDEVFS_BASE)/device.c +LIBDEVFS_SRCS-y += $(LIBDEVFS_BASE)/devfs_vnops.c diff --git a/lib/devfs/devfs.h b/lib/devfs/devfs.h index bdf50609..c2197f79 100644 --- a/lib/devfs/devfs.h +++ b/lib/devfs/devfs.h @@ -30,7 +30,7 @@ #ifndef _DEVFS_H #define _DEVFS_H -#include <assert.h> +#include <uk/assert.h> /* #define DEBUG_DEVFS 1 */ diff --git a/lib/devfs/devfs_vnops.c b/lib/devfs/devfs_vnops.c index 1e69e4a6..70987477 100644 --- a/lib/devfs/devfs_vnops.c +++ b/lib/devfs/devfs_vnops.c @@ -31,6 +31,10 @@ * devfs - device file system. */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include <sys/stat.h> #include <ctype.h> @@ -41,27 +45,32 @@ #include <limits.h> #include <fcntl.h> #include <stdio.h> +#include <sys/mount.h> -#include <osv/prex.h> -#include <osv/device.h> -#include <osv/vnode.h> -#include <osv/mount.h> -#include <osv/dentry.h> +#include <dirent.h> +#include <vfscore/prex.h> +#include <vfscore/vnode.h> +#include <vfscore/mount.h> +#include <vfscore/dentry.h> +#include <vfscore/file.h> + +#include <vfscore/fs.h> #include "devfs.h" +#include "include/device.h" + +#include <uk/ctors.h> #ifdef DEBUG_DEVFS -#define DPRINTF(a) dprintf a +#define DPRINTF(X) uk_pr_debug(X) #else -#define DPRINTF(a) do {} while (0) +#define DPRINTF(X) #endif -#define ASSERT(e) assert(e) - static uint64_t inode_count = 1; /* inode 0 is reserved to root */ static int -devfs_open(struct file *fp) +devfs_open(struct vfscore_file *fp) { struct vnode *vp = fp->f_dentry->d_vnode; char *path = fp->f_dentry->d_path; @@ -90,7 +99,7 @@ devfs_open(struct file *fp) } static int -devfs_close(struct vnode *vp, struct file *fp) +devfs_close(struct vnode *vp, struct vfscore_file *fp) { DPRINTF(("devfs_close: fp=%x\n", fp)); @@ -98,27 +107,27 @@ devfs_close(struct vnode *vp, struct file *fp) if (!strcmp(fp->f_dentry->d_path, "/")) /* root ? */ return 0; - return device_close((device*)vp->v_data); + return device_close((struct device*)vp->v_data); } static int -devfs_read(struct vnode *vp, struct file *fp, struct uio *uio, int ioflags) +devfs_read(struct vnode *vp, struct vfscore_file *fp, struct uio *uio, int ioflags) { - return device_read((device*)vp->v_data, uio, ioflags); + return device_read((struct device*)vp->v_data, uio, ioflags); } static int devfs_write(struct vnode *vp, struct uio *uio, int ioflags) { - return device_write((device*)vp->v_data, uio, ioflags); + return device_write((struct device*)vp->v_data, uio, ioflags); } static int -devfs_ioctl(struct vnode *vp, struct file *fp, u_long cmd, void *arg) +devfs_ioctl(struct vnode *vp, struct vfscore_file *fp, unsigned long cmd, void *arg) { int error; - error = device_ioctl((device*)vp->v_data, cmd, arg); + error = device_ioctl((struct device*)vp->v_data, cmd, arg); DPRINTF(("devfs_ioctl: cmd=%x\n", cmd)); return error; } @@ -149,7 +158,7 @@ devfs_lookup(struct vnode *dvp, char *name, struct vnode **vpp) break; i++; } - if (vget(dvp->v_mount, inode_count++, &vp)) { + if (vfscore_vget(dvp->v_mount, inode_count++, &vp)) { /* found in cache */ *vpp = vp; return 0; @@ -171,7 +180,7 @@ devfs_lookup(struct vnode *dvp, char *name, struct vnode **vpp) * @vp: vnode of the directory. */ static int -devfs_readdir(struct vnode *vp, struct file *fp, struct dirent *dir) +devfs_readdir(struct vnode *vp, struct vfscore_file *fp, struct dirent *dir) { struct devinfo info; int error, i; @@ -204,15 +213,10 @@ devfs_readdir(struct vnode *vp, struct file *fp, struct dirent *dir) static int devfs_unmount(struct mount *mp, int flags) { - release_mp_dentries(mp); + vfscore_release_mp_dentries(mp); return 0; } -int -devfs_init(void) -{ - return 0; -} static int devfs_getattr(struct vnode *vnode, struct vattr *attr) @@ -222,25 +226,37 @@ devfs_getattr(struct vnode *vnode, struct vattr *attr) return 0; } -#define devfs_mount ((vfsop_mount_t)vfs_nullop) -#define devfs_sync ((vfsop_sync_t)vfs_nullop) -#define devfs_vget ((vfsop_vget_t)vfs_nullop) -#define devfs_statfs ((vfsop_statfs_t)vfs_nullop) +int +vop_einval(void) +{ + return EINVAL; +} + +int +vop_eperm(void) +{ + return EPERM; +} + +#define devfs_mount ((vfsop_mount_t)vfscore_nullop) +#define devfs_sync ((vfsop_sync_t)vfscore_nullop) +#define devfs_vget ((vfsop_vget_t)vfscore_nullop) +#define devfs_statfs ((vfsop_statfs_t)vfscore_nullop) -#define devfs_seek ((vnop_seek_t)vop_nullop) -#define devfs_fsync ((vnop_fsync_t)vop_nullop) +#define devfs_seek ((vnop_seek_t)vfscore_vop_nullop) +#define devfs_fsync ((vnop_fsync_t)vfscore_vop_nullop) #define devfs_create ((vnop_create_t)vop_einval) #define devfs_remove ((vnop_remove_t)vop_einval) #define devfs_rename ((vnop_rename_t)vop_einval) #define devfs_mkdir ((vnop_mkdir_t)vop_einval) #define devfs_rmdir ((vnop_rmdir_t)vop_einval) #define devfs_setattr ((vnop_setattr_t)vop_eperm) -#define devfs_inactive ((vnop_inactive_t)vop_nullop) -#define devfs_truncate ((vnop_truncate_t)vop_nullop) +#define devfs_inactive ((vnop_inactive_t)vfscore_vop_nullop) +#define devfs_truncate ((vnop_truncate_t)vfscore_vop_nullop) #define devfs_link ((vnop_link_t)vop_eperm) -#define devfs_fallocate ((vnop_fallocate_t)vop_nullop) -#define devfs_readlink ((vnop_readlink_t)vop_nullop) -#define devfs_symlink ((vnop_symlink_t)vop_nullop) +#define devfs_fallocate ((vnop_fallocate_t)vfscore_vop_nullop) +#define devfs_readlink ((vnop_readlink_t)vfscore_vop_nullop) +#define devfs_symlink ((vnop_symlink_t)vfscore_vop_nullop) /* * vnode operations @@ -265,7 +281,7 @@ struct vnops devfs_vnops = { devfs_inactive, /* inactive */ devfs_truncate, /* truncate */ devfs_link, /* link */ - (vnop_cache_t) nullptr, /* arc */ + (vnop_cache_t) NULL, /* arc */ devfs_fallocate, /* fallocate */ devfs_readlink, /* read link */ devfs_symlink, /* symbolic link */ @@ -282,3 +298,36 @@ struct vfsops devfs_vfsops = { devfs_statfs, /* statfs */ &devfs_vnops, /* vnops */ }; + +static struct vfscore_fs_type fs_devfs = { + .vs_name = "devfs", + .vs_init = NULL, + .vs_op = &devfs_vfsops, +}; + +UK_FS_REGISTER(fs_devfs); + +__constructor_prio(101) static void devfs_init(void) +{ +#ifdef CONFIG_LIBDEVFS_USE_RAMFS + int ret; + + ret = mount("", "/", "ramfs", 0, NULL); + if (ret != 0) { + DPRINTF(("Failed to mount / in %s\n", __func__)); + return; + } + + ret = mkdir("/dev", S_IRWXU); + if (ret != 0) { + DPRINTF(("Failed to mkdir /dev in %s\n", __func__)); + return; + } + + ret = mount("", "/dev", "devfs", 0, NULL); + if (ret != 0) { + DPRINTF(("Failed to mount /dev as devfs in %s\n", __func__)); + return; + } +#endif +} diff --git a/lib/devfs/device.c b/lib/devfs/device.c index a0cd9768..f32b26dc 100644 --- a/lib/devfs/device.c +++ b/lib/devfs/device.c @@ -45,21 +45,16 @@ #include <stdio.h> #include <unistd.h> #include <errno.h> -#include <assert.h> +#include <uk/assert.h> #include <string.h> -#include <osv/prex.h> -#include <osv/mutex.h> -#include <osv/device.h> -#include <osv/debug.h> -#include <osv/buf.h> +#include <vfscore/prex.h> +#include <uk/essentials.h> +#include <uk/mutex.h> -#include <geom/geom_disk.h> - -mutex sched_mutex; -#define sched_lock() sched_mutex.lock() -#define sched_unlock() sched_mutex.unlock() +#include "include/device.h" +static struct uk_mutex devfs_lock = UK_MUTEX_INITIALIZER(devfs_lock); /* list head of the devices */ static struct device *device_list = NULL; @@ -92,85 +87,31 @@ struct partition_table_entry { uint32_t total_sectors; } __attribute__((packed)); -/* - * read_partition_table - given a device @dev, create one subdevice per partition - * found in that device. - * - * This function will read a partition table from the canonical location of the - * device pointed by @dev. For each partition found, a new device will be - * created. The newly created device will have most of its data copied from - * @dev, except for its name, offset and size. - */ -void read_partition_table(struct device *dev) -{ - struct buf *bp; - unsigned long offset; - int index; - - if (bread(dev, 0, &bp) != 0) { - debugf("read_partition_table failed for %s\n", dev->name); - return; - } - - sched_lock(); - // A real partition table (MBR) ends in the two bytes 0x55, 0xAA (see - // arch/x64/boot16.S on where we put those on the OSv image). If we - // don't find those, this is an unpartitioned disk. - if (((unsigned char*)bp->b_data)[510] == 0x55 && - ((unsigned char*)bp->b_data)[511] == 0xAA) - for (offset = 0x1be, index = 0; offset < 0x1fe; offset += 0x10, index++) { - char dev_name[MAXDEVNAME]; - struct device *new_dev; - - auto* entry = static_cast<struct partition_table_entry*>(bp->b_data + offset); - - if (entry->system_id == 0) { - continue; - } - - if (entry->starting_sector == 0) { - continue; - } - - snprintf(dev_name, MAXDEVNAME, "%s.%d", dev->name, index); - new_dev = device_create(dev->driver, dev_name, dev->flags); - free(new_dev->private_data); - - new_dev->offset = (off_t)entry->rela_sector << 9; - new_dev->size = (off_t)entry->total_sectors << 9; - new_dev->max_io_size = dev->max_io_size; - new_dev->private_data = dev->private_data; - device_set_softc(new_dev, device_get_softc(dev)); - } - - sched_unlock(); - brelse(bp); -} void device_register(struct device *dev, const char *name, int flags) { size_t len; void *priv = NULL; - assert(dev->driver != NULL); + UK_ASSERT(dev->driver != NULL); /* Check the length of name. */ len = strnlen(name, MAXDEVNAME); if (len == 0 || len >= MAXDEVNAME) return; - sched_lock(); + uk_mutex_lock(&devfs_lock); /* Check if specified name is already used. */ if (device_lookup(name) != NULL) - sys_panic("duplicate device"); + UK_CRASH("duplicate device"); /* * Allocate a device and device private data. */ if (dev->driver->devsz != 0) { if ((priv = malloc(dev->driver->devsz)) == NULL) - sys_panic("devsz"); + UK_CRASH("devsz"); memset(priv, 0, dev->driver->devsz); } @@ -184,7 +125,7 @@ void device_register(struct device *dev, const char *name, int flags) dev->max_io_size = UINT_MAX; device_list = dev; - sched_unlock(); + uk_mutex_unlock(&devfs_lock); } @@ -201,7 +142,7 @@ device_create(struct driver *drv, const char *name, int flags) struct device *dev; size_t len; - assert(drv != NULL); + UK_ASSERT(drv != NULL); /* Check the length of name. */ len = strnlen(name, MAXDEVNAME); @@ -211,27 +152,14 @@ device_create(struct driver *drv, const char *name, int flags) /* * Allocate a device structure. */ - if ((dev = new device) == NULL) - sys_panic("device_create"); + if ((dev = malloc(sizeof(struct device))) == NULL) + UK_CRASH("device_create"); - dev->driver = drv; - device_register(dev, name, flags); + dev->driver = drv; + device_register(dev, name, flags); return dev; } -#if 0 -/* - * Return device's private data. - */ -static void * -device_private(struct device *dev) -{ - assert(dev != NULL); - assert(dev->private_data != NULL); - - return dev->private_data; -} -#endif /* * Return true if specified device is valid. @@ -260,13 +188,29 @@ static int device_reference(struct device *dev) { - sched_lock(); + uk_mutex_lock(&devfs_lock); if (!device_valid(dev)) { - sched_unlock(); + uk_mutex_unlock(&devfs_lock); + return ENODEV; + } + dev->refcnt++; + uk_mutex_unlock(&devfs_lock); + return 0; +} + +/* + * Increment the reference count on an active device. + */ +static int +device_reference_locked(struct device *dev) +{ + UK_ASSERT(uk_mutex_is_locked(&devfs_lock)); + + if (!device_valid(dev)) { + uk_mutex_unlock(&devfs_lock); return ENODEV; } dev->refcnt++; - sched_unlock(); return 0; } @@ -279,9 +223,10 @@ device_release(struct device *dev) { struct device **tmp; - sched_lock(); + uk_mutex_lock(&devfs_lock); + if (--dev->refcnt > 0) { - sched_unlock(); + uk_mutex_unlock(&devfs_lock); return; } /* @@ -293,22 +238,22 @@ device_release(struct device *dev) break; } } - delete dev; - sched_unlock(); + free(dev); + uk_mutex_unlock(&devfs_lock); } int device_destroy(struct device *dev) { - sched_lock(); + uk_mutex_lock(&devfs_lock); if (!device_valid(dev)) { - sched_unlock(); + uk_mutex_unlock(&devfs_lock); return ENODEV; } dev->active = 0; + uk_mutex_unlock(&devfs_lock); device_release(dev); - sched_unlock(); return 0; } @@ -329,20 +274,20 @@ device_open(const char *name, int mode, struct device **devp) struct device *dev; int error; - sched_lock(); + uk_mutex_lock(&devfs_lock); if ((dev = device_lookup(name)) == NULL) { - sched_unlock(); + uk_mutex_unlock(&devfs_lock); return ENXIO; } - error = device_reference(dev); + + error = device_reference_locked(dev); if (error) { - sched_unlock(); return error; } - sched_unlock(); + uk_mutex_unlock(&devfs_lock); ops = dev->driver->devops; - assert(ops->open != NULL); + UK_ASSERT(ops->open != NULL); error = (*ops->open)(dev, mode); *devp = dev; @@ -366,7 +311,7 @@ device_close(struct device *dev) return error; ops = dev->driver->devops; - assert(ops->close != NULL); + UK_ASSERT(ops->close != NULL); error = (*ops->close)(dev); device_release(dev); @@ -383,7 +328,7 @@ device_read(struct device *dev, struct uio *uio, int ioflags) return error; ops = dev->driver->devops; - assert(ops->read != NULL); + UK_ASSERT(ops->read != NULL); error = (*ops->read)(dev, uio, ioflags); device_release(dev); @@ -400,7 +345,7 @@ device_write(struct device *dev, struct uio *uio, int ioflags) return error; ops = dev->driver->devops; - assert(ops->write != NULL); + UK_ASSERT(ops->write != NULL); error = (*ops->write)(dev, uio, ioflags); device_release(dev); @@ -415,7 +360,7 @@ device_write(struct device *dev, struct uio *uio, int ioflags) * pointed by the arg value. */ int -device_ioctl(struct device *dev, u_long cmd, void *arg) +device_ioctl(struct device *dev, unsigned long cmd, void *arg) { struct devops *ops; int error; @@ -424,92 +369,25 @@ device_ioctl(struct device *dev, u_long cmd, void *arg) return error; ops = dev->driver->devops; - assert(ops->ioctl != NULL); + UK_ASSERT(ops->ioctl != NULL); error = (*ops->ioctl)(dev, cmd, arg); device_release(dev); return error; } -#if 0 -/* - * Device control - devctl is similar to ioctl, but is invoked from - * other device driver rather than from user application. - */ -static int -device_control(struct device *dev, u_long cmd, void *arg) -{ - struct devops *ops; - int error; - - assert(dev != NULL); - - sched_lock(); - ops = dev->driver->devops; - assert(ops->devctl != NULL); - error = (*ops->devctl)(dev, cmd, arg); - sched_unlock(); - return error; -} - -/* - * device_broadcast - broadcast devctl command to all device objects. - * - * If "force" argument is true, we will continue command - * notification even if some driver returns an error. In this - * case, this routine returns EIO error if at least one driver - * returns an error. - * - * If force argument is false, a kernel stops the command processing - * when at least one driver returns an error. In this case, - * device_broadcast will return the error code which is returned - * by the driver. - */ -static int -device_broadcast(u_long cmd, void *arg, int force) -{ - struct device *dev; - struct devops *ops; - int error, retval = 0; - - sched_lock(); - - for (dev = device_list; dev != NULL; dev = dev->next) { - /* - * Call driver's devctl() routine. - */ - ops = dev->driver->devops; - if (ops == NULL) - continue; - - assert(ops->devctl != NULL); - error = (*ops->devctl)(dev, cmd, arg); - if (error) { - if (force) - retval = EIO; - else { - retval = error; - break; - } - } - } - sched_unlock(); - return retval; -} -#endif - /* * Return device information. */ int device_info(struct devinfo *info) { - u_long target = info->cookie; - u_long i = 0; + unsigned long target = info->cookie; + unsigned long i = 0; struct device *dev; int error = ESRCH; - sched_lock(); + uk_mutex_lock(&devfs_lock); for (dev = device_list; dev != NULL; dev = dev->next) { if (i++ == target) { info->cookie = i; @@ -520,7 +398,7 @@ device_info(struct devinfo *info) break; } } - sched_unlock(); + uk_mutex_unlock(&devfs_lock); return error; } @@ -535,3 +413,4 @@ nullop(void) { return 0; } + diff --git a/lib/devfs/include/device.h b/lib/devfs/include/device.h index 16d2e470..95e247d8 100644 --- a/lib/devfs/include/device.h +++ b/lib/devfs/include/device.h @@ -30,12 +30,9 @@ #ifndef _DEVICE_H #define _DEVICE_H -#include <sys/cdefs.h> #include <sys/types.h> -#include <osv/uio.h> - -__BEGIN_DECLS +#include <vfscore/uio.h> #define MAXDEVNAME 12 #define DO_RWMASK 0x3 @@ -47,7 +44,7 @@ struct device; * Device information */ struct devinfo { - u_long cookie; /* index cookie */ + unsigned long cookie; /* index cookie */ struct device *id; /* device id */ int flags; /* device characteristics flags */ char name[MAXDEVNAME]; /* device name */ @@ -65,8 +62,8 @@ typedef int (*devop_open_t) (struct device *, int); typedef int (*devop_close_t) (struct device *); typedef int (*devop_read_t) (struct device *, struct uio *, int); typedef int (*devop_write_t) (struct device *, struct uio *, int); -typedef int (*devop_ioctl_t) (struct device *, u_long, void *); -typedef int (*devop_devctl_t) (struct device *, u_long, void *); +typedef int (*devop_ioctl_t) (struct device *, unsigned long, void *); +typedef int (*devop_devctl_t) (struct device *, unsigned long, void *); typedef void (*devop_strategy_t)(struct bio *); /* @@ -191,7 +188,7 @@ int device_open(const char *, int, struct device **); int device_close(struct device *); int device_read(struct device *, struct uio *, int); int device_write(struct device *, struct uio *, int); -int device_ioctl(struct device *, u_long, void *); +int device_ioctl(struct device *, unsigned long, void *); int device_info(struct devinfo *); int bdev_read(struct device *dev, struct uio *uio, int ioflags); @@ -208,6 +205,4 @@ int device_destroy(struct device *dev); void device_register(struct device *device, const char *name, int flags); void read_partition_table(struct device *device); -__END_DECLS - #endif /* !_DEVICE_H */ -- 2.21.0 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |