diff mbox series

[ovs-dev,ovs-dev,ovn,2/2] ovn-nbctl.c: Add a way to delete QoS by its name or uuid.

Message ID 2019112615573569275427@cmss.chinamobile.com
State Superseded
Headers show
Series Add a way to delete QoS directly | expand

Commit Message

Tao YunXiang Nov. 26, 2019, 7:57 a.m. UTC
Add a way to delete QoS by its name or uuid
    
Currently, qos can only be deleted by indirect way which must designate
switch or more parameters. This patch change the original "qos-del" to
"ls-qos-del", and add a new "qos-del" command. By the new command, you
can delete qos by uuid or name of the qos. It is very import to support
a way to delete a table by direct way. For example, we can associate
the qos table in neutron and OVN by "name" of qos in OVN, so neutron
could find and easily delete the corresponding qos in OVN.
Signed-off-by: Yunxiang Tao <taoyunxiang@cmss.chinamobile.com>




taoyunxiang@cmss.chinamobile.com

Comments

Tao YunXiang Dec. 20, 2019, 8:08 a.m. UTC | #1
Hi, Could you review this patch。It is an important QoS feature for plugin of OVN.  

Thanks,
Yun





From: taoyunxiang@cmss.chinamobile.com
Date: 2019-11-26 15:57
To: ovs-dev
Subject: [ovs-dev,ovn,2/2] ovn-nbctl.c: Add a way to delete QoS by its name or uuid.
Add a way to delete QoS by its name or uuid
    
Currently, qos can only be deleted by indirect way which must designate
switch or more parameters. This patch change the original "qos-del" to
"ls-qos-del", and add a new "qos-del" command. By the new command, you
can delete qos by uuid or name of the qos. It is very import to support
a way to delete a table by direct way. For example, we can associate
the qos table in neutron and OVN by "name" of qos in OVN, so neutron
could find and easily delete the corresponding qos in OVN.
Signed-off-by: Yunxiang Tao <taoyunxiang@cmss.chinamobile.com>
diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
index 93e37d169..f1d64208d 100644
--- a/utilities/ovn-nbctl.c
+++ b/utilities/ovn-nbctl.c
@@ -604,8 +604,9 @@ ACL commands:\n\
 QoS commands:\n\
   qos-add SWITCH DIRECTION PRIORITY MATCH [rate=RATE [burst=BURST]] [dscp=DSCP]\n\
                             add an QoS rule to SWITCH\n\
-  qos-del SWITCH [DIRECTION [PRIORITY MATCH]]\n\
+  ls-qos-del SWITCH [DIRECTION [PRIORITY MATCH]]\n\
                             remove QoS rules from SWITCH\n\
+  qos-del QOS               remove QoS rules by name or UUID\n\
   qos-list SWITCH           print QoS rules for SWITCH\n\
 \n\
 Meter commands:\n\
@@ -2490,7 +2491,7 @@ nbctl_qos_add(struct ctl_context *ctx)
 }
 
 static void
-nbctl_qos_del(struct ctl_context *ctx)
+nbctl_ls_qos_del(struct ctl_context *ctx)
 {
     const struct nbrec_logical_switch *ls;
     char *error = ls_by_name_or_uuid(ctx, ctx->argv[1], true, &ls);
@@ -2564,6 +2565,96 @@ nbctl_qos_del(struct ctl_context *ctx)
     }
 }
 
