#!/usr/local/bin/python

# Copyright C 2002-2003 by Isilon Systems, Inc. All rights not expressly
# granted herein are reserved.
# Created in the United States of America.
# 
# This digital media is protected by U.S. and international copyright and
# intellectual property laws. Unless otherwise specified, all information
# and screens appearing as part of this digital medium, including
# software, services, documents, text, images, icons, and logos design;
# the selection, assembly, arrangement, and design thereof; and the code
# that enables its presentation, are the sole property of Isilon Systems,
# Inc.
# 
# Except as otherwise required by applicable law, no part of any
# copyrighted material may be reproduced, modified, translated,
# distributed, published, or transmitted by any means, electronic or
# mechanical, for any purpose, without the prior written consent of Isilon
# Systems. 
#  
# Isilon and Isilon Systems are registered trademarks of Isilon Systems,
# Inc.  Legion is a trademark of Isilon Systems, Inc.  All other
# trademarks and registered trademarks are the property of their
# respective holders.

# PROVIDE: isi_stackdumps
# REQUIRE: isi_bootdisk_init isi_hal_init
# BEFORE:  isi_hw_init

import sys
import isi.hw.hal as hal
import isi.sys.bootdisk as bootdisk

def determine_stackdumpdev():
    mirrored_dump_dev = \
        bootdisk.get_provider_dev(bootdisk.PROVIDER_ID_KERNELSDUMP)
    default_list = [ "/dev/ad0s1b", "/dev/ad2s1b", "/dev/ad1s1b",
                     "/dev/ad3s1b", mirrored_dump_dev ]
    mirrored_only_list = [ mirrored_dump_dev ]

    if ((hal.isAcceleratorClass() and hal.isXSeries()) or
        bootdisk.current_system_is_geom() or bootdisk.future_system_is_geom()):
        temp_list = mirrored_only_list
    else:
        temp_list = default_list

    for stack_sel_dump_device in temp_list:
        try:
            open(stack_sel_dump_device)
            return stack_sel_dump_device
        except:
            pass

MAXSTACKSIZE=128 * 1024

STACKDUMPDEV=determine_stackdumpdev()

if not STACKDUMPDEV:
    print "isi_stackdumps:  No dump location found.  Stacks will not be preserved."
    sys.exit(1)

DONGLEPARTITIONSIZE=5 * 1024 * 2 * 512 # = 5 MB

DONGLEPANICDUMPDEV=STACKDUMPDEV

DONGLEPANICOFFSET=512 * 1024 + 100 * 1024 # = SEL OFFSET + SEL SIZE

# format to print date/time in
TIME_FMT = "%04d_%02d_%02d_%02d_%02d_%02d"

import os
import os.path
import time
import glob

def preserve_stack() :
    msg = "isi_stackdumps:  "
    infile = open(STACKDUMPDEV, "r")
    dumps = infile.read(MAXSTACKSIZE)
    data = None
    pos = dumps.find("\0")
    if -1 != pos:
        data = dumps[:pos]

    if data:
        outfile = open("/var/log/messages", "ab")
        outfile.write(
            """\
Recovered following crash-dump matter from previous boot
--------------------------------------------------------
""")
            
        outfile.write(data)
        outfile.close()
        msg += "recovered stack.  "
    infile.close()
    outfile = open(STACKDUMPDEV, "wb")
    data = '\0' + dumps[1:]
    outfile.write(data)

    os.system("/sbin/sdumpon " + STACKDUMPDEV)
    outfile.close()
    msg+= "dumping on device " + STACKDUMPDEV + "."
    print msg

def preserve_panic_dump() :
    msg = "isi_panic_dump:  "
    infile = open(DONGLEPANICDUMPDEV, "r")
    infile.seek(DONGLEPANICOFFSET, 0)
    dumps = infile.read(DONGLEPARTITIONSIZE - DONGLEPANICOFFSET - 95 * 512)
    data = None
    pos = dumps.find("\0")
    if -1 != pos:
        data = dumps[:pos]
    else:
        data = dumps

    if data:
        dumpfiles = glob.glob("/var/log/isi_dongle_panic_dump.log.*")
        dumpfiles = filter(os.path.isfile, dumpfiles)
        if len(dumpfiles) >= 10:
            oldestfilename = ''
            oldestfiletime = 0
            for currentfilename in dumpfiles:
                currentfiletime = os.path.getmtime(currentfilename)
                if oldestfiletime == 0 or oldestfiletime > currentfiletime:
                    oldestfilename = currentfilename
                    oldestfiletime = currentfiletime
            if oldestfiletime > 0:
                os.remove(oldestfilename)
        now = time.localtime()
        timestamp = TIME_FMT % (now.tm_year, now.tm_mon, now.tm_mday, \
                                now.tm_hour, now.tm_min, now.tm_sec)
        outfile = open("/var/log/isi_dongle_panic_dump.log." + timestamp , "w")
        outfile.write(
            """\
Recovered following panic debug info from previous boot
-------------------------------------------------------
""")
        outfile.write(data)
        outfile.close()
        msg += "recovered dongle panic dump.  "
    infile.close()
    outfile = open(DONGLEPANICDUMPDEV, "wb")
    data = '\0' + dumps[1:]
    outfile.seek(DONGLEPANICOFFSET, 0)
    outfile.write(data)

    outfile.close()
    print msg

preserve_stack()
preserve_panic_dump()
