import subprocess, shlex
from argparse import ArgumentParser, RawTextHelpFormatter
import errno
+import pwd
def fail(msg):
print(msg)
if os.getuid() != 0:
fail('Please run this program as root/with sudo')
-pwd = os.path.abspath(os.path.dirname(__file__))
-ext_libs_path = os.path.join(pwd, 'external_libs')
+cur_dir = os.path.abspath(os.path.dirname(__file__))
+ext_libs_path = os.path.join(cur_dir, 'external_libs')
if ext_libs_path not in sys.path:
sys.path.append(ext_libs_path)
return lambda *a, **k: not f(*a, **k)
-def progress(success_check, start_msg, success_msg, fail_msg, timeout = 10, poll_rate = 0.5):
+def progress(success_check, start_msg, success_msg, fail_msg, timeout = 35, poll_rate = 0.5, fail_check = None):
sys.stdout.write('%s...' % start_msg)
sys.stdout.flush()
for i in range(int(timeout/poll_rate)):
if success_check():
print(termstyle.green(' ' + success_msg))
return 0
+ if fail_check and fail_check():
+ print(termstyle.red(' ' + fail_msg))
+ return 1
time.sleep(poll_rate)
sys.stdout.write('.')
sys.stdout.flush()
- if success_check():
- print(termstyle.green(' ' + success_msg))
- return 0
- print(termstyle.red(' ' + fail_msg))
+ print(termstyle.red(' Timeout'))
return 1
-def run_command(command, timeout = 15, poll_rate = 0.1, cwd = None):
- assert timeout > 0, 'Timeout should be positive'
- assert poll_rate > 0, 'Poll rate should be positive'
+def demote_func():
+ pw_record = pwd.getpwnam('nobody')
+ os.setgid(pw_record.pw_gid)
+ os.setuid(pw_record.pw_uid)
+
+
+def run_command(command, timeout = 30, poll_rate = 0.1, cwd = None, demote = False, is_daemon = False):
+ if not is_daemon:
+ assert timeout > 0, 'Timeout should be positive'
+ assert poll_rate > 0, 'Poll rate should be positive'
+
+ preexec_fn = demote_func if demote else None
+
+ try: # P2
+ stdout_file = tempfile.TemporaryFile(bufsize = 0)
+ except: # P3
+ stdout_file = tempfile.TemporaryFile(buffering = 0)
+
try:
- tempfile.TemporaryFile(bufsize=0)
- temp_params = {'bufsize': 0}
- except:
- tempfile.TemporaryFile(buffering=0)
- temp_params = {'buffering': 0}
- with tempfile.TemporaryFile(**temp_params) as stdout_file:
- proc = subprocess.Popen(shlex.split(command), stdout = stdout_file, stderr = subprocess.STDOUT, cwd = cwd, close_fds = True, universal_newlines = True)
+ proc = subprocess.Popen(shlex.split(command), stdout = stdout_file, stderr = subprocess.STDOUT, cwd = cwd,
+ close_fds = True, universal_newlines = True, preexec_fn = preexec_fn)
+ if is_daemon:
+ return proc, stdout_file
for i in range(int(timeout/poll_rate)):
time.sleep(poll_rate)
if proc.poll() is not None: # process stopped
return (errno.ETIMEDOUT, '%s\n\n...Timeout of %s second(s) is reached!' % (stdout_file.read(), timeout))
stdout_file.seek(0)
return (proc.returncode, stdout_file.read())
+ finally:
+ if not is_daemon:
+ stdout_file.close()
def get_daemon_pid():
if is_running():
print(termstyle.red('Scapy server is already running'))
return
- server_path = os.path.join(pwd, 'automation', 'trex_control_plane', 'stl', 'services', 'scapy_server')
- with tempfile.TemporaryFile() as stdout_file:
- subprocess.Popen(shlex.split("taskset -c %s su -s /bin/bash -c '%s scapy_zmq_server.py -s %s' nobody" % (args.core, sys.executable, args.port)),
- stdout = stdout_file, stderr = subprocess.STDOUT, cwd = server_path, close_fds = True, universal_newlines = True)
- ret = progress(is_running, 'Starting Scapy server', 'Scapy server is started', 'Scapy server failed to run')
+ check_path = cur_dir
+ last_err_path = None
+ ret = -1
+ while ret and check_path != '/':
+ ret, out = run_command("ls %s" % check_path, demote = True)
if ret:
- stdout_file.seek(0)
- print('Output: %s' % stdout_file.read())
- sys.exit(1)
+ last_err_path = check_path
+ check_path = os.path.abspath(os.path.join(check_path, '..'))
+ if last_err_path:
+ msg = '''
+Error: current path is not readable by user "nobody" (starting at {path}).
+Two possible solutions:
+
+ 1. (Recommended)
+ Copy TRex to some public location (/tmp or /scratch, assuming it has proper permissions (chmod 777 etc.))
+
+ 2. (Not recommended)
+ Change permissions of current path. (Starting from directory {path}).
+ chmod 777 {path} -R
+'''.format(path = last_err_path)
+ fail(msg)
+
+ server_path = os.path.join(cur_dir, 'automation', 'trex_control_plane', 'stl', 'services', 'scapy_server')
+ cmd = 'taskset -c {core} {python} ./scapy_zmq_server.py -s {port}'.format(core = args.core, python = sys.executable, port = args.port)
+ proc, stdout_file = run_command(cmd, demote = True, is_daemon = True, cwd = server_path)
+ ret = progress(is_running, 'Starting Scapy server', 'Scapy server is started', 'Scapy server failed to run', fail_check = proc.poll)
+ if proc.poll():
+ stdout_file.seek(0)
+ print('Output: %s' % stdout_file.read())
+ stdout_file.close()
+ sys.exit(1)
def restart_daemon():
print(termstyle.red('Scapy server is NOT running'))
return True
run_command('kill %s' % pid) # usual kill
- ret = progress(inv(is_running), 'Killing Scapy server', 'Scapy server is killed', 'failed')
+ ret = progress(inv(is_running), 'Killing Scapy server', 'Scapy server is killed', 'failed', timeout = 15)
if not ret:
return
_, out = run_command('kill -9 %s' % pid) # unconditional kill
- ret = progress(inv(is_running), 'Killing Scapy server with -9', 'Scapy server is killed', 'failed')
+ ret = progress(inv(is_running), 'Killing Scapy server with -9', 'Scapy server is killed', 'failed', timeout = 15)
if ret:
fail('Failed to kill Scapy server, even with -9. Please review manually.\nOutput: %s' % out)
+
### Main ###
if __name__ == '__main__':
OPT_CLOSE,
OPT_ARP_REF_PER,
OPT_NO_OFED_CHECK,
+ OPT_NO_SCAPY_SERVER,
OPT_ACTIVE_FLOW
};
{ OPT_NO_WATCHDOG, "--no-watchdog", SO_NONE },
{ OPT_ALLOW_COREDUMP, "--allow-coredump", SO_NONE },
{ OPT_CHECKSUM_OFFLOAD, "--checksum-offload", SO_NONE },
- { OPT_ACTIVE_FLOW, "--active-flows", SO_REQ_SEP },
+ { OPT_ACTIVE_FLOW, "--active-flows", SO_REQ_SEP },
{ OPT_CLOSE, "--close-at-end", SO_NONE },
{ OPT_ARP_REF_PER, "--arp-refresh-period", SO_REQ_SEP },
{ OPT_NO_OFED_CHECK, "--no-ofed-check", SO_NONE },
-
+ { OPT_NO_SCAPY_SERVER, "--no-scapy-server", SO_NONE },
SO_END_OF_OPTIONS
};
break;
case OPT_NO_OFED_CHECK:
break;
+ case OPT_NO_SCAPY_SERVER:
+ break;
default:
printf("Error: option %s is not handled.\n\n", args.OptionText());
- usage();
return -1;
break;
} // End of switch