Author Archives: goran

rar2fs on FreeNAS 9.2 embeded

This is a quick guide on how I configured rar2fs on my FreeNAS- and shared a rar2fs directory using Samba. My disk is mounted on /mnt/vol1.
Did some tests on my “a few years old hardware” and I got average file transfer speeds around 50 MB/s using cifs.



I found that fusefs-kmod and fusefs-libs packages comes with the FreeNAS embeded install – nice. The module is however not loaded by default.

This can be verified with this command:
>kldstat | grep fuse
27 1 0xffffffff81aaa000 aa63 fuse.ko
That row will not be returned by default.

Load the module with command “kldload fuse.ko”.

To be able to add the rar2fs binary to /usr/local/bin/ and the unrar library to /usr/local/lib/  you need to use unionfs.
First create a directory on your data disk which you can use to mount to /usr/local
>mkdir -p /mnt/vol1/opt/usr_local
Now mount the drive with command:
>mount_unionfs /mnt/vol1/opt/usr_local /usr/local

Note: If you also like to install ports using pkg_add , you also need create directory /mnt/vol1/opt/var and do a mount_unionfs /mnt/vol1/opt/var /var .

Now create a directory somewhere to put the source for unrar, fuse and rar2fs.
>mkdir -p /mnt/vol1/opt/build

Download the needed files.
>cd /mnt/vol1/opt/build
See: (In my case 2.9.3)
See: (in my case 1.20.0)

Extract fuse.
>tar zxvf fuse-2.9.3.tar.gz

Compile libunrar.
>tar zxvf unrarsrc-5.2.1.tar.gz ; cd unrar
For some reason I needed to edit the makefile and make the below changes, otherwise I got some errors, not sure if it is due to differences between linux and freebsd. (Using gmake may also work but its not included in freenas embeded)

Change row 98:

Comment out these 2 rows around row number 134.

Compile and copy the unrar library.
>make lib -f makefile
If I remember correctly, I got some make error regarding missing lgcc , I solved it by creating a temporary mount like “mount_unionfs /mnt/vol1/opt/usr/lib /usr/lib” and then a “ln -s /usr/lib/ /lib/libgcc-something”. Only needed when building libunrar.

>cp /usr/local/lib/

Now you can compile rar2fs.
>tar zxvf rar2fs-1.20.0.tar.gz ; cd rar2fs
> ./configure –with-fuse=/mnt/vol1/opt/build/fuse-2.9.3/include –with-fuse-lib=/usr/local/lib –with-unrar=/mnt/vol1/opt/build/unrar –with-unrar-lib=/usr/local/lib


>cp rar2fs /usr/local/bin/

Try if its working (don´t forget to do a kldload fuse.ko first):

>/usr/local/bin/rar2fs /mnt/vol1/path/to/your/rars/dir /mnt/vol1/rar2fs_myrars
rar2fs[90982]: mounted /mnt/vol1/rar2fs_myrars

If its not working, you can add “-o debug” to run it in debug mode.

If it is working, unmount your rarfs with “umount /mnt/vol1/rar2fs_myrars”.

Now create a startup script to run at freenas start. I added it to /mnt/vol1/opt/ , dont forget to chmod 755
I´ve added seek-length=1 option to rar2fs for performance reasons.
The allow_other option is needed for non-root access to the file system. If you want to browse it with samba, you need this option.

echo "Loading module fuse.ko ..."
/sbin/kldload fuse.ko
echo "Mounting unionfs filesystem /mnt/vol1/opt/usr_local => /usr/local ..."
/sbin/mount_unionfs /mnt/vol1/opt/usr_local /usr/local
# Uncomment below if you want this as well.
#echo "Mounting unionfs filesystem /mnt/vol1/opt/var => /var ..."
#/sbin/mount_unionfs /mnt/vol1/opt/var /var
echo "Starting rar2fs ..."
/usr/local/bin/rar2fs --seek-length=1 -o allow_other /mnt/vol1/path/to/your/rars/dir /mnt/vol1/rar2fs_myrars

Create a init script in FreeNAS. Go to System / Add Init/Shutdown scripts.

Type: Script
Path: /mnt/vol1/opt/
Pre init

