oeqa/utils/nfs: Add unfs_server function to setup a userspace NFS server

Add a nfs module into oeqa utils. This module provides unfs_server which
allows a test case to build unfs3-native and setup the unfs server on a
target directory of the host. This directory is then shared and can be
mounted by the host or a target device attached to the host (e.g. qemu
via tap or slirp). The nfs server is setup over UDP and automatically
assigns user privileged ports. The function provides the UDP ports for
the server as part of a returned python contextmanager which handles
cleanup of the server process on completion or exception.

Also add a 'udp' arg to get_free_port to get a free UDP port.

Note: unfs3 still requires the host to have rpcbind or portmap running.

(From OE-Core rev: c754fd85be85ad0a381b642365eca17cea8eb627)

Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Nathan Rossi
2019-08-28 05:06:29 +00:00
committed by Richard Purdie
parent b88477d069
commit 98e5273971
2 changed files with 41 additions and 2 deletions

View File

@@ -4,8 +4,8 @@
import socket
def get_free_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def get_free_port(udp = False):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM if not udp else socket.SOCK_DGRAM)
s.bind(('', 0))
addr = s.getsockname()
s.close()

View File

@@ -0,0 +1,39 @@
# SPDX-License-Identifier: MIT
import os
import sys
import tempfile
import contextlib
import socket
from oeqa.utils.commands import bitbake, get_bb_var, Command
from oeqa.utils.network import get_free_port
@contextlib.contextmanager
def unfs_server(directory, logger = None):
unfs_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "unfs3-native")
if not os.path.exists(os.path.join(unfs_sysroot, "usr", "bin", "unfsd")):
# build native tool
bitbake("unfs3-native -c addto_recipe_sysroot")
exports = None
cmd = None
try:
# create the exports file
with tempfile.NamedTemporaryFile(delete = False) as exports:
exports.write("{0} (rw,no_root_squash,no_all_squash,insecure)\n".format(directory).encode())
# find some ports for the server
nfsport, mountport = get_free_port(udp = True), get_free_port(udp = True)
nenv = dict(os.environ)
nenv['PATH'] = "{0}/sbin:{0}/usr/sbin:{0}/usr/bin:".format(unfs_sysroot) + nenv.get('PATH', '')
cmd = Command(["unfsd", "-d", "-p", "-N", "-e", exports.name, "-n", str(nfsport), "-m", str(mountport)],
bg = True, env = nenv, output_log = logger)
cmd.run()
yield nfsport, mountport
finally:
if cmd is not None:
cmd.stop()
if exports is not None:
# clean up exports file
os.unlink(exports.name)