Results 1 to 14 of 14

Thread: Scripted upgrades

  1. #1
    Join Date
    May 2004
    Posts
    253

    Scripted upgrades

    On another thread, the subject of scripted upgrades came up. I thought I'd start a thread specific to this, and describe my own setup.

    First, both my TiVos (S2 and S3) have modified proms, so I don't do any kernel monte shenanigans (just need to nuke the initrd image inside a new kernel). I also have a non-standard partition layout. This is what's on my Series3:

    Code:
    tivo3:~$ pdisk -l /dev/hda
    
    stat: mode = 060660, type=Block
    size = 0, blocks = 0
    HDIO_GETGEO: heads=255, sectors=63, cylinders=51329, start=0,  total=824600385
    Partition map (with 512 byte blocks) on '/dev/hda'
     #:                type name                         length   base       ( size )
     1: Apple_partition_map Apple                            63 @ 1          (  31.5K)
     2:                Ext2 hack                        1048576 @ 64         ( 512.0M)
     3:               Image Kernel 1                       8192 @ 1048640    (   4.0M)
     4:                Ext2 Root 1                       524288 @ 1056832    ( 256.0M)
     5:                Ext2 bkup                        1048576 @ 1581120    ( 512.0M)
     6:               Image Kernel 2                       8192 @ 2629696    (   4.0M)
     7:                Ext2 Root 2                       524288 @ 2637888    ( 256.0M)
     8:                Swap Linux swap                   262144 @ 3162176    ( 128.0M)
     9:                Ext2 /var                        1048576 @ 3424320    ( 512.0M)
    10:                 MFS MFS application region       589824 @ 4472896    ( 288.0M)
    11:                 MFS MFS media region          216747657 @ 5062720    ( 103.3G)
    12:                 MFS MFS application region 2     589824 @ 221810377  ( 288.0M)
    13:                 MFS MFS media region 2        268618405 @ 222400201  ( 128.0G)
    14:                 MFS MFS App by Winmfs              2048 @ 491018606  (   1.0M)
    15:                 MFS MFS Media by Winmfs      2147471360 @ 491020654  (1023.9G)
    This was done for a couple of reasons. Mainly, I wanted my hacks to persist, automatically, if /var got rebuilt. Starting with the Series3, TiVo started making the root partitions larger, but on my S2, I increased them from 128 to 256 MiB. I used partitions 2 and 5 (not used by TiVo Software, usually labelled "bootstrap") to store my hacks partition, and a backup of it. That's the important difference from a stock partition map - having a larger partition 2 allows hacks to be stored separately from the var partition. This hacks partition just gets mounted to /var/hack on boot.

    This was done by creating a partition map manually on a new (larger) disk. The partitions from the original drive were then either dd'd over (in the case of MFS and identically sized ext2 partitions), or with a tar copy (e.g. something like tar cf - * | ( cd /target; tar xfp -) ) to a newly created, larger partition.

    After getting all the partitions over from the original drive, and verifying that the new one booted and worked, I did a simple mfsadd from WinMFS to make the additional drive space availble to MFS.

    Hacks start with /etc/rc.d/rc.sysinit.author. I do several things here, and it will automatically set up "virgin" var and root partitions. The TiVo can rebuild var whenever it wants (typically if something goes wrong somewhere) and on a software upgrade, root starts afresh.

    This part first checks to make sure my hacks directory exists. If not, /var got rebuilt, and I need to fix that by creating the mount point (/var/hack), and then mounting my hacks partition (/dev/hda2 as described above). I also need to make a couple of other directories inside /var :
    Code:
    #!/bin/bash
    echo "$(date +"%d %b %T") Starting rc.sysinit.author" >> /var/log/hack
    
    #Make sure our hacks are always around...
    if [ -d /var/hack ]
    then
     echo "$(date +"%d %b %T") /var/hack OK." >> /var/log/hack
    else
     echo "$(date +"%d %b %T") /var/hack mount point missing (/var rebuilt), recreating." >> /var/log/hack
     mkdir -p /var/hack
    fi
    
    echo "$(date +"%d %b %T") Mounting /dev/hda2 at /var/hack" >> /var/log/hack
    mount /dev/hda2 /var/hack
    mkdir -p /var/slices
    mkdir -p /var/spool/cron
    There are a number of files which get added or replaced when hacking a TiVo. I keep new or modified copies in my hack partition (in /var/hack/etc/rootfiles/) So I also check to make sure this has been done:
    Code:
    if [ ! -f /etc/group.original ] || [ ! -f /etc/passwd.original ] || \
       [ ! -f /etc/termcap.original ] || [ ! -f /sbin/iptables.original ]
       then
         echo "$(date +"%d %b %T") Fixing root files" >> /var/log/hack
         /bin/mount -o remount,rw /
    #if we haven't already, save originals and replace files
         [ -f /etc/group ] || /var/hack/bin/touch /etc/group
         [ -f /etc/group.original ] || mv /etc/group /etc/group.original
         [ -f /etc/group ] || cp /var/hack/etc/rootfiles/group /etc/group
         [ -f /etc/passwd ] || /var/hack/bin/touch /etc/passwd
         [ -f /etc/passwd.original ] || mv /etc/passwd /etc/passwd.original
         [ -f /etc/passwd ] || cp /var/hack/etc/rootfiles/passwd /etc/passwd
         [ -f /etc/termcap.original ] || mv /etc/termcap /etc/termcap.original
         [ -f /etc/termcap ] || cp /var/hack/etc/rootfiles/termcap /etc/termcap
         [ -f /etc/terminfo/v/vt100 ] || mkdir -p /etc/terminfo/v ; cp /var/hack/etc/rootfiles/vt100 /etc/terminfo/v/vt100
         [ -f /etc/profile.original ] || mv /etc/profile /etc/profile.original
         [ -f /etc/profile ] || cp /var/hack/etc/rootfiles/profile /etc/profile
         [ -f /sbin/iptables.original ] ||  /etc/netfilter-disable
         [ -f /sbin/iptables.original ] || mv /sbin/iptables /sbin/iptables.original
         [ -f /sbin/iptables ] || cp /var/hack/etc/rootfiles/iptables /sbin/iptables
    
         sync
         /bin/mount -o remount,ro /
       else
         echo "$(date +"%d %b %T") Root files OK" >> /var/log/hack
    fi
    Then, I make sure a symlink to my cron jobs is present, set up the environment, and start my services:
    Code:
    #if directory doesn't exist, make the symlink
     [ -d /var/spool/cron/crontabs ] || ln -s /var/hack/etc/rootfiles/crontabs /var/spool/cron/crontabs
    #create link so uptime works
     ln -s /proc/uptime /var/run/utmp
    
    #Environment Variables
    export PATH=/var/hack/bin.override:/sbin:/bin:/tivobin:/tvbin:/var/hack/bin:/var/hack/mfs_bin:.
    export TIVO_ROOT=
    export MFS_DEVICE=/dev/hda10
    export IGNOREEOF=1000
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib/modules
    export VISUAL='/var/hack/bin/joe'
    export HOME=/var/hack
    export TERM=vt100
    export TERMINFO=/etc/terminfo
    export PS1='\h:\w$ '
    
    echo "$(date +"%d %b %T") Starting hack services" >> /var/log/hack
    
    #Start BASH on serial (can't use with serial cable box control)
    if [ "$sercon" = "true" -o "$handcraft" = "true" ]; then
         /bin/bash </dev/ttyS2 &>/dev/ttyS2 &
    fi
    
    #Setup HOSTNAME
    /var/hack/bin/hostname tivo
    
    #Load utility services
    tnlited 23 /bin/bash -login &
    /var/hack/bin/tivoftpd &
    /var/hack/bin/crond -l 9
    #/var/hack/mfs_bin/tserver &
    /var/hack/mfs_bin/vserver &
    /var/hack/TivoWebPlus/tivoweb
    /bin/hdparm -c1 -a16 /dev/hda
    My crontab regularly syncs time with my NTP server (much more accurate than what gets set by a call), and does hard links for files which get downloaded (so I capture slices for new sofware):
    Code:
    55 */4 * * *    echo $(ntpdate 192.168.168.16) >> /var/log/hack
    * * * * *       ln /var/packages/*.slice.* /var/slices/
    All of the the above basically ensures that my system can recover if things get rebuilt.

    Next post will describe how an upgrade happens...
    Last edited by mike_s; 04-03-2010 at 03:09 PM.

  2. #2
    Join Date
    May 2004
    Posts
    253

    Part 2

    Now, I'll describe the script I run to do an upgrade. /tvbin/installSw.itcl should be neutered (replace reboot with exit 0) and run, tivoapppatches.tcl should contain the patches for the new software version, then I run this:

    It starts out with some basic housekeeping. nullinitrd.gz is the empty initrd to put in a new kernel.:
    Code:
    #!/bin/bash
    nullinitrd="/var/hack/null-initrd.gz"
    rfpath="/var/hack/etc/rootfiles"
    nrpath="/var/hack/mnt"
    curpath="/var/hack/current.originals"
    oldpath="/var/hack/old.originals"
    bv="$nrpath/etc/build-version"
    
    function quit {
      echo
      echo "$2 Quitting with exit code $1"
      exit $1
      }
    
    echo
    echo "This script should only be run after running installSw.itcl"
    echo "It will identify the new kernel and root partitions, then killinitrd"
    echo "the new kernel and copy necessary files to the new root for hacks."
    echo "It also backs up any original files it modifies."
    echo
    echo
    Then, do some sanity checks:
    Code:
    echo "Getting partition info..."
    bootpage -p /dev/hda
    [ $? -eq "0" ] || quit $? "Problem with bootpage."
    
    rootpart=$(bootpage -p /dev/hda)
    rootpart=${rootpart:5:9}
    kernpart=${rootpart:0:8}$(bootpage -b /dev/hda)
    
    echo "New root is $rootpart, new kernel is $kernpart (one less)"
    echo "Enter \"Yes\" if this is correct, anthing else to exit."
    read confirm
    [ "$confirm" == "Yes" ] || quit 1 "User stop."
    Now, mount the new root, get the version number, create someplace to store backup files, grab the new kernel image, and killinitrd it:
    Code:
    echo -n "Mounting new root at $nrpath..."
    mkdir -p $nrpath
    [ $? -eq "0" ] || quit $? "Problem making directory $nrpath."
    mount $rootpart $nrpath
    [ $? -eq "0" ] || quit $? "Problem with \"mount $rootpart $nrpath\"."
    
    echo "making directory for originals..."
    curpath=/var/hack/$(tail -n 1 $bv | awk '{print $2}').originals
    [ ! -f $curpath ] || quit 1 "Problem, $curpath already exists."
    mkdir $curpath
    
    echo "copying kernel to $curpath/"
    dd if=$kernpart of=$curpath/kernel.killed bs=1024k
    [ $? -eq "0" ] || quit $? "Problem with dd from $kernpart."
    
    echo -n "Doing killinitrd..."
    killinitrd $curpath/kernel.killed $nullinitrd $curpath/kernel.original
    #no check for now, doesn't return 0 properly
    #[ $? -eq "0" ] || quit $? "Problem with killinitrd."
    echo "modified kernel is $curpath/kernel.killed"
    echo -n "Replacing kernel on $kernpart..."
    dd if=$curpath/kernel.killed of=$kernpart bs=1024k
    [ $? -eq "0" ] || quit $? "Problem with dd to $kernpart."
    echo "done."
    Now, put my files in place and backup the originals:
    Code:
    echo -n "Copying rc.sysinit.author, group, passwd, termcap, terminfo, profile, iptables to new root..."
    cp $rfpath/rc.sysinit.author $nrpath/etc/rc.d/rc.sysinit.author
    [ $? -eq "0" ] || quit $? "Problem copying rc.sysinit.author"
     [ -f $nrpath/etc/group ] || /var/hack/bin/touch $nrpath/etc/group
     [ -f $nrpath/etc/group.original ] || mv $nrpath/etc/group $nrpath/etc/group.original
     [ -f $nrpath/etc/group ] || cp $rfpath/group $nrpath/etc/group
     [ -f $nrpath/etc/passwd ] || /var/hack/bin/touch $nrpath/etc/passwd
     [ -f $nrpath/etc/passwd.original ] || mv $nrpath/etc/passwd $nrpath/etc/passwd.original
     [ -f $nrpath/etc/passwd ] || cp $rfpath/passwd $nrpath/etc/passwd
     [ -f $nrpath/etc/termcap.original ] || mv $nrpath/etc/termcap $nrpath/etc/termcap.original
     [ -f $nrpath/etc/termcap ] || cp $rfpath/termcap $nrpath/etc/termcap
     [ -f $nrpath/etc/terminfo/v/vt100 ] || mkdir -p $nrpath/etc/terminfo/v ; cp $rfpath/vt100 $nrpath/etc/terminfo/v/vt100
     [ -f $nrpath/etc/profile.original ] || mv $nrpath/etc/profile $nrpath/etc/profile.original
     [ -f $nrpath/etc/profile ] || cp $rfpath/profile $nrpath/etc/profile
     [ -f $nrpath/sbin/iptables.original ] || mv $nrpath/sbin/iptables $nrpath/sbin/iptables.original
     [ -f $nrpath/sbin/iptables ] || cp $rfpath/iptables $nrpath/sbin/iptables
     sync
    echo "done. Results:"
    ls -la $nrpath/etc/rc.d/rc.sysinit.author $nrpath/etc/group* $nrpath/etc/passwd* \
           $nrpath/etc/termcap* $nrpath/etc/terminfo/v/* $nrpath/etc/profile* $nrpath/sbin/iptables*
    echo -n "Backing up originals to $curpath..."
    cp $nrpath/etc/*original $curpath/
    [ $? -eq "0" ] || quit $? "Problem copying from $nrpath/etc/*original to $curpath."
    cp $nrpath/sbin/*original $curpath/
    [ $? -eq "0" ] || quit $? "Problem copying from $nrpath/sbin/*original to $curpath."
    cp $nrpath/tvbin/tivoapp $curpath/tivoapp.original
    [ $? -eq "0" ] || quit $? "Problem copying $nrpath/tvbin/tivoapp to $curpath/tivoapp.original."
    echo "done. Results:"
    ls -la $curpath/*original
    OK, now it's time to patch tivoapp using tvapppatch.tcl, and neuter the new installSw.itcl in prep for the next upgrade.
    Code:
    echo "Attempting to patch tivoapp..."
    echo "tvapppatch.tcl -v $(tail -n 1 $bv | awk '{print $2}') -t $nrpath/tvbin/tivoapp -confirm no"
    tvapppatch.tcl -v $(tail -n 1 $bv | awk '{print $2}') -t $nrpath/tvbin/tivoapp -confirm no
    [ $? -eq "0" ] || quit $? "Problem with patching tivoapp."
    
    echo "Attempting to patch installSw.itcl to remove reboot..."
    echo "sed -i 's/reboot/exit 0/' $nrpath/tvbin/installSw.itcl"
    sed -i 's/reboot/exit 0/' $nrpath/tvbin/installSw.itcl
    [ $? -eq "0" ] || quit $? "Problem with patching installSw.itcl."
    
    echo -n "Umounting new root..."
    umount $nrpath
    [ $? -eq "0" ] || quit $? "Problem umounting $nrpath"
    echo "done."
    echo "Original files copied into $curpath. Reboot to use new system."
    So, the 5 minute process is:
    1)get a new update
    2)update tvapppatches.tcl with new patches
    3)run /tvbin/installSw.itcl
    4)run postinstall (what I named this script)

    Th.th.th.th.that's all, folks! All ready to be rebooted.

    Oh, the cron job I mentioned will leave the slices sitting in /var/slices, so I manually back those up, too.

    I haven't bothered rewriting bufferhack so I can do that on a specified tivoapp, so that requires a second reboot.
    Last edited by mike_s; 04-03-2010 at 02:11 PM.

  3. #3
    Join Date
    Jan 2004
    Location
    n.h. usa
    Posts
    955
    interesting i dont bother nuking the kernel .. i just keep a copy of the neutered kernel an dd it back to partition 3 and 6 after a upgrade.. it seems easier..

  4. #4
    Join Date
    May 2004
    Posts
    253
    You're assuming that upgrades will always run properly with an earlier kernel. That's usually been the case, but it's definitely not guaranteed.

  5. #5
    Join Date
    Dec 2004
    Posts
    831
    Quote Originally Posted by mike_s View Post
    I also have a non-standard partition layout. This is what's on my Series3:
    OK, that all makes sense. I would definitely like to consider making similar changes to at least 1 of my S3 TiVos. There may be a little problem, however. That TiVo in particular has a 1.5T drive that was created by Win_MFS from a pair of smaller drives. I don't have a partition map handy, but I believe Win_MFS created the largest possible partition sizes - at least for the MFS regions - accessible by an unhacked S3 system. I don't recall exactly the nature of he limitation on an unhacked S3, though. Is the limit based strictly on the MFS partition sizes, or is it the total size of all the partitions put together (perhaps the highest sector number)? If the former, then it should be no big deal creating larger kernel, root, var, and backup (hack) partitions. If the latter, then this is going to take some wriggling to accomplish.
    Having trouble with TyTool? Try TyTool Documentation
    Need to hack an S3 / THD? Try S3 Hacking Script

  6. #6
    Join Date
    Dec 2004
    Posts
    831
    The answer to my question, helpfully provided by Jamie, is, "As long as the total size of the partitions on the disk does not exceed 2.2T, we're OK." Since the drive in question was 1.5T, with over 400G free space, there was no issue. I used a modified version of mike_s' scripted upgrade methods above to create a TiVo that can be upgraded insitu without losing the hacks. So far, it is looking good.
    Having trouble with TyTool? Try TyTool Documentation
    Need to hack an S3 / THD? Try S3 Hacking Script

  7. #7
    Join Date
    Dec 2004
    Posts
    831
    Thanks mike_s, for posting this most helpful guide. I have now hacked all three of my TiVos for scripted upgrades. A few minutes ago, one of my TiVos received the udate from 11.0k-E1 to 11.0k-01, and I applied a slightly modified version of your scripts to upgrade the TiVo insitu. It went swimmingly. I do have a couple of questions, however.

    1. I had expected the old release to evaporate after the upgrade, but inspection shows the old release to still be on the system, with the new one showing active. When will the old release evaporate?

    2. One of your hacks is apparently VT-100 support for the xterm sessions. This requires the file /etc/terminfo/v/vt100. Where can I obtain this file?
    Having trouble with TyTool? Try TyTool Documentation
    Need to hack an S3 / THD? Try S3 Hacking Script

  8. #8
    Join Date
    May 2004
    Posts
    253
    I'm not sure how long before the old swSystem goes away. A few days, I think. Normal, nothing to worry about.

  9. #9
    Join Date
    Dec 2004
    Posts
    831
    Thanks for the file, Mike!

    Hmm. I'll have to add a bit of code to the upgrade test. Right now it is sending a pair of e-mails out every six hours, telling me that both TiVos need to be upgraded, when they both have already been upgraded. Oh, well. It won't be difficult to fix.
    Having trouble with TyTool? Try TyTool Documentation
    Need to hack an S3 / THD? Try S3 Hacking Script

  10. #10
    Join Date
    May 2007
    Posts
    456
    How do you stop the Tivo from syncing time during the call or do you worry about that?


    echo $(ntpdate 192.168.168.16) >> /var/log/hack

  11. #11
    Join Date
    Dec 2004
    Posts
    831
    I wouldn't worry about it.
    Having trouble with TyTool? Try TyTool Documentation
    Need to hack an S3 / THD? Try S3 Hacking Script

  12. #12
    Join Date
    Dec 2004
    Posts
    831
    I decided to post my changes to mike's scripts for comparison.
    Here is my postinstall, which has a version of my hack_tivoapp script incorporated into it:

    Code:
    #!/bin/bash
    nullinitrd="/var/hack/null-linuxrc.img.gz"
    rfpath="/var/hack/etc/rootfiles"
    nrpath="/var/hack/mnt"
    curpath="/var/hack/current.originals"
    oldpath="/var/hack/old.originals"
    bv="$nrpath/etc/build-version"
    
    function quit {
      echo
      echo "$2 Quitting with exit code $1"
      exit $1
      }
    
    echo
    echo "This script should only be run after running installSw.itcl"
    echo "It will identify the new kernel and root partitions, then killinitrd"
    echo "the new kernel and copy necessary files to the new root for hacks."
    echo "It also backs up any original files it modifies."
    echo
    echo
    echo "Getting partition info..."
    bootpage -p /dev/hda
    [ $? -eq "0" ] || quit $? "Problem with bootpage."
    
    rootpart=$(bootpage -p /dev/hda)
    rootpart=${rootpart:5:9}
    kernpart=${rootpart:0:8}$(bootpage -b /dev/hda)
    
    echo "New root is $rootpart, new kernel is $kernpart (one less)"
    echo "Enter \"Yes\" if this is correct, anthing else to exit."
    read confirm
    [ "$confirm" == "Yes" ] || quit 1 "User stop."
    echo -n "Mounting new root at $nrpath..."
    mkdir -p $nrpath
    [ $? -eq "0" ] || quit $? "Problem making directory $nrpath."
    mount $rootpart $nrpath
    [ $? -eq "0" ] || quit $? "Problem with \"mount $rootpart $nrpath\"."
    
    echo "making directory for originals..."
    curpath=/var/hack/$(tail -n 1 $bv | awk '{print $2}').originals
    [ ! -f $curpath ] || quit 1 "Problem, $curpath already exists."
    mkdir $curpath
    
    echo "copying kernel to $curpath/"
    dd if=$kernpart of=$curpath/kernel.killed bs=1024k
    [ $? -eq "0" ] || quit $? "Problem with dd from $kernpart."
    
    echo -n "Doing killinitrd..."
    replace_initrd.mips $curpath/kernel.killed $nullinitrd $curpath/kernel.original
    #no check for now, doesn't return 0 properly
    #[ $? -eq "0" ] || quit $? "Problem with killinitrd."
    echo "modified kernel is $curpath/kernel.killed"
    echo -n "Replacing kernel on $kernpart..."
    dd if=$curpath/kernel.killed of=$kernpart bs=1024k
    [ $? -eq "0" ] || quit $? "Problem with dd to $kernpart."
    echo "done."
    echo -n "Copying rc.sysinit.author, group, passwd, termcap, terminfo, profile, iptables to new root..."
    cp $rfpath/rc.sysinit.author $nrpath/etc/rc.d/rc.sysinit.author
    [ $? -eq "0" ] || quit $? "Problem copying rc.sysinit.author"
     [ -f $nrpath/etc/group ] || /var/hack/utils/touch $nrpath/etc/group
     [ -f $nrpath/etc/group.original ] || mv $nrpath/etc/group $nrpath/etc/group.original
     [ -f $nrpath/etc/group ] || cp $rfpath/group $nrpath/etc/group
     [ -f $nrpath/etc/passwd ] || /var/hack/utils/touch $nrpath/etc/passwd
     [ -f $nrpath/etc/passwd.original ] || mv $nrpath/etc/passwd $nrpath/etc/passwd.original
     [ -f $nrpath/etc/passwd ] || cp $rfpath/passwd $nrpath/etc/passwd
     [ -f $nrpath/etc/termcap.original ] || mv $nrpath/etc/termcap $nrpath/etc/termcap.original
     [ -f $nrpath/etc/termcap ] || cp $rfpath/termcap $nrpath/etc/termcap
    
     [ -f $nrpath/etc/profile.original ] || mv $nrpath/etc/profile $nrpath/etc/profile.original
     [ -f $nrpath/etc/profile ] || cp $rfpath/profile $nrpath/etc/profile
     [ -f $nrpath/sbin/iptables.original ] || mv $nrpath/sbin/iptables $nrpath/sbin/iptables.original
     [ -f $nrpath/sbin/iptables ] || cp $rfpath/iptables $nrpath/sbin/iptables
     sync
    echo "done. Results:"
    ls -la $nrpath/etc/rc.d/rc.sysinit.author $nrpath/etc/group* $nrpath/etc/passwd* \
           $nrpath/etc/termcap* $nrpath/etc/terminfo/v/* $nrpath/etc/profile* $nrpath/sbin/iptables*
    echo -n "Backing up originals to $curpath..."
    cp $nrpath/etc/*original $curpath/
    [ $? -eq "0" ] || quit $? "Problem copying from $nrpath/etc/*original to $curpath."
    cp $nrpath/sbin/*original $curpath/
    [ $? -eq "0" ] || quit $? "Problem copying from $nrpath/sbin/*original to $curpath."
    cp $nrpath/tvbin/tivoapp $curpath/tivoapp.original
    [ $? -eq "0" ] || quit $? "Problem copying $nrpath/tvbin/tivoapp to $curpath/tivoapp.original."
    echo "done. Results:"
    ls -la $curpath/*original
    
    echo "Attempting to patch tivoapp..."
    SaveFile=/var/hack/Saved_Apps/tivoapp.tmp
    Archive=/var/hack/Saved_Apps/tivoapp.sav
    HackFile=/var/hack/hacks.fil
    dstring=`date +%m-%d-%y`
    cd $nrpath/tvbin
    echo Creating temporary tivoapp
    cp tivoapp $SaveFile
    
    echo "Getting the hacking parameters for tivoapp..."
    Failure=1
    while read line
    do
            offset=$(( $(echo $line | cut -d" " -f1) - 0x00400000 ))
            oldword=$(echo $line | cut -d" " -f2 | sed s'/"//g')
            newword=$(echo $line | cut -d" " -f3 | sed s'/"//g')
            echo $oldword $newword $offset
            B1=$( dd if=tivoapp skip=$offset bs=1 count=4 2> /dev/null | hexdump | grep 0000000 | cut -c9-12 )
            B2=$( dd if=tivoapp skip=$offset bs=1 count=4 2> /dev/null | hexdump | grep 0000000 | cut -c14-17 )
            testword=$B1$B2
            echo $testword
            # Check to make sure the bytes match
            if [ "$testword" == "$oldword" ];
            then
                    echo Updating tivoapp $( echo $line | cut -d" " -f4)
                    # Convert the string into a 4 byte number expression
                    escape="\x"
                    H1=${newword:0:2}
                    H2=${newword:2:2}
                    H3=${newword:4:2}
                    H4=${newword:6:2}
                    newword=$escape$H1$escape$H2$escape$H3$escape$H4
                    echo -ne "$newword" | dd conv=notrunc of=$SaveFile bs=1 seek=$offset
    	elif [ "$testword" == "$newword" ];
    	then
    		echo Failed for $oldword $newword $offset
    		echo Tivoapp already has patch at this location.
    		exit 1
            else
                    echo Failed for $oldword $newword $offset Old value: $testword
                    test -e $SaveFile && rm $SaveFile
                    exit 1
            fi
    done < $HackFile
    echo Saving old tivoapp
    test -e $Archive.$dstring && mv $Archive.$dstring $Archive.$dstring.safety
    mv tivoapp $Archive.$dstring
    mv $SaveFile tivoapp
    echo
    echo Done!
    
    echo "Attempting to patch installSw.itcl to remove reboot..."
    echo "sed -i 's/reboot/exit 0/' $nrpath/tvbin/installSw.itcl"
    sed -i 's/reboot/exit 0/' $nrpath/tvbin/installSw.itcl
    [ $? -eq "0" ] || quit $? "Problem with patching installSw.itcl."
    
    echo -n "Umounting new root..."
    umount $nrpath
    [ $? -eq "0" ] || quit $? "Problem umounting $nrpath"
    echo "done."
    echo "Original files copied into $curpath. Reboot to use new system."
    Here is my rc.sysinit.author:

    Code:
    #!/bin/bash
    export PATH=./:.:/bin:/sbin:/tvbin:/var/hack/utils
    export LD_LIBRARY_PATH=/hack/lib/":"$LD_LIBRARY_PATH
    export HOME=/hack/root
    #export TERM=xterm
    export TIVO_ROOT=
    export MFS_DEVICE=/dev/hda10
    export IGNOREEOF=1000
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib/modules
    export HOME=/var/hack
    export TERM=vt100
    export TERMINFO=/etc/terminfo
    export PS1='\h:\w# '
    
    get_date(){                                                                     
    date +"%d %b %Y %T"                                                             
    } 
    
    hacklog=/var/log/hack.log
    utils=/var/hack/utils
    
    echo "--------------------------------------------" $hacklog
    echo "$(get_date) Starting rc.sysinit.author" >> $hacklog
    
    #Make sure our hacks are always around...
    if [ -d /var/hack ]
    then
    	echo "$(get_date) /var/hack OK." >> $hacklog
    else
    	echo "$(get_date) /var/hack mount point missing (/var rebuilt), recreating." >> $hacklog
    	mkdir -p /var/hack
    fi
       
    echo "$(get_date) Mounting /dev/hda2 at /var/hack" >> $hacklog
    mount /dev/hda2 /var/hack
    mkdir -p /var/slices
    mkdir -p /var/spool/cron
    if [ ! -f /etc/passwd.original ] || [ ! -f /etc/termcap.original ] || [ ! -f /sbin/iptables.original ]
    then
    	echo "$(get_date) Fixing root files" >> $hacklog
    	/bin/mount -o remount,rw /
    #if we haven't already, save originals and replace files
    	[ -f /etc/group ] || /var/hack/utils/touch /etc/group
    	[ -f /etc/group.original ] || mv /etc/group /etc/group.original
    	[ -f /etc/group ] || cp /var/hack/etc/rootfiles/group /etc/group
    	[ -f /etc/passwd ] || /var/hack/utils/touch /etc/passwd
    	[ -f /etc/passwd.original ] || mv /etc/passwd /etc/passwd.original
    	[ -f /etc/passwd ] || cp /var/hack/etc/rootfiles/passwd /etc/passwd
    	[ -f /etc/termcap.original ] || mv /etc/termcap /etc/termcap.original
    	[ -f /etc/termcap ] || cp /var/hack/etc/rootfiles/termcap /etc/termcap
    	[ -f /etc/terminfo/v/vt100 ] || mkdir -p /etc/terminfo/v ; cp /var/hack/etc/rootfiles/vt100 /etc/terminfo/v/vt100
            [ -f /etc/profile.original ] || mv /etc/profile /etc/profile.original
    	[ -f /etc/profile ] || cp /var/hack/etc/rootfiles/profile /etc/profile
    
    	[ -f /sbin/iptables.original ] || mv /sbin/iptables /sbin/iptables.original
    	[ -f /sbin/iptables ] || cp /var/hack/etc/rootfiles/iptables /sbin/iptables
                                                                                          
    	sync
    	/bin/mount -o remount,ro /
    else
    	echo "$(get_date) Root files OK" >> $hacklog
    fi
    
    #if directory doesn't exist, make the symlink
    [ -d /var/spool/cron/crontabs ] || ln -s /var/hack/etc/rootfiles/crontabs /var/spool/cron/crontabs
    #create link so uptime works
    ln -s /proc/uptime /var/run/utmp
    
    echo "$(get_date) Starting hack services" >> $hacklog
    /sbin/tnlited 23 /bin/bash -login &
    $utils/hostname $( cat /var/hack/HostID )
    $utils/crond -l 9
    /bin/hdparm -c1 -a16 /dev/hda
    $utils/tivoftpd
    /var/hack/TivoWebPlus/tivoweb &
    $utils/tserver &
    echo "$(get_date) Loading rc.sysinit.author complete" >> $hacklog
    And finally here is the script I run on my server to notify me when one or more of the TiVos needs to be upgraded:

    Code:
    #! /bin/bash
    
    dir=/usr/share/tivoscan
    cd $dir
    tivo=$dir/tivos.list
    file=$dir/session.txt
    log=/var/log/tivoscan.log
    
    echo $(date +%Y-%m-%d_%H:%M:%S) Starting tivoscan session. >> $log
    while read line
    do
    	[ -f $file ] && rm $file
    	./tivotest.exp $line
    	if [[ -a $file ]]
    	then
    		active=$(grep ACTIVE $file |  awk '{print $3;}')
    		swlines=$(grep tyDb $file | grep -v $active | wc -l)
    		if [ $swlines -gt 0 ];
    		then
    			test=$( cat $line.status )
    			if [ "$test" == "false" ];
    			then
    				echo "TiVo $line is pending a software installation." | mail -a From:mdadm_monitor -s "RAID-Server TiVo Upgrade Notice" lrhorer@satx.rr.com leslie.rhorer@twtelecom.com lrhorer@fletchergeek.com
    				echo $(date +%Y-%m-%d_%H:%M:%S) Emailing notification of pending software for $line. >> $log
    				echo true > $line.status
    			fi
    		else
    			echo false > $line.status
    		fi
    	else
    		echo "TiVo $line did not respond to a software query." | mail -a From:mdadm_monitor -s "RAID-Server TiVo Upgrade Notice" lrhorer@satx.rr.com leslie.rhorer@twtelecom.com lrhorer@fletchergeek.com
    	fi
    done < $tivo
    [ -f $file ] && rm $file
    echo $(date +%Y-%m-%d_%H:%M:%S) Tivoscan session complete. >> $log
    The file tivos.list contains the IP addresses of the hacked tivos, one per line.
    Last edited by lrhorer; 03-09-2013 at 01:07 PM.
    Having trouble with TyTool? Try TyTool Documentation
    Need to hack an S3 / THD? Try S3 Hacking Script

  13. #13
    Join Date
    May 2007
    Posts
    456
    How does the 3rd script notify you on your server? Is there a visual notification? My server is headless, would this work for me?

    Because you say your partitions are modified I assume your changes are custom to your Tivo's. Would this work for the average person or do we need to know code and modify the scripts?

  14. #14
    Join Date
    Jun 2011
    Posts
    3
    Thank you to mike_s and lrhorer for sharing your update scripts!

    Here's another variation of the postinstall script, derived from the lrhorer's version. This one is intended to handle a more "basic" noob-friendly configuration. For example, I used it on a Tivo HD which had been hacked using the hack_tivo script that lrhorer shared here:
    http://www.dealdatabase.com/forum/sh...738#post297738

    The main difference is that most of the hack-relaed files are copied directly from the old root partition to the new one directly on the Tivo, so fewer files are required to run the script. This example assumes that the files from tivohacks64.tar.gz are being used (on Tivo HD), so those are the files that get copied. It also puts all the originals in one folder, including tivoapp.

    Code:
    #!/bin/bash
    nullinitrd="/var/hack/null-linuxrc.img.gz"
    nrpath="/var/hack/mnt"
    origpath="/var/hack/originals"
    bv="$nrpath/etc/build-version"
    
    function quit {
      echo
      echo "$2 Quitting with exit code $1"
      exit $1
      }
    
    echo
    echo "This script should only be run after neutering and then running installSw.itcl"
    echo "It will identify the new kernel and root partitions,"
    echo "then killinitrd the new kernel,"
    echo "then copy necessary files to the new root,"
    echo "then hack tivoapp."
    echo "It also backs up any original files it modifies."
    echo
    echo
    echo "Getting partition info..."
    bootpage -p /dev/hda
    [ $? -eq "0" ] || quit $? "Problem with bootpage."
    
    rootpart=$(bootpage -p /dev/hda)
    rootpart=${rootpart:5:9}
    kernpart=${rootpart:0:8}$(bootpage -b /dev/hda)
    
    echo "New root is $rootpart, new kernel is $kernpart (one less)"
    echo "Enter \"Yes\" if this is correct, anthing else to exit."
    read confirm
    [ "$confirm" == "Yes" ] || quit 1 "User stop."
    echo -n "Mounting new root at $nrpath..."
    mkdir -p $nrpath
    [ $? -eq "0" ] || quit $? "Problem making directory $nrpath."
    mount $rootpart $nrpath
    [ $? -eq "0" ] || quit $? "Problem with \"mount $rootpart $nrpath\"."
    
    echo -n "making directory for originals..."
    origpath=/var/hack/$(tail -n 1 $bv | awk '{print $2}').originals
    [ ! -f $origpath ] || quit 1 "Problem, $origpath already exists."
    mkdir $origpath
    echo "done."
    
    echo -n "copying original kernel to $origpath"
    dd if=$kernpart of=$origpath/kernel.killed bs=1024k
    [ $? -eq "0" ] || quit $? "Problem with dd from $kernpart."
    echo "done."
    
    echo -n "Doing killinitrd..."
    replace_initrd.mips $origpath/kernel.killed $nullinitrd $origpath/kernel.original
    #no check for now, doesn't return 0 properly
    #[ $? -eq "0" ] || quit $? "Problem with killinitrd."
    echo "modified kernel is $origpath/kernel.killed"
    echo -n "Replacing kernel on $kernpart..."
    dd if=$origpath/kernel.killed of=$kernpart bs=1024k
    [ $? -eq "0" ] || quit $? "Problem with dd to $kernpart."
    echo "done."
    
    #copy all files that were included in tivohacks64 in /etc, /sbin and /utils from old root to new. make backups in origpath.
    echo -n "Copying files from old root to new root..."
    [ ! -f $nrpath/etc/rc.d/rc.sysinit.author ] || cp -f $nrpath/etc/rc.d/rc.sysinit.author $origpath/rc.sysinit.author
    cp -f /etc/rc.d/rc.sysinit.author $nrpath/etc/rc.d/rc.sysinit.author
    [ $? -eq "0" ] || quit $? "Problem copying rc.sysinit.author"
    [ ! -f $nrpath/etc/bash_logout ] || cp -f $nrpath/etc/bash_logout $origpath/bash_logout
    cp -f /etc/bash_logout $nrpath/etc/bash_logout
    [ $? -eq "0" ] || quit $? "Problem copying bash_logout"
    [ ! -f $nrpath/etc/profile ] || cp -f $nrpath/etc/profile $origpath/profile
    cp -f /etc/profile $nrpath/etc/profile
    [ $? -eq "0" ] || quit $? "Problem copying profile"
    [ ! -f $nrpath/sbin/iptables ] || cp -f $nrpath/sbin/iptables $origpath/iptables
    cp -f /sbin/iptables $nrpath/sbin/iptables
    [ $? -eq "0" ] || quit $? "Problem copying iptables"
    mkdir -p $nrpath/utils
    cp -f /utils/* $nrpath/utils
    [ $? -eq "0" ] || quit $? "Problem copying utils"
    echo "done."
    
    echo "Attempting to patch tivoapp..."
    TmpFile=$origpath/tivoapp.tmp
    HackFile=/var/hack/hacks.fil
    cd $nrpath/tvbin
    echo "Creating temporary tivoapp"
    cp tivoapp $TmpFile
    
    echo "Getting the hacking parameters for tivoapp..."
    Failure=1
    while read line
    do
            offset=$(( $(echo $line | cut -d" " -f1) - 0x00400000 ))
            oldword=$(echo $line | cut -d" " -f2 | sed s'/"//g')
            newword=$(echo $line | cut -d" " -f3 | sed s'/"//g')
            echo $oldword $newword $offset
            B1=$( dd if=tivoapp skip=$offset bs=1 count=4 2> /dev/null | hexdump | grep 0000000 | cut -c9-12 )
            B2=$( dd if=tivoapp skip=$offset bs=1 count=4 2> /dev/null | hexdump | grep 0000000 | cut -c14-17 )
            testword=$B1$B2
            echo $testword
            # Check to make sure the bytes match
            if [ "$testword" == "$oldword" ];
            then
                    echo Updating tivoapp $( echo $line | cut -d" " -f4)
                    # Convert the string into a 4 byte number expression
                    escape="\x"
                    H1=${newword:0:2}
                    H2=${newword:2:2}
                    H3=${newword:4:2}
                    H4=${newword:6:2}
                    newword=$escape$H1$escape$H2$escape$H3$escape$H4
                    echo -ne "$newword" | dd conv=notrunc of=$TmpFile bs=1 seek=$offset
            elif [ "$testword" == "$newword" ];
            then
                    echo Failed for $oldword $newword $offset
                    echo Tivoapp already has patch at this location.
                    exit 1
            else
                    echo Failed for $oldword $newword $offset Old value: $testword
                    test -e $TmpFile && rm $TmpFile
                    exit 1
            fi
    done < $HackFile
    echo "Replacing tivoapp, original saved to $origpath..."
    mv tivoapp $origpath/tivoapp
    mv $TmpFile tivoapp
    echo "done."
    
    echo "Attempting to patch installSw.itcl to remove reboot..."
    cp -f $nrpath/tvbin/installSw.itcl $origpath/installSw.itcl
    echo "sed -i 's/reboot/exit 0/' $nrpath/tvbin/installSw.itcl"
    sed -i 's/reboot/exit 0/' $nrpath/tvbin/installSw.itcl
    [ $? -eq "0" ] || quit $? "Problem with patching installSw.itcl."
    echo "done."
    
    echo -n "Umounting new root..."
    sync
    sleep 10
    umount $nrpath
    [ $? -eq "0" ] || quit $? "Problem umounting $nrpath"
    echo "done."
    
    echo
    echo "All done."
    echo "Original files copied to $origpath."
    echo "Reboot to use new system."

    Here's an example procedure for updating a Tivo HD on the Tivo without pulling the drive. This of course assumes that you already have a working hacked Tivo with telnet and ftp access. Some details may vary depending on your configuration, so this is not intended to be a literal step-by-step guide, it's just an example of how I did it. Do NOT reboot before the last step!!

    1) Make sure new Tivo software version has been downloaded to the inactive partition:

    bash-2.02# echo mls /SwSystem | tivosh
    Directory of /SwSystem starting at ''

    Name Type FsId Date Time Size
    ---- ---- ---- ---- ---- ----
    11.0k-01-2-652 tyDb 1357227 03/03/11 11:03 908
    11.0m-01-2-652 tyDb 4269291 08/31/13 17:46 884
    ACTIVE tyDb 1357227 03/03/11 11:03 908

    2) Extract replace_initrd.mips.tar.gz on your PC to get null-linuxrc.img.gz, replace_initrd.mips

    3) Ftp files from PC to /var/hack on Tivo (Required files: postinstall, hacks.fil, null-linuxrc.img.gz, replace_initrd.mips)

    4) Remove updatesoftware=false from bootpage if set (This step may not be necessary? But it doesn't hurt.)

    bash-2.02# bootpage -p /dev/hda
    root=/dev/hda4 upgradesoftware=false
    bash-2.02# bootpage -P "root=/dev/hda4" /dev/hda
    Updated boot page on /dev/hda
    bash-2.02# bootpage -p /dev/hda
    root=/dev/hda4

    5) Neuter installSw.itcl by editing /tvbin/installSw.itcl, and replacing reboot line with exit 0:

    bash-2.02# mount -o remount,rw /
    bash-2.02# vi /tvbin/installSw.itcl
    bash-2.02# mount -o remount,ro /

    6) Run /tvbin/installSw.itcl to install new software. Do not reboot after this step or you will lose all hacks and Linux shell access!!

    bash-2.02# cd /tvbin
    bash-2.02# ./installSw.itcl

    7) Run postinstall script to hack new software in inactive partition.

    bash-2.02# cd /var/hack
    bash-2.02# ./postinstall

    8) Restore upgradesoftware=false bootpage flag if desired

    bash-2.02# bootpage -p /dev/hda
    root=/dev/hda7
    bash-2.02# bootpage -P "root=/dev/hda7 upgradesoftware=false" /dev/hda
    Updated boot page on /dev/hda
    bash-2.02# bootpage -p /dev/hda
    root=/dev/hda7 upgradesoftware=false

    9) Reboot

    10) If it worked, smile and enjoy!


    Other references...

    This thread contains useful info to help learn about the update procedure:
    http://www.dealdatabase.com/forum/sh...ng-to-roll-out

    This post has the most recent tivoapp patches for software version 11.0m:
    http://www.dealdatabase.com/forum/sh...574#post317574
    Last edited by spocko; 11-23-2013 at 11:30 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •