Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-23 Thread Dan Smith
JM> However, argv is one place where it pays to relax
JM> const-correctness guidelines, at least in C, because so many
JM> interfaces require non-const "char **argv" pointers.  IMHO, it's
JM> better to avoid const altogether in this limited case than to be
JM> forced to litter the code with ugly and dangerous const-adjusting
JM> casts to accommodate "correctness".

I agree with the last statement, but in this case, leaving the const
off the declaration results in a compiler warning about discarding the
inherent const qualifier from a literal string.

A *very* quick look in src/*.c doesn't reveal any other examples of
all-literal argv[] lists like this.  I'm inclined to leave the const
and the cast, but if you have a better suggestion, I'll be glad to
make the change.

Thanks!

-- 
Dan Smith
IBM Linux Technology Center
Open Hypervisor Team
email: [EMAIL PROTECTED]


pgpBGD38giQUJ.pgp
Description: PGP signature
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-21 Thread Jim Meyering
Daniel Veillard <[EMAIL PROTECTED]> wrote:
...
>> +int vethCreate(char* veth1, int veth1MaxLen,
>> +   char* veth2, int veth2MaxLen)
>> +{
>> +int rc = -1;
>> +const char *argv[] = {
>
> I think Jim insists on having const char const * [], but I bet he will explain
> this better than me :-)
>
>> +"ip", "link", "add", veth1, "type", "veth", "peer", "name", veth2, 
>> NULL

You're right that I encourage the "const correct" approach ;-)

To tell the compiler (and more importantly, the reader) that you
have a const array of const strings, you'd declare it like this:

const char *const argv[] = {

or, equivalently, the const can go after the type name of "char":

char const *const argv[] = {

However, argv is one place where it pays to relax const-correctness
guidelines, at least in C, because so many interfaces require non-const
"char **argv" pointers.  IMHO, it's better to avoid const altogether in
this limited case than to be forced to litter the code with ugly and
dangerous const-adjusting casts to accommodate "correctness".

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-20 Thread Dave Leskovec
Dan Smith wrote:
>>> +if (1 > strlen(veth1)) {
> 
> DL> Why do you check with strlen > 1 ?
> 
> To be honest, I have no idea why Dave did that.  I'll check with him
> to see if there's something we're missing.  It's probably worth a
> comment if so.
> 

So that's checking if veth1 is an empty string and hence needs to have a name
assigned.  I don't recall any special reason for using (1 > strlen()).

-- 
Best Regards,
Dave Leskovec
IBM Linux Technology Center
Open Virtualization

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-20 Thread Dan Smith
>> +#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
>> +#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg)

DL> Do you know ##__VA_ARGS ?

Yes, and I agree this not my preferred way.  However, this isn't my
code and when I went to look for other instances, I found many so I
decided not to change it.

  % cat *.c | grep DEBUG0 -c
  47

DL> Is this function safe for concurrent access ? eg. getFreeVethName
DL> called in parallel by two processes or another process creates a
DL> pair device just after you exit the loop ?

No, there is indeed a race.  However, since this just makes a
suggestion and relies on the subsequent call to try to instantiate the
interface, I don't think there's a chance for anything other than a
spurious failure.

This is specifically why I wanted to get this on the list sooner than
later.  I figured (or hoped) that given the experience in this group
that someone could offer some educated suggestions before I jumped in
and started trying to fix it.

>> +if (1 > strlen(veth1)) {

DL> Why do you check with strlen > 1 ?

To be honest, I have no idea why Dave did that.  I'll check with him
to see if there's something we're missing.  It's probably worth a
comment if so.

-- 
Dan Smith
IBM Linux Technology Center
Open Hypervisor Team
email: [EMAIL PROTECTED]


pgpP69YKohLy3.pgp
Description: PGP signature
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-20 Thread Daniel Lezcano

Dan Smith wrote:

# HG changeset patch
# User Dave Leskovec <[EMAIL PROTECTED]>
# Date 1213891164 25200
# Node ID 386c067de8995028dd11f70602081c31682dd293
# Parent  8d2afc533c91c4796512e1e71c8283e86eafd18a
[LXC] Add functions to manage veth device pairs

This gives us the ability to create a veth pair so that we can move one
into the network namespace of an LXC container.

diff -r 8d2afc533c91 -r 386c067de899 configure.in
--- a/configure.in  Tue Jun 17 15:55:03 2008 +
+++ b/configure.in  Thu Jun 19 08:59:24 2008 -0700
@@ -301,6 +301,20 @@
 if test "$with_qemu" = "yes" ; then
   AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h 
linux/if_tun.h],,
AC_MSG_ERROR([You must install kernel-headers in order to 
compile libvirt]))
+fi
+
+dnl
+dnl check for patched iproute2 for lxc network support
+dnl
+if test "$with_lxc" = "yes" ; then
+   AC_MSG_CHECKING([for NETNS support])
+   if ip link help 2>&1 | grep -q netns; then
+ with_lxc_netns="yes"
+ AC_DEFINE([HAVE_NETNS], [], [Kernel has NETNS support])
+   else
+ with_lxc_netns="no"
+   fi
+   AC_MSG_RESULT($with_lxc_netns)
 fi

 dnl Need to test if pkg-config exists
diff -r 8d2afc533c91 -r 386c067de899 src/Makefile.am
--- a/src/Makefile.am   Tue Jun 17 15:55:03 2008 +
+++ b/src/Makefile.am   Thu Jun 19 08:59:24 2008 -0700
@@ -64,6 +64,7 @@
lxc_driver.c lxc_driver.h   \
lxc_conf.c lxc_conf.h   \
lxc_container.c lxc_container.h \
+   veth.c veth.h   \
 nodeinfo.h nodeinfo.c   \
util.c util.h

diff -r 8d2afc533c91 -r 386c067de899 src/veth.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/src/veth.cThu Jun 19 08:59:24 2008 -0700
@@ -0,0 +1,247 @@
+/*
+ * Copyright IBM Corp. 2008
+ *
+ * veth.c: file description
+ *
+ * Authors:
+ *  David L. Leskovec 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include 
+
+#ifdef HAVE_NETNS
+
+#include 
+
+#include "veth.h"
+#include "internal.h"
+#include "memory.h"
+#include "util.h"
+
+#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
+#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg)


Do you know ##__VA_ARGS ?


+/* Functions */
+/**
+ * getFreeVethName:
+ * @veth: name for veth device (NULL to find first open)
+ * @maxLen: max length of veth name
+ * @startDev: device number to start at (x in vethx)
+ *
+ * Looks in /sys/class/net/ to find the first available veth device
+ * name.
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+static int getFreeVethName(char *veth, int maxLen, int startDev)
+{
+int rc = -1;
+int devNum = startDev;
+char path[PATH_MAX];
+
+snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum);


You can perhaps, use do { ... } while () here.


+while (virFileExists(path)) {
+++devNum;
+sprintf(path, "/sys/class/net/veth%d/", devNum);
+}


Is this function safe for concurrent access ? eg. getFreeVethName called 
in parallel by two processes or another process creates a pair device 
just after you exit the loop ?



+snprintf(veth, maxLen, "veth%d", devNum);
+
+rc = devNum;
+
+return rc;
+}
+
+/**
+ * vethCreate:
+ * @veth1: name for one end of veth pair
+ * @veth1MaxLen: max length of veth1 name
+ * @veth2: name for one end of veth pair
+ * @veth2MaxLen: max length of veth1 name
+ *
+ * Creates a veth device pair using the ip command:
+ * ip link add veth1 type veth peer name veth2
+ * NOTE: If veth1 and veth2 names are not specified, ip will auto assign
+ *   names.  There seems to be two problems here -
+ *   1) There doesn't seem to be a way to determine the names of the
+ *  devices that it creates.  They show up in ip link show and
+ *  under /sys/class/net/ however there is no guarantee that they
+ *  are the devices that this process just created.
+ *   2) Once one of the veth devices is moved to another namespace, it
+ *  is no longer visible in the parent namespace.  This seems to
+ *  confuse the name assignment causing it to fail with File exists.
+ *   Because of these issues, this function currently f

Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-20 Thread Daniel Veillard
On Thu, Jun 19, 2008 at 10:46:40AM -0700, Dan Smith wrote:
> DV> Hum, it's not only a kernel feature, it looks more like a
> DV> dependancy on iproute, maybe that can be checked at runtime when
> DV> initializing the lxc module, no ?
> 
> I suppose I could actually let it fail when it tries to do the actual
> move.  Would you rather a specific test during the define stage to
> reject the  if the non-netns 'ip' command is found?

  Well i was wondering if you could not try to detect if the feature
is available for example in lxcProbe() then keep the status.

> DV>   yeah I'm getting very confused by that code :-)
> 
> Agreed, I'll fix it up :)

  okay :-)

> DV> as the header template for the two new files to match the other files.
> DV> COPYING.LIB is of course LGPL 2.1
> 
> Okay, I'll change it.

  Cool, thanks !

Daniel

-- 
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard  | virtualization library  http://libvirt.org/
[EMAIL PROTECTED]  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-19 Thread Dan Smith
DS> # HG changeset patch
DS> # User Dave Leskovec <[EMAIL PROTECTED]>
DS> # Date 1213891164 25200
DS> # Node ID 386c067de8995028dd11f70602081c31682dd293
DS> # Parent  8d2afc533c91c4796512e1e71c8283e86eafd18a
DS> [LXC] Add functions to manage veth device pairs

My apologies for the HG headers.  I forgot the --plain when I sent it
out...

-- 
Dan Smith
IBM Linux Technology Center
Open Hypervisor Team
email: [EMAIL PROTECTED]


pgpQ4fsElwxWG.pgp
Description: PGP signature
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-19 Thread Dan Smith
DV> Hum, it's not only a kernel feature, it looks more like a
DV> dependancy on iproute, maybe that can be checked at runtime when
DV> initializing the lxc module, no ?

I suppose I could actually let it fail when it tries to do the actual
move.  Would you rather a specific test during the define stage to
reject the  if the non-netns 'ip' command is found?

>> +if (0 != VIR_ALLOC_N(argv[pidArgvOffset], (sizeof(int) * 3) + 1)) {
>> +goto error_out;
>> +}

DV>Hum, here i don't understand, if argv is defined as local stack data,
DV> I find a bit confusing to use it in the argument for VIR_ALLOC_N. I would
DV> use an intermediate local variable to make this cleaner/ easier to read.

>> +len = snprintf(argv[pidArgvOffset], (sizeof(int) * 3) + 1, "%d", 
>> pidInNs);

DV>   yeah I'm getting very confused by that code :-)

Agreed, I'll fix it up :)

DV>   Oh can you use

DV> /*
DV>  * veth.h:  a proper file description :-) 
DV>  *
DV>  * Copyright IBM Corp. 2008
DV>  *
DV>  * See COPYING.LIB for the License of this software
DV>  *
DV>  * Authors:
DV>  *  David L. Leskovec 
DV>  */

