Sunday, September 21, 2014

Install VMPlayer in Ubuntu 14.04 64-bit

1. Download VMware-Player-5.0.4-1945795.x86_64.bundle.
2. Run the bundle.
chmod +x VMware-Player-5.0.4-1945795.x86_64.bundle
sudo ./VMware-Player-5.0.4-1945795.x86_64.bundle
3. Run VMware Player from dashboard which will ask for modules to be compiled and added to kernel. Proceed with Install option. But vmnet will fail to build which will be shown in the error log (/tmp/vmware-root/vmware-modconfig-xxxxx.log).
4. The fix is to patch vmnet-only/filter.c file with the content below. Copy the patch code to say p.patch under /usr/lib/vmware/modules/source
--- vmnet-only/filter.c 2013-10-18 23:11:55.000000000 +0400
+++ vmnet-only/filter.c 2013-12-03 04:16:31.751352170 +0400
@@ -27,6 +27,7 @@
 #include "compat_module.h"
 #include 
 #include 
+#include 
 #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
 #   include 
 #else
@@ -203,7 +204,11 @@
 #endif

 static unsigned int
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
 VNetFilterHookFn(unsigned int hooknum,                 // IN:
+#else
+VNetFilterHookFn(const struct nf_hook_ops *ops,        // IN:
+#endif
 #ifdef VMW_NFHOOK_USES_SKB
                  struct sk_buff *skb,                  // IN:
 #else
@@ -252,7 +257,14 @@

    /* When the host transmits, hooknum is VMW_NF_INET_POST_ROUTING. */
    /* When the host receives, hooknum is VMW_NF_INET_LOCAL_IN. */
-   transmit = (hooknum == VMW_NF_INET_POST_ROUTING);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+    transmit = (hooknum == VMW_NF_INET_POST_ROUTING);
+#else
+    transmit = (ops->hooknum == VMW_NF_INET_POST_ROUTING);
+#endif
+    packetHeader = compat_skb_network_header(skb);
+    ip = (struct iphdr*)packetHeader;
sudo su -
cd /usr/lib/vmware/modules/source
tar -xvf vmnet.tar
#run the patch
patch vmnet-only/filter.c < patch.patch
tar -uvf vmnet.tar vmnet-only
rm -r vmnet-only
vmplayer
You should install the simulator as a normal user for vmplayer to boot else try running the player as root, which is not recommended.

Thursday, July 31, 2014

Install MariaDB with Custom Data Directory in Ubuntu

Here are the steps to install and configure MariaDB (v10.1.0) (a fork of MySQL) with custom data directory in Ubuntu (14.04). The MySQL server will be run as the current logged in user. You can have user as mysql, but then you will have to figure out permissions and such. If you do not want to change the default data directory then it's better to go with mysql-server package from the repository.

I was not able to get MySQL to start after changing the data directory and adding overrides in apparmor. I guess it has to do with the data directory location and permission. Next I tried installing MySQL from source so that I can specify custom directories during install time, but the build fails with this stupid ../libperfschema.a(pfs_defaults.cc.o):(.eh_frame+0x8b): undefined reference to `__gxx_personality_v0' error. But MariaDB builds and works like a champ.

1. Clone MariaDB source code from github or get the latest release version.
wget https://github.com/MariaDB/server/archive/mariadb-10.1.0.tar.gz
tar xzf mariadb-10.1.0.tar.gz
cd server-mariadb-10.1.0
2. Install dependencies.
sudo apt-get install libboost-dev libjemalloc-dev libjudy-dev bison flex libevent-dev liblzo2-dev liblz4-dev libaio-dev libpam-dev valgrind binutils-dev libatomic-ops-dev
Also check to see if any libraries are not found during the configure process. If so install the dev versions.
3. We will install MariaDB to /opt/mysql/ with data directory as say /home/username/files/mysql. The data directory corresponds to /var/lib/mysql.
cmake . -DCMAKE_INSTALL_PREFIX=/opt/mysql -DMYSQL_DATADIR=/home/username/files/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_bin -DMYSQL_UNIX_ADDR=/tmp/mysql.sock
make
sudo make install
4. Add /opt/mysql/bin and /opt/mysql/support-files to .bashrc and source ~/.bashrc the paths.
5. Create data directory if not exists and install data.
cd && mkdir -p ~/files/mysql && cd files
sudo chown -R username:groupname mysql #logged in user and group
sudo chmod 777 mysql #rw to all. But since it resides inside your home dir, others cannot get into it.
# Install db
sudo /opt/mysql/scripts/mysql_install_db --datadir=/home/username/files/mysql --basedir=/opt/mysql
# Start server
mysql.server start
# Secure the installation with root password, removing test data etc.
sudo /opt/mysql/bin/mysql_secure_installation
6. Login as root.
mysql -uroot -p
You can further configure mysql server using my.cnf file. Example files customized for the current installation will be located at /opt/mysql/support-files. You can copy any of the cnf file to /etc/mysql/my.cnf and make necessary change there. After that restart the mysql server. You can check if the right config file is loading by using strace.
strace mysqld
# .. output will contain
# stat("/etc/my.cnf", 0x7fff4759dc20)     = -1 ENOENT (No such file or directory)
# stat("/etc/mysql/my.cnf", {st_mode=S_IFREG|0644, st_size=4913, ...}) = 0
# open("/etc/mysql/my.cnf", O_RDONLY)     = 3
# ...
If you want to auto start MySQL on system startup, you can move mysql.server to /etc/init.d/ and update runlevel script execution.
sudo cp /opt/mysql/support-files/mysql.server /etc/init.d/mysql && cd /etc/init.d/
# enable auto start
sudo update-rc.d mysql defaults
# disable auto start of mysql
sudo update-rc.d mysql disable
# remove auto start of mysql altogether
sudo update-rc.d mysql remove
Basically having data directory on an encrypted filesystem would be very useful and is recommended (by me) and in such cases, do not auto start MySQL as the data will be unavailable unless you mount it manually. So is the case with your web sever data directory.

Tuesday, July 29, 2014

Install noip2 in Ubuntu

1. Download noip2 source
cd ~/Downloads
wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
tar xvzf noip-duc-linux.tar.gz
cd noip-2.1.9-1/
2. We compile it with -O3 optimization given as CFLAGS variable and install it to /opt/noip. So modify Makefile to reflect those changes (see line numbers).
CFLAGS=-O3 -Wall -g
PREFIX=/opt/noip
${TGT}: Makefile ${TGT}.c
        ${CC} ${CFLAGS} -D${ARCH} -DPREFIX=\"${PREFIX}\" ${TGT}.c -o ${TGT} ${LIBS}
3. Compile and install.
make
sudo make install
4. During the installation give in all no-ip details like username, password, no-ip domain name etc, which is similar to configuring the Windows client. The configuration file will be saved to /opt/noip/etc/no-ip2.conf. Now change the ownership of the directory to the logged in user so that no-ip can read the config file.
cd /opt
ls -la #see the ownership
sudo chown -R user:group noip  #replace user and group with your username and group most likely would be your username.
#So if your username is foo, and belongs to foo (most likely is), the run 
#sudo chown -R foo:foo noip
ls -la 
cd noip && ls -la #check ownership has been updated.
5. Setup start-stop script. You can change the prefix, optimization and such by editing the Makefile.
#Install killproc
wget ftp://ftp.suse.com/pub/projects/init/killproc-2.13.tar.gz
tar xvzf killproc-2.13.tar.gz
cd killproc-2.13/
make && sudo make install
6. Create a file /etc/init.d/noip with the following content
#! /bin/sh
# . /etc/rc.d/init.d/functions # uncomment/modify for your killproc
case "$1" in
    start)
    echo "Starting noip2."
    /opt/noip/bin/noip2
    ;;
    stop)
    echo "Shutting down noip2."
    killproc -TERM /opt/noip/bin/noip2
    ;;
    *)
    echo "Usage: $0 {start|stop}"
    exit 1
esac
exit 0
7. Now you can start and stop the service using
/etc/init.d/noip start  #start
/etc/init.d/noip stop   #stop
8. Add the service to update-rc.d to auto start at system startup.
cd /etc/init.d/
sudo update-rc.d noip defaults
9. Check is the ip is updated by logging into the noip.com website. If you are using a CNAME alias, say www of your domain name to this dynamic IP, you can check it using nslookup.
nslookup www.example.com

Tuesday, July 15, 2014

Adjust Screen Brightness in OS X using Terminal

OS X screen brightness can be adjust via Terminal using an application called brightness.
The brightness values are between 0 and 1, where 1 being the maximum brightness. Copy the file to say /usr/local/bin and run it with sudo.
sudo cp brightness /usr/local/bin/
sudo brightness 0.25

Wednesday, May 7, 2014

A Simple CSV Parser in Erlang

A simple CSV parser in Erlang. Usually splitting a line by comma would suffice unless a value itself is a string containing commas. This considers such cases as well.
parse_csv(String) -> parse_csv(String, [], [], [], false).

parse_csv([], S, Acc, [], _) -> lists:reverse(lists:map(fun(X) -> lists:reverse(lists:flatten(X)) end, [Acc|S]));
parse_csv([], S, [], L, _) -> lists:reverse(lists:map(fun(X) -> lists:reverse(lists:flatten(X)) end, [L|S]));
parse_csv(String, S, Acc, L, IsSubStr) ->
    case String of
        [$"|T] when IsSubStr =:= true ->
            % end of substring (ending quote).
            parse_csv(T, S, Acc, [$"|L], false);
        [$"|T] when IsSubStr =:= false  ->
            % beginning of a substring (beginning quote).
            parse_csv(T, S, Acc, [$"], true);
        [$,|T] when IsSubStr =:= true andalso L =/= [] ->
            % comma within a substring
            parse_csv(T, S, Acc, [$,|L], true);
        [$,|T] when IsSubStr =:= false andalso L =/= [] ->
            % comma after a substring.
            parse_csv(T, [[L|Acc]|S], [], [], false);
        [$,|T] when IsSubStr =:= false andalso L =:= [] ->
            % comma after a normal string.
            parse_csv(T, [Acc|S], [], [], false);
        [H|T] when IsSubStr =:= true ->
            % within a substring
            parse_csv(T, S, Acc, [H|L], true);
        [H|T] when IsSubStr =:= false ->
            % a normal string
            parse_csv(T, S, [H|Acc], [], false) end.
Example usage
1> c(ql).
{ok,ql}
2> ql:parse_csv("1,\"Abc, cdf\",3.0").
["1","\"Abc, cdf\"","3.0"]
3> ql:parse_csv("1,xyz,3.0").         
["1","xyz","3.0"]

Wednesday, February 26, 2014

Chrome Dev Tools For Mobile

Chrome browser has support for touch screen, mobile device emulation, accelerometer, geolocation emulation etc. Previously some of this was accessible from the Settings gear icon in the dev tools. Now it can be accessed from the console menu icon or by pressing ESC key from the dev console.



Sunday, January 12, 2014

FizzBuzz with Java 8

Using problem 1 from ProjectEuler to illustrate a few Java 8 constructs.
import java.util.stream.IntStream;

/** Project Euler Problem 1 using Java 8 idioms */
public class FizzBuzz {
    public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        long res =
            IntStream.rangeClosed(1, 10000).
            filter(x -> x % 3L == 0L || x % 5L == 0L).
            sum();
        long t2 = System.currentTimeMillis();
        System.out.println(t2-t1);
        System.out.println(res);
    }
}
No particular care is given to runtime performance. This is just to illustrate new constructs added to Java 8 like streams, filters, lambdas etc. Good to see functional programming constructs and styles getting added to mainstream languages. As of now, you can run this using Java 8 Early Access Edition with Lambda support.