Reboot your freenas box.
You can check the console output and you should see the script output like “Starting rar2fs …” etc. (Make note of any error messages)
If your rar2fs mounts well, share it using CIFS if you like.
Note: Sharing using NFS is not working according to some forum threads, something about NFS interacts with the filesystem differently.
You can also add the rar2fs filesystem as storage to a freenas jail, like Plex 🙂

UPDATE: Someone told me that gcc isnt a part of FreeNAS 9.3 , I haven´t confirmed it myself though. Its possible to just add a compiled rar2fs executable and unrar library to a 9.3 install so I made it available in the tar archive below.
If you use these you could get by with just copying rar2fs/unrar-lib to your data disk and perhaps setting LD_LIBRARY_PATH to the correct directory before running rar2fs.

THE QUICK WAY (verified it myself on a clean 9.2 and 9.3 installation):
mkdir /mnt/vol1/opt
# Download the file below
tar xvf rar2fs-freenas9-x86_64.tar
setenv LD_LIBRARY_PATH /mnt/vol1/opt ; /sbin/kldload fuse.ko ; /mnt/vol1/opt/rar2fs –seek-length=1 -o allow_other /mnt/vol1/path/to/your/rars/dir /mnt/vol1/rar2fs_mountpoint


Merlin Bigscreen – OP5 Monitor Unhandled Problems on big screen TV

A fork of Morten Bekkelunds nagios-dashboard based on the OP5 Monitor API.
There is also another fork that uses livestatus that you may want to check out as well:

Note that in my fork, the html/css and fonts/colors may have changed a lot from the original due to lots of non developers playing around 🙂



Installation instructions:

  • Extract the tar ball in the /var/www/html directory of your OP5 Monitor server.
  • You can put the files on the another server as well as long as it can reach the op5 monitor server using https – if you do, don´t forget to update the op5server variable at the top of the config.php file.
  • Make sure your user has API access permission.
  • Go to yourserver/bigscreen in your browser.
  • If you use Active Directory authentication you need to edit the login.php file and update the authtype select box and add your domain there.

The following filtering options are available for passing using the querystring by adding it to end of the url in your web browser, example: http://yourserver/bigscreen/?warnings=false&unknowns=false&nosla=false
The “nosla” option is used to filter out hosts or services which have a custom variable “_SLA” set to the value “none”.
You may also use autologin as a start page in a web browser by using url: http://yourserver/bigscreen/login.php?redir=index.php&autologin=true&username=youruser&password=yourpassword

You can get the files on github:
Or below.


Internet streaming from your Dreambox using VLC transcoding

I rewritten my PHP scripts and released them on github as “Dreambox Transcoding Manager”:

A web based management tool written in PHP that allows you to start VLC transcoding processes on a linux box that streams the video from Enigma 1 and Enigma 2 dreamboxes in realtime to a quality of your choosing. You can then access these streams using the VLC program and other video streaming clients.

tcpdump to file with auto-rotation hourly

Good example of a one liner to trace traffic using tcpdump command to log to a file, suitable for running in the background. The file can later be opened in Wireshark.

It also rotates the file hourly which makes it quicker to download logs only for a specific time period.

This example is listening for traffic from/to port 80.

nohup tcpdump -pni eth0 -s65535 -G 3600 -w '/root/tcpdump/trace_%Y-%m-%d_%H:%M:%S.pcap' port 80 &

If the tcpdump will run for a longer time or generates a lot of large log files, you easily create a separate cronjob that runs find with mtime and does a “rm” of old files.


Dreambox2Popcorn / Dreambox To Popcorn

Stream TV from a Dreambox to a Popcorn Hour. Tested using DM-500 and A-100.
Simple script to generate a html file that can be browsed on the Popcorn Hour box to change channel on the Dreambox (installed with Pli Jade image) and to stream the current channel directly from it.

Use the PHP script below from your workstation / PC.
First visit the built in Web browser on the dreambox.
Click the Web-X-TV link.
View HTML Source for the opened windows.
Copy the first array of your favorites.
channels[0] and channelRefs[0]
Copy the array data and paste to the arrays below.
Replace the mybox variable with the IP of your dreambox.
Run the script. Put the html file in a location where your Popcorn Hour can access it.


