[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Fri May 31 06:35:02 UTC 2019


The branch, master has been updated
       via  b23d005cdc6 selftest: Don't use global dirs when parsing customdc realm
       via  6defc1f183d selftest: Add check customdc has valid realm/domain
       via  f2f0ebb0733 provision: Fallback to assumption root-UID==zero
       via  900af92e868 selftest: Add more notes on using selftest with namespaces
       via  c68537d5dd4 selftest: Add helper scripts for accessing the testenv namespace
       via  067b4fc03fe selftest: Add linux namespace support (USE_NAMESPACES=1)
       via  c9e62513822 selftest: Add TESTENV_DIR "env" variable
       via  5635a7ce2fe selftest: Add helper scripts to run selftest in namespaces
       via  8e3bc591733 selftest: Allow for wider range of terminals (besides xterm)
      from  9a2c9834cb1 vfs_fruit: remove a now unnecessary include

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit b23d005cdc646e02af3c38852f75e4505070768e
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu May 30 14:55:52 2019 +1200

    selftest: Don't use global dirs when parsing customdc realm
    
    When creating the customdc, testparm would default to using
    /usr/local/samba sub-directories for creating sockets and lock files.
    Instead, pass in the tmpdir we just created as an option to the command.
    
    Normally this didn't cause a noticeable problem, however, if we run the
    command with UID-wrapper but without socket-wrapper (i.e.
    USE_NAMESPACES=1), then it fails completely.
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Fri May 31 06:34:36 UTC 2019 on sn-devel-184

commit 6defc1f183d6a9f24af1674d1dfee36d9e9bdc76
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu May 30 14:46:35 2019 +1200

    selftest: Add check customdc has valid realm/domain
    
    If we couldn't determine the realm/domain from the backup file, it's a
    lot nicer to fail early with a clear error message (rather than failing
    later on with a really obscure message).
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f2f0ebb073353196f381fe2e01e4001983710255
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Wed Oct 3 08:56:45 2018 +1300

    provision: Fallback to assumption root-UID==zero
    
    Which is not a terrible assumption to make. The super-user on linux will
    always have UID of zero, however, the super-user will not necessarily be
    called "root".
    
    This makes the provision/join commands work better when run in a
    container. (And while deploying Samba in a container is perhaps not the
    smartest move, this gives us some versatility when testing Samba).
    
    This is needed to get the provision commands working in the domain_backup
    tests when run with USE_NAMESPACES=1.
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 900af92e8684ba9c13d28f0cbbe8ab599a9b3b44
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Fri May 31 11:23:49 2019 +1200

    selftest: Add more notes on using selftest with namespaces
    
    In particular, document how to hook up a testenv to a Windows VM
    (ideally there should be a helper script to do this, but in the
    meantime some instructions are better than nothing).
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c68537d5dd4963a6e149ac4dcb0c89c51cbfae79
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Mar 28 17:40:46 2019 +1300

    selftest: Add helper scripts for accessing the testenv namespace
    
    This patch adds some helper scripts that make talking to a given
    testenv's namespace slightly easier.
    
    One of the really cool things about namespaces is you can run multiple
    different programs that can all talk to the testenv DC. However, the
    command to do this is a bit unweildly, it's based on PID so it changes
    everytime you start up a testenv, and you loose all the environment
    variables that selftest normally sets up.
    
    This patch adds a couple of helper scripts:
    - nsenter-helper.sh: this takes the variables defined in an exports_file
      and exports them all. It prints some basic help and then starts a new
      shell session (this whole script gets run in the new namespace).
      Essentially this achieves something similar to the legacy
      selftest-vars.sh script (except this one actually works).
    - mk_nsenter.sh: this generates a simple wrapper script that'll run
      nsenter and then call nsenter-helper.sh. A separate wrapper script
      gets created for each testenv. E.g. to run it, just go:
        ./st/ad_dc/nsenter.sh
    
      This is a wrapper for a more complicated command underneath like:
        nsenter -t 437353 --net --user --preserve-credentials \
          /home/timbeale/code/samba/selftest/ns/nsenter-helper.sh \
          /home/timbeale/code/samba/st/ad_dc/exports.sh
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 067b4fc03fec20e944eac2645f400471f2bc0b21
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu May 23 17:44:37 2019 +1200

    selftest: Add linux namespace support (USE_NAMESPACES=1)
    
    This hooks up the selftest/ns/* scripts added earlier with the selftest
    system, so developers can optionally run a testenv or test using linux
    namespaces instead of socket-wrapper.
    
    The idea is this is experimental functionality that we can extend
    further in future, in order to make testing Samba more versatile.
    
    + The top-level WAF script now does an 'unshare' to create a new
    top-level 'selftest' namespace in which to create the testenv(s).
    + selftest.pl creates a common 'selftest0' bridge to connect together
    the individual DCs.
    + Update Samba.pm so it can use real IPs instead of loopback addresses.
    In fork_and_exec(), we add a couple of hooks so that the binary gets
    started in a different namespace (using unshare/start_in_ns.sh), and
    the parent process connects the new child namespace up to the common
    selftest0 bridge (using add_bridge_iface.sh).
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c9e62513822fa5fce9ad29c164273a2db64ff18d
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Mar 14 17:38:22 2019 +1300

    selftest: Add TESTENV_DIR "env" variable
    
    We store the testenv directory path for the 'ctx' hashmap, but not for
    the testenv-vars hashmap (and that can be really annoying sometimes).
    Add it into the second hashmap that selftest actually keeps track of.
    Currently it's only stored in the hashmap, not actually exported as an
    environment variable (but we could easily do that if a test-case need
    this info).
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5635a7ce2fe348a3ed89ff39a02f9db135424367
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Tue Feb 26 15:54:34 2019 +1300

    selftest: Add helper scripts to run selftest in namespaces
    
    This adds the underlying scripts, but they are not actually hooked up to
    the selftest code yet, and so are not actually used.
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8e3bc591733c868320a0f91d3f3e3943bd95b92e
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Fri May 31 12:33:59 2019 +1200

    selftest: Allow for wider range of terminals (besides xterm)
    
    Allow developers to override the default @term_args, as well as the
    terminal itself.
    
    Currently, due to the nature of the args we pass to xterm (i.e. 'echo -e
    "blah.." && bash'), it doesn't make it very flexible for use with other
    terminals. By dropping these additional @term_args, it makes it much
    easier to slot in an alternative terminal.
    
    For example, these commands now work (more or less).
    
    TERMINAL="terminator" TERMINAL_ARGS="-x bash" \
     SELFTEST_TESTENV=ad_dc make testenv
    
    TERMINAL="bash" TERMINAL_ARGS="" \
     SELFTEST_TESTENV=nt4_dc make testenv
    
    TERMINAL="bash" TERMINAL_ARGS="--norc" \
     SELFTEST_TESTENV=none make testenv
    
    bash is usable, but a little weird because its output is still being
    piped. Also bash with ad_dc is a little weird because we're using tee
    for the DC's stdout. (I'd also recommend --norc, as it makes it easier
    to differentiate between the testenv shell).
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 python/samba/provision/__init__.py |  12 ++-
 selftest/ns/README                 | 162 +++++++++++++++++++++++++++++++++++++
 selftest/ns/add_bridge_iface.sh    |  22 +++++
 selftest/ns/create_bridge.sh       |  19 +++++
 selftest/ns/mk_nsenter.sh          |  32 ++++++++
 selftest/ns/nsenter-helper.sh      |  31 +++++++
 selftest/ns/start_in_ns.sh         |  61 ++++++++++++++
 selftest/selftest.pl               |  14 ++++
 selftest/target/Samba.pm           | 109 ++++++++++++++++++++++++-
 selftest/target/Samba3.pm          |   1 +
 selftest/target/Samba4.pm          |  19 ++++-
 selftest/wscript                   |  12 ++-
 12 files changed, 486 insertions(+), 8 deletions(-)
 create mode 100644 selftest/ns/README
 create mode 100755 selftest/ns/add_bridge_iface.sh
 create mode 100755 selftest/ns/create_bridge.sh
 create mode 100755 selftest/ns/mk_nsenter.sh
 create mode 100755 selftest/ns/nsenter-helper.sh
 create mode 100755 selftest/ns/start_in_ns.sh


Changeset truncated at 500 lines:

diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
index 2bb2614e629..14ab41be670 100644
--- a/python/samba/provision/__init__.py
+++ b/python/samba/provision/__init__.py
@@ -540,6 +540,16 @@ def findnss_gid(names):
     return findnss(grp.getgrnam, names)[2]
 
 
+def get_root_uid(root, logger):
+    try:
+        root_uid = findnss_uid(root)
+    except KeyError as e:
+        logger.info(e)
+        logger.info("Assuming root user has UID zero")
+        root_uid = 0
+    return root_uid
+
+
 def provision_paths_from_lp(lp, dnsdomain):
     """Set the default paths for provisioning.
 
@@ -2152,7 +2162,7 @@ def provision(logger, session_info, smbconf=None,
     if domainsid is None:
         domainsid = security.random_sid()
 
-    root_uid = findnss_uid([root or "root"])
+    root_uid = get_root_uid([root or "root"], logger)
     nobody_uid = findnss_uid([nobody or "nobody"])
     users_gid = findnss_gid([users or "users", 'users', 'other', 'staff'])
     root_gid = pwd.getpwuid(root_uid).pw_gid
diff --git a/selftest/ns/README b/selftest/ns/README
new file mode 100644
index 00000000000..a8ad1c0444f
--- /dev/null
+++ b/selftest/ns/README
@@ -0,0 +1,162 @@
+The scripts in this directory are experimental and are used to create testenvs
+in separate linux namespaces. This avoids the need for socket-wrapper.
+
+What are Namespaces
+===================
+Namespaces allow the kernel to segregate its system resources (files, CPU,
+etc), so that different processes only see the set of resources they are
+allowed to use. There are several different types of namespace: network,
+user, process, file, IPC, and so on.
+
+Key points to grasp are:
+* Each type of namespace gets managed separately by the kernel, i.e. process
+namespaces are managed separately to network namespaces, which are separate
+to user namespaces. These scripts give each testenv its own network namespace,
+but otherwise they all still share the same user/process/etc namespace.
+(In future, we may want to give each testenv its own process and user
+namespace, to better mimic a production DC).
+* Namespaces are created using the 'unshare' utility. The new selftest
+namespaces are anonymous/nameless, and so the different namespaces are
+identified by the PID of the processes running within the namespace
+(typically samba).
+* Linux supports nesting namespaces within namespaces. In this case, each
+testenv DC has its own network namespace, which is a child of the overarching
+selftest namespace (which itself is a child of whatever namespace you run
+'make test' from - usually this would be the root namespace).
+
+How does it work?
+=================
+Normally when 'make test' is run, every testenv uses a 127.0.0.x IP address
+and socket-wrapper passes the packets between them.
+
+With namespaces, we can use real IP addresses and have the packets pass through
+the kernel's IP stack normally, as it forwards them between namespaces.
+
+We use veth interfaces for this. veth is a type of virtual interface supported
+by the kernel. veth interfaces come in pairs, and act as a tunnel - any packets
+sent on a veth interface simply end up as received packets on the pair veth
+interface.
+
+We create a new veth interface pair for each testenv, and use them to connect
+up the namespaces. One end of the veth pair is added to the main selftest
+namespace, and the other end is added to a new namespace that we'll run
+samba in. E.g.
+
+selftest.pl  veth21-br ------------------------ veth21 samba (ad_dc_ntvfs)
+             10.0.0.11                          10.0.0.21
+ Namespace 1                                       Namespace 2
+
+However, we need to run multiple different testenvs and have them talk to
+each other. So to do this, we need a bridge interface ('selftest0') to connect
+up the namespaces, which essentially just acts as a hub. So connecting together
+multiple testenvs looks more like this:
+
+selftest.pl     +-- veth21-br ------------------------ veth21 samba (ad_dc_ntvfs)
+                |                                      10.0.0.21
+    selftest0 --+                                        Namespace 2
+    10.0.0.11   |
+                +-- veth22-br ------------------------ veth22 samba (vampire_dc)
+                                                       10.0.0.22
+ Namespace 1                                             Namespace 3      
+
+The veth interfaces are named vethX and vethX-br, where X is the
+SOCKET_WRAPPER_DEFAULT_IFACE for the testenv. The vethX-br interface is always
+added to the selftest0 bridge interface. 
+
+How do I use it?
+================
+To use namespaces instead of socket-wrapper, just add 'USE_NAMESPACES=1' to the
+make command, e.g.
+
+To run the 'quick' test cases using namespaces:
+USE_NAMESPACES=1 make test TESTS=quick
+
+To setup an ad_dc testenv using namespaces:
+USE_NAMESPACES=1 SELFTEST_TESTENV=ad_dc make testenv
+
+You can connect secondary shells to the namespace your testenv is running in.
+The command to do this is a little complicated, so a helper 'nsenter.sh' script
+gets autogenerated when the testenv is created. E.g. to connect to the testenv
+that the ad_dc is running in, use:
+./st/ad_dc/nsenter.sh
+
+This script also sets up the shell with all the same $SERVER/$USERNAME/etc
+variables that you normally get in xterm.
+
+To run the ad-dc-backup autobuild job using namespaces:
+USE_NAMESPACES=1 script/autobuild.py samba-ad-dc-backup --verbose --nocleanup \
+ --keeplogs --tail --testbase /tmp/samba-testbase
+
+Using the customdc testenv, you can basically now essentially your own
+light-weight samba VM. E.g.
+MY_BACKUP=/home/$USER/samba-backup-prod-domain.tar.bz2
+USE_NAMESPACES=1 BACKUP_FILE=$MY_BACKUP SELFTEST_TESTENV=customdc make testenv
+
+You can then talk to that DC in any other shell by using
+./st/customdc/nsenter.sh which enters the DC's network namespace (with
+all the $SERVER/etc env variables defined).
+
+How to join VMs to the testenv
+----------------------------------------
+I haven't tried this (beyond basic IP connectivity), but using namespaces it
+should now be possible to connect a Windows VM to a Samba testenv.
+
+1. Work out the main selftest.pl namespace PID manually, e.g.
+SELFTEST_PID= ps waux | grep selftest.pl
+
+2. Create a new veth to bridge between the selftest namespace and your PC's
+default namespace:
+sudo ip link add dev testenv-veth0 type veth peer name testenv-veth1
+
+3. Move one end of the veth tunnel into the selftest namespace:
+sudo ip link set testenv-veth1 netns $SELFTEST_PID
+
+4. Configure the veth end in the default namespace to be in the same subnet
+as the selftest network:
+sudo ip link set dev testenv-veth0 up
+sudo ip addr add 10.0.0.63/24 dev testenv-veth0
+
+5. Enter the selftest namespace, bring that end of the pipe up, and add it to
+to the main selftest0 bridge (that connects all the DCs together). We also need
+to add a default route from selftest back to your PC's default namespace.
+nsenter -t $SELFTEST_PID --net --user --preserve-credentials
+ip link set dev testenv-veth1 up
+ip link set testenv-veth1 master selftest0
+ip route add default via 10.0.0.63
+logout
+
+Your Windows VM and samba testenv should now be able to talk to each
+other over IP!
+
+6. The other step is to get DNS working. You probably need to add dns_hub
+(10.0.0.64) as a nameserver (at least on your Windows VM).
+
+This should work for using RSAT tools on samba, or joining Windows to Samba
+(depending on the schema version). Joining samba to Windows is a bit more
+tricky, as the namespaces are tied to the *running* samba process.
+
+What you'd probably want to do is run the join command to the windows VM
+outside of testenv, create an offline backup-file of the resulting DB, and
+then plug that backup-file into the customdc testenv. (And then follow the
+above veth/bridge steps to join samba to the VM).
+
+Note that the namespace disappears once you stop the testenv, so you'd
+need to do the above steps with creating the veth interface every time
+you restarted the testenv.
+
+Known limitations
+=================
+- When running a testenv, sometimes xterm can fail to startup, due to a
+  permissions problem with /dev/pts. This seems to be a particular problem
+  with the 'none' testenv.
+  A short-term work-around is to use a terminal that doesn't try to access
+  /dev/pts, e.g. just use bash as the terminal:
+  TERMINAL=bash TERMINAL_ARGS='--norc' USE_NAMESPACES=1 \
+    SELFTEST_TESTENV=none make testenv
+- Some test cases rely on socket-wrapper, so will fail when run using
+  namespaces.
+- Currently USE_NAMESPACES maps you (i.e. $USER) to root in the new namespace.
+  This means any test cases that rely on being a non-root user will fail (i.e.
+  anything that fails under 'sudo make test' will also fail with namespaces).
+- Namespaces should work within docker, but currently the 'unshare' system
+  call is disallowed on the gitlab CI runners.
diff --git a/selftest/ns/add_bridge_iface.sh b/selftest/ns/add_bridge_iface.sh
new file mode 100755
index 00000000000..da9d53a5987
--- /dev/null
+++ b/selftest/ns/add_bridge_iface.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Configures the interfaces needed for communication between namespaces.
+# This handles the bridge-end of the veth pair.
+interface=$1
+
+# the main bridge interface is called 'selftest0' (although in future we may
+# want to segregate the different domains by using different bridges)
+bridge=$2
+
+# we need to wait for the child namespace to start up and add the new
+# interface back to our new namespace
+while ! ip link show $interface > /dev/null 2>&1
+do
+    sleep 0.1
+    echo "Waiting for $interface to be created..."
+done
+
+# bring the bridge-end of the link up and add it to the bridge
+ip link set dev $interface up
+ip link set $interface master $bridge
+
diff --git a/selftest/ns/create_bridge.sh b/selftest/ns/create_bridge.sh
new file mode 100755
index 00000000000..9766cd8a565
--- /dev/null
+++ b/selftest/ns/create_bridge.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# creates a bridge interface (i.e. 'selftest0') that connects together the
+# veth interfaces for the various testenvs
+
+br_name=$1
+ip_addr=$2
+ipv6_addr=$3
+
+# make sure the loopback is up (needed for pinging between namespaces, etc)
+ip link set dev lo up
+
+# create the bridge interface and enable it
+ip link add $br_name type bridge
+ip addr add $ip_addr/24 dev $br_name
+ip addr add $ipv6_addr/112 dev $br_name
+ip link set $br_name up
+
+
diff --git a/selftest/ns/mk_nsenter.sh b/selftest/ns/mk_nsenter.sh
new file mode 100755
index 00000000000..f175d6bae73
--- /dev/null
+++ b/selftest/ns/mk_nsenter.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Helper script. If you want a 2nd shell that communicates with the testenv DC
+# you can use the nsenter command to change the namespace you're in. However,
+# this command is a bit unwieldly and changes depending on the testenv PID.
+# We can generate a helper script on the fly that abstracts all this
+# complexity, allowing you to use the same, simple command to change the
+# namespace that you're in, e.g.
+#   st/ad_dc/nsenter.sh
+
+pid=$1
+exports_file=$2
+
+# The basic command to enter the testenv's network namespace.
+# We enter the user namespace as well (as ourself, which is really the root
+# user for the namespace), otherwise we need sudo to make this work.
+nsenter_cmd="nsenter -t $pid --net --user --preserve-credentials"
+
+# By default, the nsenter command will just start a new shell in the namespace.
+# we use a wrapper helper script, which first loads all the environment
+# variables that are usually defined in selftest (and prints some basic help).
+helper_script="$(dirname $0)/nsenter-helper.sh $exports_file"
+
+# generate the dynamic script
+dyn_script="$(dirname $2)/nsenter.sh"
+echo "#!/bin/sh" > $dyn_script
+echo "$nsenter_cmd $helper_script" >> $dyn_script
+chmod 755 $dyn_script
+
+# return the script we created
+echo "$dyn_script"
+
diff --git a/selftest/ns/nsenter-helper.sh b/selftest/ns/nsenter-helper.sh
new file mode 100755
index 00000000000..f396ed4d98c
--- /dev/null
+++ b/selftest/ns/nsenter-helper.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Helper script that gets run with nsenter to manually setup a secondary shell
+# session to a given namespace testenv. This basically just sets up the same
+# environment variables as you normally get with selftest, for convenience.
+
+if [ $# -lt 1 ] ; then
+    echo "Usage: $0 <exports-file>"
+    exit 1
+fi
+
+# we get passed a exports file with all the environment variables defined
+exports_file=$1
+
+# read the exports file so the new shell has appropriate variables setup
+# (we export rather than sourcing here so they get inherited by the subshell)
+while read -r line ; do
+    export $line
+    # dump them for the user too
+    echo $line
+done < $exports_file
+
+echo ""
+echo "Entered $NETBIOSNAME namespace, with above variables defined."
+echo "Use CTRL+D or exit to leave the namespace."
+echo ""
+
+# start a shell session in the new namespace
+$SHELL
+
+
diff --git a/selftest/ns/start_in_ns.sh b/selftest/ns/start_in_ns.sh
new file mode 100755
index 00000000000..f16767d545b
--- /dev/null
+++ b/selftest/ns/start_in_ns.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Starts samba in a separate namespace. This gets passed the interface/IP
+# to use, as well as the Samba command to run. The whole script gets run
+# (via unshare) in a separate namespace.
+
+# the first 3 args are our interface-name, parent-PID, and a exports file
+# containing environment variables ($SERVER, $SERVER_IP, etc)
+interface=$1
+exports_file=$2
+parent_pid=$3
+
+# we write the testenv environment variables to file, which makes it easier
+# to work out the $SERVER, $SERVER_IP, etc
+. $exports_file
+
+# The namespaces we use are anonymous, which means other processes would need
+# to use our PID to access the new namespace
+echo "-------------------------------------------------------------"
+echo "Created namespace for $NETBIOSNAME ($ENVNAME) PID $$"
+
+# generate a helper script if the developer wants to talk to this namespace
+# in another shell
+mk_nsenter_script="$(dirname $0)/mk_nsenter.sh"
+helper_script=$($mk_nsenter_script $$ $exports_file)
+
+echo "To communicate with this testenv, use: $helper_script"
+echo "-------------------------------------------------------------"
+
+# the rest of the args are the samba command to run
+shift 3
+SAMBA_CMD=$@
+
+# make sure namespace loopback is up (it's needed for ping, etc)
+ip link set dev lo up
+
+# Create the interfaces needed for communication between namespaces.
+# We use a veth pair, which acts as a tunnel between the namespaces.
+# One end of the veth link is added to a common bridge in the top-level (i.e.
+# selftest) namespace, and the other end is added to the testenv's namespace.
+# This means each testenv DC is in its own namespace, but they can talk to
+# each other via the common bridge interface.
+# The new veth interfaces are named "vethX" and "vethX-br", where
+# X = the testenv IP (i.e. Samba::get_interface()). E.g. ad_dc = veth30,
+# and veth30-br.
+# The "vethX" interface will live in the new testenv's namespace.
+# The "vethX-br" end is added to the bridge in the main selftest namespace.
+ip link add dev $interface-br type veth peer name $interface
+
+# move the bridge end of the link back into the parent namespace.
+ip link set $interface-br netns $parent_pid
+
+# configure our IP address and bring the interface up
+ip addr add $SERVER_IP/24 dev $interface
+# Note that samba can't bind to the IPv6 address while DAD is in progress,
+# so we use 'nodad' when configuring the address
+ip addr add $SERVER_IPV6/112 dev $interface nodad
+ip link set dev $interface up
+
+# start samba
+$SAMBA_CMD
diff --git a/selftest/selftest.pl b/selftest/selftest.pl
index 228bb29ecfe..9e3d81801a6 100755
--- a/selftest/selftest.pl
+++ b/selftest/selftest.pl
@@ -424,6 +424,16 @@ if ($opt_libuid_wrapper_so_path) {
 	}
 }
 
+if (defined($ENV{USE_NAMESPACES})) {
+	print "Using linux containerization for selftest testenv(s)...\n";
+
+	# Create a common bridge to connect up the testenv namespaces. We give
+	# it the client's IP address, as this is where the tests will run from
+	my $ipv4_addr = Samba::get_ipv4_addr("client");
+	my $ipv6_addr = Samba::get_ipv6_addr("client");
+	system "$ENV{SRCDIR_ABS}/selftest/ns/create_bridge.sh selftest0 $ipv4_addr $ipv6_addr";
+}
+
 $ENV{LD_PRELOAD} = $ld_preload;
 print "LD_PRELOAD=$ENV{LD_PRELOAD}\n";
 
@@ -964,6 +974,10 @@ $envvarstr
 	my @term = ();
 	if ($ENV{TERMINAL}) {
 	    @term = ($ENV{TERMINAL});
+		# override the default terminal args (if specified)
+		if (defined($ENV{TERMINAL_ARGS})) {
+			@term_args = split(/ /, $ENV{TERMINAL_ARGS});
+		}
 	} else {
 	    @term = ("xterm", "-e");
 	    unshift(@term_args, ("bash", "-c"));
diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index 6fd8d01da06..ca3099c9d05 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -516,7 +516,13 @@ sub get_ipv4_addr
 		$swiface += $iface_num;
 	}
 
-	return "127.0.0.$swiface";
+	if (use_namespaces()) {
+		# use real IPs if selftest is running in its own network namespace
+		return "10.0.0.$swiface";
+	} else {
+		# use loopback IPs with socket-wrapper
+		return "127.0.0.$swiface";
+	}
 }
 
 sub get_ipv6_addr
@@ -541,7 +547,12 @@ sub get_interfaces_config
 	}
 	for (my $i = 0; $i < $num_ips; $i++) {
 		my $ipv4_addr = Samba::get_ipv4_addr($hostname, $i);
-		$interfaces .= "$ipv4_addr/8 ";
+		if (use_namespaces()) {
+			# use a /24 subnet with network namespaces
+			$interfaces .= "$ipv4_addr/24 ";
+		} else {
+			$interfaces .= "$ipv4_addr/8 ";
+		}
 	}
 
 	my $ipv6_addr = Samba::get_ipv6_addr($hostname);
@@ -627,10 +638,13 @@ sub fork_and_exec
 	unlink($daemon_ctx->{LOG_FILE});
 	print "STARTING $daemon_ctx->{NAME} for $ENV{ENVNAME}...";
 
+	my $parent_pid = $$;
 	my $pid = fork();
 
 	# exec the daemon in the child process
 	if ($pid == 0) {
+		my @preargs = ();
+
 		# redirect the daemon's stdout/stderr to a log file
 		if (defined($daemon_ctx->{TEE_STDOUT})) {
 			# in some cases, we want out from samba to go to the log file,
@@ -671,12 +685,27 @@ sub fork_and_exec
 		close($env_vars->{STDIN_PIPE});
 		open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
 
+		# if using kernel namespaces, prepend the command so the process runs in
+		# its own namespace
+		if (Samba::use_namespaces()) {
+			@preargs = ns_exec_preargs($parent_pid, $env_vars);
+		}
+
 		# the command args are stored as an array reference (because...Perl),
 		# so convert the reference back to an array
 		my @full_cmd = @{ $daemon_ctx->{FULL_CMD} };
-		exec(@full_cmd) or die("Unable to start $ENV{MAKE_TEST_BINARY}: $!");
+
+		exec(@preargs, @full_cmd) or die("Unable to start $ENV{MAKE_TEST_BINARY}: $!");
 	}
+
 	print "DONE ($pid)\n";
+
+	# if using kernel namespaces, we now establish a connection between the
+	# main selftest namespace (i.e. this process) and the new child namespace
+	if (use_namespaces()) {
+		ns_child_forked($pid, $env_vars);
+	}
+
 	return $pid;
 }


-- 
Samba Shared Repository



More information about the samba-cvs mailing list