Sunday, October 16, 2011

Prime algorithm in assembler

One of the greatest strengths of assembly language is the extreme compactness of code. Digging though my old files I found this gem that prints all prime numbers under 2^32. The COM file size is 165 bytes. That's right! You could memorize the bytes if you wanted to and hand assemble it.

The algorithm is not sieve (which would create 2^31 locations and strike off multiples of primes). Rather this is a space optimized algorithm that repeatedly divides each number n from 2 to sqrt(n) to determine if a number is prime. This algorithm uses no additional storage than the 165 bytes to hold the code.



.model tiny
.code
.386
        org     100h
start:
main    proc
        xor     eax,eax
        mov     al,3
@@m2:
        call    isprime
        jnc     @@m1
        call    printdword
        call    printcrlf
@@m1:
        inc     eax
        jnz     @@m2


        mov     ax,4c00h
        int     21h
main    endp


isprime proc
        pushad
        mov     esi,eax         ; save number
        xor     ecx,ecx
        mov     ebx,ecx
        mov     edx,ecx         ; edx = 0
        call    sqrt
        mov     cx,ax           ; save sqrt
        mov     bl,2            ; ebx = 2 (divisor)
@@i2:
        mov     eax,esi         ; restore number
        cmp     ecx,ebx         ; is sqrt < divisor?
        jl      @@i4            ; yes, no need to divide any more
        div     ebx
        or      edx,edx
        jz      @@i1
        xor     edx,edx
        inc     ebx
        jnz     @@i2
@@i4:
        stc
        jmp     @@i3
@@i1:
        clc
@@i3:
        popad
        ret
isprime endp


sqrt    proc
        push    ebx
        push    ecx


        xor     ecx,ecx
        mov     ebx,ecx
@@s2:
        inc     ebx
        sub     eax,ebx
        jl      @@s1
        inc     cx
        inc     ebx
        jmp     @@s2
@@s1:
        mov     ax,cx


        pop     ecx
        pop     ebx
        ret
sqrt    endp


printdword      proc
        pushad
        xor     ebx,ebx
        mov     cx,bx
        mov     bl,10
@@p1:
        xor     edx,edx
        div     ebx
        push    dx
        inc     cx
        or      eax,eax
        jnz     @@p1
@@p2:
        pop     ax
        add     al,'0'
        mov     dl,al
        mov     ah,02
        int     21h
        loop    @@p2


        popad
        ret
printdword      endp

printcrlf       proc
        pusha
        mov     dl,13
        mov     ah,02
        int     21h
        mov     dl,10
        mov     ah,2
        int     21h
        popa
        ret
printcrlf       endp
        end     start




Tuesday, August 16, 2011

Fix for NFS v4 inverse squashing

Due to an NFS Bug, when ZFS is shared over NFS4 on the client side all files will appear owned by nobody:nogroup. If idmapd is not set it will be 4294967294: 4294967294.

The client can still read and write and the files will appear normally on the server. Chown will fail, which means you cannot run VM images off this share.

Mounting this with nfs option vers=3 in /etc/fstab is the only workaround until the bug is fixed.


Native (non-FUSE) ZFS on linux

Thanks to Darik Horn, we can have native ZFS on linux. Instructions here. Works on natty, but may have issues on Lucid.

Note:

  1. Preemptible kernels not supported. This should be OK for servers. 
  2. The ppa does not actually cover all dependencies. I had to figure out zlib1g-dev and uuid-dev


sudo add-apt-repository ppa:dajhorn/zfs
sudo apt-get update
sudo apt-get install zlib1g-dev uuid-dev ubuntu-zfs 

If you get the following error, the build is unsuccessful:

Failed to load ZFS module stack.
Load the module manually by running 'insmod /zfs.ko' as root.

To determine missing dependencies:

