diff options
-rw-r--r-- | libmachdevrump/Makefile | 14 | ||||
-rw-r--r-- | libmachdevrump/block.c | 203 | ||||
-rw-r--r-- | libmachdevrump/ds_routines.c | 7 | ||||
-rw-r--r-- | rumpdisk/Makefile | 7 |
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 = █ 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 = █ 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 $@ |