Hi, see attached patch.

On 3/4/20 6:45 pm, Samuel Thibault wrote:
> I don't see the reason why for most of them: libpthread.a,
> libpciaccess.a, libdl.a are not _pic.a variants for instance.
> 
> For a start, try to use non-pic variants for libtrivfs,
> libshouldbeinlibc, libports, libiohelp, libihash, libfshelp. Then try
> also for libmachdev. And my guess is that only the rump ones seemingly
> need it, and possibly it just means that the rump package builds them in
> an odd way.

I fixed this, except rump.

> Isn't that ./buildrump.sh/src/sys/sys/ioccom.h ?

Oh yea, I have added that one instead to our tree (rump doesn't have it).

>>> There are a couple mach_print debugging calls left.

Oops, yeah done.

Damien
>From fd76bb26a629dbe42840ff8807047fe531494bc0 Mon Sep 17 00:00:00 2001
From: Damien Zammit <dam...@zamaudio.com>
Date: Sun, 29 Mar 2020 22:37:23 +1100
Subject: [PATCH] rumpdisk: Add userspace disk support via librump

---
 Makefile              |   4 +
 configure.ac          |  14 ++
 rumpdisk/Makefile     |  35 +++++
 rumpdisk/block-rump.c | 341 ++++++++++++++++++++++++++++++++++++++++++
 rumpdisk/block-rump.h |  23 +++
 rumpdisk/ioc-rump.h   |  32 ++++
 rumpdisk/main.c       |  39 +++++
 7 files changed, 488 insertions(+)
 create mode 100644 rumpdisk/Makefile
 create mode 100644 rumpdisk/block-rump.c
 create mode 100644 rumpdisk/block-rump.h
 create mode 100644 rumpdisk/ioc-rump.h
 create mode 100644 rumpdisk/main.c

diff --git a/Makefile b/Makefile
index 6b1e8066..caf99921 100644
--- a/Makefile
+++ b/Makefile
@@ -49,6 +49,10 @@ prog-subdirs = auth proc exec term \
 	       acpi \
 	       shutdown
 
+ifeq ($(HAVE_LIBRUMP),1)
+prog-subdirs += rumpdisk
+endif
+
 ifeq ($(HAVE_SUN_RPC),yes)
 prog-subdirs += nfs nfsd
 endif
diff --git a/configure.ac b/configure.ac
index 897a9146..76c10df3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,6 +243,20 @@ AS_IF([test "x$with_libz" != xno], [
 ])
 AC_SUBST([HAVE_LIBZ])
 
+AC_ARG_WITH([librump],
+  [AS_HELP_STRING([--without-librump], [disable librump])], , [with_librump=yes])
+
+AC_DEFUN([LIBRUMP_FAIL], [
+  AC_MSG_FAILURE([Please install required libraries or use --without-librump.])
+])
+AS_IF([test "x$with_librump" != xno], [
+  AC_CHECK_HEADER([rump/rump.h],
+    [AC_DEFINE(HAVE_RUMP_RUMP_H)],
+    [LIBRUMP_FAIL])
+  AC_CHECK_LIB(rump, rump_init, [HAVE_LIBRUMP=1], [LIBRUMP_FAIL])
+])
+AC_SUBST([HAVE_LIBRUMP])
+
 AC_ARG_ENABLE(boot-store-types,
 [  --enable-boot-store-types=TYPES...
 			  list of store types included in statically
diff --git a/rumpdisk/Makefile b/rumpdisk/Makefile
new file mode 100644
index 00000000..ab4c3ef7
--- /dev/null
+++ b/rumpdisk/Makefile
@@ -0,0 +1,35 @@
+#
+#   Copyright (C) 2019 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU General Public License as
+#   published by the Free Software Foundation; either version 2, or (at
+#   your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+RUMPPATH=/usr/lib
+RUMPLIBS=rump rumpuser rumpdev rumpdev_disk rumpdev_pci rumpvfs rumpdev_ahcisata
+RUMPEXTRA=rumpdev_scsipi
+
+dir := rumpdisk
+makemode := server
+
+SRCS = main.c block-rump.c
+LCLHDRS = block-rump.h ioc-rump.h
+target = rumpdisk
+OBJS = $(SRCS:.c=.o)
+HURDLIBS = machdev ports trivfs shouldbeinlibc iohelp ihash fshelp 
+LDLIBS += -lpthread -lpciaccess -ldl
+LDLIBS += -Wl,--whole-archive $(RUMPLIBS:%=$(RUMPPATH)/lib%_pic.a) -Wl,--no-whole-archive $(RUMPEXTRA:%=$(RUMPPATH)/lib%_pic.a)
+
+include ../Makeconf
+
+rumpdisk.static: main.o block-rump.o
diff --git a/rumpdisk/block-rump.c b/rumpdisk/block-rump.c
new file mode 100644
index 00000000..6ab66eeb
--- /dev/null
+++ b/rumpdisk/block-rump.c
@@ -0,0 +1,341 @@
+/*
+ * Rump block driver support
+ *
+ * Copyright (C) 2019 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "mach_U.h"
+
+#include <mach.h>
+#include <hurd.h>
+#include <hurd/ports.h>
+
+#define MACH_INCLUDE
+
+#include "libmachdev/machdev.h"
+#include "device_reply_U.h"
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+#include <rump/rumperrno2host.h>
+#include "ioc-rump.h"
+
+#define DISK_NAME_LEN 32
+
+/* One of these is associated with each open instance of a device.  */
+struct block_data
+{
+  struct port_info port;	/* device port */
+  struct machdev_emul_device device;	/* generic device structure */
+  dev_mode_t mode;		/* r/w etc */
+  int rump_fd;			/* block device fd handle */
+  char name[DISK_NAME_LEN];	/* eg /dev/wd0 */
+  off_t media_size;		/* total block device size */
+  uint32_t block_size;		/* size in bytes of 1 sector */
+  bool taken;			/* simple refcount */
+  struct block_data *next;
+};
+
+/* Return a send right associated with network device ND.  */
+static mach_port_t
+dev_to_port (void *nd)
+{
+  return (nd ? ports_get_send_right (nd) : MACH_PORT_NULL);
+}
+
+static struct block_data *block_head;
+static struct machdev_device_emulation_ops rump_block_emulation_ops;
+
+static struct block_data *
+search_bd (char *name)
+{
+  struct block_data *bd = block_head;
+
+  while (bd)
+    {
+      if (!strcmp (bd->name, name))
+	return bd;
+      bd = bd->next;
+    }
+  return NULL;
+}
+
+/* BSD name of whole disk device is /dev/wdXd
+ * but we will receive /dev/wdX as the name */
+static void
+translate_name (char *name, char *output)
+{
+  snprintf (output, DISK_NAME_LEN, "%sd", name);
+}
+
+static int
+dev_mode_to_rump_mode (const dev_mode_t mode)
+{
+  int ret = 0;
+  if (mode & D_READ)
+    {
+      if (mode & D_WRITE)
+	ret = RUMP_O_RDWR;
+      else
+	ret = RUMP_O_RDONLY;
+    }
+  else
+    {
+      if (mode & D_WRITE)
+	ret = RUMP_O_WRONLY;
+    }
+  return ret;
+}
+
+static void
+device_init (void)
+{
+  rump_init ();
+}
+
+static io_return_t
+device_close (void *d)
+{
+  io_return_t err;
+  struct block_data *bd = d;
+
+  err = rump_errno2host (rump_sys_close (bd->rump_fd));
+
+  return err;
+}
+
+static void
+device_dealloc (void *d)
+{
+  rump_sys_reboot (0, NULL);
+}
+
+static io_return_t
+device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
+	     dev_mode_t mode, char *name, device_t * devp,
+	     mach_msg_type_name_t * devicePoly)
+{
+  io_return_t err = D_SUCCESS;
+  struct block_data *bd = NULL;
+  char dev_name[DISK_NAME_LEN + 1];
+  off_t media_size;
+  uint32_t block_size;
+
+  translate_name (name, dev_name);
+
+  /* Find previous device or open if new */
+  bd = search_bd (name);
+  if (!bd)
+    {
+      err = machdev_create_device_port (sizeof (*bd), &bd);
+
+      snprintf (bd->name, DISK_NAME_LEN, "%s", name);
+      bd->mode = mode;
+      bd->device.emul_data = bd;
+      bd->device.emul_ops = &rump_block_emulation_ops;
+      bd->next = block_head;
+      block_head = bd;
+
+      err = rump_sys_open (dev_name, dev_mode_to_rump_mode (bd->mode));
+      if (err < 0)
+	{
+	  err = rump_errno2host (errno);
+	  goto out;
+	}
+      bd->rump_fd = err;
+
+      err = rump_sys_ioctl (bd->rump_fd, DIOCGMEDIASIZE, &media_size);
+      if (err < 0)
+	{
+	  mach_print ("DIOCGMEDIASIZE ioctl fails\n");
+	  err = D_NO_SUCH_DEVICE;
+	  goto out;
+	}
+
+      err = rump_sys_ioctl (bd->rump_fd, DIOCGSECTORSIZE, &block_size);
+      if (err < 0)
+	{
+	  mach_print ("DIOCGSECTORSIZE ioctl fails\n");
+	  err = D_NO_SUCH_DEVICE;
+	  goto out;
+	}
+      bd->media_size = media_size;
+      bd->block_size = block_size;
+
+      err = D_SUCCESS;
+    }
+
+out:
+  if (err)
+    {
+      if (bd)
+	{
+	  ports_port_deref (bd);
+	  ports_destroy_right (bd);
+	  bd = NULL;
+	}
+    }
+
+  if (bd)
+    {
+      *devp = ports_get_right (bd);
+      *devicePoly = MACH_MSG_TYPE_MAKE_SEND;
+    }
+  return err;
+}
+
+static io_return_t
+device_write (void *d, mach_port_t reply_port,
+	      mach_msg_type_name_t reply_port_type, dev_mode_t mode,
+	      recnum_t bn, io_buf_ptr_t data, unsigned int count,
+	      int *bytes_written)
+{
+  struct block_data *bd = d;
+  io_return_t err = D_SUCCESS;
+  int64_t written = 0;
+
+  if ((bd->mode & D_WRITE) == 0)
+    return D_INVALID_OPERATION;
+
+  if (rump_sys_lseek (bd->rump_fd, (off_t) bn * bd->block_size, SEEK_SET) < 0)
+    {
+      *bytes_written = 0;
+      return EIO;
+    }
+
+  written = rump_sys_write (bd->rump_fd, data, count);
+  if (written < 0)
+    {
+      *bytes_written = 0;
+      return EIO;
+    }
+  else
+    {
+      *bytes_written = (int)written;
+      return D_SUCCESS;
+    }
+}
+
+static io_return_t
+device_read (void *d, mach_port_t reply_port,
+	     mach_msg_type_name_t reply_port_type, dev_mode_t mode,
+	     recnum_t bn, int count, io_buf_ptr_t * data,
+	     unsigned *bytes_read)
+{
+  struct block_data *bd = d;
+  io_return_t err = D_SUCCESS;
+  char *buf;
+  int pagesize = sysconf (_SC_PAGE_SIZE);
+  int npages = (count + pagesize - 1) / pagesize;
+
+  if ((bd->mode & D_READ) == 0)
+    return D_INVALID_OPERATION;
+
+  if (count == 0)
+    return D_SUCCESS;
+
+  *data = 0;
+  buf = mmap (NULL, npages * pagesize, PROT_READ | PROT_WRITE,
+	      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+  if (buf == MAP_FAILED)
+    return errno;
+
+  if (rump_sys_lseek (bd->rump_fd, (off_t) bn * bd->block_size, SEEK_SET) < 0)
+    {
+      *bytes_read = 0;
+      return EIO;
+    }
+
+  err = rump_sys_read (bd->rump_fd, buf, count);
+  if (err < 0)
+    {
+      *bytes_read = 0;
+      munmap (buf, npages * pagesize);
+      return EIO;
+    }
+  else
+    {
+      *bytes_read = err;
+      *data = buf;
+      return D_SUCCESS;
+    }
+}
+
+static io_return_t
+device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
+		   mach_msg_type_number_t * count)
+{
+  struct block_data *bd = d;
+
+  switch (flavor)
+    {
+    case DEV_GET_SIZE:
+      status[DEV_GET_SIZE_RECORD_SIZE] = bd->block_size;
+      status[DEV_GET_SIZE_DEVICE_SIZE] = bd->media_size;
+      *count = 2;
+      break;
+    case DEV_GET_RECORDS:
+      status[DEV_GET_RECORDS_RECORD_SIZE] = bd->block_size;
+      status[DEV_GET_RECORDS_DEVICE_RECORDS] =
+	bd->media_size / (unsigned long long) bd->block_size;
+      *count = 2;
+      break;
+    default:
+      return D_INVALID_OPERATION;
+      break;
+    }
+  return D_SUCCESS;
+}
+
+/* FIXME:
+ * Call rump_sys_aio_read/write and return MIG_NO_REPLY from
+ * device_read/write, and send the mig reply once the aio request has
+ * completed. That way, only the aio request will be kept in rumpdisk
+ * memory instead of a whole thread structure.
+ */
+static struct machdev_device_emulation_ops rump_block_emulation_ops = {
+  device_init,
+  NULL,
+  device_dealloc,
+  dev_to_port,
+  device_open,
+  device_close,
+  device_write, /* FIXME: make multithreaded */
+  NULL,
+  device_read, /* FIXME: make multithreaded */
+  NULL,
+  NULL,
+  device_get_status,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
+
+void
+rump_register_block (void)
+{
+  machdev_register (&rump_block_emulation_ops);
+}
diff --git a/rumpdisk/block-rump.h b/rumpdisk/block-rump.h
new file mode 100644
index 00000000..be70b9eb
--- /dev/null
+++ b/rumpdisk/block-rump.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2020 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _BLOCK_RUMP_H_
+#define _BLOCK_RUMP_H_
+
+void rump_register_block (void);
+
+#endif
diff --git a/rumpdisk/ioc-rump.h b/rumpdisk/ioc-rump.h
new file mode 100644
index 00000000..c7d51a4e
--- /dev/null
+++ b/rumpdisk/ioc-rump.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _IOC_RUMP_H_
+#define _IOC_RUMP_H_
+
+#define IOCPARM_MASK    0x1fff
+#define IOCPARM_SHIFT   16
+#define IOCGROUP_SHIFT  8
+#define _IOC(inout, group, num, len) \
+    ((inout) | (((len) & IOCPARM_MASK) << IOCPARM_SHIFT) | \
+    ((group) << IOCGROUP_SHIFT) | (num))
+#define IOC_OUT         (unsigned long)0x40000000
+#define _IOR(g,n,t)     _IOC(IOC_OUT,   (g), (n), sizeof(t))
+#define  DIOCGMEDIASIZE  _IOR('d', 132, off_t)
+#define  DIOCGSECTORSIZE _IOR('d', 133, unsigned int)
+
+#endif
diff --git a/rumpdisk/main.c b/rumpdisk/main.c
new file mode 100644
index 00000000..0181f685
--- /dev/null
+++ b/rumpdisk/main.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "libmachdev/machdev.h"
+#include "block-rump.h"
+#include <pthread.h>
+#include <mach.h>
+
+int
+main ()
+{
+  int err;
+  pthread_t t;
+
+  rump_register_block ();
+  machdev_device_init ();
+  machdev_trivfs_init ();
+  err = pthread_create (&t, NULL, machdev_server, NULL);
+  if (err)
+    return err;
+  pthread_detach (t);
+  machdev_trivfs_server ();
+  return 0;
+}
-- 
2.25.1

Reply via email to