Make unixctl_command_register() idempotent
authorSimon Horman <horms@verge.net.au>
Mon, 14 Nov 2011 08:41:28 +0000 (17:41 +0900)
committerBen Pfaff <blp@nicira.com>
Mon, 14 Nov 2011 17:17:15 +0000 (09:17 -0800)
The assert() statement in unixctl_command_register() implies that it is
intended to be idempotent but inserting the same name and callback twice
would fail because:

* The callback is not stored directly in the hash, rather it the
  cb element of a struct unixctl_command which is stored in the hash.

* Insertion would be attempted even if the entry was already present.

lib/unixctl.c

index 7cc7e5e234a6ee4e45d79ededbf8e150c488d68a..d75166fe424117c0a5d3703c6223a0bc1cfb3343 100644 (file)
@@ -115,9 +115,14 @@ unixctl_command_register(const char *name, const char *args,
         unixctl_cb_func *cb, void *aux)
 {
     struct unixctl_command *command;
+    struct unixctl_command *lookup = shash_find_data(&commands, name);
+
+    assert(!lookup || lookup->cb == cb);
+
+    if (lookup) {
+        return;
+    }
 
-    assert(!shash_find_data(&commands, name)
-           || shash_find_data(&commands, name) == cb);
     command = xmalloc(sizeof *command);
     command->args = args;
     command->cb = cb;