Re: [Spice-devel] [spice-gtk PATCH v5 1/6] giopipe: don't fail on create_source

2015-06-03 Thread Victor Toso
Hi,

> > +static GList *
> > +set_all_sources_ready (GList *sources)
> > +{
> > +GList *it = sources;
> > +while (it != NULL) {
> > +GSource *s = it->data;
> > +GList *next = it->next;
> > +
> > +if (s == NULL || g_source_is_destroyed(s)) {
> > +/* remove */
> > +sources = g_list_delete_link(sources, it);
> > +g_clear_pointer(&s, g_source_unref);
> > +} else {
> > +/* dispatch */
> > +g_source_set_ready_time(s, 0);
> > +}
> > +it = next;
> > +}
> > +return sources;
> > +}
> > +
> >  static void
> >  pipe_input_stream_check_source (PipeInputStream *self)
> >  {
> > -if (self->source && !g_source_is_destroyed(self->source) &&
> > +GSource *source;
> > +
> > +if (self->sources == NULL)
> > +return;
> > +
> > +source = self->sources->data;
> > +if (source && !g_source_is_destroyed(source) &&
> >  g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
> > -g_source_set_ready_time(self->source, 0);
> > +self->sources = set_all_sources_ready(self->sources);
>
> No idea why you check the first source here. I think the function could be 
> just like:
>
> if (g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
>self->sources = set_all_sources_ready(self->sources)
>

That's true. I'll try to be more careful. Do you want a new version or
the patch (with this change) is in acceptable state?

Thanks,

> > @@ -330,9 +347,14 @@ pipe_output_stream_dispose(GObject *object)
> >  static void
> >  pipe_output_stream_check_source (PipeOutputStream *self)
> >  {
> > -if (self->source && !g_source_is_destroyed(self->source) &&
> > +GSource * source;
> > +if (self->sources == NULL)
> > +return;
> > +
> > +source = self->sources->data;
> > +if (source && !g_source_is_destroyed(source) &&
> >  
> > g_pollable_output_stream_is_writable(G_POLLABLE_OUTPUT_STREAM(self)))
> > -g_source_set_ready_time(self->source, 0);
> > +self->sources = set_all_sources_ready(self->sources);
>
> same here

I"ll change as well!
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [spice-gtk PATCH v6 1/6] giopipe: don't fail on create_source

2015-06-03 Thread Victor Toso
PipeInputStream and PipeOutputStream should not fail when creating
GPollableStream source as this currently does not work with default
write_all and read_all functions;

In order to avoid creating zombie GSource in create_source of both
PipeInputStream and PipeOutputStream, we track all created GSources and
set them to be dispatched when data is available to read/write. It is
worth to mention that concurrent write/read is not possible with current
giopipe and only the last created GSource will read the data as it is
dispatched first.
---
 gtk/giopipe.c | 69 +--
 1 file changed, 39 insertions(+), 30 deletions(-)

diff --git a/gtk/giopipe.c b/gtk/giopipe.c
index 50edb5b..0e654ce 100644
--- a/gtk/giopipe.c
+++ b/gtk/giopipe.c
@@ -44,7 +44,7 @@ struct _PipeInputStream
  * closing.
  */
 gboolean peer_closed;
-GSource *source;
+GList *sources;
 };
 
 struct _PipeInputStreamClass
@@ -69,7 +69,7 @@ struct _PipeOutputStream
 const gchar *buffer;
 gsize count;
 gboolean peer_closed;
-GSource *source;
+GList *sources;
 };
 
 struct _PipeOutputStreamClass
@@ -120,12 +120,35 @@ pipe_input_stream_read (GInputStream  *stream,
 return count;
 }
 
+static GList *
+set_all_sources_ready (GList *sources)
+{
+GList *it = sources;
+while (it != NULL) {
+GSource *s = it->data;
+GList *next = it->next;
+
+if (s == NULL || g_source_is_destroyed(s)) {
+/* remove */
+sources = g_list_delete_link(sources, it);
+g_clear_pointer(&s, g_source_unref);
+} else {
+/* dispatch */
+g_source_set_ready_time(s, 0);
+}
+it = next;
+}
+return sources;
+}
+
 static void
 pipe_input_stream_check_source (PipeInputStream *self)
 {
-if (self->source && !g_source_is_destroyed(self->source) &&
-g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
-g_source_set_ready_time(self->source, 0);
+if (self->sources == NULL)
+return;
+
+if (g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
+self->sources = set_all_sources_ready(self->sources);
 }
 
 static gboolean
@@ -193,10 +216,8 @@ pipe_input_stream_dispose(GObject *object)
 self->peer = NULL;
 }
 
-if (self->source) {
-g_source_unref(self->source);
-self->source = NULL;
-}
+g_list_free_full (self->sources, (GDestroyNotify) g_source_unref);
+self->sources = NULL;
 
 G_OBJECT_CLASS(pipe_input_stream_parent_class)->dispose (object);
 }
@@ -234,14 +255,8 @@ pipe_input_stream_create_source (GPollableInputStream 
*stream,
 PipeInputStream *self = PIPE_INPUT_STREAM(stream);
 GSource *pollable_source;
 
-g_return_val_if_fail (self->source == NULL ||
-  g_source_is_destroyed (self->source), NULL);
-
-if (self->source && g_source_is_destroyed (self->source))
-g_source_unref (self->source);
-
 pollable_source = g_pollable_source_new_full (self, NULL, cancellable);
-self->source = g_source_ref (pollable_source);
+self->sources = g_list_prepend (self->sources, g_source_ref 
(pollable_source));
 
 return pollable_source;
 }
@@ -319,10 +334,8 @@ pipe_output_stream_dispose(GObject *object)
 self->peer = NULL;
 }
 
-if (self->source) {
-g_source_unref(self->source);
-self->source = NULL;
-}
+g_list_free_full (self->sources, (GDestroyNotify) g_source_unref);
+self->sources = NULL;
 
 G_OBJECT_CLASS(pipe_output_stream_parent_class)->dispose (object);
 }
@@ -330,9 +343,11 @@ pipe_output_stream_dispose(GObject *object)
 static void
 pipe_output_stream_check_source (PipeOutputStream *self)
 {
-if (self->source && !g_source_is_destroyed(self->source) &&
-g_pollable_output_stream_is_writable(G_POLLABLE_OUTPUT_STREAM(self)))
-g_source_set_ready_time(self->source, 0);
+if (self->sources == NULL)
+return;
+
+if (g_pollable_output_stream_is_writable(G_POLLABLE_OUTPUT_STREAM(self)))
+self->sources = set_all_sources_ready(self->sources);
 }
 
 static gboolean
@@ -416,14 +431,8 @@ pipe_output_stream_create_source (GPollableOutputStream 
*stream,
 PipeOutputStream *self = PIPE_OUTPUT_STREAM(stream);
 GSource *pollable_source;
 
-g_return_val_if_fail (self->source == NULL ||
-  g_source_is_destroyed (self->source), NULL);
-
-if (self->source && g_source_is_destroyed (self->source))
-g_source_unref (self->source);
-
 pollable_source = g_pollable_source_new_full (self, NULL, cancellable);
-self->source = g_source_ref (pollable_source);
+self->sources = g_list_prepend (self->sources, g_source_ref 
(pollable_source));
 
 return pollable_source;
 }
-- 
2.4.2

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedes

Re: [Spice-devel] [spice-gtk PATCH v6 1/6] giopipe: don't fail on create_source

2015-06-03 Thread Victor Toso
> +if (self->sources == NULL)
> +return;

I forgot to remove this in both functions :(
Oh well..
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [spice-gtk PATCH v7 1/6] giopipe: don't fail on create_source

2015-06-03 Thread Victor Toso
PipeInputStream and PipeOutputStream should not fail when creating
GPollableStream source as this currently does not work with default
write_all and read_all functions;

In order to avoid creating zombie GSource in create_source of both
PipeInputStream and PipeOutputStream, we track all created GSources and
set them to be dispatched when data is available to read/write. It is
worth to mention that concurrent write/read is not possible with current
giopipe and only the last created GSource will read the data as it is
dispatched first.
---
 gtk/giopipe.c | 63 +++
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/gtk/giopipe.c b/gtk/giopipe.c
index 50edb5b..a96783f 100644
--- a/gtk/giopipe.c
+++ b/gtk/giopipe.c
@@ -44,7 +44,7 @@ struct _PipeInputStream
  * closing.
  */
 gboolean peer_closed;
-GSource *source;
+GList *sources;
 };
 
 struct _PipeInputStreamClass
@@ -69,7 +69,7 @@ struct _PipeOutputStream
 const gchar *buffer;
 gsize count;
 gboolean peer_closed;
-GSource *source;
+GList *sources;
 };
 
 struct _PipeOutputStreamClass
@@ -120,12 +120,32 @@ pipe_input_stream_read (GInputStream  *stream,
 return count;
 }
 
+static GList *
+set_all_sources_ready (GList *sources)
+{
+GList *it = sources;
+while (it != NULL) {
+GSource *s = it->data;
+GList *next = it->next;
+
+if (s == NULL || g_source_is_destroyed(s)) {
+/* remove */
+sources = g_list_delete_link(sources, it);
+g_clear_pointer(&s, g_source_unref);
+} else {
+/* dispatch */
+g_source_set_ready_time(s, 0);
+}
+it = next;
+}
+return sources;
+}
+
 static void
 pipe_input_stream_check_source (PipeInputStream *self)
 {
-if (self->source && !g_source_is_destroyed(self->source) &&
-g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
-g_source_set_ready_time(self->source, 0);
+if (g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
+self->sources = set_all_sources_ready(self->sources);
 }
 
 static gboolean
@@ -193,10 +213,8 @@ pipe_input_stream_dispose(GObject *object)
 self->peer = NULL;
 }
 
-if (self->source) {
-g_source_unref(self->source);
-self->source = NULL;
-}
+g_list_free_full (self->sources, (GDestroyNotify) g_source_unref);
+self->sources = NULL;
 
 G_OBJECT_CLASS(pipe_input_stream_parent_class)->dispose (object);
 }
@@ -234,14 +252,8 @@ pipe_input_stream_create_source (GPollableInputStream 
*stream,
 PipeInputStream *self = PIPE_INPUT_STREAM(stream);
 GSource *pollable_source;
 
-g_return_val_if_fail (self->source == NULL ||
-  g_source_is_destroyed (self->source), NULL);
-
-if (self->source && g_source_is_destroyed (self->source))
-g_source_unref (self->source);
-
 pollable_source = g_pollable_source_new_full (self, NULL, cancellable);
-self->source = g_source_ref (pollable_source);
+self->sources = g_list_prepend (self->sources, g_source_ref 
(pollable_source));
 
 return pollable_source;
 }
@@ -319,10 +331,8 @@ pipe_output_stream_dispose(GObject *object)
 self->peer = NULL;
 }
 
