示例#1
0
def list_all_lind_paths(startingdir='/'):
  """
   <Purpose>
      Returns a list of all files / dirs in the lind fs.   Each has an absolute
      name.   This is similar to 'find startingdir'.

   <Arguments>
      startingdir: the path to start with.

   <Exceptions>
      If startingdir is not a dir, this is a SyscallError.

   <Side Effects>
      None

   <Returns>
      A list of strings that correspond to absolute names.   For example:
      ['/','/etc/','/etc/passwd']
  """
  
  # BUG: This code may need to be revisited with symlinks...

  # this will throw exceptions when given bad data...
  lind_test_server.chdir_syscall(startingdir)

  return _find_all_paths_recursively(startingdir)
def list_all_lind_paths(startingdir='/'):
  """
   <Purpose>
      Returns a list of all files / dirs in the lind fs.   Each has an absolute
      name.   This is similar to 'find startingdir'.

   <Arguments>
      startingdir: the path to start with.

   <Exceptions>
      If startingdir is not a dir, this is a SyscallError.

   <Side Effects>
      None

   <Returns>
      A list of strings that correspond to absolute names.   For example:
      ['/','/etc/','/etc/passwd']
  """
  
  # BUG: This code may need to be revisited with symlinks...

  # this will throw exceptions when given bad data...
  lind_test_server.chdir_syscall(startingdir)

  return _find_all_paths_recursively(startingdir)
示例#3
0
def cd_cmd(dir):

	assert(dir)
	try:
		lind_test_server.chdir_syscall(dir)
	except lind_test_server.SyscallError, e:
		print "Could not cd. Error: %s" % e
示例#4
0
def cp_recursive(source, dest):
	
	new_file_name = dest.split("/")[-1]#get just the new file's name
	
    # check if the source file is a directory
	if(not os.path.isdir(source)):
	
		# keep same name if none specified
		if not new_file_name:
			new_file_name = source.split("/")[-1]
	
        # not a directory, just make sure the path exists, then copy the file into the virtual FS
		path_str = check_path_exists(dest)# we should create the path if it doesnt exist (but print a warning)!
		copy_file(source, path_str, new_file_name)
	else:
        # if it IS a dir we need to do a little more work.
		path_str = check_path_exists(dest)#add the path up to the directory
		lind_test_server.chdir_syscall(path_str)#chdir to the end of that new path
		
		mode = stat.S_IMODE(os.stat(source).st_mode)
		
        #print "in cp " +  source + "/" + new_file_name + "..." + str(mode) + "..." + str(S_IRWXU)
		try:
			lind_test_server.chdir_syscall(new_file_name)#chdir to that new directory
		except lind_test_server.SyscallError:
			lind_test_server.mkdir_syscall(new_file_name, mode)#make a directory for the new directory
			lind_test_server.chdir_syscall(new_file_name)#chdir to that new directory
		
        # then we loop through each of the subfiles of the directory, and recursively call the cp function
        #  keeping track of both the native file location as well as the virtual file location!
		for c in os.listdir(source):
			cp_recursive(source + "/" + c, dest + "/" + c)
示例#5
0
def check_path_exists(path):
	path_list = path.split("/")[0:-1]#get each directory in the path, excluding the new file's name
	lind_test_server.chdir_syscall("/")#start at root
	path_str = "/"#this string will hold the whole path of the destination file (excluding the filename itself)
		
	# loop through each dir in the path
	for p in path_list:
		if(p == ""): # ignore the empty string returned from splitting root dir '/'
			continue
		path_str += (p + "/")#c oncat the dir to the full path string
		
		# try to chdir (if it fails, means the directory doesnt exist)
		try:
			lind_test_server.chdir_syscall(p)
		# if (when) the exception is caught, create a new dir and chdir to it
		except lind_test_server.SyscallError:
			
			# this seems to cause an assertion to fail!
			#try: # get the mode if the dir exists in the fs
			#	mode = stat.S_IMODE(os.stat(path_str).st_mode)
			#except OSError: # if not set to default 777
			#	mode = lind_test_server.S_IRWXA
			mode = lind_test_server.S_IRWXA
						
			lind_test_server.mkdir_syscall(p, mode)
			lind_test_server.chdir_syscall(p)
	return path_str
