X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fpalacios-stream.c;h=411c119600ae077039d82e9a9594f2a4777c7749;hb=176c87563accd1bddbd195fa830d1d0156030ffc;hp=702475c06de513bfb8e3171f8fe3c90c47b2d420;hpb=26ffaf22ebf784cbcd12f1899317d02ced7b352f;p=palacios.releases.git diff --git a/linux_module/palacios-stream.c b/linux_module/palacios-stream.c index 702475c..411c119 100644 --- a/linux_module/palacios-stream.c +++ b/linux_module/palacios-stream.c @@ -6,13 +6,39 @@ #include #include #include +#include + + +#include +#include "linux-exts.h" +#include "palacios-ringbuffer.h" +#include "palacios-vm.h" + +#define STREAM_BUF_SIZE 1024 +#define STREAM_NAME_LEN 128 + -#include -#include "palacios-stream.h" static struct list_head global_streams; -int stream_enqueue(struct stream_buffer * stream, char * buf, int len) { +struct stream_buffer { + char name[STREAM_NAME_LEN]; + struct ringbuf * buf; + + wait_queue_head_t intr_queue; + spinlock_t lock; + + struct v3_guest * guest; + struct list_head stream_node; +}; + + +// Currently just the list of open streams +struct vm_stream_state { + struct list_head open_streams; +}; + +static int stream_enqueue(struct stream_buffer * stream, char * buf, int len) { int bytes = 0; bytes = ringbuf_write(stream->buf, buf, len); @@ -21,7 +47,7 @@ int stream_enqueue(struct stream_buffer * stream, char * buf, int len) { } -int stream_dequeue(struct stream_buffer * stream, char * buf, int len) { +static int stream_dequeue(struct stream_buffer * stream, char * buf, int len) { int bytes = 0; bytes = ringbuf_read(stream->buf, buf, len); @@ -29,19 +55,31 @@ int stream_dequeue(struct stream_buffer * stream, char * buf, int len) { return bytes; } -int stream_datalen(struct stream_buffer * stream){ +static int stream_datalen(struct stream_buffer * stream){ return ringbuf_data_len(stream->buf); } -struct stream_buffer * find_stream_by_name(struct v3_guest * guest, const char * name) { + + + +static struct stream_buffer * find_stream_by_name(struct v3_guest * guest, const char * name) { struct stream_buffer * stream = NULL; struct list_head * stream_list = NULL; + struct vm_stream_state * vm_state = NULL; + if (guest == NULL) { stream_list = &global_streams; } else { - stream_list = &(guest->streams); + vm_state = get_vm_ext_data(guest, "STREAM_INTERFACE"); + + if (vm_state == NULL) { + printk("ERROR: Could not locate vm stream state for extension STREAM_INTERFACE\n"); + return NULL; + } + + stream_list = &(vm_state->open_streams); } list_for_each_entry(stream, stream_list, stream_node) { @@ -57,6 +95,16 @@ struct stream_buffer * find_stream_by_name(struct v3_guest * guest, const char * static void * palacios_stream_open(const char * name, void * private_data) { struct v3_guest * guest = (struct v3_guest *)private_data; struct stream_buffer * stream = NULL; + struct vm_stream_state * vm_state = NULL; + + if (guest != NULL) { + vm_state = get_vm_ext_data(guest, "STREAM_INTERFACE"); + + if (vm_state == NULL) { + printk("ERROR: Could not locate vm stream state for extension STREAM_INTERFACE\n"); + return NULL; + } + } if (find_stream_by_name(guest, name) != NULL) { printk("Stream already exists\n"); @@ -76,7 +124,7 @@ static void * palacios_stream_open(const char * name, void * private_data) { if (guest == NULL) { list_add(&(stream->stream_node), &(global_streams)); } else { - list_add(&(stream->stream_node), &(guest->streams)); + list_add(&(stream->stream_node), &(vm_state->open_streams)); } return stream; @@ -106,21 +154,75 @@ static void palacios_stream_close(void * stream_ptr) { } -struct v3_stream_hooks palacios_stream_hooks = { +static struct v3_stream_hooks palacios_stream_hooks = { .open = palacios_stream_open, .write = palacios_stream_write, .close = palacios_stream_close, }; -void palacios_init_stream() { +static int stream_init( void ) { INIT_LIST_HEAD(&(global_streams)); V3_Init_Stream(&palacios_stream_hooks); + + return 0; } -void palacios_deinit_stream() { +static int stream_deinit( void ) { if (!list_empty(&(global_streams))) { printk("Error removing module with open streams\n"); } + + return 0; } + +static int stream_connect(struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) { + void __user * argp = (void __user *)arg; + char path_name[STREAM_NAME_LEN]; + + if (copy_from_user(path_name, argp, STREAM_NAME_LEN)) { + printk("%s(%d): copy from user error...\n", __FILE__, __LINE__); + return -EFAULT; + } + + printk("ERROR: Opening Streams is currently not implemented...\n"); + + return -EFAULT; +} + + +static int guest_stream_init(struct v3_guest * guest, void ** vm_data) { + struct vm_stream_state * state = kmalloc(sizeof(struct vm_stream_state), GFP_KERNEL); + + INIT_LIST_HEAD(&(state->open_streams)); + *vm_data = state; + + + add_guest_ctrl(guest, V3_VM_STREAM_CONNECT, stream_connect, state); + + return 0; +} + + +static int guest_stream_deinit(struct v3_guest * guest, void * vm_data) { + struct vm_stream_state * state = vm_data; + if (!list_empty(&(state->open_streams))) { + printk("Error shutting down VM with open streams\n"); + } + + return 0; +} + + + +static struct linux_ext stream_ext = { + .name = "STREAM_INTERFACE", + .init = stream_init, + .deinit = stream_deinit, + .guest_init = guest_stream_init, + .guest_deinit = guest_stream_deinit +}; + + +register_extension(&stream_ext);