echo '
<html xml:lang="en" lang="en" xmlns="">
<body link="007f00" vlink="007f00" alink="007f00" bgcolor="7f0000">
<font face="Arial" color=#ffffff size="9"><br />

$mybox = "";

$channels = array("Channel Blaha", "Channel 2 Blaha");

$channelRefs = array("1:0:1:a8e:2c:46:fff80000:0:0:0:", "1:0:1:a8e:2c:46:fff80000:0:0:0:");

for ($i=0; $i<count($channels); $i++) {
  $chan = substr($channels[$i],0,strpos($channels[$i],"-")-1);
  echo "<a href=\"http://root:dreambox@$mybox/cgi-bin/zapTo?mode=zap&path=" . $channelRefs[$i] . "\">Change channel to $chan</a>" . " | <a href=\"http://$mybox:31344\" vod> Watch TV</a><br/>\n";

echo '

Sending snmp traps from shell scripts

This is short post describing a simple way to send snmp traps from shell scripts using net-snmp snmptrap program on Linux systems.
Create the below shell script. Make sure you have at least 1 trapsink section in your snmpd.conf


snmptrap() {
  for traphost in $(cat /etc/snmp/snmpd.conf | grep trapsink | awk '{print $2}')
    /usr/bin/snmptrap -v 2c -c $SNMPCOMMUNITY $traphost '' DISMAN-SCRIPT-MIB::smScriptResult smRunArgument s "$1" smRunResult s "$2"

snmptrap "TestTrap" "This is a test trap"

This would produce a SNMP trap to your management server looking a bit like this:

2010-02-26 15:30 : DISMAN-SCRIPT-MIB:smScriptResult SNMP Trap
Received Time:2010-02-26 15:30:02
Source: (
Variable Bindings
sysUpTime:= 160 days 6 hours 36 minutes 37,28 seconds (1384779728)
snmpTrapOID:= DISMAN-SCRIPT-MIB : smScriptResult (
smRunArgument:= TestTrap
smRunResult:= This is a test trap

Note: One of the difficulties I found when investigating this was to find a suitable generic MIB to use so I ended up with the DISMAN-SCRIPT-MIB. If you a better way to this, feel free to post a comment.

Monitoring VMware Data Recovery using Nagios

This is a modification of some code I found on VMware forums.
I´ve added some IF checks and nagios return codes + added a way to call the script from nagios nrpe.
(Sorry but I don´t remember where I got the original code now so no contribution list available)
The script checks the VMDR log /var/vmware/datarecovery/operations_log.utx and if errors are found, it will be alerted.
It will also alert when no data has been written to the log for more than a day. I run VMDR every day so this suits me fine but you may want to disable this check.

  1. Logon to the VMDR appliance with SSH
  2. Create the file /usr/lib64/nagios/plugins/ containing this code:
    errorfile=/var/vmware/datarecovery/errors/$(date "+%Y-%m-%d_%H%M%S").txt
    cat /dev/null >> /var/vmware/datarecovery/olderror.out
    strings -e l /var/vmware/datarecovery/operations_log.utx | grep -i "error" | awk -F"$" '{print substr($2,5, 30) substr($3, 9, 100) substr ($6, 17, 30) $8}' > /var/vmware/datarecovery/newerror.out
    # Compare new list of all errors to old list of all errors
    if ! diff /var/vmware/datarecovery/olderror.out /var/vmware/datarecovery/newerror.out >/dev/null
      diff /var/vmware/datarecovery/olderror.out /var/vmware/datarecovery/newerror.out  | grep ">"  > $errorfile
      err=$(cat $errorfile | grep -c ">")
      mv /var/vmware/datarecovery/newerror.out /var/vmware/datarecovery/olderror.out -f
      echo "WARNING - $err new VMDR errors exist. See log file $errorfile for more details. | errors=$err"
      exit 1
      # No errors, but check that VMDR has run recently (today or yesterday)
      today=$(date "+%-m/%-d/%Y")
      yesterday=$(date "+%-m/%-d/%Y" --date="1 days ago")
      strings -e l /var/vmware/datarecovery/operations_log.utx | grep "Performing incremental back up" | egrep "${today}|${yesterday}" >/dev/null 2>&1
      if [ "$?" -ne "0" ]; then
        echo "CRITICAL - VMDR has not run recently (today or yesterday) | errors=1"
        exit 2
        echo "OK - No VMDR errors | errors=0"
        exit 0
  3. Create the directory /var/vmware/datarecovery/errors
  4. Edit /etc/sudoers and add:
    nagios  ALL=NOPASSWD: /usr/lib64/nagios/plugins/
    (don´t forget to remove the comment for Defaults requiretty – otherwise nrpe can´t use sudoers)
  5. The rpm nagios-nrpe needs to be installed to the appliance. It has some dependencies but I installed it with –nodeps and it works just fine.
  6. Add this row to /etc/nagios/nrpe.cfg:
    command[check_vmdr]=sudo /usr/lib64/nagios/plugins/
  7. I also copied the check_disk plugin to the appliance and added this row to nrpe.cfg to monitor disk usage:
    command[check_disk]=/usr/lib64/nagios/plugins/check_disk -w 10% -c 5% -p /SCSI*
  8. service nrpe start ; chkconfig nrpe on
  9. Done.

Simple backup script for VMware ESX VMs

– UPDATE 2013-02-04 –
This is a simple backup script for ESX that I use for backing up my virtual machines on my stand alone ESX server at home.
For my data disks I use traditional backup in the OS so I only backup the vmdks containing the OS and exclude the data vmdks where all my big files are located, this is done by touching a .exclude file in the same directory, example “VMName_1-flat.vmdk.exclude”.
The backup can be performed while the VMs are turned on since a snapshot is taken first, releasing the lock on the VMDK file. And when the backup is completed, the snapshot is removed. This means that the script needs to handle the possibility of failed snapshots.
For me, a successful backup is more important than a little downtime on my VMs so I turn of the VM if that happens.

Note: script only tested on ESXi 5.1


# Add cron job to this file: /var/spool/cron/crontabs/root
# 10   0    *   *   *   /vmfs/volumes/datastore1/scripts/ >/vmfs/volumes/datastore1/scripts/backup-vms.log 2>&1
# Check crond pross id
# cat /var/run/
# Kill old crond
# /bin/kill $(cat /var/run/
#  Restart cron jobs (for 5.1)
# /usr/lib/vmware/busybox/bin/busybox crond
# Check again crond pross id (Should not be above id)
# cat /var/run/

today=$(date "+%A")
VMs="Solaris Tellus-ng Venus Mercury-ng"

if [ ! -d "$destdir" ]; then
  mkdir -p $destdir

for vm in $VMs; do
  echo "Backing up $vm ..."
  if [ -d "$VMdir" ]; then
    vmid=$(vim-cmd vmsvc/getallvms | grep $vm | awk '{ print $1 }')
    if [ "$vmid" -gt "0" ]; then
      echo "Creating a snapshot of the VM ..."
      vim-cmd vmsvc/snapshot.create $vmid backup-snap "Snapshot for backup script" 0 1
      if [ "$?" -ne "0" ]; then
        echo "Failed to create snapshot, shutting it down instead ..."
        vim-cmd vmsvc/power.shutdown $vmid
        echo "Sleeping 60 seconds to wait for VM shutdown ..."
        sleep 60
        echo "Checking if VM state is powered off ..."
        vim-cmd vmsvc/power.getstate $vmid | grep "Powered off"
        if [ "$?" -ne "0" ]; then
          echo "VM is still not powered off , you´re going DOWN bitch!..."
          vim-cmd vmsvc/ $vmid
          sleep 5
      echo "Starting backup of VM files ..."
      if [ ! -d "$VMdestdir" ]; then
        mkdir $VMdestdir
        rm -rf $VMdestdir/*
      for file in $(ls -1 $VMdir | egrep -v "flat|exclude|delta|vswp"); do
        if [ -f "$VMdir/$file.exclude" ]; then
          echo "Excluding $file ..."
          if [ "$fext" == "vmdk" ]; then
            grep parentFileNameHint $VMdir/$file >/dev/null
            if [ "$?" -eq "0" ]; then
              echo "Vmdk is snapshot file , ignoring ..."
              echo "Copying $fext file $file using vmkfstools ..."
              vmkfstools -d thin -i $VMdir/$file $VMdestdir/$file
            echo "Copying $fext file $file ..."
            cp $VMdir/$file $VMdestdir/
      echo "Backup completed ..."
      vim-cmd vmsvc/power.getstate $vmid | grep "Powered off"
      if [ "$?" -eq "0" ]; then
        vim-cmd vmsvc/power.on $vmid
        vim-cmd vmsvc/snapshot.removeall $vmid
        echo "Copying vmx file again (since changed after snap removal) ..."
        cp $VMdir/*.vmx $VMdestdir/
      echo "vmid is not numeric."
    echo "VMdir $VMdir does not exist"

Video encoding for different purposes

This is a post for some ffmpeg/mencoder commands for encoding/extracting video/audio etc…

Utilities used:

# Encoding to AVI/XVID (Also playable by CorePlayer for Windows Mobile)
# br=92 means audio bitrate is 92 kb/s
# -xy 800 means resolution width is 800 pixels
# fixed_quant=5 is quality factor
mencoder.exe “Movie.mkv” -oac mp3lame -lameopts abr:br=92 -ovc xvid -vf scale -zoom -xy 800 -xvidencopts fixed_quant=5 -o “Movie.avi”

# Same as above but with subtitles
# Try these two settings to set subtitles layout:
# -subfont-text-scale 3.3
# -subpos 96
mencoder.exe “Movie.mkv” -oac mp3lame -lameopts abr:br=92 -ovc xvid -vf scale -zoom -xy 800 -xvidencopts fixed_quant=5 -o “Movie.avi” -sub

# Encoding to mpeg4/aac – Playable on many phones like Sony Ericsson, Samsung, Windows Mobile 5 and higher, etc …
ffmpeg.exe -i “Movie.avi” -acodec libfaac -b 320000 -r 25 -s 320×244 -vcodec mpeg4 -ab 96000 “Movie.mp4″

# Encoding to mpeg4/arm/3gp – Playable on older Sony Ericsson phones, etc
ffmpeg.exe -y -i “Movie.avi” -s qcif -vcodec mpeg4 -acodec libopencore_amrnb -ac 1 -ar 8000 -r 25 -ab 12200 -s 220×176 -b 192000 “Kung Fu Panda.3gp”

# Extract AC3 and re-encode audio from a movie.
# To extract second audio stream, use: -map 0:2
ffmpeg.exe -i “Movie.mkv” -vn -acodec ac3 -ac 6 -ab 320000 “Movie-Audio.ac3″

uTorrent RSS Downloader and e-mail notification for completed downloads

I recently found the nice feature RSS Downloader in uTorrent where you can choose to download things automatically using RSS.
This function lacks one thing – some kind of message or notification when it has started or finished a download.
So I created the below Windows Power Shell script that runs every 10 minutes and sends an e-mail if a new torrent has been added to the uTorrent data-directory and if that torrent´s name can be found in the uTorrent rss.dat file – which stores a list of all torrents downloaded using RSS Downloader.

# GetNewuTorrentDownloads.ps1
# uTorrent RSS Downloader notification script
$From = ""
$To = ""
$tenminutesago = (get-date).AddMinutes(-10)
# Note: you may need to change the path to your uTorrent data directory.
$recs = Get-ChildItem "C:\Users\Administrator\AppData\Roaming\uTorrent\*.torrent" |
        where-object {$_.lastwritetime -gt $tenminutesago} |
        Sort-Object LastWriteTime -Descending
if ( $recs.Length -gt 0 ) {
  foreach ($TorrentFile in $recs) {
    $TorrentName = $TorrentFile.Name.Replace(".torrent", "")
    $TorrentDownloaded = $TorrentFile.LastWriteTime
    # Note: you may need to change the path to your uTorrent data directory.
    $sel = select-string -pattern $TorrentName -path C:\Users\Administrator\AppData\Roaming\uTorrent\rss.dat
    if ($sel -ne $null) {
        $subject = "$TorrentName has been downloaded"
        $body = "The torrent $TorrentName was downloaded at $TorrentDownloaded ."
        $smtp = New-Object System.Net.Mail.SmtpClient("", "25");
        # Uncomment the below row if your ISP´s outgoing mail server requires authentication.
        #$smtp.Credentials = New-Object System.Net.NetworkCredential("username", "password");
        $smtp.Send($From, $To, $subject, $body);