示例#6
0
def generate_fs(syscalls, home_env=None):
  """
  <Purpose>
    This is the only public function of this module. It takes a list of
    Syscall objects as an argument and generates a Lind fs based on the
    information gathered from these system calls.

  <Arguments>
    syscalls:
      A list of Syscall objects, representing system calls parsed from a trace
      file.

    home_env:
      The HOME environment variable extracted from the traced execve sytem call.

  <Exceptions>
    None
  
  <Side Effects>
    Generates a set of files that make up the Lind file system.

  <Returns>
    None

  """

  # load an initial lind file system.
  lind_test_server._blank_fs_init()

  # Keep track of all the file paths dealt with and make a note of whether the
  # file was added to the lind fs or not. Example: {"filename.txt":True,
  # "filename2.txt":False} where True indicates the file was added into the lind
  # fs and False means the file was seen but wasn't added to the lind fs. We
  # keep track of all the paths met so far for two reasons. Firstly, we want to
  # construct the INITIAL file system state, so we only deal with the first
  # occurence of each path. For example consider the following sequence of 
  # traced system calls example:
  #
  #   11443 open("test.txt", O_RDONLY) = -1 ENOENT (No such file or directory)
  #     ...
  #   11443 open("test.txt", O_RDONLY) = 3
  #
  # In this example when the "test.txt" path is met for the first time, the file
  # does not exist (indicated by: -1 ENOENT). Subsequently, the "test.txt" path
  # is met again and in this case the file does exist. In this case we do NOT
  # want to include the "test.txt" file in the lind fs, because the initial file
  # system state did not include this file, even though the file is eventually
  # created.
  #
  # The second reason we keep track of all the paths met and whether they were 
  # added in the lind fs is to confirm whether the lind fs was constructed 
  # successfully.
  seen_paths = {}

  # a list of system calls that include a filepath in their arguments. We only
  # care about these system calls so only the actions representing of these
  # system calls will be examined.
  syscalls_with_path = ['open', 'creat', 'statfs', 'access', 'stat', 'link', 
                        'unlink', 'chdir', 'rmdir', 'mkdir']
  
  for action in actions:
    # the general format of an action is the following:
    # (syscall_name, (arguments tuple), (return tuple))
    # 
    # Example successful syscall action:
    # ('open_syscall', ('syscalls.txt', ['O_RDONLY', 'O_CREAT'], 
    #    ['S_IWUSR', 'S_IRUSR', 'S_IWGRP', 'S_IRGRP', 'S_IROTH']), 
    #            (3, None))
    #
    # Example unsuccessful syscall actions:
    # ('access_syscall', ('/etc/ld.so.nohwcap', ['F_OK']), 
    #                  (-1, 'ENOENT'))
    # ('mkdir_syscall', ('syscalls_dir', ['S_IRWXU', 'S_IRWXG', 
    #        'S_IXOTH', 'S_IROTH']), (-1, 'EEXIST'))
    syscall_name, syscall_parameters, syscall_result = action

    if DEBUG:
      print "Action:", action

    # each syscall name should end with _syscall
    if not syscall_name.endswith("_syscall"):
      raise Exception("Unexpected name of system call '" + 
                      syscall_name + "'")

    # remove the _syscall part from the syscall name
    syscall_name = syscall_name[:syscall_name.find("_syscall")]

    if syscall_name in syscalls_with_path:

      # TODO: I should consider O_CREAT O_EXECL and O_TRUNC flags.

      # check if the system call is open and whether it includes the O_CREAT
      # flag. If it does, set the o_creat flag to True, otherwise set it to
      # False. The o_creat flag will be used when trying to add a file, to
      # indicate how to handle the case the actual file is missing.
      # Specifically, when trying to add a file into the lind fs that does not
      # exist in the local fs, an exception will be raised, unless the o_creat
      # flag is set to True, in which case a warning will be printed instead.
      o_creat = False
      if syscall_name == "open":
        open_flags = action[1][1]
        if "O_CREAT" in open_flags:
          o_creat = True
      
      # Similarly, if the system call is creat, set the o_creat flag to True
      if syscall_name == "creat":
        o_creat = True

      # get the file path from the action
      path = action[1][0]

      # We want the initial file system state. So deal only with the earliest
      # syscall pertaining to a path.      
      if path not in seen_paths:
        # if the syscall was successful, copy file/dir into the lind fs.
        if syscall_result != (-1, 'ENOENT'):
          path, path_added = _copy_path_into_lind(path, home_path, o_creat)
          
          # remember this path was seen and whether it was added to the lind fs.
          seen_paths[path] = path_added
        
        else:
          # remember this path was seen but not added to the lind fs.
          seen_paths[path] = False

      # the link syscall contains a second path.
      if syscall_name == 'link':
        # ('link_syscall', ('syscalls.txt', 'syscalls.link'), (0, None))
        path2 = action[1][1]

        if path2 not in seen_paths:
          # if we got an exists error, the file must have been there
          # already, so we add it in the lind fs.
          if syscall_result == (-1, 'EEXIST'):
            path2, path_added = _copy_path_into_lind(path2, home_path, o_creat)
            
            # remember this path was seen and whether it was added to the lind fs.
            seen_paths[path2] = path_added
          
          else:
            # remember this path was seen but not added to the lind fs.
            seen_paths[path2] = False

      """
        TODO: Can add support for symlink here. Slightly more tricky due to 
        return part and error messages.
      """

      # change the home directory and the lind current directory so that future 
      # references to relative paths will be handled correctly.
      if syscall_name == 'chdir':
        home_path = os.path.join(home_path, path)
        home_path = os.path.normpath(home_path)
        lind_test_server.chdir_syscall(home_path)

      
  
  if DEBUG:
    print
    print "Seen Paths"
    print seen_paths

  # all actions are now read. Let's confirm that lind fs is as expected.
  all_lind_paths = list_all_lind_paths()

  if DEBUG:
    print
    print "Lind Paths"
    print all_lind_paths

  for seen_path in seen_paths:
    # convert to lind absolute path.
    abs_seen_path = seen_path
    if not abs_seen_path.startswith("/"):
      abs_seen_path = "/" + abs_seen_path

    abs_seen_path = os.path.normpath(abs_seen_path)

    # skip the root
    if abs_seen_path == "/":
      continue

    if seen_paths[seen_path]:
      # the file should be in lind fs.
      if abs_seen_path not in all_lind_paths:
        raise Exception("Expected file '" + abs_seen_path + 
                        "' not found in Lind fs")
    else:
      # file should not be in lind fs.
      if abs_seen_path in all_lind_paths:
        raise Exception("Unexpected file '" + abs_seen_path + "' in Lind fs")
