[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 2/2] Virtual frame buffer: user space backend



"Christian Limpach" <christian.limpach@xxxxxxxxx> writes:

> On 6/26/06, Markus Armbruster <armbru@xxxxxxxxxx> wrote:
>> Straightforward conversion to Xenstore.
>>
>> Applies to hg repository at http://hg.codemonkey.ws/vncfb
>
> This also looks ok, two of the frontend issues apply here as well:
> - handling of the ring indexes (masking of indexes and use of barriers)
> - xenbus transactions can fail and there's no code to retry failed 
> transactions

Both done.  Same barrier confusion as for front end.

> Additionally, it would be good to use the vnc server code which we're
> going to use in the updated ioemu.  Sharing code for the framebuffers
> for pv and non-pv domains is good and we don't want the dependency on
> libvncserver anymore and the qemu vnc code is much compacter.  You'll
> want to grab the vnc files which come with qemu 0.8.1
> (http://xenbits.xensource.com/chris/ioemu-cvs-qemu-0.8.1.tar.bz2) and
> then apply the following two patches:
> http://xenbits.xensource.com/chris/xs-tools-ioemu.pq.hg?f=18f45f0721d8;file=vnc-cleanup;style=raw
> http://xenbits.xensource.com/chris/xs-tools-ioemu.pq.hg?f=bc42f3c29c74;file=vnc-fixes;style=raw
>
> Ideally, we'd move qemu's vnc support into a library to make it reusable.
>
>    christian

Downloaded it, patches applied with liberal fuzz, configure warned
about gcc 4 issues, and gcc 4 promptly choked.  I'll dig deeper as
soon as I find the time.


diff -r f67e0a168879 Makefile
--- a/Makefile  Tue Jan 24 16:14:00 2006 -0500
+++ b/Makefile  Mon Jul 10 20:18:57 2006 +0200
@@ -2,7 +2,7 @@ CFLAGS += -g -Wall
 
 ifneq ($(XENDIR),)
 CFLAGS += -I$(XENDIR)/tools/libxc -I$(XENDIR)/linux-2.6.12-xenU/include
-LDFLAGS += -L$(XENDIR)/tools/libxc
+LDFLAGS += -L$(XENDIR)/tools/libxc -L$(XENDIR)/tools/xenstore
 endif
 
 all: vncfb sdlfb
@@ -13,7 +13,7 @@ sdlfb: sdlfb.o xenfb.o
 sdlfb: sdlfb.o xenfb.o
 
 sdlfb.o: CFLAGS += $(shell sdl-config --cflags)
-sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl
+sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl -lxenstore
 
 clean:
        $(RM) *.o *~ vncfb
@@ -22,4 +22,4 @@ keymapping.o: CFLAGS += $(shell pkg-conf
 
 vncfb: vncfb.o xenfb.o keymapping.o
 vncfb.o: CFLAGS += $(shell libvncserver-config --cflags)
-vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl
+vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore
diff -r f67e0a168879 vncfb.c
--- a/vncfb.c   Tue Jan 24 16:14:00 2006 -0500
+++ b/vncfb.c   Mon Jul 10 20:18:57 2006 +0200
@@ -39,7 +39,12 @@ static void on_ptr_event(int buttonMask,
        last_y = y;
 }
 
+#if 0
 #define BUG() do { printf("%d\n", __LINE__); return 1; } while(0)
+#else
+extern void abort();
+#define BUG() abort();
+#endif
 
 static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h)
 {
diff -r f67e0a168879 xenfb.c
--- a/xenfb.c   Tue Jan 24 16:14:00 2006 -0500
+++ b/xenfb.c   Mon Jul 10 20:18:57 2006 +0200
@@ -16,6 +16,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
+#include <xs.h>
 
 #include "xenfb.h"
 
@@ -100,53 +101,80 @@ void xenfb_delete(struct xenfb *xenfb_pu
 
 static int xenfb_fb_event(struct xenfb_private *xenfb, union xenfb_in_event 
*event)
 {
-       uint32_t cons, prod;
+       uint32_t prod;
        struct xenfb_page *info = xenfb->fb_info;
-
-       cons = XENFB_MASK_RING(info->in_cons, info->in);
-       prod = XENFB_MASK_RING(info->in_prod, info->in);
-
-       if (XENFB_MASK_RING(prod + 1, info->in) != cons) {
-               struct ioctl_evtchn_notify notify;
-
-               memcpy(&info->in[prod], event, sizeof(*event));
-               info->in_prod = XENFB_MASK_RING(prod + 1, info->in);
-               notify.port = xenfb->fbdev_port;
-               return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, &notify);
-       }
-
-       errno = EAGAIN;
-       return -1;
+       struct ioctl_evtchn_notify notify;
+
+       prod = info->in_prod;
+       if (prod - info->in_cons == XENFB_RING_SIZE(info->in)) {
+           errno = EAGAIN;
+           return -1;
+       }
+
+       XENFB_RING_REF(info->in, prod) = *event;
+       info->in_prod = prod + 1;
+       notify.port = xenfb->fbdev_port;
+       return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
 static int xenfb_kbd_event(struct xenfb_private *xenfb, union xenkbd_in_event 
*event)
 {
-       uint32_t cons, prod;
+       uint32_t prod;
        struct xenkbd_info *info = xenfb->kbd_info;
-
-       cons = XENKBD_MASK_RING(info->in_cons, info->in);
-       prod = XENKBD_MASK_RING(info->in_prod, info->in);
-
-       if (XENKBD_MASK_RING(prod + 1, info->in) != cons) {
-               struct ioctl_evtchn_notify notify;
-
-               memcpy(&info->in[prod], event, sizeof(*event));
-               info->in_prod = XENKBD_MASK_RING(prod + 1, info->in);
-               notify.port = xenfb->kbd_port;
-               return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, &notify);
-       }
-
-       errno = EAGAIN;
-       return -1;
+       struct ioctl_evtchn_notify notify;
+
+       prod = info->in_prod;
+       if (prod - info->in_cons == XENKBD_RING_SIZE(info->in)) {
+           errno = EAGAIN;
+           return -1;
+       }
+
+       XENKBD_RING_REF(info->in, prod) = *event;
+       info->in_prod = prod + 1;
+       notify.port = xenfb->kbd_port;
+       return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
+static char *xenfb_path_in_dom(struct xs_handle *h,
+                        unsigned domid, const char *path,
+                        char *buffer, size_t size)
+{
+       char *domp = xs_get_domain_path(h, domid);
+       int n = snprintf(buffer, size, "%s/%s", domp, path);
+       free(domp);
+       if (n >= size)
+               return NULL;
+       return buffer;
+}
+
+static int xenfb_xs_scanf1(struct xs_handle *xsh, unsigned domid,
+                          const char *path, const char *fmt,
+                          void *dest)
+{
+       char buffer[1024];
+       char *p;
+       int ret;
+
+       p = xenfb_path_in_dom(xsh, domid, path, buffer, sizeof(buffer));
+       p = xs_read(xsh, XBT_NULL, p, NULL);
+       if (!p)
+               return -ENOENT;
+       ret = sscanf(p, fmt, dest);
+       free(p);
+       if (ret != 1)
+               return -EDOM;
+       return 0;
 }
 
 bool xenfb_set_domid(struct xenfb *xenfb_pub, int domid)
 {
        struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
        char buffer[1024];
-       FILE *f;
+       struct xs_handle *xsh;
+       unsigned dummy;
+       int ret;
+       char *p, **vec;
        struct ioctl_evtchn_bind_interdomain bind;
-       time_t timeout;
 
        if (xenfb->domid != -1) {
                xenfb_unset_domid(xenfb);
@@ -154,47 +182,53 @@ bool xenfb_set_domid(struct xenfb *xenfb
                        return true;
        }
 
-       printf("%d\n", __LINE__);
-
-       snprintf(buffer, sizeof(buffer), "/var/run/xenfb/%d.mfn", domid);
-       timeout = time(0);
-       do {
-               f = fopen(buffer, "r");
-               if (!f) {
-                       struct timeval tv = { 0, 500 };
-                       select(0, NULL, NULL, NULL, &tv);
-               }
-       } while (f == NULL && (timeout + 10) > time(0));
-
-       if (!f || fscanf(f, "%lu", &xenfb->fbdev_mfn) != 1)
+       xsh = xs_daemon_open_readonly();
+       if (!xsh)
+           goto error;
+
+       p = xenfb_path_in_dom(xsh, domid, "vfb", buffer, sizeof(buffer));
+       if (!xs_watch(xsh, p, ""))
                goto error;
-       fclose(f); f = NULL;
-
-       printf("%d\n", __LINE__);
-
-       snprintf(buffer, sizeof(buffer), "/var/run/xenfb/%d.evtchn", domid);
-       f = fopen(buffer, "r");
-       if (!f || fscanf(f, "%d", &xenfb->fbdev_evtchn) != 1)
+       p = xenfb_path_in_dom(xsh, domid, "vkbd", buffer, sizeof(buffer));
+       if (!xs_watch(xsh, p, ""))
                goto error;
-       fclose(f); f = NULL;
-
-       printf("%d\n", __LINE__);
-
-       snprintf(buffer, sizeof(buffer), "/var/run/xenkbd/%d.mfn", domid);
-       f = fopen(buffer, "r");
-       if (!f || fscanf(f, "%lu", &xenfb->kbd_mfn) != 1)
-               goto error;
-       fclose(f); f = NULL;
-
-       printf("%d\n", __LINE__);
-
-       snprintf(buffer, sizeof(buffer), "/var/run/xenkbd/%d.evtchn", domid);
-       f = fopen(buffer, "r");
-       if (!f || fscanf(f, "%d", &xenfb->kbd_evtchn) != 1)
-               goto error;
-       fclose(f); f = NULL;
-       
-       printf("%d\n", __LINE__);
+
+       for (;;) {
+               ret = xenfb_xs_scanf1(xsh, domid, "vfb/page-ref", "%lu",
+                                     &xenfb->fbdev_mfn);
+               if (ret == -ENOENT || ret == -EAGAIN)
+                       goto wait;
+               if (ret < 0)
+                       goto error;
+               ret = xenfb_xs_scanf1(xsh, domid, "vfb/event-channel", "%u",
+                                     &xenfb->fbdev_evtchn);
+               if (ret == -ENOENT || ret == -EAGAIN)
+                       goto wait;
+               if (ret < 0)
+                       goto error;
+               ret = xenfb_xs_scanf1(xsh, domid, "vkbd/page-ref", "%lu",
+                                     &xenfb->kbd_mfn);
+               if (ret == -ENOENT || ret == -EAGAIN)
+                       goto wait;
+               if (ret < 0)
+                       goto error;
+               ret = xenfb_xs_scanf1(xsh, domid, "vkbd/event-channel", "%u",
+                                     &xenfb->kbd_evtchn);
+               if (ret == -ENOENT || ret == -EAGAIN)
+                       goto wait;
+               if (ret < 0)
+                       goto error;
+               break;
+
+       wait:
+               printf("Waiting...\n");
+               vec = xs_read_watch(xsh, &dummy);
+               if (!vec)
+                       goto error;
+               free(vec);
+       }
+       xs_daemon_close(xsh);
+       xsh = NULL;
 
        printf("%d, %d, %d\n", xenfb->fd, xenfb->fbdev_evtchn, domid);
 
@@ -312,9 +346,9 @@ bool xenfb_set_domid(struct xenfb *xenfb
        }
  error:
        printf("%d\n", __LINE__);
-       if (f) {
-               int serrno = errno;
-               fclose(f);
+       if (xsh) {
+               int serrno = errno;
+               xs_daemon_close(xsh);
                errno = serrno;
        }
 
@@ -332,11 +366,10 @@ static void xenfb_on_fb_event(struct xen
        uint32_t prod, cons;
        struct xenfb_page *info = xenfb->fb_info;
 
-       prod = XENFB_MASK_RING(info->out_prod, info->out);
-       cons = XENFB_MASK_RING(info->out_cons, info->out);
-
-       for (; cons != prod; cons = XENFB_MASK_RING(cons + 1, info->out)) {
-               union xenfb_out_event *event = &info->out[cons];
+       prod = info->out_prod;
+       rmb();                  /* ensure we see ring contents up to prod */
+       for (cons = info->out_cons; cons != prod; cons++) {
+               union xenfb_out_event *event = &XENFB_RING_REF(info->out, cons);
 
                switch (event->type) {
                case XENFB_TYPE_UPDATE:
@@ -344,7 +377,7 @@ static void xenfb_on_fb_event(struct xen
                        break;
                }
        }
-
+       /* FIXME do I need a wmb() here? */
        info->out_cons = cons;
 }
 
@@ -353,18 +386,17 @@ static void xenfb_on_kbd_event(struct xe
        uint32_t prod, cons;
        struct xenkbd_info *info = xenfb->kbd_info;
 
-       prod = XENKBD_MASK_RING(info->out_prod, info->out);
-       cons = XENKBD_MASK_RING(info->out_cons, info->out);
-
-       for (; cons != prod; cons = XENKBD_MASK_RING(cons + 1, info->out)) {
-               union xenkbd_out_event *event = &info->out[cons];
+       prod = info->out_prod;
+       rmb();                  /* ensure we see ring contents up to prod */
+       for (cons = info->out_cons; cons != prod; cons++) {
+               union xenkbd_out_event *event = &XENKBD_RING_REF(info->out, 
cons);
 
                switch (event->type) {
                default:
                        break;
                }
        }
-
+       /* FIXME do I need a wmb() here? */
        info->out_cons = cons;
 }
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.