-if (self->source) {
-g_source_unref(self->source);
-self->source = NULL;
-}
+g_list_free_full (self->sources, (GDestroyNotify) g_source_unref);
+self->sources = NULL;
 
 G_OBJECT_CLASS(pipe_output_stream_parent_class)->dispose (object);
 }
@@ -330,9 +340,8 @@ pipe_output_stream_dispose(GObject *object)
 static void
 pipe_output_stream_check_source (PipeOutputStream *self)
 {
-if (self->source && !g_source_is_destroyed(self->source) &&
-g_pollable_output_stream_is_writable(G_POLLABLE_OUTPUT_STREAM(self)))
-g_source_set_ready_time(self->source, 0);
+if (g_pollable_output_stream_is_writable(G_POLLABLE_OUTPUT_STREAM(self)))
+self->sources = set_all_sources_ready(self->sources);
 }
 
 static gboolean
@@ -416,14 +425,8 @@ pipe_output_stream_create_source (GPollableOutputStream 
*stream,
 PipeOutputStream *self = PIPE_OUTPUT_STREAM(stream);
 GSource *pollable_source;
 
-g_return_val_if_fail (self->source == NULL ||
-  g_source_is_destroyed (self->source), NULL);
-
-if (self->source && g_source_is_destroyed (self->source))
-g_source_unref (self->source);
-
 pollable_source = g_pollable_source_new_full (self, NULL, cancellable);
-self->source = g_source_ref (pollable_source);
+self->sources = g_list_prepend (self->sources, g_source_ref 
(pollable_source));
 
 return pollable_source;
 }
-- 
2.4.2

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 02/11] drm/qxl: Do not leak memory if qxl_release_list_add fails

2015-06-03 Thread Frediano Ziglio
If the function fails reference counter to the object is not decremented
causing leaks.
This is hard to spot as it happens only on very low memory situations.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index afd7297..e8b5207 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -122,8 +122,10 @@ static struct qxl_bo *qxlhw_handle_to_bo(struct qxl_device 
*qdev,
qobj = gem_to_qxl_bo(gobj);
 
ret = qxl_release_list_add(release, qobj);
-   if (ret)
+   if (ret) {
+   drm_gem_object_unreference_unlocked(gobj);
return NULL;
+   }
 
return qobj;
 }
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 06/11] drm/qxl: Fix return for qxl_release_alloc

2015-06-03 Thread Frediano Ziglio
This function return handle to allocated release object which is an int.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_release.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index d9b2568..6fd8e50 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -122,7 +122,7 @@ static const struct fence_ops qxl_fence_ops = {
.wait = qxl_fence_wait,
 };
 
-static uint64_t
+static int
 qxl_release_alloc(struct qxl_device *qdev, int type,
  struct qxl_release **ret)
 {
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 01/11] drm/qxl: Do not cause spice-server to clean our objects

2015-06-03 Thread Frediano Ziglio
If objects are moved back from system memory to VRAM (and spice id
created again) memory is already initialized so we need to set flag
to not clear memory.
If you don't do it after a while using desktop many images turns to
black or transparents.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_cmd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index bd5404e..85ed5dc 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -502,6 +502,7 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
 
cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
cmd->type = QXL_SURFACE_CMD_CREATE;
+   cmd->flags = QXL_SURF_FLAG_KEEP_DATA;
cmd->u.surface_create.format = surf->surf.format;
cmd->u.surface_create.width = surf->surf.width;
cmd->u.surface_create.height = surf->surf.height;
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 07/11] drm/qxl: Handle correctly failures in qxl_alloc_relase_reserved

