summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmachdevrump/Makefile14
-rw-r--r--libmachdevrump/block.c203
-rw-r--r--libmachdevrump/ds_routines.c7
-rw-r--r--rumpdisk/Makefile7
4 files changed, 144 insertions, 87 deletions
diff --git a/libmachdevrump/Makefile b/libmachdevrump/Makefile
index d876c89f..1c6724af 100644
--- a/libmachdevrump/Makefile
+++ b/libmachdevrump/Makefile
@@ -15,19 +15,27 @@
# along with the GNU Hurd; see the file COPYING. If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+RUMPLIB=/usr/lib/librump
+RUMPLIBS=$(RUMPLIB)_pic.a \
+ $(RUMPLIB)user_pic.a \
+ $(RUMPLIB)dev_pic.a \
+ $(RUMPLIB)dev_disk_pic.a \
+ $(RUMPLIB)dev_pci_pic.a \
+ $(RUMPLIB)vfs_pic.a \
+ $(RUMPLIB)dev_ahcisata_pic.a
+
dir := libmachdevrump
makemode := library
libname = libmachdevrump
SRCS = deviceUser.c machUser.c ds_routines.c trivfs_server.c \
device_replyUser.c deviceServer.c notifyServer.c block.c
-#block.c
LCLHDRS = dev_hdr.h device_emul.h ds_routines.h vm_param.h \
io_req.h machdevrump.h errno-base.h
installhdrs = machdevrump.h
HURDLIBS = ports trivfs
-LDLIBS += -lpthread
-LDLIBS += -lrump -lrumpdev -lrumpdev_disk -lrumpdev_pci -lrumpvfs -lrumpdev_scsipi -lrumpdev_ahcisata
+LDLIBS += -lpthread -ldl -lpciaccess
+LDLIBS += -Wl,--whole-archive $(RUMPLIBS) -Wl,--no-whole-archive $(RUMPLIB)dev_scsipi_pic.a
OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
diff --git a/libmachdevrump/block.c b/libmachdevrump/block.c
index a1f272bc..9648d981 100644
--- a/libmachdevrump/block.c
+++ b/libmachdevrump/block.c
@@ -23,6 +23,7 @@
#include <stdbool.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <semaphore.h>
#include "mach_U.h"
@@ -60,9 +61,13 @@ struct block_data
struct emul_device device; /* generic device structure */
dev_mode_t mode;
int rump_fd; /* block device fd handle */
- off_t media_size; /* total block device size */
+ uint64_t media_size; /* total block device size */
uint32_t block_size; /* size in bytes of 1 sector */
- bool taken; /* simple refcount */
+ bool opened; /* device is currently open */
+ bool opening; /* entered open */
+ bool closing; /* entered close */
+ sem_t busy_open; /* semaphore for device currently opening */
+ sem_t busy_close; /* semaphore for device currently closing */
};
/* Return a send right associated with network device ND. */
@@ -74,8 +79,12 @@ dev_to_port (void *nd)
: MACH_PORT_NULL);
}
-static struct block_data block_ref;
static struct device_emulation_ops rump_block_emulation_ops;
+static struct block_data block = {
+ .opening = false,
+ .closing = false,
+ .opened = false
+ };
#define DISK_NAME_LEN 32
@@ -113,14 +122,31 @@ device_close (void *d)
{
io_return_t err;
struct block_data *bd = d;
-
+
+ /* We are now busy closing */
+ sem_init(&bd->busy_close, 0, 0);
+ bd->closing = true;
+
+ /* If starting to open, wait until not opening */
+ if (bd->opening) {
+ sem_wait(&bd->busy_open);
+ }
+
err = rump_errno2host (rump_sys_close (bd->rump_fd));
- block_ref.taken = false;
-
+
+ bd->opened = false;
+ sem_post(&bd->busy_close);
+ bd->closing = false;
return err;
}
static void
+device_init (void)
+{
+ rump_init();
+}
+
+static void
device_dealloc (void *d)
{
rump_sys_reboot(0, NULL);
@@ -131,88 +157,98 @@ 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;
+ int err = D_SUCCESS;
+ struct block_data *bd = &block;
char *dev_name;
- mach_print("hello open\n");
+ /* We are now busy opening */
+ sem_init(&bd->busy_open, 0, 0);
+ bd->opening = true;
+
+ mach_print("device_open\n");
dev_name = translate_name (name);
- if (dev_name == NULL)
+
+ /* If starting to close, wait until not closing */
+ if (bd->closing) {
+ sem_wait(&bd->busy_close);
+ }
+
+ if (bd->opened)
{
- mach_print ("no such device\n");
- return D_NO_SUCH_DEVICE;
+ mach_print ("re-open\n");
+ goto succeed;
}
err = create_device_port (sizeof (*bd), &bd);
if (err)
- {
- mach_print ("after create_device_port: cannot create a port\n");
- goto out;
- }
-
- if (block_ref.taken)
{
- bd->rump_fd = block_ref.rump_fd;
+ mach_print ("create_device_port: cannot create a port\n");
+ goto fail;
}
- else
+
+ bd->rump_fd = rump_sys_open (dev_name, dev_mode_to_rump_mode (mode));
+ if (bd->rump_fd < 0)
{
- rump_init();
- bd->rump_fd = rump_sys_open (dev_name, dev_mode_to_rump_mode (mode));
- if (bd->rump_fd < 0)
- {
- mach_print ("rump_sys_open fails: ");
- mach_print (dev_name);
- mach_print ("\n");
- err = rump_errno2host (errno);
- goto out;
- }
- block_ref.taken = true;
- block_ref.rump_fd = bd->rump_fd;
+ mach_print ("rump_sys_open failure\n");
+ err = rump_errno2host (errno);
+ goto fail;
}
- off_t media_size;
+ uint64_t media_size;
err = rump_sys_ioctl (bd->rump_fd, DIOCGMEDIASIZE, &media_size);
- if (err)
+ if (err < 0)
{
mach_print ("DIOCGMEDIASIZE ioctl fails\n");
device_close(bd);
- return rump_errno2host (errno);
+ err = rump_errno2host (errno);
+ goto fail;
}
-
- uint32_t block_size;
+
+ uint32_t block_size = 512;
+/* FIXME
err = rump_sys_ioctl (bd->rump_fd, DIOCGSECTORSIZE, &block_size);
- if (err)
+ if (err < 0)
{
mach_print ("DIOCGSECTORSIZE ioctl fails\n");
device_close(bd);
- return rump_errno2host (errno);
+ err = rump_errno2host (errno);
+ goto out;
}
-
- bd->device.emul_data = bd;
+*/
+ bd->device.emul_data = &block;
bd->device.emul_ops = &rump_block_emulation_ops;
- bd->mode = mode;
bd->media_size = media_size;
bd->block_size = block_size;
-
+ bd->mode = mode;
err = D_SUCCESS;
+ ports_port_deref (bd);
+ goto succeed;
-out:
+fail:
free (dev_name);
- if (err)
- {
- if (bd)
- {
- ports_destroy_right (bd);
- bd = NULL;
- }
- }
- else
- {
- *devp = ports_get_send_right (bd);
- ports_port_deref (bd);
- *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
- }
- return err;
+ if (bd)
+ ports_destroy_right (bd);
+ *devp = (device_t) MACH_PORT_NULL;
+ sem_post(&bd->busy_open);
+ bd->opening = false;
+ return D_NO_SUCH_DEVICE;
+
+succeed:
+/*
+ if (bd->want)
+ {
+ bd->want = false;
+ thread_wakeup ((event_t) bd);
+ }
+*/
+ free (dev_name);
+ *devp = (device_t)&bd->device;
+ *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
+ mach_print ("device_open ALL GOOD!\n");
+ bd->opened = true;
+ sem_post(&bd->busy_open);
+ bd->opening = false;
+ return D_SUCCESS;
}
static io_return_t
@@ -222,30 +258,36 @@ device_write (void *d, mach_port_t reply_port,
int *bytes_written)
{
struct block_data *bd = d;
- io_return_t err = D_SUCCESS;
+ int err = 0;
+ off_t records = count / bd->block_size;
if ((bd->mode & D_WRITE) == 0)
return D_INVALID_OPERATION;
+ if (records * bd->block_size != count)
+ return D_INVALID_SIZE;
+
+ if (count == 0)
+ return D_SUCCESS;
+
err = rump_sys_lseek (bd->rump_fd, bn * bd->block_size, SEEK_SET);
if (err < 0)
{
- err = MIG_NO_REPLY;
- return err;
+ *bytes_written = 0;
+ return MIG_NO_REPLY;
}
err = rump_sys_write (bd->rump_fd, data, count);
if (err < 0)
{
- err = MIG_NO_REPLY;
- return err;
+ *bytes_written = 0;
+ return MIG_NO_REPLY;
}
else
{
*bytes_written = err;
- err = D_SUCCESS;
- ds_device_write_reply (reply_port, reply_port_type, err, *bytes_written);
- return err;
+ ds_device_write_reply (reply_port, reply_port_type, D_SUCCESS, *bytes_written);
+ return D_SUCCESS;
}
}
@@ -283,15 +325,14 @@ device_read (void *d, mach_port_t reply_port,
err = rump_sys_read(bd->rump_fd, buf, count);
if (err < 0)
{
- err = MIG_NO_REPLY;
- return err;
+ *bytes_read = 0;
+ return MIG_NO_REPLY;
}
else
{
*bytes_read = err;
- err = D_SUCCESS;
- ds_device_read_reply (reply_port, reply_port_type, err, buf, *bytes_read);
- return err;
+ ds_device_read_reply (reply_port, reply_port_type, D_SUCCESS, buf, *bytes_read);
+ return D_SUCCESS;
}
}
@@ -301,21 +342,23 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
{
struct block_data *bd = d;
mach_print("device_get_status\n");
+
+ if (!bd->opened)
+ return D_INVALID_OPERATION;
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;
+ status[DEV_GET_SIZE_DEVICE_SIZE] = (unsigned long long)bd->media_size;
+ status[DEV_GET_SIZE_RECORD_SIZE] = 512;
+ *count = DEV_GET_SIZE_COUNT;
break;
case DEV_GET_RECORDS:
- status[DEV_GET_RECORDS_RECORD_SIZE] = bd->block_size;
- status[DEV_GET_RECORDS_DEVICE_RECORDS] = bd->media_size / bd->block_size;
- *count = 2;
+ status[DEV_GET_RECORDS_DEVICE_RECORDS] = (bd->media_size / (unsigned long long)512);
+ status[DEV_GET_RECORDS_RECORD_SIZE] = 512;
+ *count = DEV_GET_RECORDS_COUNT;
break;
default:
- return D_INVALID_OPERATION;
break;
}
return D_SUCCESS;
@@ -323,7 +366,7 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
static struct device_emulation_ops rump_block_emulation_ops =
{
- NULL,
+ device_init,
NULL,
device_dealloc,
dev_to_port,
diff --git a/libmachdevrump/ds_routines.c b/libmachdevrump/ds_routines.c
index 6966a103..1597bba9 100644
--- a/libmachdevrump/ds_routines.c
+++ b/libmachdevrump/ds_routines.c
@@ -70,12 +70,11 @@
struct port_bucket *device_bucket;
struct port_class *dev_class;
-#define NUM_EMULATION num_emul
#define MAX_NUM_EMULATION 32
/* List of emulations. */
static struct device_emulation_ops *emulation_list[MAX_NUM_EMULATION];
-static int num_emul;
+static int num_emul = 0;
boolean_t is_master_device (mach_port_t port);
@@ -100,7 +99,7 @@ ds_device_open (mach_port_t open_port, mach_port_t reply_port,
}
/* Call each emulation's open routine to find the device. */
- for (i = 0; i < NUM_EMULATION; i++)
+ for (i = 0; i < num_emul; i++)
{
err = (*emulation_list[i]->open) (reply_port, reply_port_type,
mode, name, devp, devicePoly);
@@ -292,7 +291,7 @@ void rump_device_init()
device_bucket = ports_create_bucket ();
dev_class = ports_create_class (0, 0);
- for (i = 0; i < NUM_EMULATION; i++) {
+ for (i = 0; i < num_emul; i++) {
if (emulation_list[i]->init)
emulation_list[i]->init();
}
diff --git a/rumpdisk/Makefile b/rumpdisk/Makefile
index b8015f2c..bf136c28 100644
--- a/rumpdisk/Makefile
+++ b/rumpdisk/Makefile
@@ -15,6 +15,10 @@
# 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 := utility
@@ -25,3 +29,6 @@ HURDLIBS = machdevrump
LDLIBS += -lpthread
include ../Makeconf
+
+rumpdisk.static: main.o
+ $(CC) -static main.o -Wl,--whole-archive $(RUMPLIBS:%=$(RUMPPATH)/lib%_pic.a) ../libmachdevrump/libmachdevrump_pic.a -Wl,--no-whole-archive $(RUMPEXTRA:%=$(RUMPPATH)/lib%_pic.a) ../libtrivfs/libtrivfs_pic.a ../libshouldbeinlibc/libshouldbeinlibc_pic.a ../libports/libports_pic.a ../libiohelp/libiohelp_pic.a ../libihash/libihash_pic.a ../libfshelp/libfshelp_pic.a /usr/lib/i386-gnu/libpthread.a /usr/lib/i386-gnu/libpciaccess.a /usr/lib/i386-gnu/libdl.a -o $@