Skip to content

Commit

Permalink
Add uart logging and file outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Pemberton committed Dec 12, 2018
1 parent c05107b commit 6a9f851
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 45 deletions.
2 changes: 2 additions & 0 deletions runOutput/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
67 changes: 35 additions & 32 deletions sw-manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ def main():
help="Launch the specified job. Defaults to running the base image.")
launch_parser.add_argument('-i', '--initramfs', action='store_true', help="Launch the initramfs version of this workload")

# # Init Command
# init_parser = subparsers.add_parser(
# 'init', help="Initialize workloads (using 'host_init' script)")
# init_parser.set_defaults(func=handleInit)

args = parser.parse_args()
setRunName(args)

args.workdir = os.path.abspath(args.workdir)
# args.config_file = os.path.join(args.workdir, args.config_file)
Expand Down Expand Up @@ -220,16 +216,15 @@ def handleBuild(args, cfgs):
# The order isn't critical here, we should have defined the dependencies correctly in loader
doit.doit_cmd.DoitMain(loader).run(binList + imgList)

def launchSpike(config, initramfs=False):
log = logging.getLogger()
def getSpikeCmd(config, initramfs=False):
if initramfs:
sp.check_call(['spike', '-p4', '-m4096', config['bin'] + '-initramfs'])
return ['spike', '-p4', '-m4096', config['bin'] + '-initramfs']
elif 'img' not in config:
sp.check_call(['spike', '-p4', '-m4096', config['bin']])
return ['spike', '-p4', '-m4096', config['bin']]
else:
raise ValueError("Spike does not support disk-based configurations")

def launchQemu(config, initramfs=False):
def getQemuCmd(config, initramfs=False):
log = logging.getLogger()

if initramfs:
Expand All @@ -251,9 +246,9 @@ def launchQemu(config, initramfs=False):
if 'img' in config and not initramfs:
cmd = cmd + ['-device', 'virtio-blk-device,drive=hd0',
'-drive', 'file=' + config['img'] + ',format=raw,id=hd0']
cmd = cmd + ['-append', 'ro root=/dev/vda']
cmd = cmd + ['-append', '"ro root=/dev/vda"']

sp.check_call(cmd)
return cmd

def handleLaunch(args, cfgs):
log = logging.getLogger()
Expand All @@ -264,24 +259,26 @@ def handleLaunch(args, cfgs):
else:
# Run the base image
config = cfgs[args.config_file]


runResDir = os.path.join(res_dir, getRunName(), config['name'])
uartLog = os.path.join(runResDir, "uartlog")
os.makedirs(runResDir)

if args.spike:
if 'img' in config and 'initramfs' not in config:
sys.exit("Spike currently does not support disk-based " +
"configurations. Please use an initramfs based image.")
launchSpike(config, args.initramfs)
cmd = getSpikeCmd(config, args.initramfs)
else:
launchQemu(config, args.initramfs)

# def handleInit(args, cfgs):
# log = logging.getLogger()
# config = cfgs[args.config_file]
# if 'host-init' in config:
# log.info("Applying host-init: " + config['host-init'])
# if not os.path.exists(config['host-init']):
# raise ValueError("host-init script " + config['host-init'] + " not found.")
#
# run([config['host-init']], cwd=config['workdir'])
cmd = getQemuCmd(config, args.initramfs)

sp.check_call(" ".join(cmd) + " | tee " + uartLog, shell=True)

if 'outputs' in config:
outputSpec = [ FileSpec(src=f, dst=runResDir + "/") for f in config['outputs']]
copyImgFiles(config['img'], outputSpec, direction='out')

log.info("Run output available in: " + runResDir)

# Now build linux/bbl
def makeBin(config, initramfs=False):
Expand Down Expand Up @@ -312,8 +309,6 @@ def makeBin(config, initramfs=False):
shutil.copy('riscv-pk/build/bbl', config['bin'] + '-initramfs')
else:
shutil.copy('riscv-pk/build/bbl', config['bin'])
# elif config['distro'] != 'bare':
# raise ValueError("No linux config defined. This is only supported for workloads based on 'bare'")

def makeImage(config):
log = logging.getLogger()
Expand All @@ -330,7 +325,7 @@ def makeImage(config):

if 'files' in config:
log.info("Applying file list: " + str(config['files']))
applyFiles(config['img'], config['files'])
copyImgFiles(config['img'], config['files'], 'in')

if 'guest-init' in config:
log.info("Applying init script: " + config['guest-init'])
Expand Down Expand Up @@ -366,10 +361,13 @@ def makeImage(config):
# Note that all paths must be absolute
def applyOverlay(img, overlay):
log = logging.getLogger()
applyFiles(img, [FileSpec(src=os.path.join(overlay, "*"), dst='/')])
copyImgFiles(img, [FileSpec(src=os.path.join(overlay, "*"), dst='/')], 'in')