2015-06-03 Thread Frediano Ziglio
Free resources correctly if function fails

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_release.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index 6fd8e50..00604ed 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -363,6 +363,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, 
unsigned long size,
ret = qxl_release_bo_alloc(qdev, 
&qdev->current_release_bo[cur_idx]);
if (ret) {
mutex_unlock(&qdev->release_mutex);
+   qxl_release_free(qdev, *release);
return ret;
}
}
@@ -377,13 +378,17 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, 
unsigned long size,
 
mutex_unlock(&qdev->release_mutex);
 
-   qxl_release_list_add(*release, bo);
+   ret = qxl_release_list_add(*release, bo);
+   qxl_bo_unref(&bo);
+   if (ret) {
+   qxl_release_free(qdev, *release);
+   return ret;
+   }
 
info = qxl_release_map(qdev, *release);
info->id = idr_ret;
qxl_release_unmap(qdev, *release, info);
 
-   qxl_bo_unref(&bo);
return ret;
 }
 
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 04/11] drm/qxl: Avoid double free on error

2015-06-03 Thread Frediano Ziglio
Is we are not able to get source bo object from handle we free
destination bo object and call cleanup code however destination
object was already inserted in reloc_info array (num_relocs was
already incremented) so on cleanup we free destination again.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index 230ab84..85b3808 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -240,8 +240,6 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
qxlhw_handle_to_bo(qdev, file_priv,
   reloc.src_handle, release);
if (!reloc_info[i].src_bo) {
-   if (reloc_info[i].dst_bo != cmd_bo)
-   
drm_gem_object_unreference_unlocked(&reloc_info[i].dst_bo->gem_base);
ret = -EINVAL;
goto out_free_bos;
}
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 05/11] drm/qxl: Handle all errors in qxl_surface_evict

2015-06-03 Thread Frediano Ziglio
Only EBUSY error was handled. This could cause code to believe
reserve was successful while it failed.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_cmd.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index 85ed5dc..b18f84c 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -612,8 +612,8 @@ static int qxl_reap_surf(struct qxl_device *qdev, struct 
qxl_bo *surf, bool stal
int ret;
 
ret = qxl_bo_reserve(surf, false);
-   if (ret == -EBUSY)
-   return -EBUSY;
+   if (ret)
+   return ret;
 
if (stall)
mutex_unlock(&qdev->surf_evict_mutex);
@@ -622,9 +622,9 @@ static int qxl_reap_surf(struct qxl_device *qdev, struct 
qxl_bo *surf, bool stal
 
if (stall)
mutex_lock(&qdev->surf_evict_mutex);
-   if (ret == -EBUSY) {
+   if (ret) {
qxl_bo_unreserve(surf);
-   return -EBUSY;
+   return ret;
}
 
qxl_surface_evict_locked(qdev, surf, true);
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 08/11] drm/qxl: Remove format string errors

2015-06-03 Thread Frediano Ziglio
Enable format string checks for qxl_io_log and remove resulting warnings
which could lead to memory errors on different platform or just printing
wrong information.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_cmd.c | 2 +-
 drivers/gpu/drm/qxl/qxl_display.c | 2 +-
 drivers/gpu/drm/qxl/qxl_drv.h | 2 +-
 drivers/gpu/drm/qxl/qxl_release.c | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index b18f84c..edc1eec 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -248,7 +248,7 @@ int qxl_garbage_collect(struct qxl_device *qdev)
}
}
 
-   QXL_INFO(qdev, "%s: %lld\n", __func__, i);
+   QXL_INFO(qdev, "%s: %d\n", __func__, i);
 
return i;
 }
diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 4a0a8b2..a8dbb3e 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -67,7 +67,7 @@ static int qxl_display_copy_rom_client_monitors_config(struct 
qxl_device *qdev)
crc = crc32(0, (const uint8_t *)&qdev->rom->client_monitors_config,
  sizeof(qdev->rom->client_monitors_config));
if (crc != qdev->rom->client_monitors_config_crc) {
-   qxl_io_log(qdev, "crc mismatch: have %X (%d) != %X\n", crc,
+   qxl_io_log(qdev, "crc mismatch: have %X (%zd) != %X\n", crc,
   sizeof(qdev->rom->client_monitors_config),
   qdev->rom->client_monitors_config_crc);
return 1;
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 6745c44..62ef8be 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -328,7 +328,7 @@ struct qxl_device {
 };
 
 /* forward declaration for QXL_INFO_IO */
-void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...);
+__printf(2,3) void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...);
 
 extern const struct drm_ioctl_desc qxl_ioctls[];
 extern int qxl_max_ioctl;
diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index 00604ed..b66ec33 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -153,7 +153,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
return handle;
}
*ret = release;
-   QXL_INFO(qdev, "allocated release %lld\n", handle);
+   QXL_INFO(qdev, "allocated release %d\n", handle);
release->id = handle;
return handle;
 }
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 00/11 v2] Miscellaneous stability patches

2015-06-03 Thread Frediano Ziglio
This set of patches mainly contains fix for some memory issues
using quite aggressively surfaces and other minor problems like
images going black after a while.

There are no code change from v1, changes:
- fix path prefix
- rebased on drm-next branch;
- add "drm/qxl" prefix on subject;
- add reviewed by.

About which patches should be applied surely (attempting to put a priority)
- "Move main reference counter to GEM object instead of TTM ones" this can
  causes memory corruption even not wanting to;
- "Avoid double free on error" this can be cause leaks in kernel if user space
  wants, mitigated by the fact that usually DRM inodes are owned by root;
- "Handle all errors in qxl_surface_evict" could cause corruption too, not
  really probable but taking into account that Xorg implementation use a lot
  signals is not so impossible;
- "Handle correctly failures in qxl_alloc_relase_reserved", "Do not leak memory
  if qxl_release_list_add fails" just cause leaks on situation where memory is
  already REALLY low, can be omitted;
- "Fix print statement not using uninitialized variable", "Remove format string
  errors" should just print garbage and debugging is disabled by default, not
  necessary.

Frediano Ziglio (11):
  drm/qxl: Do not cause spice-server to clean our objects
  drm/qxl: Do not leak memory if qxl_release_list_add fails
  drm/qxl: Fix print statement not using uninitialized variable
  drm/qxl: Avoid double free on error
  drm/qxl: Handle all errors in qxl_surface_evict
  drm/qxl: Fix return for qxl_release_alloc
  drm/qxl: Handle correctly failures in qxl_alloc_relase_reserved
  drm/qxl: Remove format string errors
  drm/qxl: Move main reference counter to GEM object instead of TTM ones
  drm/qxl: Simplify cleaning qxl processing command
  drm/qxl: Propagate correctly errors from qxlhw_handle_to_bo

 drivers/gpu/drm/qxl/qxl_cmd.c | 11 +-
 drivers/gpu/drm/qxl/qxl_display.c |  2 +-
 drivers/gpu/drm/qxl/qxl_drv.h |  2 +-
 drivers/gpu/drm/qxl/qxl_gem.c | 10 +++--
 drivers/gpu/drm/qxl/qxl_ioctl.c   | 46 +++
 drivers/gpu/drm/qxl/qxl_object.c  | 11 --
 drivers/gpu/drm/qxl/qxl_release.c | 13 +++
 7 files changed, 46 insertions(+), 49 deletions(-)

-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 03/11] drm/qxl: Fix print statement not using uninitialized variable

2015-06-03 Thread Frediano Ziglio
reloc_info[i] is not still initialized in the print statement.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index e8b5207..230ab84 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -212,7 +212,7 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
/* add the bos to the list of bos to validate -
   need to validate first then process relocs? */