DV> as the header template for the two new files to match the other files.
DV> COPYING.LIB is of course LGPL 2.1

Okay, I'll change it.

Thanks!

-- 
Dan Smith
IBM Linux Technology Center
Open Hypervisor Team
email: [EMAIL PROTECTED]


pgpS5wIMskw77.pgp
Description: PGP signature
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-19 Thread Daniel Veillard
On Thu, Jun 19, 2008 at 08:59:52AM -0700, Dan Smith wrote:
> # HG changeset patch
> # User Dave Leskovec <[EMAIL PROTECTED]>
> # Date 1213891164 25200
> # Node ID 386c067de8995028dd11f70602081c31682dd293
> # Parent  8d2afc533c91c4796512e1e71c8283e86eafd18a
> [LXC] Add functions to manage veth device pairs
> 
> This gives us the ability to create a veth pair so that we can move one
> into the network namespace of an LXC container.

  Basically it's executing ip commands, so the real code changes are outside
of libvirt.

> diff -r 8d2afc533c91 -r 386c067de899 configure.in
> --- a/configure.inTue Jun 17 15:55:03 2008 +
> +++ b/configure.inThu Jun 19 08:59:24 2008 -0700
> @@ -301,6 +301,20 @@
>  if test "$with_qemu" = "yes" ; then
>AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h 
> linux/if_tun.h],,
> AC_MSG_ERROR([You must install kernel-headers in order to 
> compile libvirt]))
> +fi
> +
> +dnl
> +dnl check for patched iproute2 for lxc network support
> +dnl
> +if test "$with_lxc" = "yes" ; then
> +   AC_MSG_CHECKING([for NETNS support])
> +   if ip link help 2>&1 | grep -q netns; then
> + with_lxc_netns="yes"
> + AC_DEFINE([HAVE_NETNS], [], [Kernel has NETNS support])
> +   else
> + with_lxc_netns="no"
> +   fi
> +   AC_MSG_RESULT($with_lxc_netns)
>  fi

 Hum, it's not only a kernel feature, it looks more like a dependancy on
