113540Sandrea.mondelli@ucf.edu#!/usr/bin/env python2.7 21376Sbinkertn@umich.edu# Copyright (c) 2005 The Regents of The University of Michigan 31376Sbinkertn@umich.edu# All rights reserved. 41376Sbinkertn@umich.edu# 51376Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without 61376Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are 71376Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright 81376Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer; 91376Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright 101376Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the 111376Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution; 121376Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its 131376Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from 141376Sbinkertn@umich.edu# this software without specific prior written permission. 151376Sbinkertn@umich.edu# 161376Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171376Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181376Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191376Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201376Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211376Sbinkertn@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221376Sbinkertn@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231376Sbinkertn@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241376Sbinkertn@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251376Sbinkertn@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261376Sbinkertn@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271376Sbinkertn@umich.edu# 281376Sbinkertn@umich.edu# Authors: Nathan Binkert 291376Sbinkertn@umich.edu# Steve Reinhardt 301376Sbinkertn@umich.edu# Ali Saidi 311376Sbinkertn@umich.edu 321881Sbinkertn@umich.eduimport os, os.path, shutil, signal, socket, sys 331376Sbinkertn@umich.edufrom os import environ as env 341376Sbinkertn@umich.edufrom os.path import join as joinpath, expanduser 351376Sbinkertn@umich.edu 361881Sbinkertn@umich.edudef date(): 371881Sbinkertn@umich.edu import time 381881Sbinkertn@umich.edu return time.strftime('%a %b %e %H:%M:%S %Z %Y', time.localtime()) 391881Sbinkertn@umich.edu 401881Sbinkertn@umich.edudef cleandir(dir): 411881Sbinkertn@umich.edu for root, dirs, files in os.walk(dir, False): 421881Sbinkertn@umich.edu for name in files: 431881Sbinkertn@umich.edu os.remove(joinpath(root, name)) 441881Sbinkertn@umich.edu for name in dirs: 451881Sbinkertn@umich.edu os.rmdir(joinpath(root, name)) 461881Sbinkertn@umich.edu 471376Sbinkertn@umich.educlass rsync: 481376Sbinkertn@umich.edu def __init__(self): 491376Sbinkertn@umich.edu self.sudo = False 501376Sbinkertn@umich.edu self.rsync = 'rsync' 511376Sbinkertn@umich.edu self.compress = False 521376Sbinkertn@umich.edu self.archive = True 531376Sbinkertn@umich.edu self.delete = False 541376Sbinkertn@umich.edu self.options = '' 551376Sbinkertn@umich.edu 561376Sbinkertn@umich.edu def do(self, src, dst): 571376Sbinkertn@umich.edu args = [] 581376Sbinkertn@umich.edu if self.sudo: 591376Sbinkertn@umich.edu args.append('sudo') 601376Sbinkertn@umich.edu 611376Sbinkertn@umich.edu args.append(self.rsync) 621376Sbinkertn@umich.edu if (self.archive): 631376Sbinkertn@umich.edu args.append('-a') 641376Sbinkertn@umich.edu if (self.compress): 651376Sbinkertn@umich.edu args.append('-z') 661376Sbinkertn@umich.edu if (self.delete): 671376Sbinkertn@umich.edu args.append('--delete') 681376Sbinkertn@umich.edu if len(self.options): 691376Sbinkertn@umich.edu args.append(self.options) 701376Sbinkertn@umich.edu args.append(src) 711376Sbinkertn@umich.edu args.append(dst) 721376Sbinkertn@umich.edu 731376Sbinkertn@umich.edu return os.spawnvp(os.P_WAIT, args[0], args) 741376Sbinkertn@umich.edu 751881Sbinkertn@umich.educlass JobDir(object): 761881Sbinkertn@umich.edu def __init__(self, dir): 771881Sbinkertn@umich.edu self.dir = dir 781376Sbinkertn@umich.edu 791881Sbinkertn@umich.edu def file(self, filename): 801881Sbinkertn@umich.edu return joinpath(self.dir, filename) 811376Sbinkertn@umich.edu 821881Sbinkertn@umich.edu def create(self): 831881Sbinkertn@umich.edu if os.path.exists(self.dir): 841881Sbinkertn@umich.edu if not os.path.isdir(self.dir): 851881Sbinkertn@umich.edu sys.exit('%s is not a directory. Cannot build job' % self.dir) 861881Sbinkertn@umich.edu else: 871881Sbinkertn@umich.edu os.mkdir(self.dir) 881376Sbinkertn@umich.edu 891881Sbinkertn@umich.edu def exists(self): 901881Sbinkertn@umich.edu return os.path.isdir(self.dir) 911881Sbinkertn@umich.edu 921881Sbinkertn@umich.edu def clean(self): 931881Sbinkertn@umich.edu cleandir(self.dir) 941881Sbinkertn@umich.edu 951881Sbinkertn@umich.edu def hasfile(self, filename): 961881Sbinkertn@umich.edu return os.path.isfile(self.file(filename)) 971881Sbinkertn@umich.edu 981881Sbinkertn@umich.edu def echofile(self, filename, string): 991881Sbinkertn@umich.edu filename = self.file(filename) 1001881Sbinkertn@umich.edu try: 1011881Sbinkertn@umich.edu f = file(filename, 'w') 1021881Sbinkertn@umich.edu print >>f, string 1031881Sbinkertn@umich.edu f.flush() 1041881Sbinkertn@umich.edu f.close() 1051881Sbinkertn@umich.edu except IOError,e: 1061881Sbinkertn@umich.edu sys.exit(e) 1071881Sbinkertn@umich.edu 1081881Sbinkertn@umich.edu def rmfile(self, filename): 1091881Sbinkertn@umich.edu filename = self.file(filename) 1101881Sbinkertn@umich.edu if os.path.isfile(filename): 1111881Sbinkertn@umich.edu os.unlink(filename) 1121881Sbinkertn@umich.edu 1131881Sbinkertn@umich.edu def readval(self, filename): 1141881Sbinkertn@umich.edu filename = self.file(filename) 1151881Sbinkertn@umich.edu f = file(filename, 'r') 1161881Sbinkertn@umich.edu value = f.readline().strip() 1171881Sbinkertn@umich.edu f.close() 1181881Sbinkertn@umich.edu return value 1191881Sbinkertn@umich.edu 1201881Sbinkertn@umich.edu def setstatus(self, string): 1211881Sbinkertn@umich.edu filename = self.file('.status') 1221881Sbinkertn@umich.edu try: 1231881Sbinkertn@umich.edu f = file(filename, 'a') 1241881Sbinkertn@umich.edu print >>f, string 1251881Sbinkertn@umich.edu f.flush() 1261881Sbinkertn@umich.edu f.close() 1271881Sbinkertn@umich.edu except IOError,e: 1281881Sbinkertn@umich.edu sys.exit(e) 1291881Sbinkertn@umich.edu 1301881Sbinkertn@umich.edu def getstatus(self): 1311881Sbinkertn@umich.edu filename = self.file('.status') 1321881Sbinkertn@umich.edu try: 1331881Sbinkertn@umich.edu f = file(filename, 'r') 1341881Sbinkertn@umich.edu except IOError, e: 1351881Sbinkertn@umich.edu return 'none' 1361881Sbinkertn@umich.edu 1371881Sbinkertn@umich.edu # fast forward to the end 1381881Sbinkertn@umich.edu for line in f: pass 1391881Sbinkertn@umich.edu 1401881Sbinkertn@umich.edu # the first word on the last line is the status 1411881Sbinkertn@umich.edu return line.split(' ')[0] 1421881Sbinkertn@umich.edu 1431881Sbinkertn@umich.edu def __str__(self): 1441881Sbinkertn@umich.edu return self.dir 1451376Sbinkertn@umich.edu 1461376Sbinkertn@umich.eduif __name__ == '__main__': 1471376Sbinkertn@umich.edu rootdir = env.setdefault('ROOTDIR', os.getcwd()) 1481816Sbinkertn@umich.edu pbs_jobid = env['PBS_JOBID'] 1491816Sbinkertn@umich.edu pbs_jobname = env['PBS_JOBNAME'] 1501376Sbinkertn@umich.edu basedir = joinpath(rootdir, 'Base') 1511816Sbinkertn@umich.edu jobname = env.setdefault('JOBNAME', pbs_jobname) 1521916Sbinkertn@umich.edu jobfile = env.setdefault('JOBFILE', joinpath(rootdir, 'Test.py')) 1531816Sbinkertn@umich.edu outdir = env.setdefault('OUTPUT_DIR', joinpath(rootdir, jobname)) 1541816Sbinkertn@umich.edu env['POOLJOB'] = 'True' 1551376Sbinkertn@umich.edu 1561816Sbinkertn@umich.edu if os.path.isdir("/work"): 1571816Sbinkertn@umich.edu workbase = "/work" 1581816Sbinkertn@umich.edu else: 1591816Sbinkertn@umich.edu workbase = "/tmp/" 1601816Sbinkertn@umich.edu 1611816Sbinkertn@umich.edu workdir = joinpath(workbase, '%s.%s' % (env['USER'], pbs_jobid)) 1621881Sbinkertn@umich.edu host = socket.gethostname() 1631376Sbinkertn@umich.edu 1641376Sbinkertn@umich.edu os.umask(0022) 1651376Sbinkertn@umich.edu 1661881Sbinkertn@umich.edu jobdir = JobDir(outdir) 1671881Sbinkertn@umich.edu 1681881Sbinkertn@umich.edu started = date() 1691881Sbinkertn@umich.edu jobdir.echofile('.running', started) 1701881Sbinkertn@umich.edu jobdir.rmfile('.queued') 1711881Sbinkertn@umich.edu jobdir.echofile('.host', host) 1721881Sbinkertn@umich.edu 1731881Sbinkertn@umich.edu jobdir.setstatus('running on %s on %s' % (host, started)) 1741376Sbinkertn@umich.edu 1751376Sbinkertn@umich.edu if os.path.isdir(workdir): 1761376Sbinkertn@umich.edu cleandir(workdir) 1771376Sbinkertn@umich.edu else: 1781376Sbinkertn@umich.edu os.mkdir(workdir) 1791376Sbinkertn@umich.edu 1801881Sbinkertn@umich.edu if False and os.path.isdir('/z/dist'): 1811376Sbinkertn@umich.edu sync = rsync() 1821376Sbinkertn@umich.edu sync.delete = True 1831376Sbinkertn@umich.edu sync.sudo = True 1841376Sbinkertn@umich.edu sync.do('poolfs::dist/m5/', '/z/dist/m5/') 1851376Sbinkertn@umich.edu 1861376Sbinkertn@umich.edu try: 1871376Sbinkertn@umich.edu os.chdir(workdir) 1881376Sbinkertn@umich.edu except OSError,e: 1891376Sbinkertn@umich.edu sys.exit(e) 1901376Sbinkertn@umich.edu 1911881Sbinkertn@umich.edu os.symlink(jobdir.file('output'), 'status.out') 1921376Sbinkertn@umich.edu 1931712Sstever@eecs.umich.edu args = [ joinpath(basedir, 'm5'), joinpath(basedir, 'run.py') ] 1941376Sbinkertn@umich.edu if not len(args): 1951376Sbinkertn@umich.edu sys.exit("no arguments") 1961376Sbinkertn@umich.edu 1971881Sbinkertn@umich.edu print 'starting job... %s' % started 1981376Sbinkertn@umich.edu print ' '.join(args) 1991376Sbinkertn@umich.edu print 2001376Sbinkertn@umich.edu sys.stdout.flush() 2011376Sbinkertn@umich.edu 2021376Sbinkertn@umich.edu childpid = os.fork() 2031376Sbinkertn@umich.edu if not childpid: 2041376Sbinkertn@umich.edu # Execute command 2051376Sbinkertn@umich.edu sys.stdin.close() 2061881Sbinkertn@umich.edu fd = os.open(jobdir.file("output"), 2071376Sbinkertn@umich.edu os.O_WRONLY | os.O_CREAT | os.O_TRUNC) 2081376Sbinkertn@umich.edu os.dup2(fd, sys.stdout.fileno()) 2091376Sbinkertn@umich.edu os.dup2(fd, sys.stderr.fileno()) 2101376Sbinkertn@umich.edu os.execvp(args[0], args) 2111376Sbinkertn@umich.edu 2121376Sbinkertn@umich.edu def handler(signum, frame): 2131376Sbinkertn@umich.edu if childpid != 0: 2141376Sbinkertn@umich.edu os.kill(childpid, signum) 2151376Sbinkertn@umich.edu 2161376Sbinkertn@umich.edu signal.signal(signal.SIGHUP, handler) 2171376Sbinkertn@umich.edu signal.signal(signal.SIGINT, handler) 2181376Sbinkertn@umich.edu signal.signal(signal.SIGQUIT, handler) 2191376Sbinkertn@umich.edu signal.signal(signal.SIGTERM, handler) 2201376Sbinkertn@umich.edu signal.signal(signal.SIGCONT, handler) 2211376Sbinkertn@umich.edu signal.signal(signal.SIGUSR1, handler) 2221376Sbinkertn@umich.edu signal.signal(signal.SIGUSR2, handler) 2231376Sbinkertn@umich.edu 2241376Sbinkertn@umich.edu done = 0 2251376Sbinkertn@umich.edu while not done: 2261376Sbinkertn@umich.edu try: 2271376Sbinkertn@umich.edu thepid,ec = os.waitpid(childpid, 0) 2281376Sbinkertn@umich.edu if ec: 2291376Sbinkertn@umich.edu print 'Exit code ', ec 2301881Sbinkertn@umich.edu status = 'failure' 2311376Sbinkertn@umich.edu else: 2321881Sbinkertn@umich.edu status = 'success' 2331376Sbinkertn@umich.edu done = 1 2341376Sbinkertn@umich.edu except OSError: 2351376Sbinkertn@umich.edu pass 2361376Sbinkertn@umich.edu 2371881Sbinkertn@umich.edu complete = date() 2381881Sbinkertn@umich.edu print '\njob complete... %s' % complete 2391881Sbinkertn@umich.edu jobdir.echofile('.%s' % status, complete) 2401881Sbinkertn@umich.edu jobdir.rmfile('.running') 2411881Sbinkertn@umich.edu jobdir.setstatus('%s on %s' % (status, complete)) 242