if (reloc.reloc_type != QXL_RELOC_TYPE_BO && reloc.reloc_type 
!= QXL_RELOC_TYPE_SURF) {
-   DRM_DEBUG("unknown reloc type %d\n", 
reloc_info[i].type);
+   DRM_DEBUG("unknown reloc type %d\n", reloc.reloc_type);
 
ret = -EINVAL;
goto out_free_bos;
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 10/11] drm/qxl: Simplify cleaning qxl processing command

2015-06-03 Thread Frediano Ziglio
In qxlhw_handle_to_bo we incremented counters twice, one time for release object
and one for reloc_info.
In the main function however reloc_info references was drop much earlier than
release so keeping the pointer only on release is safe and make cleaning
process easier.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index 85b3808..bb326ff 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -122,10 +122,9 @@ static struct qxl_bo *qxlhw_handle_to_bo(struct qxl_device 
*qdev,
qobj = gem_to_qxl_bo(gobj);
 
ret = qxl_release_list_add(release, qobj);
-   if (ret) {
-   drm_gem_object_unreference_unlocked(gobj);
+   drm_gem_object_unreference_unlocked(gobj);
+   if (ret)
return NULL;
-   }
 
return qobj;
 }
@@ -145,7 +144,7 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
struct qxl_release *release;
struct qxl_bo *cmd_bo;
void *fb_cmd;
-   int i, j, ret, num_relocs;
+   int i, ret, num_relocs;
int unwritten;
 
switch (cmd->type) {
@@ -269,12 +268,6 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
qxl_release_fence_buffer_objects(release);
 
 out_free_bos:
-   for (j = 0; j < num_relocs; j++) {
-   if (reloc_info[j].dst_bo != cmd_bo)
-   
drm_gem_object_unreference_unlocked(&reloc_info[j].dst_bo->gem_base);
-   if (reloc_info[j].src_bo && reloc_info[j].src_bo != cmd_bo)
-   
drm_gem_object_unreference_unlocked(&reloc_info[j].src_bo->gem_base);
-   }
 out_free_release:
if (ret)
qxl_release_free(qdev, release);
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 09/11] drm/qxl: Move main reference counter to GEM object instead of TTM ones

2015-06-03 Thread Frediano Ziglio
qxl_bo structure has two reference counters, one in the GEM object and
another in the TTM object. The GEM object keep a counter to the TTM object
so when GEM counter reached zero the TTM counter (using qxl_bo_unref) was
decremented. The qxl object is fully freed (both GEM and TTM part are cleaned)
when the TTM counter reach zero.
One issue was that surface idr structure has no owning on qxl_bo objects however
it contains a pointer to qxl_bo object. This caused some nasty race condition
for instance qxl_bo object was reaped even after counter was already zero.
This patch fix these races moving main counter (the one used by qxl_bo_(un)ref)
to GEM object which cleanup routine (qxl_gem_object_free) remove the idr pointer
(using qxl_surface_evict) when the counters are still valid.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_gem.c| 10 --
 drivers/gpu/drm/qxl/qxl_object.c | 11 ---
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c
index b96f0c9..d9746e9 100644
--- a/drivers/gpu/drm/qxl/qxl_gem.c
+++ b/drivers/gpu/drm/qxl/qxl_gem.c
@@ -31,9 +31,15 @@
 void qxl_gem_object_free(struct drm_gem_object *gobj)
 {
struct qxl_bo *qobj = gem_to_qxl_bo(gobj);
+   struct qxl_device *qdev;
+   struct ttm_buffer_object *tbo;
 
-   if (qobj)
-   qxl_bo_unref(&qobj);
+   qdev = (struct qxl_device *)gobj->dev->dev_private;
+
+   qxl_surface_evict(qdev, qobj, false);
+
+   tbo = &qobj->tbo;
+   ttm_bo_unref(&tbo);
 }
 
 int qxl_gem_object_create(struct qxl_device *qdev, int size,
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index cdeaf08..6d6f33d 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -208,19 +208,16 @@ void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev,
 
 void qxl_bo_unref(struct qxl_bo **bo)
 {
-   struct ttm_buffer_object *tbo;
-
if ((*bo) == NULL)
return;
-   tbo = &((*bo)->tbo);
-   ttm_bo_unref(&tbo);
-   if (tbo == NULL)
-   *bo = NULL;
+
+   drm_gem_object_unreference_unlocked(&(*bo)->gem_base);
+   *bo = NULL;
 }
 
 struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
 {
-   ttm_bo_reference(&bo->tbo);
+   drm_gem_object_reference(&bo->gem_base);
return bo;
 }
 
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH 11/11] drm/qxl: Propagate correctly errors from qxlhw_handle_to_bo

2015-06-03 Thread Frediano Ziglio
This function could return a NULL pointer in case of handle not
present and in case of out of memory conditions however caller
function always returned EINVAL error hiding a possible ENOMEM.
This patch change the function to return the error instead to
be able to propagate the error instead of assuming EINVAL.

Signed-off-by: Frediano Ziglio 
Reviewed-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 33 ++---
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index bb326ff..37f1faf 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -107,9 +107,9 @@ apply_surf_reloc(struct qxl_device *qdev, struct 
qxl_reloc_info *info)
 }
 
 /* return holding the reference to this object */
-static struct qxl_bo *qxlhw_handle_to_bo(struct qxl_device *qdev,
-struct drm_file *file_priv, uint64_t 
handle,
-struct qxl_release *release)
+static int qxlhw_handle_to_bo(struct qxl_device *qdev,
+ struct drm_file *file_priv, uint64_t handle,
+ struct qxl_release *release, struct qxl_bo 
**qbo_p)
 {
struct drm_gem_object *gobj;
struct qxl_bo *qobj;
@@ -117,16 +117,17 @@ static struct qxl_bo *qxlhw_handle_to_bo(struct 
qxl_device *qdev,
 
gobj = drm_gem_object_lookup(qdev->ddev, file_priv, handle);
if (!gobj)
-   return NULL;
+   return -EINVAL;
 
qobj = gem_to_qxl_bo(gobj);
 
ret = qxl_release_list_add(release, qobj);
drm_gem_object_unreference_unlocked(gobj);
if (ret)
-   return NULL;
+   return ret;
 
-   return qobj;
+   *qbo_p = qobj;
+   return 0;
 }
 
 /*
@@ -219,13 +220,10 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
reloc_info[i].type = reloc.reloc_type;
 
if (reloc.dst_handle) {
-   reloc_info[i].dst_bo = qxlhw_handle_to_bo(qdev, 
file_priv,
- 
reloc.dst_handle, release);
-   if (!reloc_info[i].dst_bo) {
-   ret = -EINVAL;
-   reloc_info[i].src_bo = NULL;
+   ret = qxlhw_handle_to_bo(qdev, file_priv, 
reloc.dst_handle, release,
+&reloc_info[i].dst_bo);
+   if (ret)
goto out_free_bos;
-   }
reloc_info[i].dst_offset = reloc.dst_offset;
} else {
reloc_info[i].dst_bo = cmd_bo;
@@ -234,14 +232,11 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
num_relocs++;
 
/* reserve and validate the reloc dst bo */
-   if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle > 
0) {
-   reloc_info[i].src_bo =
-   qxlhw_handle_to_bo(qdev, file_priv,
-  reloc.src_handle, release);
-   if (!reloc_info[i].src_bo) {
-   ret = -EINVAL;
+   if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle) {
+   ret = qxlhw_handle_to_bo(qdev, file_priv, 
reloc.src_handle, release,
+&reloc_info[i].src_bo);
+   if (ret)
goto out_free_bos;
-   }
reloc_info[i].src_offset = reloc.src_offset;
} else {
reloc_info[i].src_bo = NULL;
-- 
2.1.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH spice-server v2 2/2] Handle preferred image compression messages

