Friday, May 24, 2013

Android Emulator performance - Windows 8 vs Ubuntu 13.04

I mentioned earlier I've been trying Ubuntu for Android development, and today I'll try to capture the difference in performance of the Android emulator on the two platforms. I haven't seen much difference in terms of Eclipse performance, but when it comes down to the Emulator it is quite obvious.

I'm not quite sure what makes the difference so large, might be the OS or maybe the QEMU software implementation on each OS. I chose to test with Android 4.2.2 AVD images just to push it - older versions like Android 2.1 or 2.3 seem to work better.

Also I'm running the tests on my home Dell laptop which is a few years old, making the difference even more obvious. I find Windows 8 on this machine faster than Windows 7 and generally a pleasant experience while probably on par with Ubuntu 13.04 in terms of performance.

While I find Windows more familiar and easier to use, because of the poor Android emulator experience on Windows I find using Ubuntu a less annoying experience for this particular task.

Environment


Machine

  • Dell Vostro 1520
  • 15.4” Widescreen WXGA+ CCLF, anti-glare (1440x900);
  • Intel Core 2 Duo P8600 (2.4 GHz, 1066 Mhz, 3 MB cache);
  • Intel® 45 Express chipset
  • Intel Integrated GMA 4500MHD;
  • 4 GB RAM, 800 MHz DDR2 Dual Channel;
  • 320 GB Seagate ST9320423ASG 7200 rpm, NCQ enabled;

    Windows 8

    • Windows 8 (x64)
      Version: 6.2.9200
    • android-sdk\tools\emulator-x86.exe
      Version: n/a
      Build Time: Tue May 14 02:49:56 2013
    • Intel HAXM 1.0.6 
    • Intel 4 Series Express display driver
      WDDM 1.1, 8.15.10.2702

    Ubuntu 13.04

    • Ubuntu 13.04 (x64)
      Linux VOSTRO 3.8.0-21-generic #32-Ubuntu SMP Tue May 14 22:16:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
    • android-sdk/tools/emulator64-x86
      Android emulator version 22.0 (build_id OPENMASTER-675183)

    Eclipse / Android SDK

    • Eclipse 4.3 M7 x64, Kepler
      • 20130509-1105 (x64) - Windows
      • 20130225-0426 (x64) - Ubuntu
    • Oracle / Sun JDK 1.7.0_21 (x64)
    • Android SDK Tools 22
    • Android SDK Platform Tools 17
    • Android 4.2.2 (API 17) - Intel x86 Atom System Image rev. 1

    Android Virtual Devices


    Phone

    • 3.2" QVGA (320 x 480: mdpi)
    • Android 4.2.2 - API Level 17
    • Intel Atom (x86)
    • RAM: 512 MB
    • VM Heap: 16 MB
    • Internal Storage: 200 MB
    • SD Card: 200 MB
    • Use Host GPU

    Nexus 7

    • Nexus 7 (7.27", 800 x 1280: tvdpi)
    • Android 4.2.2 - API Level 17
    • Intel Atom (x86)
    • RAM: 512 MB
    • VM Heap: 32 MB
    • Internal Storage: 200 MB
    • SD Card: 200 MB
    • Use Host GPU

    Windows 8


    Performance on the Phone AVD is acceptable although slightly laggy, using Intel HAXM 1.0.6 and "Use Host GPU" option. My GPU chip / driver don't seem to support OpenGL 2.0 (1.1 only?), showing in the startup messages.
    Starting emulator for AVD 'Phone_4.2'
    Failed to create Context 0x3005
    could not get wglGetExtensionsStringARB
    emulator: WARNING: Could not initialize OpenglES emulation, using software renderer.
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    emulator: device fd:688
    HAX is working and emulator runs in fast virt mode
    AnTuTu Benchmark v3.3 scores:
    • Total: 13,837
    • CPU: 7,503
    • GPU: 141
    • RAM: 5,643
    • I/O: 550

    For Nexus 7 AVD, I had to drop down the RAM to 512 MB to get HAXM working with it, maybe because I configured HAXM earlier to only use 512 MB, trying to avoid the system running out of memory (only 4 GB of RAM). The experience is laggy (1-2 seconds wait between activities), barely usable - disabling animations helps a bit.
    Starting emulator for AVD 'Nexus_7'
    Failed to create Context 0x3005
    could not get wglGetExtensionsStringARB
    emulator: WARNING: Could not initialize OpenglES emulation, using software renderer.
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    could not get wglGetExtensionsStringARB
    emulator: device fd:692
    HAX is working and emulator runs in fast virt mode
    emulator: emulator window was out of view and was recentered
    AnTuTu Benchmark v3.3 scores:
    • Total: 11,572
    • CPU: 6,282
    • GPU: 42
    • RAM: 4,713
    • I/O: 535

    Ubuntu 13.04


    Emulators start in seconds (15-30) to desktop, compared to minutes (1-3) in Windows!

    Phone 4.2 AVD is quite snappy, and haven't done anything special for it like install KVM. No additional messages at startup. AnTuTu shows same OpenGL 1.1 on screen during testing, but the FPS is much higher (~60 fps)!

    AnTuTu Benchmark v3.3 scores:
    • Total: 15,440
    • CPU: 7,728
    • GPU: 1,234
    • RAM: 5,918
    • I/O: 560

    Nexus 7 AVD starts quickly and it's very snappy! Navigation through activities and scrolling is very responsive, a huge difference from Windows. Some error messages at image startup though:
    Starting emulator for AVD 'Nexus_7'
    Failed to load libGL.so
    error libGL.so: cannot open shared object file: No such file or directory
    Failed to load libGL.so
    error libGL.so: cannot open shared object file: No such file or directory
    emulator: emulator window was out of view and was recentered
    Reading this thread I created the link below to fix the error message - didn't see any change in the scores though.
    # sudo apt-get install libgl1-mesa-dev
    # sudo ln -sv /usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/libGL.so
    ‘/usr/lib/libGL.so’ -> ‘/usr/lib/x86_64-linux-gnu/libGL.so’
    
    AnTuTu Benchmark v3.3 scores:
    • Total: 14,104
    • CPU: 7,365
    • GPU: 538
    • RAM: 5,662
    • I/O: 560

    Saturday, May 18, 2013

    Seagate GoFlex Home NAS - SVN server installation

    This comes with a story as well, out of some need, not just technical curiosity :-) I recently gave Ubuntu a shot to see how it compares with Windows for Android development (I might post something about it later), and for Windows I used a local VisualSVN Server - a no brainer SVN server package, very easy to install and maintain. When in Ubuntu I can't use it, well, not as it is. I can obviously set up an SVN server on Ubuntu and point to the same repositories (I've actually managed to access them through running svnserve and svn:// URLs as a start), but having a separate SVN server on GoFlex Home would make me feel better knowing that base copy is on another machine in case my laptop HDD crashes, I would only loose the working copy.


    Preparation


    See previous post where we installed ipkg (will use it to install the SVN package) and we setup a system account for HDD storage (will use the same again to store the SVN repositories).

    SVN software

    bash-3.2# ipkg install svn
    Installing svn (1.7.7-1) to root...
    Downloading http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable/svn_1.7.7-1_arm.ipk
    package apr-util suggests installing sqlite
    package apr-util suggests installing openldap-libs
    Installing neon (0.29.6-1) to root...
    [...]
    Successfully terminated.
    
    bash-3.2# svnadmin --version
    svnadmin, version 1.7.7 (r1393599)
       compiled Oct 10 2012, 00:19:36
    [...]

    SVN repositories


    We will prepare the SVN repositories location (/srv/svn linked to external storage), where you can create a new blank repository (I'll call it test):

    bash-3.2# mkdir -p /home/0loop0/srv/svn/
    bash-3.2# ln -sv /home/0loop0/srv/svn/ /srv/
    
    bash-3.2# cd /srv/svn
    bash-3.2# df -h .
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/loop0            985M   50M  885M   6% /home/0loop0
    
    bash-3.2# mkdir repos
    bash-3.2# cd repos
    
    bash-3.2# svnadmin create test
    bash-3.2# svnadmin verify test
    * Verified revision 0.
    
    bash-3.2# svn mkdir file:///srv/svn/repos/test/trunk -m "Initial commit"
    Committed revision 1.
    
    bash-3.2# svn mkdir file:///srv/svn/repos/test/branches -m "Initial commit"
    Committed revision 2.
    
    bash-3.2# svn mkdir file:///srv/svn/repos/test/tags -m "Initial commit"
    Committed revision 3.
    
    bash-3.2# svn list -v file:///srv/svn/repos/test/
          3 root                  May 18 21:35 ./
          2 root                  May 18 21:35 branches/
          3 root                  May 18 21:35 tags/
          1 root                  May 18 21:34 trunk/

    OR, if you have a dump file from a previous repository, you can restore that instead:
    bash-3.2# cd /srv/svn/repos
    
    bash-3.2# svnadmin create android-apps
    bash-3.2# svnadmin load android-apps < android-apps.svn-dump

    SVN server (http://) - FAIL


    Unfortunately, although this is how I saw it setup in the first place (no additional processes, running as a module in Appache HTTP server), I couldn't get this working. After linking the additional config and changing it to correctly point to the modules (change LoadModule from libexec to /opt/libexec/...), the process will die with Segmentation fault.

    bash-3.2# ln -sv /opt/etc/apache2/conf.d/mod_dav_svn.conf /etc/httpd/conf.d/
    create symbolic link `/etc/httpd/conf.d/mod_dav_svn.conf' to `/opt/etc/apache2/conf.d/mod_dav_svn.conf'
    
    bash-3.2# vi /etc/httpd/conf.d/mod_dav_svn.conf
    
    bash-3.2# service httpd restart
    Stopping httpd:                                            [  OK  ]
    Starting httpd: /bin/bash: line 1:  8741 Segmentation fault      /usr/sbin/httpd
                                                               [FAILED]

    Trying to debug this doesn't show more than maybe an incompatibility between the APR library used to compile Apache HTTP server and the modules...
    bash-3.2# apk install gdb
    [...]
    
    bash-3.2# gdb httpd
    GNU gdb 6.8
    [...]
    
    (gdb) run
    Starting program: /usr/sbin/httpd
    (no debugging symbols found)
    (no debugging symbols found)
    [Thread debugging using libthread_db enabled]
    [New Thread 0x404d1000 (LWP 7770)]
    
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0x404d1000 (LWP 7770)]
    0x40736034 in apr_pool_create_ex () from /opt/lib/libapr.so.0

    Fix it back by removing the link, otherwise the webserver will not start next time:

    bash-3.2# unlink /etc/httpd/conf.d/mod_dav_svn.conf
    
    bash-3.2# service httpd restart
    Stopping httpd:                                            [FAILED]
    Starting httpd:                                            [  OK  ]


    SVN server (svn://)

    Although not ideal, as it requires a separate process (svnserver) and it will make it harder to setup as we will need to start it with a script to run the external partition is mounted, here we go...

    bash-3.2# cd /etc/oe-initscripts/oe-bootfinish/start.d/
    
    bash-3.2# cat > 1_svnserve << EOL
    /opt/bin/svnserve -d -r /srv/svn/repos
    EOL
    
    bash-3.2# cat 1_svnserve
    /opt/bin/svnserve -d -M 8 -r /srv/svn/repos
    
    bash-3.2# chmod a+x 1_svnserve

    Test the script, see how the SVN server works:

    bash-3.2# ./1_svnserve
    
    bash-3.2# svn list -v svn://localhost/test
          3 root                  May 18 21:35 ./
          2 root                  May 18 21:35 branches/
          3 root                  May 18 21:35 tags/
          1 root                  May 18 21:34 trunk/
    Let's also create the stop script - remember in previous post we created the unmount script with a "9_" prefix so that we can create the svnserve script with a lower prefix to make it run before it, otherwise the partition will be in use and won't be able to unmount and flush, possibly leading to loss of data or corruption of the SVN repository...
    bash-3.2# cd /etc/oe-initscripts/oe-bootfinish/stop.d/
    
    bash-3.2# cat > 8_svnserve << EOL
    killall svnserve
    EOL
    
    bash-3.2# chmod a+x 8_svnserve
    Trying the stop script...
    bash-3.2# ./8_svnserve
    
    bash-3.2# svn list -v svn://localhost/test
    svn: E000111: Unable to connect to a repository at URL 'svn://localhost/test'
    svn: E000111: Can't connect to host 'localhost': Connection refused

    Finally reboot and try accessing the repository from another machine, using svn://goflex_home/test/ (on Windows) or svn://ip_address/test (on Linux - that's because of the character in the name, nslookup works with "goflex home", but not svn...)

    SVN backup


    As we've mounted the SVN repositories inside of the file partition, I know I would feel more comfortable to know there is a backup that I can easily access if that gets corrupted. So what we're going to do is to setup a script to run either every night or every two days and make a dump of the repository, and make that available in the \\goflex_home\GoFlex Home Backup directory.
    bash-3.2# cd /srv/svn
    bash-3.2# cat > svn-backup << EOL
    #!/bin/bash
    
    if [ -z "\$1" ]; then
      echo -e "Usage:\n   \$0 repository-name"
      exit 99
    fi
    
    OUTPUT_DIR=/home/system/GoFlex\ Home\ Backup/svn
    OUTPUT_FILE=\$1.svn-dump-\$(date +"%Y%m%d-%H%M%S")
    KEEP_DAYS=31
    
    /opt/bin/svnadmin -M 8 -q dump /srv/svn/repos/\$1 > "\$OUTPUT_DIR/\$OUTPUT_FILE"
    /usr/bin/zip -m -2 -j "\$OUTPUT_DIR/\$OUTPUT_FILE.zip" "\$OUTPUT_DIR/\$OUTPUT_FILE"
    
    echo -e "\nTrimming backups - older than \$KEEP_DAYS days..."
    find "\$OUTPUT_DIR" -name "\$1.*.zip" -mtime +\$KEEP_DAYS -exec ls {} \; -exec rm {} \;
    EOL
    
    bash-3.2# chmod a+x svn-backup
    
    bash-3.2# cd "/home/system/GoFlex Home Backup/"
    bash-3.2# mkdir svn
    bash-3.2# cd svn
    
    bash-3.2# /srv/svn/svn-backup test
    * Dumped revision 0.
    * Dumped revision 1.
    * Dumped revision 2.
    * Dumped revision 3.
       adding: test.svn-dump-20130518-234455 (deflated 71%)
    
    Trimming backups - older than 31 days...
    
    bash-3.2# ls -la *
    total 0
    -rwxrwxrwx 1 apache users 320 May 18 22:07 test.svn-dump-20130518-220731.zip

    Now that we tested the command line we're going to add it to the cron to run every night at 11pm.
    bash-3.2# cat > /etc/cron.d/svn-backup << EOL
    0 23 * * * root /srv/svn/svn-backup test
    EOL
    
    bash-3.2# cat /etc/cron.d/svn-backup
    0 23 * * * root /srv/svn/svn-backup test

    Seagate GoFlex Home NAS - Installing a package manager (again)

    This is a redo of the previous post, with which a had a few annoying problems.

    First, the symbolic links in /opt/lib on NTFS were broken on next boot (converted into plain files) generating the "file too short" errors when running ipkg command - a fix I guess would be to duplicate the .so libraries to replace the symlinks.

    Then later I ran into a very odd issue with Subversion, where the repository created on NTFS would be seen as corrupted. Creating a repository temporarily in /tmp would verify ok, moving it to NTFS would have the error again.
    bash-3.2# cd /home/system/GoFlex\ Home\ Personal/tmp/
    bash-3.2# svnadmin create test
    bash-3.2# svnadmin verify test
    svnadmin: E160004: Corrupt node-revision '0.0.r0/17'
    svnadmin: E160004: Missing cpath field in node-rev '0.0.r0/17'
    Although I don't feel too comfortable with the complexity of the new setup, we will follow the good work done on OpenStora Forums (here), where pippone is suggesting to use a Linux partition image on the HDD and mount it as a loop device. So here we go...

    * * *

    Create Linux partition image


    We will create a 1GB image (to hold /opt and the SVN files later on) - this will be visible through \\goflex_home\GoFlex Home Personal (system account), although when mounted it will be in use so you won't be able to delete it by accident. If you want to hide it, start the filename with a dot (.).
    bash-3.2# cd /home/system/GoFlex\ Home\ Personal/
    
    bash-3.2# dd if=/dev/zero of=ext3_linux_partition.img bs=4k count=256000
    256000+0 records in 256000+0 records out 1048576000 bytes (1.0 GB) copied, 15.6834 seconds, 66.9 MB/s
    
    bash-3.2# losetup /dev/loop0 "`pwd`/ext3_linux_partition.img"
    bash-3.2# losetup -a
    /dev/loop0: [0800]:15206 (/home/system/GoFlex Home Personal/ext3_linux_partition.img)
    
    bash-3.2# mkfs.ext3 /dev/loop0
    mke2fs 1.39 (29-May-2006)
    [...]
    
    bash-3.2# mkdir /home/0loop0
    bash-3.2# mount /dev/loop0 /home/0loop0/
    
    bash-3.2# df -h /home/0loop0
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/loop0            985M   18M  917M   2% /home/0loop0
    
    bash-3.2# ls -la /home/0loop0
    total 20
    drwxr-xr-x  4 root root  4096 May 18 18:37 .
    drwxr-xr-x 14 root root  1024 May 18 17:39 ..
    drwx------  2 root root 16384 May 18 17:35 lost+found
    What we did so far was to create the partition image, setup it up as a loop device and mount it into /home/0loop0. This is not permanent, the mount will be lost with the next boot.

    Persisting the changes


    To make this permanent, the same thread is suggesting to change the /etc/init.d/eo-bootfinish script. But on a second look, the start and stop sections allow for additional external scripts, and that's where we're going to create them. I've named the script with a digit prefix so we can control the order in which they are running - later on we are going to add a command to start svnserve and we want to make sure the partition is mount first.
    bash-3.2# cd /etc/oe-initscripts/oe-bootfinish/start.d/
    
    bash-3.2# cat > 0_loop0 << EOL
    losetup /dev/loop0 "/home/system/GoFlex Home Personal/ext3_linux_partition.img"
    mount /dev/loop0 /home/0loop0/
    EOL
    
    bash-3.2# cat 0_loop0
    losetup /dev/loop0 "/home/system/GoFlex Home Personal/ext3_linux_partition.img"
    mount /dev/loop0 /home/0loop0/
    
    bash-3.2# chmod a+x 0_loop0
    Issue a reboot and check it once back on:
    bash-3.2# df -h /home/0loop0
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/loop0            985M   18M  917M   2% /home/0loop0

    While here, we will also prepare a shutdown script to un-mount and disconnect the loop device.
    bash-3.2# cd /etc/oe-initscripts/oe-bootfinish/stop.d/
    
    bash-3.2# cat > 9_loop0 <<EOL
    umount /home/0loop0
    losetup -d /dev/loop0
    EOL
    
    bash-3.2# cat 9_loop0
    umount /home/0loop0
    losetup -d /dev/loop0
    
    bash-3.2# chmod a+x 9_loop0
    Try running it directly to see if it does the job (/home/0loop0 is now the original directory on NAND, the mount is gone, notice Filesystem value):
    bash-3.2# /etc/oe-initscripts/oe-bootfinish/stop.d/9_loop0
    
    bash-3.2# df -h /home/0loop0
    Filesystem            Size  Used Avail Use% Mounted on
    ubi0:rootfs           212M  161M   51M  77% /

    Relocate /opt to external partition image

    bash-3.2# df -h /opt
    Filesystem            Size  Used Avail Use% Mounted on
    ubi0:rootfs           212M  161M   51M  77% /
    
    bash-3.2# mv /opt/ /home/0loop0/
    
    bash-3.2# ln -sv /home/0loop0/opt/ /opt
    create symbolic link `/opt' to `/home/0loop0/opt/'
    
    bash-3.2# df -h /opt
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/loop0            985M   18M  917M   2% /home/0loop0

    Installing the package manager (finally...)

    bash-3.2# cd /opt
    
    bash-3.2# wget http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable/ipkg-opt_0.99.163-10_arm.ipk
    [...]
    18:41:31 (80.4 KB/s) - `ipkg-opt_0.99.163-10_arm.ipk' saved [74474/74474]
    
    bash-3.2# tar xvf ipkg-opt_0.99.163-10_arm.ipk
    ./debian-binary
    ./data.tar.gz
    ./control.tar.gz
    
    bash-3.2# tar xvf data.tar.gz
    ./
    ./opt/
    [...]
    
    bash-3.2# rm control.tar.gz data.tar.gz debian-binary ipkg-opt_0.99.163-10_arm.ipk
    
    bash-3.2# mv opt/* .
    bash-3.2# rmdir opt
    
    bash-3.2# ls /opt
    bin  etc  lib  share
    
    bash-3.2# /opt/bin/ipkg -version
    ipkg version 0.99.163
    
    bash-3.2# echo src cs08q1armel http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable >> /opt/etc/ipkg.conf
    
    bash-3.2# /opt/bin/ipkg update
    Downloading http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable/Packages
    Updated list of available packages in /opt/lib/ipkg/lists/cs08q1armel
    Successfully terminated.

    Wednesday, May 15, 2013

    Seagate GoFlex Home NAS - Installing a package manager

    This comes with a longer story, so I'll try to keep it short. When researching which NAS to buy at the time I found the OpenStora Wiki going in detail on all the things that you can do with not only Netgear Stora, but also with Seagate GoFlex Home NAS, which made it very appealing to me for a small network server. So today, we're going to follow one of the tutorials and install a package  manager, in preparation for other things, like hopefully installing an SVN server :-)

    A word of warning before we go on - if you are not comfortable with the Linux commands and all that, it's probably best to read up more before you do anything, as you might break your NAS system. The good news is that you might be able to factory reset it, but still it's something that you don't want to come to.

    Update 2013-05-18


    Although this should still work with it's problems (see end of the post), you should follow the new post for an alternative solution.

    Preparation


    Aside from the usual personal accounts, I've created a system account as an Administrator through the web interface. The reason for that is we're going to use it's GoFlex Home Personal directory which resides on the HDD to store things outside of the Flash drive - this is to avoid wear as well as running into space issues (df / shows it only has 50 MB left). Just as well you can use your own personal account if you want to.

    SSH remote access


    The OpenStora Easy Root Access wiki page covers it very well. As the article recommends, Putty for Windows or Ubuntu is a very good choice as it allows you to create a session you can reuse later - you can customize things like the font (Window > Appearance) or more useful the auto-login username (Connection > Data), as this is quite long and not that easy to type (USERNAME_hipserv2_seagateplug_XXXX-XXXX-XXXX-XXXX). You can find the product key on the bottom of the unit, or remotely after you logon through the web interface (http://goflex_home) see the About GoFlex Home link in the bottom left corner.

    Installing the package manager


    This is pretty much following the steps in the OpenStora Installing a package manager wiki page, with just a change around the relocation of the /opt to the HDD.

    1. Switch to root access (ignore the audit error):
    -bash-3.2$ sudo -E -s
    Password:
    audit_log_user_command(): Connection refused
    bash-3.2# whoami
    root
    
    2. Move the /opt directory to the HDD and create a symbolic link to it:
    bash-3.2# df /opt
    Filesystem           1K-blocks      Used Available Use% Mounted on
    ubi0:rootfs             216180    164508     51672  77% /
    
    bash-3.2# mv /opt/ /home/system/GoFlex\ Home\ Personal/
    
    bash-3.2# ln -sv /home/system/GoFlex\ Home\ Personal/opt/ /opt
    create symbolic link `/opt' to `/home/system/GoFlex Home Personal/opt/'
    
    bash-3.2# df /opt
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/sda             2930255996 471090240 2459165756  17% /home/system/GoFlex Home Personal
    
    Additionally, we're going to allow everyone to read from the new location:
    bash-3.2# chmod a+rx /home/system/
    bash-3.2# chmod a+rx /home/system/GoFlex\ Home\ Personal/
    bash-3.2# chmod a+rx /home/system/GoFlex\ Home\ Personal/opt/
    
    3. Download and extract the ipkg package.
    bash-3.2# cd /home/system/GoFlex\ Home\ Personal/
    
    bash-3.2# wget http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable/ipkg-opt_0.99.163-10_arm.ipk
    [...]
    14:56:40 (80.4 KB/s) - `ipkg-opt_0.99.163-10_arm.ipk' saved [74474/74474]
    
    bash-3.2# tar -xvf ipkg-opt_0.99.163-10_arm.ipk
    ./debian-binary
    ./data.tar.gz
    ./control.tar.gz
    
    bash-3.2# tar -xvf data.tar.gz
    ./
    ./opt/
    ./opt/bin/
    [...]
    
    bash-3.2# rm control.tar.gz data.tar.gz debian-binary ipkg-opt_0.99.163-10_arm.ipk
    
    bash-3.2# /opt/bin/ipkg -version
    ipkg version 0.99.163
    
    bash-3.2# echo src cs08q1armel http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable >> /opt/etc/ipkg.conf
    
    bash-3.2# /opt/bin/ipkg update
    Downloading http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable/Packages
    Updated list of available packages in /opt/lib/ipkg/lists/cs08q1armel
    Successfully terminated
    

    4. PATH variable (optional)

    Finally, we're going to alter the PATH environment variable so you can run programs from /opt/bin and /opt/sbin, otherwise you'll have to always specify the full path - see the OpenStora wiki page.

    It is probably a good idea to keep the existing SSH session and open up a new one to test the new PATH. This way you have a working session to fix things back, otherwise you'll loose direct access to system commands and you'll have to specify full paths for everything (I know it happened to me :)


    Update 2013-05-17:


    If you find on next reboot that ipkg fails with the message below, it appears to be a problem with the symbolic links on NTFS, see this thread here - they seemed to be valid when first extracted... Since they were links to each other, I will just duplicate the file to replace the links.

    bash-3.2# ipkg
    ipkg: error while loading shared libraries: /opt/lib/libipkg.so.0: file too short
    
    bash-3.2# ls -la /opt/lib/
    total 152
    -rwxrwxrwx 1 apache users     82 May 17 23:45 1
    drwxrwxrwx 1 apache users   4096 May 15 15:00 ipkg
    -r-xr-xr-x 1 apache users     42 May 15 14:57 libipkg.so
    -r-xr-xr-x 1 apache users     42 May 15 14:57 libipkg.so.0
    -rwxrwxrwx 1 apache users 150260 Feb 15  2012 libipkg.so.0.0.0
    
    bash-3.2# cp libipkg.so.0.0.0 libipkg.so
    bash-3.2# cp libipkg.so.0.0.0 libipkg.so.0
    
    bash-3.2# ipkg -v
    ipkg version 0.99.163