Skip to content

Commit

Permalink
lib: New data structure - smap.
Browse files Browse the repository at this point in the history
A smap is a string to string hash map.  It has a cleaner interface
than shash's which were traditionally used for the same purpose.
This patch implements the data structure, and changes netdev and
its providers to use it.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
  • Loading branch information
ejj committed Jun 14, 2012
1 parent 37344ff commit 79f1cbe
Show file tree
Hide file tree
Showing 13 changed files with 558 additions and 287 deletions.
2 changes: 2 additions & 0 deletions lib/automake.mk
Expand Up @@ -141,6 +141,8 @@ lib_libopenvswitch_a_SOURCES = \
lib/simap.h \
lib/signals.c \
lib/signals.h \
lib/smap.c \
lib/smap.h \
lib/socket-util.c \
lib/socket-util.h \
lib/sort.c \
Expand Down
101 changes: 51 additions & 50 deletions lib/netdev-linux.c
Expand Up @@ -181,7 +181,7 @@ struct tc_ops {
*
* (This function is null for tc_ops_other, which cannot be installed. For
* other TC classes it should always be nonnull.) */
int (*tc_install)(struct netdev *netdev, const struct shash *details);
int (*tc_install)(struct netdev *netdev, const struct smap *details);

/* Called when the netdev code determines (through a Netlink query) that
* this TC class's qdisc is installed on 'netdev', but we didn't install
Expand Down Expand Up @@ -221,7 +221,7 @@ struct tc_ops {
*
* This function may be null if 'tc' is not configurable.
*/
int (*qdisc_get)(const struct netdev *netdev, struct shash *details);
int (*qdisc_get)(const struct netdev *netdev, struct smap *details);

/* Reconfigures 'netdev->tc' according to 'details', performing any
* required Netlink calls to complete the reconfiguration.
Expand All @@ -232,7 +232,7 @@ struct tc_ops {
*
* This function may be null if 'tc' is not configurable.
*/
int (*qdisc_set)(struct netdev *, const struct shash *details);
int (*qdisc_set)(struct netdev *, const struct smap *details);

/* Retrieves details of 'queue' on 'netdev->tc' into 'details'. 'queue' is
* one of the 'struct tc_queue's within 'netdev->tc->queues'.
Expand All @@ -248,7 +248,7 @@ struct tc_ops {
* This function may be null if 'tc' does not have queues ('n_queues' is
* 0). */
int (*class_get)(const struct netdev *netdev, const struct tc_queue *queue,
struct shash *details);
struct smap *details);

/* Configures or reconfigures 'queue_id' on 'netdev->tc' according to
* 'details', perfoming any required Netlink calls to complete the
Expand All @@ -262,7 +262,7 @@ struct tc_ops {
* This function may be null if 'tc' does not have queues or its queues are
* not configurable. */
int (*class_set)(struct netdev *, unsigned int queue_id,
const struct shash *details);
const struct smap *details);