2015-06-03 Thread Christophe Fergeau
On Tue, Jun 02, 2015 at 06:26:09PM +0200, Javier Celaya wrote:
> El Martes, 2 de junio de 2015 14:33:35 Christophe Fergeau escribió:
> > My last remaining comment about this patch is that now the client can
> > force the server to use a given compression method. This is something
> > the server admin might not want to allow (think "too expensive
> > compression methods).
> > Maybe image_compression should default to SPICE_IMAGE_COMPRESS_DEFAULT
> > rather than _AUTO_GLZ, and we should only allow
> > display_channel_handle_preferred_compression() to override
> > COMPRESS_DEFAULT, but not other values?
> > 
> > Christophe
> 
> I see. However, currently, QEMU always sets image_compression to the one it 
> gets 
> from command-line or _AUTO_GLZ by default. There is no way to know from 
> within 
> spice-server whether the admin specified an image compression method or not, 
> without patching QEMU too.

Ah hrm, spice-server has an _AUTO_GLZ default value, but QEMU indeed
forces the default too, so we can't change this only with spice-server
changes. We could forbid the client from changing compression when it's
!= AUTO_GLZ, but that probably be weird/unexpected?

Christophe


pgpJjbsR5lf6S.pgp
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH spice-gtk v3 2/3] Cmdline: Get the preferred-compression property

2015-06-03 Thread Christophe Fergeau
On Tue, Jun 02, 2015 at 05:54:18PM +0200, Javier Celaya wrote:
> El Martes, 2 de junio de 2015 14:25:23 usted escribió:
> > For what it's worth, once your enum is registered as a GEnum, you can do
> > something like gvir_config_genum_get_value
> > https://libvirt.org/git/?p=libvirt-glib.git;a=blob;f=libvirt-gconfig/libvirt
> > -gconfig-
> helpers.c;h=0314a72fd5dfcf8e47df34e7243610071f91b0ee;hb=HEAD#l264
> > in order to go from string representation to integer. As this is only
> > needed once here, maybe not worth it.
> > 
> > Christophe
> 
> I supposed so, but I also want to filter out some enum names, like "invalid" 
> and "lz4" 
> where not supported, so it seemed more clear in this way.-- 

Sure, your current patch is fine with me.

Christophe


pgp0zTO7ZoAdV.pgp
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [PATCH spice-gtk v3 3/3] Display: Send a preferred compression message on init.

2015-06-03 Thread Christophe Fergeau
On Tue, Jun 02, 2015 at 06:04:57PM +0200, Javier Celaya wrote:
> El Martes, 2 de junio de 2015 14:26:58 Christophe Fergeau escribió:
> > I'd deal with the "preferred_compression >=
> > SPICE_IMAGE_COMPRESS_ENUM_END" case with a g_warn_if_fail() as
> > g_param_spec_enum should guarantee that you won't get a value not
> > covered by the registered GEnum.
> > 
> > Christophe
> 
> Then I shouldn't check it at all... After all, there is no check for the 
> other two properties 
> in that function (cache-size and glz-window-size). I would rather remove the 
> "preferred_compression < SPICE_IMAGE_COMPRESS_ENUM_END" condition.-- 

Sure, fine with me.

Christophe


pgpYGL8jHtJMh.pgp
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [spice-xpi] Workaround firefox-gtk3 bug

2015-06-03 Thread Christophe Fergeau
Ping ?

Christophe

On Thu, May 28, 2015 at 01:37:24PM +0200, Christophe Fergeau wrote:
> When it's built with gtk3, firefox plugin-container will use some
> LD_PRELOAD hack in order to be able to load the gtk2 flash plugin.
> However, this LD_PRELOAD'ed .so will cause gtk3 remote-viewer to crash
> when it's started by spice-xpi
> 
> This commit just cleans up the unwanted LD_PRELOAD variable from the
> environment before starting remote-viewer.
> ---
>  SpiceXPI/src/plugin/controller.cpp | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/SpiceXPI/src/plugin/controller.cpp 
> b/SpiceXPI/src/plugin/controller.cpp
> index f8cd39d..63a669d 100644
> --- a/SpiceXPI/src/plugin/controller.cpp
> +++ b/SpiceXPI/src/plugin/controller.cpp
> @@ -169,6 +169,13 @@ gpointer SpiceController::ClientThread(gpointer data)
>  else
>  env = g_environ_setenv(env, "SPICE_PROXY", 
> fake_this->m_proxy.c_str(), TRUE);
>  
> +// Work around bug in firefox gtk3 builds, see
> +// https://bugzilla.redhat.com/show_bug.cgi?id=1217076
> +// http://emilio.pozuelo.org/posts/75
> +//
> +// This LD_PRELOAD'ed library causes gtk3 applications to crash
> +env = g_environ_unsetenv(env, "LD_PRELOAD");
> +
>  // Try to spawn main client
>  client_argv = fake_this->GetClientPath();
>  if (client_argv != NULL) {
> -- 
> 2.4.1
> 
> ___
> Spice-devel mailing list
> Spice-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel


pgpCNqTze5l9j.pgp
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] [vdagent-linux] Prepare for 0.16.0 release

2015-06-03 Thread Christophe Fergeau
On Wed, May 27, 2015 at 03:17:18PM +0200, Christophe Fergeau wrote:
> ---
> Hey,
> 
> As suggested by poma, it might be a good time to have a 0.16.0 release of
> spice-vdagent. Let me know what you think :)

Since I haven't heard objections, I'll move forward with this soon.

Christophe


pgpEhP2aiGvZp.pgp
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v2] Add password length check

2015-06-03 Thread Cédric Bosdonnat
Don't allow setting a too long password.
---

 Diff to v1: only kept the admin/user password setting check

 server/reds.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/server/reds.c b/server/reds.c
index 6d70b68..5579109 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -3503,6 +3503,8 @@ SPICE_GNUC_VISIBLE int 
spice_server_set_ticket(SpiceServer *s,
 taTicket.expiration_time = now + lifetime;
 }
 if (passwd != NULL) {
+if (strlen(passwd) > SPICE_MAX_PASSWORD_LENGTH)
+return -1;
 g_strlcpy(taTicket.password, passwd, sizeof(taTicket.password));
 } else {
 memset(taTicket.password, 0, sizeof(taTicket.password));
-- 
2.1.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH v4] Check too long password

2015-06-03 Thread Cédric Bosdonnat
Make sure that the password lenght is under the maximum lenght. If not
report it as an authentication failure with an adapted message.
---
 Diff to v3:

   * Removed the checks on the server side and the corresponding code here
   * Removed the new error code to reuse SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD.
   * spice_channel_send_spice_ticket returns SpiceChannelEvent instead of a 