+/* Remove qos*/
+static void
+remove_qos(const struct nbrec_logical_switch *ls, size_t idx)
+{
+
+    /* First remove 'qos' from the array of qos_rules.  This is what will
+     * actually cause the qos to be deleted when the transaction is
+     * sent to the database server (due to garbage collection). */
+    struct nbrec_qos **new_qos_rules
+        = xmemdup(ls->qos_rules, sizeof *new_qos_rules * ls->n_qos_rules);
+    new_qos_rules[idx] = new_qos_rules[ls->n_qos_rules - 1];
+    nbrec_logical_switch_verify_qos_rules(ls);
+    nbrec_logical_switch_set_qos_rules(ls, new_qos_rules, \
+                                      ls->n_qos_rules - 1);
+    free(new_qos_rules);
+
+    /* Delete 'qos' from the IDL.This won't have a real effect on the
+     * database server (the IDL will suppress it in fact) but it means that it
+     * won't show up when we iterate with NBREC_LOGICAL_QOS_FOR_EACH later. */
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+qos_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist,
+                   const struct nbrec_qos **qos_p)
+{
+    const struct nbrec_qos *qos = NULL;
+    *qos_p = NULL;
+
+    struct uuid qos_uuid;
+    bool is_uuid = uuid_from_string(&qos_uuid, id);
+    if (is_uuid) {
+        qos = nbrec_qos_get_for_uuid(ctx->idl, &qos_uuid);
+    }
+
+    if (!qos) {
+        const struct nbrec_qos *iter;
+
+        NBREC_QOS_FOR_EACH(iter, ctx->idl) {
+            if (strcmp(iter->name, id)) {
+                continue;
+            }
+            if (qos) {
+                return xasprintf("Multiple qos named '%s'.  "
+                                 "Use a UUID.", id);
+            }
+            qos = iter;
+        }
+    }
+
+    if (!qos && must_exist) {
+        return xasprintf("%s: qos %s not found",
+                         id, is_uuid ? "UUID" : "name");
+    }
+
+    *qos_p = qos;
+    return NULL;
+}
+
+static void
+nbctl_qos_del(struct ctl_context *ctx)
+{
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
+    const char *id = ctx->argv[1];
+    const struct nbrec_qos *qos = NULL;
+
+    char *error = qos_by_name_or_uuid(ctx, id, must_exist, &qos);
+    if (error) {
+        ctx->error = error;
+        return;
+    }
+    if (!qos) {
+        return;
+    }
+
+        /* Find the switch that contains 'qos_rules', then delete it. */
+    const struct nbrec_logical_switch *ls;
+    NBREC_LOGICAL_SWITCH_FOR_EACH (ls, ctx->idl) {
+        for (size_t i = 0; i < ls->n_qos_rules; i++) {
+            if (ls->qos_rules[i] == qos) {
+                remove_qos(ls, i);
+                return;
+            }
+        }
+    }
+
+    /* Can't happen because of the database schema. */
+    ctl_error(ctx, "qos %s is not part of any logical switch",
+              ctx->argv[1]);
+}
+
 static int
 meter_cmp(const void *meter1_, const void *meter2_)
 {
@@ -5652,8 +5743,9 @@ static const struct ctl_command_syntax nbctl_commands[] = {
     { "qos-add", 5, 7,
       "SWITCH DIRECTION PRIORITY MATCH [rate=RATE [burst=BURST]] [dscp=DSCP]",
       NULL, nbctl_qos_add, NULL, "--may-exist", RW },
-    { "qos-del", 1, 4, "SWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
-      nbctl_qos_del, NULL, "", RW },
+    { "qos-del", 1, 1, "QOS", NULL, nbctl_qos_del, NULL, "--if-exists", RW },
+    { "ls-qos-del", 1, 4, "SWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
+      nbctl_ls_qos_del, NULL, "", RW },
     { "qos-list", 1, 1, "SWITCH", NULL, nbctl_qos_list, NULL, "", RO },
 
     /* meter commands. */




taoyunxiang@cmss.chinamobile.com
diff mbox series

Patch

diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
index 93e37d169..f1d64208d 100644
--- a/utilities/ovn-nbctl.c
+++ b/utilities/ovn-nbctl.c
@@ -604,8 +604,9 @@  ACL commands:\n\
 QoS commands:\n\
   qos-add SWITCH DIRECTION PRIORITY MATCH [rate=RATE [burst=BURST]] [dscp=DSCP]\n\
                             add an QoS rule to SWITCH\n\
-  qos-del SWITCH [DIRECTION [PRIORITY MATCH]]\n\
+  ls-qos-del SWITCH [DIRECTION [PRIORITY MATCH]]\n\
                             remove QoS rules from SWITCH\n\
+  qos-del QOS               remove QoS rules by name or UUID\n\
   qos-list SWITCH           print QoS rules for SWITCH\n\
 \n\
 Meter commands:\n\
@@ -2490,7 +2491,7 @@  nbctl_qos_add(struct ctl_context *ctx)
 }
 
 static void
-nbctl_qos_del(struct ctl_context *ctx)
+nbctl_ls_qos_del(struct ctl_context *ctx)
 {
     const struct nbrec_logical_switch *ls;
     char *error = ls_by_name_or_uuid(ctx, ctx->argv[1], true, &ls);
@@ -2564,6 +2565,96 @@  nbctl_qos_del(struct ctl_context *ctx)
     }
 }
 