/* Deletes 'queue' from 'netdev->tc'. 'queue' is one of the 'struct
* tc_queue's within 'netdev->tc->queues'.
Expand Down Expand Up @@ -1845,7 +1845,7 @@ netdev_linux_get_qos_capabilities(const struct netdev *netdev OVS_UNUSED,

static int
netdev_linux_get_qos(const struct netdev *netdev,
const char **typep, struct shash *details)
const char **typep, struct smap *details)
{
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev));
Expand All @@ -1864,7 +1864,7 @@ netdev_linux_get_qos(const struct netdev *netdev,

static int
netdev_linux_set_qos(struct netdev *netdev,
const char *type, const struct shash *details)
const char *type, const struct smap *details)
{
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev));
Expand Down Expand Up @@ -1901,7 +1901,7 @@ netdev_linux_set_qos(struct netdev *netdev,

static int
netdev_linux_get_queue(const struct netdev *netdev,
unsigned int queue_id, struct shash *details)
unsigned int queue_id, struct smap *details)
{
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev));
Expand All @@ -1920,7 +1920,7 @@ netdev_linux_get_queue(const struct netdev *netdev,

static int
netdev_linux_set_queue(struct netdev *netdev,
unsigned int queue_id, const struct shash *details)
unsigned int queue_id, const struct smap *details)
{
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev));
Expand Down Expand Up @@ -2002,7 +2002,7 @@ netdev_linux_dump_queues(const struct netdev *netdev,
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev));
struct tc_queue *queue, *next_queue;
struct shash details;
struct smap details;
int last_error;
int error;

Expand All @@ -2014,10 +2014,10 @@ netdev_linux_dump_queues(const struct netdev *netdev,
}

last_error = 0;
shash_init(&details);
smap_init(&details);
HMAP_FOR_EACH_SAFE (queue, next_queue, hmap_node,
&netdev_dev->tc->queues) {
shash_clear(&details);
smap_clear(&details);

error = netdev_dev->tc->ops->class_get(netdev, queue, &details);
if (!error) {
Expand All @@ -2026,7 +2026,7 @@ netdev_linux_dump_queues(const struct netdev *netdev,
last_error = error;
}
}
shash_destroy(&details);
smap_destroy(&details);

return last_error;
}
Expand Down Expand Up @@ -2271,25 +2271,26 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop,
}

static int
netdev_linux_get_drv_info(const struct netdev *netdev, struct shash *sh)
netdev_linux_get_drv_info(const struct netdev *netdev, struct smap *smap)
{
int error;
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev));

error = netdev_linux_get_drvinfo(netdev_dev);
if (!error) {
shash_add(sh, "driver_name", xstrdup(netdev_dev->drvinfo.driver));
shash_add(sh, "driver_version", xstrdup(netdev_dev->drvinfo.version));
shash_add(sh, "firmware_version", xstrdup(netdev_dev->drvinfo.fw_version));
smap_add(smap, "driver_name", netdev_dev->drvinfo.driver);
smap_add(smap, "driver_version", netdev_dev->drvinfo.version);
smap_add(smap, "firmware_version", netdev_dev->drvinfo.fw_version);
}
return error;
}

static int
netdev_internal_get_drv_info(const struct netdev *netdev OVS_UNUSED, struct shash *sh)
netdev_internal_get_drv_info(const struct netdev *netdev OVS_UNUSED,
struct smap *smap)
{
shash_add(sh, "driver_name", xstrdup("openvswitch"));
smap_add(smap, "driver_name", "openvswitch");
return 0;
}

Expand Down Expand Up @@ -2651,11 +2652,11 @@ htb_parse_tcmsg__(struct ofpbuf *tcmsg, unsigned int *queue_id,

static void
htb_parse_qdisc_details__(struct netdev *netdev,
const struct shash *details, struct htb_class *hc)
const struct smap *details, struct htb_class *hc)
{
const char *max_rate_s;

max_rate_s = shash_find_data(details, "max-rate");
max_rate_s = smap_get(details, "max-rate");
hc->max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
if (!hc->max_rate) {
enum netdev_features current;
Expand All @@ -2670,13 +2671,13 @@ htb_parse_qdisc_details__(struct netdev *netdev,

static int
htb_parse_class_details__(struct netdev *netdev,
const struct shash *details, struct htb_class *hc)
const struct smap *details, struct htb_class *hc)
{
const struct htb *htb = htb_get__(netdev);
const char *min_rate_s = shash_find_data(details, "min-rate");
const char *max_rate_s = shash_find_data(details, "max-rate");
const char *burst_s = shash_find_data(details, "burst");
const char *priority_s = shash_find_data(details, "priority");
const char *min_rate_s = smap_get(details, "min-rate");
const char *max_rate_s = smap_get(details, "max-rate");
const char *burst_s = smap_get(details, "burst");
const char *priority_s = smap_get(details, "priority");
int mtu, error;

error = netdev_get_mtu(netdev, &mtu);
Expand Down Expand Up @@ -2734,7 +2735,7 @@ htb_query_class__(const struct netdev *netdev, unsigned int handle,
}

static int
htb_tc_install(struct netdev *netdev, const struct shash *details)
htb_tc_install(struct netdev *netdev, const struct smap *details)
{
int error;

Expand Down Expand Up @@ -2826,15 +2827,15 @@ htb_tc_destroy(struct tc *tc)
}

static int
htb_qdisc_get(const struct netdev *netdev, struct shash *details)
htb_qdisc_get(const struct netdev *netdev, struct smap *details)
{
const struct htb *htb = htb_get__(netdev);
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * htb->max_rate));
smap_add_format(details, "max-rate", "%llu", 8ULL * htb->max_rate);
return 0;
}

static int
htb_qdisc_set(struct netdev *netdev, const struct shash *details)
htb_qdisc_set(struct netdev *netdev, const struct smap *details)
{
struct htb_class hc;
int error;
Expand All @@ -2850,24 +2851,24 @@ htb_qdisc_set(struct netdev *netdev, const struct shash *details)

static int
htb_class_get(const struct netdev *netdev OVS_UNUSED,
const struct tc_queue *queue, struct shash *details)
const struct tc_queue *queue, struct smap *details)
{
const struct htb_class *hc = htb_class_cast__(queue);

shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate));
smap_add_format(details, "min-rate", "%llu", 8ULL * hc->min_rate);
if (hc->min_rate != hc->max_rate) {
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate));
smap_add_format(details, "max-rate", "%llu", 8ULL * hc->max_rate);
}
shash_add(details, "burst", xasprintf("%llu", 8ULL * hc->burst));
smap_add_format(details, "burst", "%llu", 8ULL * hc->burst);
if (hc->priority) {
shash_add(details, "priority", xasprintf("%u", hc->priority));
smap_add_format(details, "priority", "%u", hc->priority);
}
return 0;
}

static int
htb_class_set(struct netdev *netdev, unsigned int queue_id,
const struct shash *details)
const struct smap *details)
{
struct htb_class hc;
int error;
Expand Down Expand Up @@ -3127,13 +3128,13 @@ hfsc_query_class__(const struct netdev *netdev, unsigned int handle,
}

static void
hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details,
hfsc_parse_qdisc_details__(struct netdev *netdev, const struct smap *details,
struct hfsc_class *class)
{
uint32_t max_rate;
const char *max_rate_s;

max_rate_s = shash_find_data(details, "max-rate");
max_rate_s = smap_get(details, "max-rate");
max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;

if (!max_rate) {
Expand All @@ -3149,16 +3150,16 @@ hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details,

static int
hfsc_parse_class_details__(struct netdev *netdev,
const struct shash *details,
const struct smap *details,
struct hfsc_class * class)
{
const struct hfsc *hfsc;
uint32_t min_rate, max_rate;
const char *min_rate_s, *max_rate_s;

hfsc = hfsc_get__(netdev);
min_rate_s = shash_find_data(details, "min-rate");
max_rate_s = shash_find_data(details, "max-rate");
min_rate_s = smap_get(details, "min-rate");
max_rate_s = smap_get(details, "max-rate");

min_rate = min_rate_s ? strtoull(min_rate_s, NULL, 10) / 8 : 0;
min_rate = MAX(min_rate, 1);
Expand Down Expand Up @@ -3259,7 +3260,7 @@ hfsc_setup_class__(struct netdev *netdev, unsigned int handle,
}

static int
hfsc_tc_install(struct netdev *netdev, const struct shash *details)
hfsc_tc_install(struct netdev *netdev, const struct smap *details)
{
int error;
struct hfsc_class class;
Expand Down Expand Up @@ -3327,16 +3328,16 @@ hfsc_tc_destroy(struct tc *tc)
}

static int
hfsc_qdisc_get(const struct netdev *netdev, struct shash *details)
hfsc_qdisc_get(const struct netdev *netdev, struct smap *details)
{
const struct hfsc *hfsc;
hfsc = hfsc_get__(netdev);
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hfsc->max_rate));
smap_add_format(details, "max-rate", "%llu", 8ULL * hfsc->max_rate);
return 0;
}

static int
hfsc_qdisc_set(struct netdev *netdev, const struct shash *details)
hfsc_qdisc_set(struct netdev *netdev, const struct smap *details)
{
int error;
struct hfsc_class class;
Expand All @@ -3354,21 +3355,21 @@ hfsc_qdisc_set(struct netdev *netdev, const struct shash *details)

static int
hfsc_class_get(const struct netdev *netdev OVS_UNUSED,
const struct tc_queue *queue, struct shash *details)
const struct tc_queue *queue, struct smap *details)
{
const struct hfsc_class *hc;

hc = hfsc_class_cast__(queue);
shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate));
smap_add_format(details, "min-rate", "%llu", 8ULL * hc->min_rate);
if (hc->min_rate != hc->max_rate) {
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate));
smap_add_format(details, "max-rate", "%llu", 8ULL * hc->max_rate);
}
return 0;
}

static int
hfsc_class_set(struct netdev *netdev, unsigned int queue_id,
const struct shash *details)
const struct smap *details)
{
int error;
struct hfsc_class class;
Expand Down Expand Up @@ -3473,7 +3474,7 @@ default_install__(struct netdev *netdev)

static int
default_tc_install(struct netdev *netdev,
const struct shash *details OVS_UNUSED)
const struct smap *details OVS_UNUSED)
{
default_install__(netdev);
return 0;
Expand Down

0 comments on commit 79f1cbe

Please sign in to comment.