[ABRT PATCH v3] rewrite shell script for moving vmcores into python closes #676

Richard Marko rmarko at redhat.com
Thu Aug 8 14:31:33 UTC 2013


Thanks! Pushed.

On 08/08/2013 04:19 PM, Petr Kubat wrote:
> Signed-off-by: Petr Kubat <pkubat at redhat.com>
> ---
>  src/hooks/Makefile.am               |   4 +-
>  src/hooks/abrt-harvest-vmcore.in    |  82 ----------------
>  src/hooks/abrt_harvest_vmcore.py.in | 181 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 183 insertions(+), 84 deletions(-)
>  delete mode 100644 src/hooks/abrt-harvest-vmcore.in
>  create mode 100644 src/hooks/abrt_harvest_vmcore.py.in
>
> diff --git a/src/hooks/Makefile.am b/src/hooks/Makefile.am
> index de97a88..dfa791c 100644
> --- a/src/hooks/Makefile.am
> +++ b/src/hooks/Makefile.am
> @@ -60,7 +60,7 @@ pyhook_PYTHON = \
>  
>  EXTRA_DIST = abrt_exception_handler.py.in \
>  	abrt-install-ccpp-hook.in \
> -	abrt-harvest-vmcore.in \
> +	abrt_harvest_vmcore.py.in \
>  	abrt-harvest-uefioops.in
>  
>  CLEANFILES := $(notdir $(wildcard *~)) $(notdir $(wildcard *\#)) $(notdir $(wildcard \.\#*)) $(notdir $(wildcard *.pyc)) $(man1_MANS)
> @@ -85,7 +85,7 @@ abrt-install-ccpp-hook: abrt-install-ccpp-hook.in
>  	    -e s,\@libexecdir\@,$(libexecdir),g \
>  		$< >$@
>  
> -abrt-harvest-vmcore: abrt-harvest-vmcore.in
> +abrt-harvest-vmcore: abrt_harvest_vmcore.py.in
>  	sed -e s,\@CONF_DIR\@,\$(CONF_DIR)\,g \
>  	    -e s,\@DEFAULT_DUMP_LOCATION\@,$(DEFAULT_DUMP_LOCATION),g \
>  		$< >$@
> diff --git a/src/hooks/abrt-harvest-vmcore.in b/src/hooks/abrt-harvest-vmcore.in
> deleted file mode 100644
> index a9ed1a2..0000000
> --- a/src/hooks/abrt-harvest-vmcore.in
> +++ /dev/null
> @@ -1,82 +0,0 @@
> -#!/bin/sh
> -#
> -# This script is meant to be run once at system startup after abrtd is up
> -# and running. It moves all vmcore directories in /var/crash
> -# (which are presumably created by kdump) to abrtd spool directory.
> -#
> -# The goal is to let abrtd notice and process them as new problem data dirs.
> -#
> -
> -cd /var/crash 2>/dev/null || exit 0
> -
> -# Wait for abrtd to start. Give it at least 1 second to initialize.
> -i=10
> -while ! pidof abrtd >/dev/null; do
> -	if test $((i--)) = 0; then
> -		exit 1
> -	fi
> -	sleep 1
> -done
> -sleep 1
> -
> -umask 077
> -
> -CopyVMcore=`sed -n '/^CopyVMcore[ \t]*=/ s/.*=[ \t]*//p' @CONF_DIR@/abrt-harvest-vmcore.conf 2>/dev/null`
> -ABRTDumpDir=`sed -n '/^DumpLocation[ \t]*=/ s/.*=[ \t]*//p' @CONF_DIR@/abrt.conf 2>/dev/null`
> -
> -if test -z "$ABRTDumpDir"; then
> -    ABRTDumpDir="@DEFAULT_DUMP_LOCATION@"
> -fi
> -
> -move_core=false
> -if test x"$CopyVMcore" = x"no" || test x"$CopyVMcore" = x"0"; then
> -	move_core=true
> -fi
> -
> -for d in *; do
> -	test -d "$d" || continue
> -	test -f "$d/vmcore" || continue
> -
> -	dst="$ABRTDumpDir/vmcore-$d"
> -
> -	# Did we already copy it last time we booted?
> -	test -d "$dst" && continue
> -	test -d "$dst.new" && 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.
> -	#
> -	# This is the efficient way:
> -	#mv -- "$d" "/var/tmp/abrt/vmcore-$d.new" || continue
> -	# ...and this is what selinux forces me to do
> -	# (otherwise files have wrong context and abrtd can't access them):
> -	cp -r --no-preserve=all -- "$d" "$dst.new" || {
> -		rm -rf -- "$dst.new"
> -		continue
> -	}
> -	$move_core && rm -rf -- "$d"
> -
> -	# Let abrtd know what type of problem it is:
> -	printf 'vmcore'            >"$dst.new/analyzer"
> -	printf 'vmcore'            >"$dst.new/type"
> -	printf 'kernel'            >"$dst.new/component"
> -	printf '%s' "`date '+%s'`" >"$dst.new/time"
> -	printf '%s' "`uname -i`"   >"$dst.new/architecture"
> -	cp     "$dst.new/time"      "$dst.new/last_occurrence"
> -	printf '0'                 >"$dst.new/uid"
> -	# TODO: need to generate *real* UUID,
> -	# one which has a real chance of catching dups!
> -	# This one generates different hashes even for similar cores:
> -	printf '%s' "`sha1sum <"$dst.new/vmcore" | cut -d" " -f1`" >"$dst.new/uuid"
> -	cp /etc/system-release "$dst.new/os_release" || {
> -		cp /etc/redhat-release "$dst.new/os_release" || {
> -			cp /etc/SuSE-release "$dst.new/os_release"
> -		}
> -	}
> -	cp /etc/os-release "$dst.new/os_info"
> -
> -	chown -R 0:0 -- "$dst.new"
> -	chmod -R u+rwX,go-rwxst -- "$dst.new"
> -	mv -- "$dst.new" "$dst"
> -done
> diff --git a/src/hooks/abrt_harvest_vmcore.py.in b/src/hooks/abrt_harvest_vmcore.py.in
> new file mode 100644
> index 0000000..abdf895
> --- /dev/null
> +++ b/src/hooks/abrt_harvest_vmcore.py.in
> @@ -0,0 +1,181 @@
> +#!/usr/bin/python
> +"""
> + This script is meant to be run once at system startup after abrtd is up
> + and running. It moves all vmcore directories in /var/crash
> + (which are presumably created by kdump) to abrtd spool directory.
> +
> + The goal is to let abrtd notice and process them as new problem data dirs.
> +"""
> +
> +import os
> +import ConfigParser
> +import StringIO
> +import shutil
> +import time
> +import hashlib
> +
> +# Path to the vmcore directories
> +CORE_DIR = '/var/crash'
> +
> +
> +def write_to_file(path, content):
> +    """
> +    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)
> +
> +
> +def change_mode_rec(dest):
> +    """
> +    A simple function to recursively change file mode for a directory.
> +
> +    dest - path to the directory
> +    """
> +
> +    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)
> +
> +
> +def create_abrtd_info(dest):
> +    """
> +    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.
> +
> +    dest - path to the vmcore directory
> +    """
> +
> +    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'))
> +
> +
> +def harvest_vmcore():
> +    """
> +    This function moves vmcore directories from /var/crash to a dump dir.
> +
> +    The script also creates additional files used to tell abrt what kind of
> +    problem it is and creates an uuid from the vmcore using a sha1 hash
> +    function.
> +    """
> +
> +    if not os.path.exists('/etc/os-release'):
> +        exit(0)
> +
> +    # Wait for abrtd to start. Give it at least 1 second to initialize.
> +    for i in xrange(10):
> +        if i is 9:
> +            exit(1)
> +        elif os.system('pidof abrtd >/dev/null'):
> +            time.sleep(1)
> +        else:
> +            break
> +
> +    os.umask(077)
> +
> +    # Check abrt config files for copy/move settings and
> +    config = ConfigParser.ConfigParser()
> +    # We need to add a root section as ConfigParser doesn't know how to work
> +    # with config files without any sections
> +    with open('@CONF_DIR@/abrt-harvest-vmcore.conf') as conf_file:
> +        conf_str = '[section]\n' + conf_file.read()
> +    conf_fp = StringIO.StringIO(conf_str)
> +    config.readfp(conf_fp)
> +    copyvmcore = config.get('section', 'CopyVMcore')
> +    with open('@CONF_DIR@/abrt.conf') as conf_file:
> +        conf_str = '[section]\n' + conf_file.read()
> +    conf_fp = StringIO.StringIO(conf_str)
> +    config = ConfigParser.ConfigParser()
> +    config.readfp(conf_fp)
> +    try:
> +        abrtdumpdir = config.get('section', 'DumpLocation')
> +    except ConfigParser.NoOptionError:
> +        abrtdumpdir = '@DEFAULT_DUMP_LOCATION@'
> +
> +    # Go through all directories in /var/crash
> +    for cfile in os.listdir(CORE_DIR):
> +        f_full = os.path.join(CORE_DIR, cfile)
> +        if not os.path.isdir(f_full):
> +            continue
> +        files = [ff for ff in os.listdir(f_full)
> +                 if os.path.isfile(os.path.join(f_full, ff))]
> +        if 'vmcore' not in files:
> +            continue
> +
> +        destdir = os.path.join(abrtdumpdir, ('vmcore-' + cfile))
> +        destdirnew = destdir + '.new'
> +        # Did we already copy it last time we booted?
> +        if os.path.isdir(destdir):
> +            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.
> +        shutil.copytree(f_full, destdirnew)
> +        if copyvmcore == 'no':
> +            shutil.rmtree(f_full)
> +
> +        # Let abrtd know what type of problem it is:
> +        create_abrtd_info(destdirnew)
> +
> +        # chown -R 0:0
> +        change_owner_rec(destdirnew)
> +        # chmod -R u+rwX,go-rwxst
> +        change_mode_rec(destdirnew)
> +
> +        # Get rid of  the .new suffix
> +        shutil.move(destdirnew, destdir)
> +
> +
> +if __name__ == '__main__':
> +    harvest_vmcore()


-- 
Richard Marko



More information about the Crash-catcher mailing list