[Spice-devel] [spice PATCH 04/55] reds: add tracking for char devices

Yonit Halperin yhalperi at redhat.com
Wed Aug 15 00:55:44 PDT 2012


The list of attached char_devices will be used in the next patch
for notifying each instance of SpiceCharDeviceState when the vm
is started or stopped.
---
 server/char_device.c |    1 +
 server/reds.c        |   44 ++++++++++++++++++++++++++++++++++++++++++++
 server/reds.h        |    1 +
 3 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/server/char_device.c b/server/char_device.c
index e87c029..c28e548 100644
--- a/server/char_device.c
+++ b/server/char_device.c
@@ -644,6 +644,7 @@ static void spice_char_device_state_unref(SpiceCharDeviceState *char_dev)
 
 void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev)
 {
+    reds_on_char_device_state_destroy(char_dev);
     core->timer_remove(char_dev->write_to_dev_timer);
     write_buffers_queue_free(&char_dev->write_queue);
     write_buffers_queue_free(&char_dev->write_bufs_pool);
diff --git a/server/reds.c b/server/reds.c
index 53f0a39..4e8a008 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -220,6 +220,11 @@ typedef struct RedsMigTargetClient {
     Ring pending_links;
 } RedsMigTargetClient;
 
+typedef struct SpiceCharDeviceStateItem {
+    RingItem link;
+    SpiceCharDeviceState *st;
+} SpiceCharDeviceStateItem;
+
 typedef struct RedsState {
     int listen_socket;
     int secure_listen_socket;
@@ -247,6 +252,8 @@ typedef struct RedsState {
     SpiceTimer *mig_timer;
     SpiceTimer *mm_timer;
 
+    Ring char_devs_states; /* list of SpiceCharDeviceStateItem */
+
     SSL_CTX *ctx;
 
 #ifdef RED_STATISTICS
@@ -300,6 +307,8 @@ struct ChannelSecurityOptions {
 static void migrate_timeout(void *opaque);
 static RedsMigTargetClient* reds_mig_target_client_find(RedClient *client);
 static void reds_mig_target_client_free(RedsMigTargetClient *mig_client);
+static void reds_char_device_add_state(SpiceCharDeviceState *st);
+static void reds_char_device_remove_state(SpiceCharDeviceState *st);
 
 static ChannelSecurityOptions *channels_security = NULL;
 static int default_channel_security =
@@ -3189,6 +3198,37 @@ SPICE_GNUC_VISIBLE const char** spice_server_char_device_recognized_subtypes(voi
     return spice_server_char_device_recognized_subtypes_list;
 }
 
+static void reds_char_device_add_state(SpiceCharDeviceState *st)
+{
+    SpiceCharDeviceStateItem *item = spice_new0(SpiceCharDeviceStateItem, 1);
+
+    item->st = st;
+
+    ring_add(&reds->char_devs_states, &item->link);
+}
+
+static void reds_char_device_remove_state(SpiceCharDeviceState *st)
+{
+    RingItem *item;
+
+    RING_FOREACH(item, &reds->char_devs_states) {
+        SpiceCharDeviceStateItem *st_item;
+
+        st_item = SPICE_CONTAINEROF(item, SpiceCharDeviceStateItem, link);
+        if (st_item->st == st) {
+            ring_remove(item);
+            free(st_item);
+            return;
+        }
+    }
+    spice_error("char dev state not found %p", st);
+}
+
+void reds_on_char_device_state_destroy(SpiceCharDeviceState *dev)
+{
+    reds_char_device_remove_state(dev);
+}
+
 static int spice_server_char_device_add_interface(SpiceServer *s,
                                            SpiceBaseInstance *sin)
 {
@@ -3196,6 +3236,8 @@ static int spice_server_char_device_add_interface(SpiceServer *s,
             SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
     SpiceCharDeviceState *dev_state = NULL;
 
+    spice_assert(s == reds);
+
     spice_info("CHAR_DEVICE %s", char_device->subtype);
     if (strcmp(char_device->subtype, SUBTYPE_VDAGENT) == 0) {
         if (vdagent) {
@@ -3219,6 +3261,7 @@ static int spice_server_char_device_add_interface(SpiceServer *s,
         /* setting the char_device state to "started" for backward compatibily with
          * qemu releases that don't call spice api for start/stop (not implemented yet) */
         spice_char_device_start(char_device->st);
+        reds_char_device_add_state(char_device->st);
     } else {
         spice_warning("failed to create device state for %s", char_device->subtype);
     }
@@ -3432,6 +3475,7 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     main_dispatcher_init(core);
     ring_init(&reds->channels);
     ring_init(&reds->mig_target_clients);
+    ring_init(&reds->char_devs_states);
 
     if (!(reds->mig_timer = core->timer_add(migrate_timeout, NULL))) {
         spice_error("migration timer create failed");
diff --git a/server/reds.h b/server/reds.h
index f3d2ffa..87125d2 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -155,5 +155,6 @@ void reds_on_main_migrate_connected(void); //should be called when all the clien
 void reds_on_main_receive_migrate_data(MainMigrateData *data, uint8_t *end);
 void reds_on_main_mouse_mode_request(void *message, size_t size);
 void reds_on_client_migrate_complete(RedClient *client);
+void reds_on_char_device_state_destroy(SpiceCharDeviceState *dev);
 
 #endif
-- 
1.7.7.6



More information about the Spice-devel mailing list