示例#7
0
from lind_fs_constants import *
import lind_test_server

# Let's add a few directories to the system and see if it works...
lind_test_server._blank_fs_init()

lind_test_server.mkdir_syscall('/bar',S_IRWXA)

lind_test_server.mkdir_syscall('/bar/baz',S_IRWXA)

lind_test_server.mkdir_syscall('/bar/baz/yaargh',0)

lind_test_server.access_syscall('bar',F_OK)

# go to bar and look for baz...
lind_test_server.chdir_syscall('bar')

lind_test_server.access_syscall('baz',F_OK)

# go to back up and look bar...
lind_test_server.chdir_syscall('..')

lind_test_server.access_syscall('bar',F_OK)

# go to the yaargh dir
lind_test_server.chdir_syscall('/bar/baz/yaargh')

lind_test_server.access_syscall('../../baz',F_OK)

示例#8
0
def generate_fs(actions, trace_path):
    # Relative paths found in actions are related to this HOME_PATH. It is initially
    # set to an empty string which ultimately translates to the current directory.
    home_path = ''

    # read the trace and examine the execve syscall to see if the HOME environment
    # variable is set to somewhere else. This usually happens when running
    # benchmarks. The reason to do this is because actions referring to files
    # using relative paths, might refere to these files relative to the HOME
    # variable defined in the execve syscall.
    fh = open(trace_path, "r")
    # the execve syscall is the first action of the trace file
    execve_line = fh.readline()
    fh.close()

    # If the 'HOME' variable is defined in the execve line, the HOME_PATH
    # variable will be set to the path of 'HOME'.
    if execve_line.find("execve(") != -1:
        execve_parts = execve_line.split(", ")
        # the parameter of the HOME variable in the execve syscall has this format:
        # "HOME=/home/savvas/tests/" including the double quotes.
        for part in execve_parts:
            if part.startswith("\"HOME="):
                part = part.strip("\"")
                assert (part.startswith("HOME="))
                home_path = part[part.find("HOME=") + 5:]

    # load an initial lind file system.
    lind_test_server._blank_fs_init()

    # Keep track of all the file paths dealt with and make a note of whether the
    # file was added to the lind fs or not. Example: {"filename.txt":True,
    # "filename2.txt":False} where True indicates the file was added into the lind
    # fs and False means the file was seen but wasn't added to the lind fs. We
    # keep track of all the paths met so far for two reasons. Firstly, we want to
    # construct the INITIAL file system state, so we only deal with the first
    # occurence of each path. For example consider the following sequence of
    # traced system calls example:
    #
    #   11443 open("test.txt", O_RDONLY) = -1 ENOENT (No such file or directory)
    #     ...
    #   11443 open("test.txt", O_RDONLY) = 3
    #
    # In this example when the "test.txt" path is met for the first time, the file
    # does not exist (indicated by: -1 ENOENT). Subsequently, the "test.txt" path
    # is met again and in this case the file does exist. In this case we do NOT
    # want to include the "test.txt" file in the lind fs, because the initial file
    # system state did not include this file, even though the file is eventually
    # created.
    #
    # The second reason we keep track of all the paths met and whether they were
    # added in the lind fs is to confirm whether the lind fs was constructed
    # successfully.
    seen_paths = {}

    # a list of system calls that include a filepath in their arguments. We only
    # care about these system calls so only the actions representing of these
    # system calls will be examined.
    syscalls_with_path = [
        'open', 'creat', 'statfs', 'access', 'stat', 'link', 'unlink', 'chdir',
        'rmdir', 'mkdir'
    ]

    for action in actions:
        # the general format of an action is the following:
        # (syscall_name, (arguments tuple), (return tuple))
        #
        # Example successful syscall action:
        # ('open_syscall', ('syscalls.txt', ['O_RDONLY', 'O_CREAT'],
        #    ['S_IWUSR', 'S_IRUSR', 'S_IWGRP', 'S_IRGRP', 'S_IROTH']),
        #            (3, None))
        #
        # Example unsuccessful syscall actions:
        # ('access_syscall', ('/etc/ld.so.nohwcap', ['F_OK']),
        #                  (-1, 'ENOENT'))
        # ('mkdir_syscall', ('syscalls_dir', ['S_IRWXU', 'S_IRWXG',
        #        'S_IXOTH', 'S_IROTH']), (-1, 'EEXIST'))
        syscall_name, syscall_parameters, syscall_result = action

        if DEBUG:
            print "Action:", action

        # each syscall name should end with _syscall
        if not syscall_name.endswith("_syscall"):
            raise Exception("Unexpected name of system call '" + syscall_name +
                            "'")

        # remove the _syscall part from the syscall name
        syscall_name = syscall_name[:syscall_name.find("_syscall")]

        if syscall_name in syscalls_with_path:

            # TODO: I should consider O_CREAT O_EXECL and O_TRUNC flags.

            # check if the system call is open and whether it includes the O_CREAT
            # flag. If it does, set the o_creat flag to True, otherwise set it to
            # False. The o_creat flag will be used when trying to add a file, to
            # indicate how to handle the case the actual file is missing.
            # Specifically, when trying to add a file into the lind fs that does not
            # exist in the local fs, an exception will be raised, unless the o_creat
            # flag is set to True, in which case a warning will be printed instead.
            o_creat = False
            if syscall_name == "open":
                open_flags = action[1][1]
                if "O_CREAT" in open_flags:
                    o_creat = True

            # Similarly, if the system call is creat, set the o_creat flag to True
            if syscall_name == "creat":
                o_creat = True

            # get the file path from the action
            path = action[1][0]

            # We want the initial file system state. So deal only with the earliest
            # syscall pertaining to a path.
            if path not in seen_paths:
                # if the syscall was successful, copy file/dir into the lind fs.
                if syscall_result != (-1, 'ENOENT'):
                    path, path_added = _copy_path_into_lind(
                        path, home_path, o_creat)

                    # remember this path was seen and whether it was added to the lind fs.
                    seen_paths[path] = path_added

                else:
                    # remember this path was seen but not added to the lind fs.
                    seen_paths[path] = False

            # the link syscall contains a second path.
            if syscall_name == 'link':
                # ('link_syscall', ('syscalls.txt', 'syscalls.link'), (0, None))
                path2 = action[1][1]

                if path2 not in seen_paths:
                    # if we got an exists error, the file must have been there
                    # already, so we add it in the lind fs.
                    if syscall_result == (-1, 'EEXIST'):
                        path2, path_added = _copy_path_into_lind(
                            path2, home_path, o_creat)

                        # remember this path was seen and whether it was added to the lind fs.
                        seen_paths[path2] = path_added

                    else:
                        # remember this path was seen but not added to the lind fs.
                        seen_paths[path2] = False
            """
        TODO: Can add support for symlink here. Slightly more tricky due to 
        return part and error messages.
      """

            # change the home directory and the lind current directory so that future
            # references to relative paths will be handled correctly.
            if syscall_name == 'chdir':
                home_path = os.path.join(home_path, path)
                home_path = os.path.normpath(home_path)
                lind_test_server.chdir_syscall(home_path)

    if DEBUG:
        print
        print "Seen Paths"
        print seen_paths

    # all actions are now read. Let's confirm that lind fs is as expected.
    all_lind_paths = list_all_lind_paths()

    if DEBUG:
        print
        print "Lind Paths"
        print all_lind_paths

    for seen_path in seen_paths:
        # convert to lind absolute path.
        abs_seen_path = seen_path
        if not abs_seen_path.startswith("/"):
            abs_seen_path = "/" + abs_seen_path

        abs_seen_path = os.path.normpath(abs_seen_path)

        # skip the root
        if abs_seen_path == "/":
            continue

        if seen_paths[seen_path]:
            # the file should be in lind fs.
            if abs_seen_path not in all_lind_paths:
                raise Exception("Expected file '" + abs_seen_path +
                                "' not found in Lind fs")
        else:
            # file should not be in lind fs.
            if abs_seen_path in all_lind_paths:
                raise Exception("Unexpected file '" + abs_seen_path +
                                "' in Lind fs")