gboolean:
 this helps properly propagating the kind of error to the client.

 gtk/spice-channel.c | 80 ++---
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 4e7d8b7..d01b147 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -1010,7 +1010,34 @@ static int spice_channel_read(SpiceChannel *channel, 
void *data, size_t length)
 }
 
 /* coroutine context */
-static void spice_channel_send_spice_ticket(SpiceChannel *channel)
+static void spice_channel_failed_authentication(SpiceChannel *channel,
+gboolean invalidPassword)
+{
+SpiceChannelPrivate *c = channel->priv;
+
+if (c->auth_needs_username_and_password)
+g_set_error_literal(&c->error,
+SPICE_CLIENT_ERROR,
+
SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME,
+_("Authentication failed: password and username 
are required"));
+else if (invalidPassword)
+g_set_error_literal(&c->error,
+SPICE_CLIENT_ERROR,
+SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
+_("Authentication failed: password is too long"));
+else
+g_set_error_literal(&c->error,
+SPICE_CLIENT_ERROR,
+SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
+_("Authentication failed: password is required"));
+
+c->event = SPICE_CHANNEL_ERROR_AUTH;
+
+c->has_error = TRUE; /* force disconnect */
+}
+
+/* coroutine context */
+static SpiceChannelEvent spice_channel_send_spice_ticket(SpiceChannel *channel)
 {
 SpiceChannelPrivate *c = channel->priv;
 EVP_PKEY *pubkey;
@@ -1020,13 +1047,14 @@ static void 
spice_channel_send_spice_ticket(SpiceChannel *channel)
 char *password;
 uint8_t *encrypted;
 int rc;
+SpiceChannelEvent ret = SPICE_CHANNEL_ERROR_LINK;
 
 bioKey = BIO_new(BIO_s_mem());
-g_return_if_fail(bioKey != NULL);
+g_return_val_if_fail(bioKey != NULL, ret);
 
 BIO_write(bioKey, c->peer_msg->pub_key, SPICE_TICKET_PUBKEY_BYTES);
 pubkey = d2i_PUBKEY_bio(bioKey, NULL);
-g_return_if_fail(pubkey != NULL);
+g_return_val_if_fail(pubkey != NULL, ret);
 
 rsa = pubkey->pkey.rsa;
 nRSASize = RSA_size(rsa);
@@ -1039,36 +1067,24 @@ static void 
spice_channel_send_spice_ticket(SpiceChannel *channel)
 g_object_get(c->session, "password", &password, NULL);
 if (password == NULL)
 password = g_strdup("");
+if (strlen(password) > SPICE_MAX_PASSWORD_LENGTH) {
+spice_channel_failed_authentication(channel, TRUE);
+ret = SPICE_CHANNEL_ERROR_AUTH;
+goto cleanup;
+}
 rc = RSA_public_encrypt(strlen(password) + 1, (uint8_t*)password,
 encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
 g_warn_if_fail(rc > 0);
 
 spice_channel_write(channel, encrypted, nRSASize);
+ret = SPICE_CHANNEL_NONE;
+
+cleanup:
 memset(encrypted, 0, nRSASize);
 EVP_PKEY_free(pubkey);
 BIO_free(bioKey);
 g_free(password);
-}
-
-/* coroutine context */
-static void spice_channel_failed_authentication(SpiceChannel *channel)
-{
-SpiceChannelPrivate *c = channel->priv;
-
-if (c->auth_needs_username_and_password)
-g_set_error_literal(&c->error,
-SPICE_CLIENT_ERROR,
-
SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME,
-_("Authentication failed: password and username 
are required"));
-else
-g_set_error_literal(&c->error,
-SPICE_CLIENT_ERROR,
-SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
-_("Authentication failed: password is required"));
-
-c->event = SPICE_CHANNEL_ERROR_AUTH;
-
-c->has_error = TRUE; /* force disconnect */
+return ret;
 }
 
 /* coroutine context */
@@ -1088,7 +1104,7 @@ static gboolean spice_channel_recv_auth(SpiceChannel 
*channel)
 
 if (link_res != SPICE_LINK_ERR_OK) {
 CHANNEL_DEBUG(channel, "link result: reply %d", link_res);
-spice_channel_failed_authentication(channel);
+spice_channel_failed_authentication(channel, FALSE);
 return FALSE;
 }
 
@@ -1662,7 +1678,7 @@ error:
 if (saslconn)
 sasl_dispose(&saslconn);
 
-spice_channel_failed_authentication(channel);
+spice_channel_failed_authenticat

Re: [Spice-devel] [PATCH v4] Check too long password

2015-06-03 Thread Daniel P. Berrange
On Wed, Jun 03, 2015 at 04:22:35PM +0200, Cédric Bosdonnat wrote:
> Make sure that the password lenght is under the maximum lenght. If not

Nit-pick if you re-post,  s/lenght/length/g or someone can fixup when
merging

> report it as an authentication failure with an adapted message.
> ---
>  Diff to v3:
> 
>* Removed the checks on the server side and the corresponding code here
>* Removed the new error code to reuse 
> SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD.
>* spice_channel_send_spice_ticket returns SpiceChannelEvent instead of a 
> gboolean:
>  this helps properly propagating the kind of error to the client.
> 

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH spice-gtk v4 2/3] Add a preferred-compression program option

2015-06-03 Thread Javier Celaya
---
 gtk/spice-option.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/gtk/spice-option.c b/gtk/spice-option.c
index 958e03c..463a3e3 100644
--- a/gtk/spice-option.c
+++ b/gtk/spice-option.c
@@ -41,6 +41,7 @@ static gint cache_size = 0;
 static gint glz_window_size = 0;
 static gchar *secure_channels = NULL;
 static gchar *shared_dir = NULL;
+static SpiceImageCompress preferred_compression = SPICE_IMAGE_COMPRESS_INVALID;
 
 G_GNUC_NORETURN
 static void option_version(void)
@@ -149,6 +150,33 @@ static gboolean parse_usbredir_filter(const gchar 
*option_name,
 return TRUE;
 }
 
+static gboolean parse_preferred_compression(const gchar *option_name, const 
gchar *value,
+gpointer data, GError **error)
+{
+if (!strcmp(value, "auto-glz")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_AUTO_GLZ;
+} else if (!strcmp(value, "auto-lz")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_AUTO_LZ;
+} else if (!strcmp(value, "quic")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_QUIC;
+} else if (!strcmp(value, "glz")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_GLZ;
+} else if (!strcmp(value, "lz")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_LZ;
+#ifdef USE_LZ4
+} else if (!strcmp(value, "lz4")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_LZ4;
+#endif
+} else if (!strcmp(value, "off")) {
+preferred_compression = SPICE_IMAGE_COMPRESS_OFF;
+} else {
+preferred_compression = SPICE_IMAGE_COMPRESS_INVALID;
+g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+_("Image compression algorithm %s not supported"), value);
+return FALSE;
+}
+return TRUE;
+}
 
 /**
  * spice_get_option_group: (skip)
@@ -194,6 +222,13 @@ GOptionGroup* spice_get_option_group(void)
   N_("Glz compression history size"), N_("") },
 { "spice-shared-dir", '\0', 0, G_OPTION_ARG_FILENAME, &shared_dir,
   N_("Shared directory"), N_("") },
+{ "spice-preferred-compression", '\0', 0, G_OPTION_ARG_CALLBACK, 
parse_preferred_compression,
+  N_("Preferred image compression algorithm"),
+#ifdef USE_LZ4
+  "" },
+#else
+  "" },
+#endif
 
 { "spice-debug", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, 
option_debug,
   N_("Enable Spice-GTK debugging"), NULL },
@@ -281,4 +316,6 @@ void spice_set_session_option(SpiceSession *session)
 g_object_set(session, "glz-window-size", glz_window_size, NULL);
 if (shared_dir)
 g_object_set(session, "shared-dir", shared_dir, NULL);
+if (preferred_compression != SPICE_IMAGE_COMPRESS_INVALID)
+g_object_set(session, "preferred-compression", preferred_compression, 
NULL);
 }
-- 
1.9.3

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH spice-gtk v4 3/3] Display: Send a preferred compression message on init.

2015-06-03 Thread Javier Celaya
If the user prefers a specific compression algorithm, report it when
setting up the display channel.
---
 gtk/channel-display.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/gtk/channel-display.c b/gtk/channel-display.c
index efe2259..5dd3f71 100644
--- a/gtk/channel-display.c
+++ b/gtk/channel-display.c
@@ -789,12 +789,15 @@ static void spice_display_channel_up(SpiceChannel 
*channel)
 SpiceMsgOut *out;
 SpiceSession *s = spice_channel_get_session(channel);
 SpiceMsgcDisplayInit init;
+SpiceMsgcDisplayPreferredCompression pref_comp_msg;
 int cache_size;
 int glz_window_size;
+SpiceImageCompress preferred_compression = SPICE_IMAGE_COMPRESS_INVALID;
 
 g_object_get(s,
  "cache-size", &cache_size,
  "glz-window-size", &glz_window_size,
+ "preferred-compression", &preferred_compression,
  NULL);
 CHANNEL_DEBUG(channel, "%s: cache_size %d, glz_window_size %d (bytes)", 
__FUNCTION__,
   cache_size, glz_window_size);
@@ -810,6 +813,14 @@ static void spice_display_channel_up(SpiceChannel *channel)
this monitor */
 if (channel->priv->channel_id != 0)
 g_coroutine_object_notify(G_OBJECT(channel), "monitors");
+
+if (spice_channel_test_capability(channel, 
SPICE_DISPLAY_CAP_PREF_COMPRESSION) &&
+preferred_compression > SPICE_IMAGE_COMPRESS_INVALID) {
+pref_comp_msg.image_compression = preferred_compression;
+out = spice_msg_out_new(channel, 
SPICE_MSGC_DISPLAY_PREFERRED_COMPRESSION);
+out->marshallers->msgc_display_preferred_compression(out->marshaller, 
&pref_comp_msg);
+spice_msg_out_send_internal(out);
+}
 }
 
 #define DRAW(type) {\
-- 
1.9.3

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH spice-html5 1/3] Minor change to error message formating.

2015-06-03 Thread Jeremy White
Signed-off-by: Jeremy White 
---
 display.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/display.js b/display.js
index 814ada6..a749dae 100644
--- a/display.js
+++ b/display.js
@@ -469,11 +469,11 @@ SpiceDisplayConn.prototype.process_channel_message = 
function(msg)
 if (!this.streams)
 this.streams = new Array();
 if (this.streams[m.id])
-console.log("Stream already exists");
+console.log("Stream " + m.id + " already exists");
 else
 this.streams[m.id] = m;
 if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
-console.log("Unhandled stream codec: "+m.codec_type);
+console.log("Unhandled stream codec: " + m.codec_type);
 return true;
 }
 