+/* Remove qos*/
+static void
+remove_qos(const struct nbrec_logical_switch *ls, size_t idx)
+{
+
+    /* First remove 'qos' from the array of qos_rules.  This is what will
+     * actually cause the qos to be deleted when the transaction is
+     * sent to the database server (due to garbage collection). */
+    struct nbrec_qos **new_qos_rules
+        = xmemdup(ls->qos_rules, sizeof *new_qos_rules * ls->n_qos_rules);
+    new_qos_rules[idx] = new_qos_rules[ls->n_qos_rules - 1];
+    nbrec_logical_switch_verify_qos_rules(ls);
+    nbrec_logical_switch_set_qos_rules(ls, new_qos_rules, \
+                                      ls->n_qos_rules - 1);
+    free(new_qos_rules);
+
+    /* Delete 'qos' from the IDL.This won't have a real effect on the
+     * database server (the IDL will suppress it in fact) but it means that it
+     * won't show up when we iterate with NBREC_LOGICAL_QOS_FOR_EACH later. */
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+qos_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist,
+                   const struct nbrec_qos **qos_p)
+{
+    const struct nbrec_qos *qos = NULL;
+    *qos_p = NULL;
+
+    struct uuid qos_uuid;
+    bool is_uuid = uuid_from_string(&qos_uuid, id);
+    if (is_uuid) {
+        qos = nbrec_qos_get_for_uuid(ctx->idl, &qos_uuid);
+    }
+
+    if (!qos) {
+        const struct nbrec_qos *iter;
+
+        NBREC_QOS_FOR_EACH(iter, ctx->idl) {
+            if (strcmp(iter->name, id)) {
+                continue;
+            }
+            if (qos) {
+                return xasprintf("Multiple qos named '%s'.  "
+                                 "Use a UUID.", id);
+            }
+            qos = iter;
+        }
+    }
+
+    if (!qos && must_exist) {
+        return xasprintf("%s: qos %s not found",
+                         id, is_uuid ? "UUID" : "name");
+    }
+
+    *qos_p = qos;
+    return NULL;
+}
+
+static void
+nbctl_qos_del(struct ctl_context *ctx)
+{
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
+    const char *id = ctx->argv[1];
+    const struct nbrec_qos *qos = NULL;
+
+    char *error = qos_by_name_or_uuid(ctx, id, must_exist, &qos);
+    if (error) {
+        ctx->error = error;
+        return;
+    }
+    if (!qos) {
+        return;
+    }
+
+        /* Find the switch that contains 'qos_rules', then delete it. */
+    const struct nbrec_logical_switch *ls;
+    NBREC_LOGICAL_SWITCH_FOR_EACH (ls, ctx->idl) {
+        for (size_t i = 0; i < ls->n_qos_rules; i++) {
+            if (ls->qos_rules[i] == qos) {
+                remove_qos(ls, i);
+                return;
+            }
+        }
+    }
+
+    /* Can't happen because of the database schema. */
+    ctl_error(ctx, "qos %s is not part of any logical switch",
+              ctx->argv[1]);
+}
+
 static int
 meter_cmp(const void *meter1_, const void *meter2_)
 {
@@ -5652,8 +5743,9 @@  static const struct ctl_command_syntax nbctl_commands[] = {
     { "qos-add", 5, 7,
       "SWITCH DIRECTION PRIORITY MATCH [rate=RATE [burst=BURST]] [dscp=DSCP]",
       NULL, nbctl_qos_add, NULL, "--may-exist", RW },
-    { "qos-del", 1, 4, "SWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
-      nbctl_qos_del, NULL, "", RW },
+    { "qos-del", 1, 1, "QOS", NULL, nbctl_qos_del, NULL, "--if-exists", RW },
+    { "ls-qos-del", 1, 4, "SWITCH [DIRECTION [PRIORITY MATCH]]", NULL,
+      nbctl_ls_qos_del, NULL, "", RW },
     { "qos-list", 1, 1, "SWITCH", NULL, nbctl_qos_list, NULL, "", RO },
 
     /* meter commands. */