cd /var/lib/dkms/zfs/*/build
./configure. # Error message will tell you what dependencies are missing
make
make install

Repeat or other directories under dkms if they had errors. If you get any error regarding unknown symbol or module format, you have booted the wrong kernel.

Update: As of Ubuntu precise 12.04, ubuntu-zfs installs flawlessly and takes care of all dependencies.

Wednesday, July 27, 2011

Migrating running VMs using virsh

Prerequisites:


  1. All VM images are mounted on a shared location,  for example: /vmimages. If any images are qcow2 images with a backing file, those files also need to be present on shared locations.
  2. kvm-pxe needs to be installed. If not, the migration occurs, but the VM is suspended at the destination.
  3. Optional: If you want to be able to do this from scripts, setup ssh keys so you don't need to enter passwords


Migrate with the following command as root on the source host:


virsh migrate --live vmname qemu+ssh://destination.host/system

or if you are not on source, you can first connect to the source host


virsh --connect qemu://source.host/system migrate --live vmname \
      qemu+ssh://destination.host/system



Sunday, July 03, 2011

Read only root on VMs

Follow the instructions from here: https://help.ubuntu.com/community/aufsRootFileSystemOnUsbFlash


disable app-armor on dhclient (otherwise networking will fail)
sudo aa-complain /etc/apparmor.d/sbin.dhclient




edit /etc/grub.d/00_header to not show menu on unclean close:


# if [ "\${recordfail}" = 1 ]
# then
set timeout=-1
#else
set timeout=${2}
#fi


Optionally, you can choose to not unmount NFS paritions, etc in /etc/rc0.d/S35networking and S40unmountfs

Thursday, June 30, 2011

Exporting ZFS filesystem over NFS

First you need to install nfs-kernel-server. You also need a later kernel: 2.6.35 or better

Install zfs native (or zfs-fuse):

sudo add-apt-repository ppa:dajhorn/zfs
sudo apt-get update
sudo apt-get install ubuntu-zfs 

By default NFS sharing is off. To export a zfs filesystem, say zfs/home:


#Setup shared FS
zfs create -o compression=on -o atime=off -o sharesmb=on zfs/home

#export RO
zfs set sharenfs=ro zfs/home

#stop exporting. Also for next command to take effect
zfs set sharenfs=off zfs/home  

# export RW, fsid needs to be unique per filesystem
zfs set \
 sharenfs=10.1.1.0/24:rw,fsid=100,no_subtree_check,async,no_root_squash zfs/home

# add this to /etc/rc.local
zfs share -a

#To mount from OSX use the following command. -P option is for secure (<1024) ports
mount_nfs -P 10.1.1.1:/zfs/home/${USER} /mnt/home

Later invocations override earlier, so to export RW to only one host and RO to others:



zfs set sharenfs=off zfs/backup
zfs set sharenfs=10.0.0.0/8:ro,no_subtree_check,async,no_root_squash zfs/backup
zfs set sharenfs=10.1.1.1:rw,no_subtree_check,async,no_root_squash zfs/backup

The host writing the backup is 10.1.1.1 and will get read/write access. The rest will get read only access.

Note: Setting the mountpoint property of a ZFS dataset to anything other than the default pool/dataset will cause it to be exported with all_squash. Do not change the mountpoint if you want to NFS share a dataset

If you are getting a lot of stale NFS handles, the IO requests are timing out before they can be serviced due to heavy IO load. Mount your NFS shares using these options (example fstab entry):


server:/zfs/dataset    /mnt       nfs     defaults,timeo=20,retrans=5,rsize=8192,wsize=8192,intr    0       0


The timeo to 2 seconds from default of 0.7 seconds is the most important attribute.

Friday, June 03, 2011

Minimal graphical Ubuntu install


#!/bin/sh
# Minimal Ubuntu Graphical install
sudo apt-get install gnome-panel gdm gnome-terminal network-manager-gnome \
network-manager gnome-power-manager chromium-browser \
ubuntu-artwork libaudiofile0 flashplugin-installer

Wednesday, May 18, 2011

Time machine on a network drive

A very good explanation of how to use a network drive for time machine. However, there is no need to reboot your OS X once you change the setting. I also make a shell script to create a time machine compatible network drive using all the above steps automatically. Enjoy!



#!/bin/sh
# Create a time machine compatible network drive 
# (c) codebytez.blogspot.com
NETLOC=$1
if [ -z "$1" ]
then
        echo Usage: $0 /Volumes/network_volume \[size\]
        exit 1
fi

if [ -z "$2" ]
then
        SIZE=100g
else
        SIZE=$2
fi

defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
MAC=`ifconfig en0 | grep ether | perl -lne 'print @f if (@f = /[0-9a-f]{2}/g)'`
HOST=`echo $HOSTNAME | perl -F'\.' -lane 'print $F[0]'`
VOL=${HOST}_${MAC}.sparsebundle
hdiutil create -size $SIZE -fs HFS+J -volname "Time Machine" $VOL
rsync -aE $VOL $NETLOC
rm -rf $VOL
echo Created $NETLOC/$VOL
echo Select as backup disk in Time Machine Preferences