nodereality

node c0re

Using ufsid with FreeBSD

written by Ghirai, on Jan 14, 2010 9:57:00 PM.

This feature has been present since 7.2, but it's less verbose in 8.0 (we'll get to that soon). Basically these labels decouple the devices from the actual device node.

What this means is that you can move the devices around (like on a different hardware port, different system, even different driver/controller), and all your mountpoints will work fine.

You could also use plain UFS labels (which serve the same purpose), with the only difference being that plain UFS labels exist if someone created them, and you also need to pay attention to duplicates. On the other hand ufsids are always present without any additional action, and they are unique.

Before 8.0, you would see the ufsid labels in dmesg by default. Now you have to add this to /boot/loader.conf and reboot:

kern.geom.label.debug=1

You will see something like this in dmesg:

GEOM_LABEL[1]: UFS2 file system detected on ad2s1a.
GEOM_LABEL[1]: Label for provider ad8s1a is ufsid/5b30a2f125a1d114.

In fstab you can now have instead of your usual entries:

# Device        Mountpoint
/dev/ad2s1a     /

this:

# Device                        Mountpoint
/dev/ufsid/5b30a2f125a1d114     /

Because swap is not an actual filesystem, you need to make a plain UFS label for it:

#glabel label swap /dev/ad2s1b

Then add it to /etc/fstab as well:

# Device        Mountpoint
/dev/label/swap     none

That's it, you can now reboot an enjoy your portable disks.

Important: ufsids will not work with geli. The reason is that the ufsid for your encrypted provider will only be available after geli has attached, and for that you obviously can't use that very same ufsid because it doesn't exist yet. If anyone has a solution for this let me know.

Monitoring nginx with munin

written by Ghirai, on Jan 6, 2010 11:34:00 PM.

If you ever wanted to know how to graph nginx requests, here's one way of doing it.

You can tail the logfile(s) and calculate the requests in a give time interval, but fortunately there's a much simpler way. The first thing to do is to set things up so that we can read the statistics. Edit your nginx.conf and add the following (doesn't matter in which server{} block you add it):

location /my_nginx_stats {
  stub_status on;
  access_log off;
  allow 127.0.0.1;
  deny all;
}

If you want to gather data from a remote machine, change the allow line, or remove it alltogether (in that case remove the deny line as well).

Now if you browse to http://127.0.0.1/my_nginx_stats you will see something like this:

Active connections: 1 
server accepts handled requests
 21 21 23 
Reading: 0 Writing: 1 Waiting: 0 

With this data it's trivial to write a munin plugin:

#!/usr/local/bin/python
import sys
import urllib

LOCATION = 'http://127.0.0.1/my_nginx_stats'

if len(sys.argv) == 2 and sys.argv[1] == "autoconf":

  print "yes"

elif len(sys.argv) == 2 and sys.argv[1] == "config":

  print 'graph_title nginx connections'
  print 'graph_vlabel current connection count'
  print 'graph_category Web'

  print 'conn.label connections'
  print 'graph_args --base 1000 -l 0'

else:

  h = urllib.urlopen(LOCATION)
  t = h.read()
  h.close()

  l = t.split('\n')[0]
  conn = int(l[20:-1])-1

  print 'conn.value %s' % conn

Finally, here's a picture to go with the code:

example nginx munin graph

Abusing Fish (For Fun, Not Profit)

written by Alan, on Jan 3, 2010 9:42:00 PM.

I have been very bored and then yesterday Remy showed me this. And doing so was a very bad idea, let me explain why.

Tankedcam is an interactive fish tank. Backed by a servo board and a front-end webpage, you're able to press buttons to control what happens inside the tank. The live demo on the website contains a few interesting things.

  • Dino - Open/close the jaw of the dino. (I see it as a fish chomper)
  • Air Stone - A jet of bubbles. (Bubble blaster right?)
  • Flashlight - Makes things bright. (Blinds em -.-)

However, I cant press the buttons fast enough to chomp anything and the flashlight turns off after 10 seconds. But I can abuse the programming. The webpage sends GET requests when you press one of the buttons on the controller although a session ID and timestamp is needed. There is a very simple way to overcome this, i'll just use javascript mouse events to simulate the onclick event of the buttons.

Few minutes later I have a very simple script that rapidly 'clicks' the open and close buttons for the dino jaw. I add support for the other tank functions and Fish Hack Script was finished.

One thing I have noticed if I lower the timer the whole servo starts to play up, maybe it cant draw enough power. :(

Anyway, have fun the script is here (UPDATE: Right click save, nodereality referer has been blocked). If you catch a fish in the chomper I want a picture, there is also some snails that come out at night they move slower. I had fun throwing one of the top off the chopper.

munin plugin for gstat

written by Ghirai, on Dec 29, 2009 1:02:00 AM.

gstat(8) is an utility that shows GEOM providers (and consumers) statistics.

It would be useful to have a munin plugin that plots IO activity if you have a storage box or a similar setup where there's a lot of disk action going on.

The code is for Python 2.6; if you're running 3.x you need to make slight adjustments (like print). Usage instructions are in the comments.

#!/usr/bin/env python
'''
Munin plugin to monitor I/O transactions of geom(4) devices
on FreeBSD as reported by gstat(8).

To get the list of devices you might want to monitor,
run gstat.
If your device contains '/', substitute it with '_';
example: mirror/myarray -> mirror_myarray

Install it as any other munin plugin (if you want to monitor
device foo, symlink the plugin in your plugins directory
as gstat_foo.py).

The plugin need to be run as root.
Add these 2 lines to your plugins.conf:
[gstat_*]
user root

You need to restart munin_node for the changes to take effect.


Written by ghirai-at-ghirai-d0t-com
'''

import sys
from subprocess import Popen,PIPE
from string import split


device = sys.argv[0][(sys.argv[0].find('_')+1):]
if device == None: sys.exit(1)

device = device.replace('_','/')

if len(sys.argv) == 2 and sys.argv[1] == "autoconf":

  print "yes"

elif len(sys.argv) == 2 and sys.argv[1] == "config":

  print 'graph_title I/O transactions for %s' % device
  print 'graph_vlabel Transfers in kBps'
  print 'graph_category Disk'

  print 'r.label read'
  print 'w.label write'

  print 'graph_args --base 1000 -l 0'

else:

  r = 0
  w = 0

  res = Popen(['gstat','-b'],stdout=PIPE).stdout.read()
  res = res.split('\n')

  for ln in res:

    lns = split(ln)
    lns.reverse()

    try:
      if lns[0] == device:
        r = lns[6]
        w = lns[3]
        break
    except IndexError:
      break

  print 'r.value %s' % r
  print 'w.value %s' % w

Maintenance over

written by Ghirai, on Dec 23, 2009 10:28:00 PM.

Hopefully. All the old posts will be back in the near future.

We apologize for the prolonged downtime; it was a combination of hardware failures, lazyness, one's inability to decide on software, and lack of time.