From 3f8c7bd84c33a2281857becaf6e177d74de1da42 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Mon, 8 Jun 2015 19:39:24 +0200 Subject: [PATCH] vmcore: use libreport dd API in the harvestor The dd API ensure correct permissions and owner. Signed-off-by: Jakub Filak --- src/hooks/abrt_harvest_vmcore.py.in | 155 ++++++++++++++---------------------- 1 file changed, 59 insertions(+), 96 deletions(-) diff --git a/src/hooks/abrt_harvest_vmcore.py.in b/src/hooks/abrt_harvest_vmcore.py.in index 990a2b1..c85db8c 100644 --- a/src/hooks/abrt_harvest_vmcore.py.in +++ b/src/hooks/abrt_harvest_vmcore.py.in @@ -16,6 +16,7 @@ import augeas from subprocess import Popen, PIPE import problem +import report def errx(message, code=1): @@ -105,85 +106,39 @@ def parse_kdump(): return path -def write_to_file(path, content): +def create_abrtd_info(dest, uuid): """ - A function for writing into a file - - path - path to the file - content - content to write into the file - """ - - with open(path, 'w') as wfile: - wfile.write(content) - - -def change_owner_rec(dest): - """ - A simple function to recursively change file mode for a directory. - - dest - path to the directory - """ - - os.chown(dest, 0, 0) - for root, dirs, files in os.walk(dest): - for i in dirs: - os.chown(os.path.join(root, i), 0, 0) - for i in files: - os.chown(os.path.join(root, i), 0, 0) - + A simple function to write important information for the abrt daemon into + the vmcore directory to let abrtd know what kind of problem it is. -def change_mode_rec(dest): + dest - path to the vmcore directory + uuid - unique indentifier of the vmcore """ - A simple function to recursively change file mode for a directory. - dest - path to the directory - """ + dd = report.dd_create(dest, 0) + if dd is None: + return None - os.chmod(dest, 0700) - for root, dirs, files in os.walk(dest): - for i in dirs: - os.chmod(os.path.join(root, i), 0700) - for i in files: - os.chmod(os.path.join(root, i), 0600) + dd.create_basic_files(0) + dd.save_text('analyzer', 'abrt-vmcore') + dd.save_text('type', 'vmcore') + dd.save_text('component', 'kernel') + dd.save_text('uuid', uuid) + return dd -def create_abrtd_info(dest): +def delete_and_close(dd, dd_dirname): """ - A simple function to write important information for the abrt daemon into - the vmcore directory to let abrtd know what kind of problem it is. + Deletes the given dump directory and closes it. - dest - path to the vmcore directory + dd - dump directory object + dd_dirname - full path to dump directory """ + if not dd.delete() == 0: + sys.stderr.write("Unable to delete '%s'\n" % (dd_dirname)) + return - write_to_file(os.path.join(dest, 'analyzer'), 'vmcore') - write_to_file(os.path.join(dest, 'type'), 'vmcore') - write_to_file(os.path.join(dest, 'component'), 'kernel') - write_to_file(os.path.join(dest, 'time'), str(time.time()).split('.')[0]) - shutil.copy(os.path.join(dest, 'time'), - os.path.join(dest, 'last_occurrence')) - write_to_file(os.path.join(dest, 'architecture'), os.uname()[4]) - write_to_file(os.path.join(dest, 'uid'), '0') - - # TODO: need to generate *real* UUID, - # one which has a real chance of catching dups! - # This one generates different hashes even for similar cores: - hashobj = hashlib.sha1() - # Iterate over the file a line at a time in order to not load the whole - # vmcore file - with open(os.path.join(dest, 'vmcore'), 'r') as corefile: - for line in corefile: - hashobj.update(line) - write_to_file(os.path.join(dest, 'uuid'), hashobj.hexdigest()) - - # Write os info into the vmcore directory - if os.path.exists('/etc/system-release'): - shutil.copy('/etc/system-release', os.path.join(dest, 'os_release')) - elif os.path.exists('/etc/redhat-release'): - shutil.copy('/etc/redhat-release', os.path.join(dest, 'os_release')) - elif os.path.exists('/etc/SuSE-release'): - shutil.copy('/etc/SuSE-release', os.path.join(dest, 'os_release')) - if os.path.exists('/etc/os-release'): - shutil.copy('/etc/os-release', os.path.join(dest, 'os_info')) + dd.close() def harvest_vmcore(): @@ -212,8 +167,6 @@ def harvest_vmcore(): else: break - os.umask(077) - # Check abrt config files for copy/move settings and try: conf = problem.load_plugin_conf_file("vmcore.conf") @@ -257,6 +210,8 @@ def harvest_vmcore(): "VMCore dir '%s' doesn't contain 'vmcore' file.\n" % f_full) continue + # We use .new suffix - we must make sure abrtd doesn't try + # to process partially-copied directory. destdir = os.path.join(abrtdumpdir, ('vmcore-' + cfile)) destdirnew = destdir + '.new' # Did we already copy it last time we booted? @@ -264,38 +219,46 @@ def harvest_vmcore(): continue if os.path.isdir(destdirnew): continue - # Copy/move vmcore directory to abrt spool dir. - # We use .new suffix - we must make sure abrtd doesn't try - # to process partially-copied directory. - - try: - shutil.copytree(f_full, destdirnew) - except (OSError, shutil.Error): - sys.stderr.write("Unable to copy '%s' to '%s'. Skipping\n" - % (f_full, destdirnew)) - # delete .new dir so we don't create mess - shutil.rmtree(destdirnew) + # TODO: need to generate *real* UUID, + # one which has a real chance of catching dups! + # This one generates different hashes even for similar cores: + hashobj = hashlib.sha1() + # Iterate over the file a line at a time in order to not load the whole + # vmcore file + with open(os.path.join(f_full, 'vmcore'), 'r') as corefile: + for line in corefile: + hashobj.update(line) + + dd = create_abrtd_info(destdirnew, hashobj.hexdigest()) + if dd is None: + sys.stderr.write("Unable to create problem directory info") continue - try: - # Let abrtd know what type of problem it is: - create_abrtd_info(destdirnew) - except EnvironmentError as ex: - sys.stderr.write("Unable to create problem directory info: " + str(ex)) + # Copy/move vmcore directory to abrt spool dir. + for name in os.listdir(f_full): + full_name = os.path.join(f_full, name) + + # Skip sub-directories, abrt ignores them in its processing anyway + if not os.path.isfile(full_name): + continue + try: - shutil.rmtree(destdirnew) - except Exception as ex: - sys.stderr.write("Unable to remove incomplete problem directory: " + str(ex)) - continue + if not dd.copy_file(name, full_name) == 0: + raise OSError + except (OSError, shutil.Error): + sys.stderr.write("Unable to copy '%s' to '%s'. Skipping\n" + % (full_name, destdirnew)) + delete_and_close(dd) + continue - # chown -R 0:0 - change_owner_rec(destdirnew) - # chmod -R u+rwX,go-rwxst - change_mode_rec(destdirnew) + # Get rid of the .new suffix + if not dd.rename(destdir) == 0: + sys.stderr.write("Unable to rename '%s' to '%s'. Skipping\n" % (destdirnew, destdir)) + delete_and_close(dd) + continue - # Get rid of the .new suffix - shutil.move(destdirnew, destdir) + dd.close() if copyvmcore == 'no': try: -- 1.8.3.1