Extend the server-side profiler code to handle reboots as well. Sadly,
this is a bit of a kludge, but I can't see any better solution without
redesigning the client-side profiler interface first.
I handle a reboot by pulling back any existing profiler data right
after a reboot and then re-starting the profiler. This generally works
because most of the profilers are idempotent; either they write into
different files in each run, or they just continuously append logs
to a log file of some kind and so concatenating all their output
is good enough.
In general there's unfortunately no reliable way to signal the
profilers before a reboot occurs, we can only deal with it after the
fact, so we don't have the option of adding some sort of
save-and-restore methods to the client-side interface that could be
used to deal with this.
Right now we simply don't have any real use cases anyway where we want
to run a profiler on top of a reboot test where the profiler requires
special handling after a reboot. Until we actually have an example of
that to work with, trying to implement support for that situation
may just be overdesigning things anyway.
Risk: Medium
Visibility: Server-side profilers will be restarted after a reboot
during a test.
Signed-off-by: John Admanski <jadmanski@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@2526 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index b7695ba..f85213f 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -670,6 +670,43 @@
return arch
+def merge_trees(src, dest):
+ """
+ Merges a source directory tree at 'src' into a destination tree at
+ 'dest'. If a path is a file in both trees than the file in the source
+ tree is APPENDED to the one in the destination tree. If a path is
+ a directory in both trees then the directories are recursively merged
+ with this function. In any other case, the function will skip the
+ paths that cannot be merged (instead of failing).
+ """
+ if not os.path.exists(src):
+ return # exists only in dest
+ elif not os.path.exists(dest):
+ if os.path.isfile(src):
+ shutil.copy2(src, dest) # file only in src
+ else:
+ shutil.copytree(src, dest, symlinks=True) # dir only in src
+ return
+ elif os.path.isfile(src) and os.path.isfile(dest):
+ # src & dest are files in both trees, append src to dest
+ destfile = open(dest, "a")
+ try:
+ srcfile = open(src)
+ try:
+ destfile.write(srcfile.read())
+ finally:
+ srcfile.close()
+ finally:
+ destfile.close()
+ elif os.path.isdir(src) and os.path.isdir(dest):
+ # src & dest are directories in both trees, so recursively merge
+ for name in os.listdir(src):
+ merge_trees(os.path.join(src, name), os.path.join(dest, name))
+ else:
+ # src & dest both exist, but are incompatible
+ return
+
+
class CmdResult(object):
"""
Command execution result.