struct list txq;
};
+/* Protects 'dummy_list'. */
+static struct ovs_mutex dummy_list_mutex = OVS_MUTEX_INITIALIZER;
+
+/* Contains all 'struct dummy_dev's. */
+static struct list dummy_list OVS_GUARDED_BY(dummy_list_mutex)
+ = LIST_INITIALIZER(&dummy_list);
+
struct netdev_dummy {
struct netdev up;
+ /* In dummy_list. */
+ struct list list_node OVS_GUARDED_BY(dummy_list_mutex);
+
/* Protects all members below. */
- struct ovs_mutex mutex;
+ struct ovs_mutex mutex OVS_ACQ_AFTER(dummy_list_mutex);
uint8_t hwaddr[ETH_ADDR_LEN];
int mtu;
struct list rxes; /* List of child "netdev_rx_dummy"s. */
};
-static const struct netdev_class dummy_class;
-
/* Max 'recv_queue_len' in struct netdev_dummy. */
#define NETDEV_DUMMY_MAX_QUEUE 100
static void
netdev_dummy_run(void)
{
- struct shash dummy_netdevs;
- struct shash_node *node;
+ struct netdev_dummy *dev;
- shash_init(&dummy_netdevs);
- netdev_get_devices(&dummy_class, &dummy_netdevs);
- SHASH_FOR_EACH (node, &dummy_netdevs) {
- struct netdev_dummy *dev = node->data;
+ ovs_mutex_lock(&dummy_list_mutex);
+ LIST_FOR_EACH (dev, list_node, &dummy_list) {
size_t i;
ovs_mutex_lock(&dev->mutex);
}
ovs_mutex_unlock(&dev->mutex);
- netdev_close(&dev->up);
}
- shash_destroy(&dummy_netdevs);
+ ovs_mutex_unlock(&dummy_list_mutex);
}
static void
static void
netdev_dummy_wait(void)
{
- struct shash dummy_netdevs;
- struct shash_node *node;
+ struct netdev_dummy *dev;
- shash_init(&dummy_netdevs);
- netdev_get_devices(&dummy_class, &dummy_netdevs);
- SHASH_FOR_EACH (node, &dummy_netdevs) {
- struct netdev_dummy *dev = node->data;
+ ovs_mutex_lock(&dummy_list_mutex);
+ LIST_FOR_EACH (dev, list_node, &dummy_list) {
size_t i;
ovs_mutex_lock(&dev->mutex);
stream_recv_wait(s->stream);
}
ovs_mutex_unlock(&dev->mutex);
- netdev_close(&dev->up);
}
- shash_destroy(&dummy_netdevs);
+ ovs_mutex_unlock(&dummy_list_mutex);
}
static struct netdev *
list_init(&netdev->rxes);
+ ovs_mutex_lock(&dummy_list_mutex);
+ list_push_back(&dummy_list, &netdev->list_node);
+ ovs_mutex_unlock(&dummy_list_mutex);
+
return 0;
}
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
size_t i;
+ ovs_mutex_lock(&dummy_list_mutex);
+ list_remove(&netdev->list_node);
+ ovs_mutex_unlock(&dummy_list_mutex);
+
pstream_close(netdev->pstream);
for (i = 0; i < netdev->n_streams; i++) {
dummy_stream_close(&netdev->streams[i]);
return;
}
} else {
- struct shash dummy_netdevs;
- struct shash_node *node;
-
- shash_init(&dummy_netdevs);
- netdev_get_devices(&dummy_class, &dummy_netdevs);
- SHASH_FOR_EACH (node, &dummy_netdevs) {
- struct netdev *netdev_ = node->data;
- struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+ struct netdev_dummy *netdev;
+ ovs_mutex_lock(&dummy_list_mutex);
+ LIST_FOR_EACH (netdev, list_node, &dummy_list) {
ovs_mutex_lock(&netdev->mutex);
netdev_dummy_set_admin_state__(netdev, up);
ovs_mutex_unlock(&netdev->mutex);
-
- netdev_close(netdev_);
}
- shash_destroy(&dummy_netdevs);
+ ovs_mutex_unlock(&dummy_list_mutex);
}
unixctl_command_reply(conn, "OK");
}