iproute, maybe that can be checked at runtime when initializing the lxc 
module, no ?

[...]
> +static int getFreeVethName(char *veth, int maxLen, int startDev)
> +{
> +int rc = -1;
> +int devNum = startDev;
> +char path[PATH_MAX];
> +
> +snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum);
> +while (virFileExists(path)) {
> +++devNum;
> +sprintf(path, "/sys/class/net/veth%d/", devNum);

  use snprintf there too

> +}
> +
> +snprintf(veth, maxLen, "veth%d", devNum);
> +
> +rc = devNum;
> +
> +return rc;
> +}
> +
> +/**
> + * vethCreate:
> + * @veth1: name for one end of veth pair
> + * @veth1MaxLen: max length of veth1 name
> + * @veth2: name for one end of veth pair
> + * @veth2MaxLen: max length of veth1 name
> + *
> + * Creates a veth device pair using the ip command:
> + * ip link add veth1 type veth peer name veth2
> + * NOTE: If veth1 and veth2 names are not specified, ip will auto assign
> + *   names.  There seems to be two problems here -
> + *   1) There doesn't seem to be a way to determine the names of the
> + *  devices that it creates.  They show up in ip link show and
> + *  under /sys/class/net/ however there is no guarantee that they
> + *  are the devices that this process just created.
> + *   2) Once one of the veth devices is moved to another namespace, it
> + *  is no longer visible in the parent namespace.  This seems to
> + *  confuse the name assignment causing it to fail with File exists.
> + *   Because of these issues, this function currently forces the caller
> + *   to fully specify the veth device names.
> + *
> + * Returns 0 on success or -1 in case of error
> + */
> +int vethCreate(char* veth1, int veth1MaxLen,
> +   char* veth2, int veth2MaxLen)
> +{
> +int rc = -1;
> +const char *argv[] = {

I think Jim insists on having const char const * [], but I bet he will explain
this better than me :-)

> +"ip", "link", "add", veth1, "type", "veth", "peer", "name", veth2, 
> NULL
> +};
[...]
> +/**
> + * moveInterfaceToNetNs:
> + * @interface: name of device
> + * @pidInNs: PID of process in target net namespace
> + *
> + * Moves the given device into the target net namespace specified by the 
> given
> + * pid using this command:
> + * ip link set interface netns pidInNs
> + *
> + * Returns 0 on success or -1 in case of error
> + */
> +int moveInterfaceToNetNs(const char* interface, int pidInNs)
> +{
> +int rc;
> +/* offset of the pid field in the following args */
> +const int pidArgvOffset = 5;
> +const char *argv[] = {
> +"ip", "link", "set", interface, "netns", NULL, NULL
> +};
> +int cmdResult;
> +int len;
> +
> +if (NULL == interface) {
> +goto error_out;
> +}
> +
> +if (0 != VIR_ALLOC_N(argv[pidArgvOffset], (sizeof(int) * 3) + 1)) {
> +goto error_out;
> +}

   Hum, here i don't understand, if argv is defined as local stack data,
I find a bit confusing to use it in the argument for VIR_ALLOC_N. I would
use an intermediate local variable to make this cleaner/ easier to read.

> +len = snprintf(argv[pidArgvOffset], (sizeof(int) * 3) + 1, "%d", 
> pidInNs);

  yeah I'm getting very confused by that code :-)

> +if (len >= (sizeof(int) * 3) + 1) {
> +goto cleanup;
> +}
> +
> +rc = virRun(NULL, (char**)argv, &cmdResult);
> +
> +if (0 == rc) {
> +   rc = cmdResult;
> +}
> +
> +cleanup:
> +VIR_FREE(argv[pidArgvOffset]);
> +
> +error_out:

[libvirt] [PATCH 1 of 3] [LXC] Add functions to manage veth device pairs

2008-06-19 Thread Dan Smith
# HG changeset patch
# User Dave Leskovec <[EMAIL PROTECTED]>
# Date 1213891164 25200
# Node ID 386c067de8995028dd11f70602081c31682dd293
# Parent  8d2afc533c91c4796512e1e71c8283e86eafd18a
[LXC] Add functions to manage veth device pairs

This gives us the ability to create a veth pair so that we can move one
into the network namespace of an LXC container.

diff -r 8d2afc533c91 -r 386c067de899 configure.in
--- a/configure.in  Tue Jun 17 15:55:03 2008 +
+++ b/configure.in  Thu Jun 19 08:59:24 2008 -0700
@@ -301,6 +301,20 @@
 if test "$with_qemu" = "yes" ; then
   AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h 
linux/if_tun.h],,
AC_MSG_ERROR([You must install kernel-headers in order to 
compile libvirt]))
+fi
+
+dnl
+dnl check for patched iproute2 for lxc network support
+dnl
+if test "$with_lxc" = "yes" ; then
+   AC_MSG_CHECKING([for NETNS support])
+   if ip link help 2>&1 | grep -q netns; then
+ with_lxc_netns="yes"
+ AC_DEFINE([HAVE_NETNS], [], [Kernel has NETNS support])
+   else
+ with_lxc_netns="no"
+   fi
+   AC_MSG_RESULT($with_lxc_netns)
 fi
 
 dnl Need to test if pkg-config exists
