Choose color scheme

Category Archives: I.T.

  • iPXE booting with vlan support

    Getting a version of iPXE that supports vlans

    Download

    ipxe_with_vlan_support_2014-06-12.iso

    Build it yourself

    git clone git://git.ipxe.org/ipxe.git
    cd ipxe/src
    sed -i 's///#define VLAN_CMD/#define VLAN_CMD/' config/general.h
    make
    

    There is multiple ways you can use your compiled binary, for testing just mounting bin/ipxe.iso and booting from it is good.

    Using it

    Boot from the ROM/ISO.

    CTRL+B to get a command line when prompted.

    Then assuming a desired vlan ID of 123:

    vcreate --tag 123 net0
    dhcp net0-123
    chain tftp://${next-server}/${filename}
    
  • PHP 2-dimensional array sorting algorithms

    For 2-dimensional arrays looking like:

    Array
    (
        [0] => Array
            (
                [id] => 1
                [name] => roger
                [age] => 31
            )
    
        [1] => Array
            (
                [id] => 2
                [name] => brutus
                [age] => 24
            )
    
        [2] => Array
            (
                [id] => 3
                [name] => ganesh
                [age] => 92
            )
    
    )
    

    I find that comb sort is usually the fastest but its worst case is much worst than quick sort so it could become a bottleneck depending on your data.

    <?php
    
        ini_set( 'memory_limit', '128M' ) ;
    
    
        /**
        * @desc bubble_sort for 2 dimensional array (all the arrays of the 2nd dimension need to have the field $sort_by)
        * @param array^2 $data the array of arrays
        * @param string $sort_by the parameter that will be used for comparison
        * @param string $sort_direction "asc": ascending, "desc": descending
        */
        function bubble_sort( $data, $sort_by, $sort_direction ) {
            if( $sort_direction=='asc' ) {
                for( $i=1 ; $i<count($data) ; $i++ ) {
                    for( $j=1 ; $j<count($data) ; $j++ ) {
                        if( $data[$j-1][$sort_by]>$data[$j][$sort_by] ) {
                            $temp = $data[$j-1] ;
                            $data[$j-1] = $data[$j] ;
                            $data[$j] = $temp ;
                        }
                    }
                }
            } else {
                for( $i=1 ; $i<count($data) ; $i++ ) {
                    for( $j=1 ; $j<count($data) ; $j++ ) {
                        if( $data[$j-1][$sort_by]<$data[$j][$sort_by] ) {
                            $temp = $data[$j-1] ;
                            $data[$j-1] = $data[$j] ;
                            $data[$j] = $temp ;
                        }
                    }
                }
            }
            return $data ;
        }
    
    
        /**
        * @desc comb_sort for 2 dimensional array (all the arrays of the 2nd dimension need to have the field $sort_by)
        * @param array^2 $data the array of arrays
        * @param string $sort_by the parameter that will be used for comparison
        * @param string $sort_direction "asc": ascending, "desc": descending
        */
        function comb_sort( $data, $sort_by, $sort_direction ) {
            $gap   = count( $data ) ;
            $swaps = -1 ;
            while( !($gap<=1 && $swaps==0) ) {
                if( $gap>1 ) {
                    $gap = $gap/1.3 ;
                    if( $gap==10 || $gap==9 ) {
                        $gap = 11 ;
                    }
                }
                $i = 0 ;
                $swaps = 0 ;
                while( !(($i+$gap)>=count($data)) ) {
                    if( ($sort_direction=='asc' && $data[$i][$sort_by]>$data[$i+$gap][$sort_by]) ||
                        ($sort_direction=='desc' && $data[$i][$sort_by]<$data[$i+$gap][$sort_by]) ) {
                        $temp = $data[$i] ;
                        $data[$i] = $data[$i+$gap] ;
                        $data[$i+$gap] = $temp ;
                        $swaps = 1 ;
                    }
                    $i++ ;
                }
            }
    
            return $data ;
        }
    
    
        /**
        * @desc quick_sort for 2 dimensional arrays (all the arrays of the 2nd dimension need to have the field $sort_by)
        * @param array^2 $data the array of arrays
        * @param string $sort_by the parameter that will be used for comparison
        * @param string $sort_direction "asc": ascending, "desc": descending
        */
        function quick_sort( $data, $sort_by, $sort_direction ) {
            if( count($data)<=1 || $sort_by=='' ) {
                return $data ;
            } else {
                $pivot = $data[0][$sort_by] ;
                $x = $y = array() ;
                for( $i=1 ; $i<count($data) ; $i++ ) {
                    if( $data[$i][$sort_by]<$pivot ) {
                        if( $sort_direction=="asc" ) {
                            $x[] = $data[$i] ;
                        } else {
                            $y[] = $data[$i] ;
                        }
                    } else {
                        if( $sort_direction=="asc" ) {
                            $y[] = $data[$i] ;
                        } else {
                            $x[] = $data[$i] ;
                        }
                    }
                }
                return array_merge( quick_sort($x, $sort_by, $sort_direction), array($data[0]), quick_sort($y, $sort_by, $sort_direction) ) ;
            }
        }
    ?>
    
  • Gnuplot one-liner from Hell

    Here’s a convenient one liner to chronologically plot data on the command line

    Screenshot

    Screen Shot 2014-04-02 at 11.18.44 AM

    Command

    
    
    export width=`stty size | cut -d " " -f2`; export height=`stty size | cut -d " " -f1`-10; cat /tmp/data | sed "s/ /T/" | gnuplot -e "set terminal dumb $width $height; set autoscale; set xdata time; set timefmt \"%Y-%m-%dT%H:%M:%S\"; set xlabel \"time\"; set ylabel \"counter\"; plot '-' using 1:2 with lines"
    
    
    

    Data

    /tmp/data contains the following:

    2000-01-01 00:00:00 1
    2000-01-01 01:00:00 2
    2000-01-01 02:00:00 3
    2000-01-01 03:00:00 2
    2000-01-01 04:00:00 3
    2000-01-01 05:00:00 4
    2000-01-01 06:00:00 5
    2000-01-01 07:00:00 4
    2000-01-01 08:00:00 3
    2000-01-01 09:00:00 4
    2000-01-01 10:00:00 4
    2000-01-01 11:00:00 5
    2000-01-01 12:00:00 4
    2000-01-01 13:00:00 4
    2000-01-01 14:00:00 3
    2000-01-01 15:00:00 2
    2000-01-01 16:00:00 3
    2000-01-01 17:00:00 4
    2000-01-01 18:00:00 4
    2000-01-01 19:00:00 5
    2000-01-01 20:00:00 6
    2000-01-01 21:00:00 6
    2000-01-01 22:00:00 7
    2000-01-01 23:00:00 8
    2000-01-02 00:00:00 7
    2000-01-02 01:00:00 7
    2000-01-02 02:00:00 6
    2000-01-02 03:00:00 8
    2000-01-02 04:00:00 9
    2000-01-02 05:00:00 9
    2000-01-02 06:00:00 9
    2000-01-02 07:00:00 8
    2000-01-02 08:00:00 7
    2000-01-02 09:00:00 5
    2000-01-02 10:00:00 4
    2000-01-02 11:00:00 4
    2000-01-02 12:00:00 4
    2000-01-02 13:00:00 3
    2000-01-02 14:00:00 2
    2000-01-02 15:00:00 2
    2000-01-02 16:00:00 1
  • Pulling the number keyboard in iOS’ Safari while disabling client side input validation

    Safari on iOS allows you to pull a specific keyboard for an input field. For example if I have a field expecting numeric input, we’ll make sure that our input has the attribute of “number” rather than the usual “text” as such:

    <input type="number"/>

    This will save users a few clicks; however Safari forces input validation on the client-side when you do that. Meaning if you wanted a numeric keyboard by default while allowing other characters, you input will fail.

    IMG_0798

    Not only is it highlighted in red, this.value also returns null as opposed to what is clearly in the field, rendering it unusable.

    When the field is set to “-10”

    Screen Shot 2013-11-20 at 10.14.10 AM

    When the field is set to “+10”

    Screen Shot 2013-11-20 at 10.14.03 AM

    One would think that explicitly defining a pattern to check for would let Safari know that we are interested in trumping its input validation but such is not the case. As a result, the following does not help our cause:

    <input type="number" pattern="(-+){0,1}[0-9]{1,}">

    So here’s a completely hackish way to get the keyboard you want with no input validation:

    <input type="number" pattern="(-+){0,1}[0-9]{1,}" onFocus="that=this; setTimeout(function(){ that.setAttribute('type','text'); },10);" onBlur="that=this; setTimeout(function(){ that.setAttribute('type','number'); },10);"/>;

    That’s right, after iOS pulled the right keyboard, we change the field type to “text”. Note that the client will still display some red around the field as it will perform the validation but at least this.value will return what’s in the friggin’ field.

    Note 1: the setTimeout is necessary, if we perform the change immediately onFocus, safari pulls the text keyboard.

    Note 2: the that=this indirection is necessary to save a reference of the object to the context of setTimeout.

  • 3 years

    Is how long it took before he discovered the arcade is actually more than a piece of furniture. He is still figuring out the controls as he is used to the iPad where there is little to no indirection between the controls and the output.

    IMG_1137

  • A website to make the meal math easier on the parents

    http://www.akrin.com/diabetes

    List of current features:

    1. It uses the USDA National Nutrient Database as the basis for all the foods you can search (your tax dollars at work).
    2. You can add your own recipes, ingredients whatever else is not in the base database. We find that we add all the foods we use even if it’s just bread because a bread with a label is always more accurate than the generic/average bread as defined in the USDA database. It’s also nice for adding your family specials once and for all and never have to do the math again.
    3. What you add is not shared amongst users and it only visible to you.
    4. It tries to learn which foods come back to help pick them later on.
    5. It remembers which amounts you last used
    6. Calculates insulin dose on the fly
    7. Very simple & streamlined navigation for the least work for the parents

    This is still very much a work in progress but has made our meals a lot more agreeable already.

  • Markov chains music generation

    Here’s a project I’ve had on the back-burner for many years. Following the natural progression of generating stuff based on Markov chains, I decided a while ago to port the algorithm to music.

    Music presents many challenges that I haven’t been able to address well so far. As a result, what the algorithm produces always had a bitter unfinished aftertaste to me, hence why I haven’t published anything about it for years.

    • Music is multidimensional, time is relevant and needs it own analysis and subsequent generation
    • The interconnectedness of different instruments from the piece is important as well.
    • Random generation even based on Markov chains fails to produce any structure. The pieces all sound like a long solo without chorus or any other repetition that would give us what we strive for: anticipation. In other words, it’s perfect for jazz.

    I’m hoping that publishing this will give me the kick in the nuts necessary to keep improving it. Without further ado, here’s what I have so far.


    Future improvements:

    • add to corpus
    • clean pieces analyzed of noise
    • try to infuse structure
  • FreeBSD manual multipath script

    I recently ran into an issue installing FreeBSD on a system that already had some disks & zpools. Because the disks were partitioned previously, automatic multipath was not an option as the last sector of all hard drives isn’t available to store an ID. The remaining option is to do manual multipath, and it needs to be done every time the system boots.

    Here’s an rc script that will run early in the sequence and create a multipath “link” between drives based on their serial number.

    /etc/rc.d/manual_multipath

    #!/bin/sh
    
    # PROVIDES: manual_multipath
    # REQUIRE: sysctl
    # BEFORE: hostid
    
    . /etc/rc.subr
    
    name="manual_multipath"
    start_cmd="${name}_start"
    stop_cmd=":"
    
    manual_multipath_start()
    {
            echo "> manual_multipath script started"
            echo "> linking drives with the same serial number with gmultipath"
            counter=0
            serials=""
            devices=`/usr/bin/find /dev -maxdepth 1 -regex '.*da[0-9]*' | /usr/bin/cut -d '/' -f 3`
            for device in $devices
            do
                    echo $device
                    serial=`camcontrol inquiry $device -S`
                    substring=`echo "$serials" | /usr/bin/sed -n "s/|$serial|.*//p" | /usr/bin/wc -c`
                    if [ $substring -eq 0 ]
                    then
                            found_multi=0
                            arg1="$device"
                            arg2="$device"
                            for newdevice in $devices
                            do
                                    newserial=`camcontrol inquiry $newdevice -S`
                                    if [ "$device" != "$newdevice" -a "$serial" == "$newserial" ]
                                    then
                                            echo "  same as $newdevice!"
                                            counter=`expr $counter + 1`
                                            found_multi=1
                                            arg1=$arg1"$newdevice"
                                            arg2=$arg2" $newdevice"
                                    fi
                            done
                            if [ $found_multi -eq 1 ]
                            then
                                    gmultipath create $arg1 $arg2
                            fi
                    fi
                    serials=$serials"|$serial|"
            done
            echo "> manual_multipath script finished, found $counter matches"
    }
    
    load_rc_config $name
    run_rc_command "$1"

    Don’t forget to “chmod 555 /etc/rc.d/manual_multipath”.

    Lastly, when importing a zpool from the drives you just multipathed, make sure to specify where to look for devices or you might end up importing a mix of multipath and regular devices. Make sure to “zpool import -d /dev/multipath”.

    I’m delving pretty deep into FreeBSD, time to grow an epic beard.

  • More Dr. Meter fun

    Finger

    Arm

    Hair

    Salt

    Nutella (gross)

    Peanut

    Serrated knife blade

    Ballpoint pen

    Printed beer logo

    Cloth

    Melting snow

    [flv:http://ben.akrin.com/wp-content/uploads/2013/02/temp.flv http://ben.akrin.com/wp-content/uploads/2013/02/Screen-Shot-2013-02-24-at-11.53.58-PM.png 640 426]