-- 
2.1.4

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH spice-html5 3/3] Add support for stream reports.

2015-06-03 Thread Jeremy White
This helps video playback do a slightly better job of keeping up
in the browser.  It's not a dramatic effect, but enough to start making
video playback almost tolerable.

Signed-off-by: Jeremy White 
---
 display.js   | 67 ++--
 enums.js |  1 +
 main.js  |  3 +++
 spiceconn.js |  3 ++-
 spicemsg.js  | 54 
 5 files changed, 116 insertions(+), 12 deletions(-)

diff --git a/display.js b/display.js
index 7027230..7938527 100644
--- a/display.js
+++ b/display.js
@@ -477,31 +477,48 @@ SpiceDisplayConn.prototype.process_channel_message = 
function(msg)
 return true;
 }
 
-if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
+if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA ||
+msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
 {
-var m = new SpiceMsgDisplayStreamData(msg.data);
+var m;
+if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
+m = new SpiceMsgDisplayStreamDataSized(msg.data);
+else
+m = new SpiceMsgDisplayStreamData(msg.data);
+
 if (!this.streams[m.base.id])
 {
 console.log("no stream for data");
 return false;
 }
+
+var mmtime = (Date.now() - this.parent.our_mm_time) + 
this.parent.mm_time;
+var latency = m.base.multi_media_time - mmtime;
+
 if (this.streams[m.base.id].codec_type === 
SPICE_VIDEO_CODEC_TYPE_MJPEG)
-{
-process_mjpeg_stream_data(this, m);
+process_mjpeg_stream_data(this, m, latency);
+
+if ("report" in this.streams[m.base.id])
+process_stream_data_report(this, m, mmtime, latency);
 
-}
 return true;
 }
 
-if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
+if (msg.type == SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT)
 {
-var m = new SpiceMsgDisplayStreamDataSized(msg.data);
-if (this.streams[m.base.id].codec_type === 
SPICE_VIDEO_CODEC_TYPE_MJPEG)
-process_mjpeg_stream_data(this, m);
+var m = new SpiceMsgDisplayStreamActivateReport(msg.data);
+
+var report = new SpiceMsgcDisplayStreamReport(m.stream_id, 
m.unique_id);
+if (this.streams[m.stream_id])
+{
+this.streams[m.stream_id].report = report;
+this.streams[m.stream_id].max_window_size = m.max_window_size;
+this.streams[m.stream_id].timeout_ms = m.timeout_ms
+}
+
 return true;
 }
 
-
 if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
 {
 var m = new SpiceMsgDisplayStreamClip(msg.data);
@@ -811,8 +828,15 @@ function handle_draw_jpeg_onload()
 }
 }
 
-function process_mjpeg_stream_data(sc, m)
+function process_mjpeg_stream_data(sc, m, latency)
 {
+if (latency < 0)
+{
+if ("report" in sc.streams[m.base.id])
+sc.streams[m.base.id].report.num_drops++;
+return;
+}
+
 var tmpstr = "data:image/jpeg,";
 var img = new Image;
 var i;
@@ -837,3 +861,24 @@ function process_mjpeg_stream_data(sc, m)
 img.src = tmpstr;
 }
 
+function process_stream_data_report(sc, m, mmtime, latency)
+{
+sc.streams[m.base.id].report.num_frames++;
+if (sc.streams[m.base.id].report.start_frame_mm_time == 0)
+sc.streams[m.base.id].report.start_frame_mm_time = 
m.base.multi_media_time;
+
+if (sc.streams[m.base.id].report.num_frames > 
sc.streams[m.base.id].max_window_size ||
+(m.base.multi_media_time - 
sc.streams[m.base.id].report.start_frame_mm_time) > 
sc.streams[m.base.id].timeout_ms)
+{
+sc.streams[m.base.id].report.end_frame_mm_time = 
m.base.multi_media_time;
+sc.streams[m.base.id].report.last_frame_delay = latency;
+
+var msg = new SpiceMiniData();
+msg.build_msg(SPICE_MSGC_DISPLAY_STREAM_REPORT, 
sc.streams[m.base.id].report);
+sc.send_msg(msg);
+
+sc.streams[m.base.id].report.start_frame_mm_time = 0;
+sc.streams[m.base.id].report.num_frames = 0;
+sc.streams[m.base.id].report.num_drops = 0;
+}
+}
diff --git a/enums.js b/enums.js
index 7f55e46..6e94025 100644
--- a/enums.js
+++ b/enums.js
@@ -133,6 +133,7 @@ var SPICE_MSG_DISPLAY_DRAW_COMPOSITE= 318;
 var SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT = 319;
 
 var SPICE_MSGC_DISPLAY_INIT = 101;