# Copies a list of type FileSpec ('files') into the destination image (img)
def applyFiles(img, files):
# Copies a list of type FileSpec ('files') to/from the destination image (img)
# img - path to image file to use
# files - list of FileSpecs to use
# direction - "in" or "out" for copying files into or out of the image (respectively)
def copyImgFiles(img, files, direction):
log = logging.getLogger()

if not os.path.exists(mnt):
Expand All @@ -388,7 +386,12 @@ def applyFiles(img, files):
# Note: shell=True because f.src is allowed to contain globs
# Note: os.path.join can't handle overlay-style concats (e.g. join('foo/bar', '/baz') == '/baz')
# run('cp -a ' + f.src + " " + os.path.normpath(mnt + f.dst), shell=True)
run('sudo rsync -a --chown=root:root ' + f.src + " " + os.path.normpath(mnt + f.dst), shell=True)
if direction == 'in':
run('sudo rsync -a --chown=root:root ' + f.src + " " + os.path.normpath(mnt + f.dst), shell=True)
elif direction == 'out':
run('sudo rsync -a --chown=root:root ' + os.path.normpath(mnt + f.src) + " " + f.dst, shell=True)
else:
raise ValueError("direction option must be either 'in' or 'out'")
finally:
# run(['guestunmount', mnt])
# run(['fusermount', '-u', mnt])
Expand Down
2 changes: 1 addition & 1 deletion test/command.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name" : "command",
"base" : "br-base.json",
"command" : "echo I Ran!"
"command" : "echo Global: command >> /root/runOutput && cat /root/runOutput"
}
9 changes: 6 additions & 3 deletions test/smoke2.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
"name" : "smoke2",
"base" : "br-base.json",
"overlay" : "overlay",
"guest-init" : "guest-init.sh",
"guest-init" : "init.sh",
"outputs" : [ "/root/runOutput" ],
"run" : "run.sh",
"jobs" : [
{
"name" : "j0",
"files" : [ ["j0_output", "/root/"] ],
"guest-init" : "guest-init0.sh",
"guest-init" : "init0.sh",
"outputs" : [ "/root/j0_output" ],
"run" : "run0.sh"
},
{
"name" : "j1",
"files" : [ ["j1_output", "/root/"] ],
"guest-init" : "guest-init1.sh",
"outputs" : [ "/root/j1_output" ],
"guest-init" : "init1.sh",
"run" : "run1.sh"
}
]
Expand Down
7 changes: 5 additions & 2 deletions util/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
'host-init',
# Path to folder containing overlay files to apply to img
'overlay',
# List of tuples of files to add [(dest_dir, srcFile),...]
# List of tuples of files to add [(guest_dest, host_src),...]
'files',
# List of files to copy out of the image after running it. Files will
# be flattened into results dir. [guest_src0, guest_src1, ...]
'outputs',
# Path to script to run on the guest every time it boots
'run',
# An inline command to run at startup (cannot be set along with 'run')
Expand Down Expand Up @@ -56,7 +59,7 @@

# These are the options that should be inherited from base configs (if not
# explicitly provided)
configInherit = ['runSpec', 'files', 'linux-config', 'builder', 'distro']
configInherit = ['runSpec', 'files', 'outputs', 'linux-config', 'builder', 'distro']

# These are the permissible base-distributions to use (they get treated special)
distros = {
Expand Down
26 changes: 19 additions & 7 deletions util/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,35 @@
root_dir = os.getcwd()
image_dir = os.path.join(root_dir, "images")
linux_dir = os.path.join(root_dir, "riscv-linux")
log_dir = os.path.join(root_dir, "logs")
res_dir = os.path.join(root_dir, "runOutput")
mnt = os.path.join(root_dir, "disk-mount")
commandScript = os.path.join(root_dir, "_command.sh")

jlevel = "-j" + str(os.cpu_count())
runName = ""

# Create a unique run name
def setRunName(args):
global runName

timeline = time.strftime("%Y-%m-%d--%H-%M-%S", time.gmtime())
randname = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(16))

runName = os.path.splitext(os.path.basename(args.config_file))[0] + \
"-" + args.command + \
"-" + timeline + \
"-" + randname

def getRunName():
return runName

# logging setup
def initLogging(args):
rootLogger = logging.getLogger()
rootLogger.setLevel(logging.NOTSET) # capture everything

# Create a unique log name
timeline = time.strftime("%Y-%m-%d--%H-%M-%S", time.gmtime())
randname = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(16))

logPath = os.path.join(root_dir, "logs", os.path.splitext(os.path.basename(args.config_file))[0] +
"-" + timeline + "-" +
"-" + randname + ".log")
logPath = os.path.join(log_dir, getRunName() + ".log")

# formatting for log to file
fileHandler = logging.FileHandler(str(logPath))
Expand Down

0 comments on commit 6a9f851

Please sign in to comment.