diff -r 8d2afc533c91 -r 386c067de899 src/Makefile.am
--- a/src/Makefile.am   Tue Jun 17 15:55:03 2008 +
+++ b/src/Makefile.am   Thu Jun 19 08:59:24 2008 -0700
@@ -64,6 +64,7 @@
lxc_driver.c lxc_driver.h   \
lxc_conf.c lxc_conf.h   \
lxc_container.c lxc_container.h \
+   veth.c veth.h   \
 nodeinfo.h nodeinfo.c   \
util.c util.h
 
diff -r 8d2afc533c91 -r 386c067de899 src/veth.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/src/veth.cThu Jun 19 08:59:24 2008 -0700
@@ -0,0 +1,247 @@
+/*
+ * Copyright IBM Corp. 2008
+ *
+ * veth.c: file description
+ *
+ * Authors:
+ *  David L. Leskovec 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include 
+
+#ifdef HAVE_NETNS
+
+#include 
+
+#include "veth.h"
+#include "internal.h"
+#include "memory.h"
+#include "util.h"
+
+#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
+#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg)
+
+/* Functions */
+/**
+ * getFreeVethName:
+ * @veth: name for veth device (NULL to find first open)
+ * @maxLen: max length of veth name
+ * @startDev: device number to start at (x in vethx)
+ *
+ * Looks in /sys/class/net/ to find the first available veth device
+ * name.
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+static int getFreeVethName(char *veth, int maxLen, int startDev)
+{
+int rc = -1;
+int devNum = startDev;
+char path[PATH_MAX];
+
+snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum);
+while (virFileExists(path)) {
+++devNum;
+sprintf(path, "/sys/class/net/veth%d/", devNum);
+}
+
+snprintf(veth, maxLen, "veth%d", devNum);
+
+rc = devNum;
+
+return rc;
+}
+
+/**
+ * vethCreate:
+ * @veth1: name for one end of veth pair
+ * @veth1MaxLen: max length of veth1 name
+ * @veth2: name for one end of veth pair
+ * @veth2MaxLen: max length of veth1 name
+ *
+ * Creates a veth device pair using the ip command:
+ * ip link add veth1 type veth peer name veth2
+ * NOTE: If veth1 and veth2 names are not specified, ip will auto assign
+ *   names.  There seems to be two problems here -
+ *   1) There doesn't seem to be a way to determine the names of the
+ *  devices that it creates.  They show up in ip link show and
+ *  under /sys/class/net/ however there is no guarantee that they
+ *  are the devices that this process just created.
+ *   2) Once one of the veth devices is moved to another namespace, it
+ *  is no longer visible in the parent namespace.  This seems to
+ *  confuse the name assignment causing it to fail with File exists.
+ *   Because of these issues, this function currently forces the caller
+ *   to fully specify the veth device names.
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+int vethCreate(char* veth1, int veth1MaxLen,
+   char* veth2, int veth2MaxLen)
+{
+int rc = -1;
+const char *argv[] = {
+"