+var SPICE_MSGC_DISPLAY_STREAM_REPORT= 102;
 
 var SPICE_MSG_INPUTS_INIT   = 101;
 var SPICE_MSG_INPUTS_KEY_MODIFIERS  = 102;
diff --git a/main.js b/main.js
index bfc102a..99b2274 100644
--- a/main.js
+++ b/main.js
@@ -86,6 +86,9 @@ SpiceMainConn.prototype.process_channel_message = 
function(msg)
   " ; ram_hint "+ 
this.main_init.ram_hint);
 }
 
+this.our_mm_time = Date.now();
+this.mm_time = this.main_init.multi_media_time;
+
 this.handle_mouse_mode(this.main_init.current_mouse_mode,

[Spice-devel] [PATCH spice-html5 2/3] Implement support for sized data streams.

2015-06-03 Thread Jeremy White
Signed-off-by: Jeremy White 
---
 display.js   | 60 ++--
 enums.js | 11 +++
 spiceconn.js |  4 
 spicemsg.js  | 23 +++
 4 files changed, 76 insertions(+), 22 deletions(-)

diff --git a/display.js b/display.js
index a749dae..7027230 100644
--- a/display.js
+++ b/display.js
@@ -487,32 +487,21 @@ SpiceDisplayConn.prototype.process_channel_message = 
function(msg)
 }
 if (this.streams[m.base.id].codec_type === 
SPICE_VIDEO_CODEC_TYPE_MJPEG)
 {
-var tmpstr = "data:image/jpeg,";
-var img = new Image;
-var i;
-for (i = 0; i < m.data.length; i++)
-{
-tmpstr +=  '%';
-if (m.data[i] < 16)
-tmpstr += '0';
-tmpstr += m.data[i].toString(16);
-}
-var strm_base = new SpiceMsgDisplayBase();
-strm_base.surface_id = this.streams[m.base.id].surface_id;
-strm_base.box = this.streams[m.base.id].dest;
-strm_base.clip = this.streams[m.base.id].clip;
-img.o =
-{ base: strm_base,
-  tag: "mjpeg." + m.base.id,
-  descriptor: null,
-  sc : this,
-};
-img.onload = handle_draw_jpeg_onload;
-img.src = tmpstr;
+process_mjpeg_stream_data(this, m);
+
 }
 return true;
 }
 
+if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
+{
+var m = new SpiceMsgDisplayStreamDataSized(msg.data);
+if (this.streams[m.base.id].codec_type === 
SPICE_VIDEO_CODEC_TYPE_MJPEG)
+process_mjpeg_stream_data(this, m);
+return true;
+}
+
+
 if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
 {
 var m = new SpiceMsgDisplayStreamClip(msg.data);
@@ -821,3 +810,30 @@ function handle_draw_jpeg_onload()
 this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
 }
 }
+
+function process_mjpeg_stream_data(sc, m)
+{
+var tmpstr = "data:image/jpeg,";
+var img = new Image;
+var i;
+for (i = 0; i < m.data.length; i++)
+{
+tmpstr +=  '%';
+if (m.data[i] < 16)
+tmpstr += '0';
+tmpstr += m.data[i].toString(16);
+}
+var strm_base = new SpiceMsgDisplayBase();
+strm_base.surface_id = sc.streams[m.base.id].surface_id;
+strm_base.box = m.dest || sc.streams[m.base.id].dest;
+strm_base.clip = sc.streams[m.base.id].clip;
+img.o =
+{ base: strm_base,
+  tag: "mjpeg." + m.base.id,
+  descriptor: null,
+  sc : sc,
+};
+img.onload = handle_draw_jpeg_onload;
+img.src = tmpstr;
+}
+
diff --git a/enums.js b/enums.js
index 17d77cb..7f55e46 100644
--- a/enums.js
+++ b/enums.js
@@ -127,6 +127,10 @@ var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT  = 312;
 var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND  = 313;
 var SPICE_MSG_DISPLAY_SURFACE_CREATE= 314;
 var SPICE_MSG_DISPLAY_SURFACE_DESTROY   = 315;
+var SPICE_MSG_DISPLAY_STREAM_DATA_SIZED = 316;
+var SPICE_MSG_DISPLAY_MONITORS_CONFIG   = 317;
+var SPICE_MSG_DISPLAY_DRAW_COMPOSITE= 318;
+var SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT = 319;
 
 var SPICE_MSGC_DISPLAY_INIT = 101;
 
@@ -171,6 +175,13 @@ var SPICE_MAIN_CAP_NAME_AND_UUID  = 1;
 var SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS = 2;
 var SPICE_MAIN_CAP_SEAMLESS_MIGRATE   = 3;
 
+var SPICE_DISPLAY_CAP_SIZED_STREAM= 0;
+var SPICE_DISPLAY_CAP_MONITORS_CONFIG = 1;
+var SPICE_DISPLAY_CAP_COMPOSITE   = 2;
+var SPICE_DISPLAY_CAP_A8_SURFACE  = 3;
+var SPICE_DISPLAY_CAP_STREAM_REPORT   = 4;
+var SPICE_DISPLAY_CAP_LZ4_COMPRESSION = 5;
+
 var SPICE_AUDIO_DATA_MODE_INVALID   = 0;
 var SPICE_AUDIO_DATA_MODE_RAW   = 1;
 var SPICE_AUDIO_DATA_MODE_CELT_0_5_1= 2;
diff --git a/spiceconn.js b/spiceconn.js
index ec42d8d..b7043c0 100644
--- a/spiceconn.js
+++ b/spiceconn.js
@@ -133,6 +133,10 @@ SpiceConn.prototype =
 msg.channel_caps.push(
 (1 << SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS)
 );
+else if (msg.channel_type == SPICE_CHANNEL_DISPLAY)
+msg.channel_caps.push(
+(1 << SPICE_DISPLAY_CAP_SIZED_STREAM)
+);
 
 hdr.size = msg.buffer_size();
 
diff --git a/spicemsg.js b/spicemsg.js
index e167b3d..4b78d94 100644
--- a/spicemsg.js
+++ b/spicemsg.js
@@ -1146,6 +1146,29 @@ SpiceMsgDisplayStreamData.prototype =
 },
 }
 
+function SpiceMsgDisplayStreamDataSized(a, at)
+{
+this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamDataSized.prototype =
+{
+from_buffer: function(a, at)
+{
+at = at || 0;
+var dv = new SpiceDataView(a);
+this.base = new SpiceStreamDataHeader;
+at = this.base.from_dv(dv, at, a);
+this.width = dv.getUint32(at, true); at += 4;
+this.height = dv.getUint32