If not, my proposal:
 I set an incomplete (prefix) lxc.network.hwaddr in default conf.
lxc-create complete it randomly and write it to the container's config.

Does it make sense?

I think so.  Just 'xx' in place of real numbers?

I do not/can't code in C, but perhaps I should try  ...

Guillaume ZITTA

Please be kind, it's the second time I do "C" of my life :)

Note about randinit():
that kind of util can be used in network.c/lxc_mkifname() and lxccontainer.c/new_hwaddr()

It works for me, I did 1000 destroy/create (with fake template) in 43 sec without mac duplicate.

If I'm not completely doing wrong, I'll provide patch for manpage and HAVE_RAND_R ifdef.

please comment.

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index c5ec4f3..5721e05 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -509,6 +509,24 @@ static int macvlan_mode(int *valuep, const char *value)
        return -1;
 }

+char *rand_complete_hwaddr(const char *hwaddr)
+{
+       const char hex[] = "0123456789abcdef";
+       char *retval=NULL;
+       retval = strdup(hwaddr);
+       char *curs = retval;
+
+       randinit();
+
+       while (*curs != '\0')
+       {
+               if ( *curs == 'x' || *curs == 'X' )
+                       *curs = hex[rand() & 0x0F];
+               curs++;
+       }
+       return retval;
+}
+
 static int config_network_flags(const char *key, const char *value,
                                struct lxc_conf *lxc_conf)
 {
@@ -576,11 +594,13 @@ static int config_network_hwaddr(const char *key, const char *value,
 {
        struct lxc_netdev *netdev;

-       netdev = network_netdev(key, value, &lxc_conf->network);
+       const char *newval = rand_complete_hwaddr(value);
+
+       netdev = network_netdev(key, newval, &lxc_conf->network);
        if (!netdev)
                return -1;

-       return config_string_item(&netdev->hwaddr, value);
+       return config_string_item(&netdev->hwaddr, newval);
 }

 static int config_network_vlan_id(const char *key, const char *value,
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 785f3e6..204179e 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1126,3 +1126,25 @@ void **lxc_append_null_to_array(void **array, size_t count)
        }
        return array;
 }
+
+void randinit(void)
+{
+       /*
+       srand pre-seed function based on /dev/urandom
+       */
+       FILE *f;
+       process_lock();
+       f = fopen("/dev/urandom", "r");
+       process_unlock();
+       if (f) {
+               unsigned int seed;
+               int ret = fread(&seed, sizeof(seed), 1, f);
+               if (ret != 1)
+                       seed = time(NULL);
+               process_lock();
+               fclose(f);
+               process_unlock();
+               srand(seed);
+       } else
+               srand(time(NULL));
+}
\ No newline at end of file
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 945f1de..f20339b 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -270,4 +270,7 @@ extern void **lxc_dup_array(void **array, lxc_dup_fn element_dup_fn, lxc_free_fn
 extern void **lxc_append_null_to_array(void **array, size_t count);

 extern void dump_stacktrace(void);
+
+//initialize rand with urandom
+extern void randinit(void);
 #endif

_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to