Aug 082013
 

I use FreeBSD. I’ve used it since 1998. For me, it does good stuff, reliably, and predictably. The community is very supportive and helpful. That goes a long way when choosing your open source operating system.

Included within FreeBSD, since FreeBSD 4.0 in March 2000, is a great tool for separating out services and to provide a virtualization strategy: jails. Some will argue that jails are not virtualization. I contend that it’s a perfectly acceptable method of virtualization.

I can create 28 jails on a single host system and use them for teaching purposes. Each student can ssh in, use FreeBSD and learn the basics and then move on to advanced topics. All on a single machine. The cost of creating one host with N jails is considerably less than purchasing and running N pieces of hardware.

Bacula

This post is about getting Bacula running in a jail, but the same strategy can be applied to any jail which needs to access hardware which is, by default, not accessible within a jail. I’ve been using Bacula since 2004, and it really is the best backup system I’ve ever used. In the past, I’ve always run Bacula on the host sytem, and never in a jail. I recently moved both the Director and the Storage Daemon into a jail. That move happened about two weeks ago. Now I want that Storage Daemon to use a tape library. In my case, I want one jail, and only that jail, to have access to the tape library; specifically, the autochanger and the tape drive.

How do you give permission to a jail?

Early on, I didn’t know how to grant permissions for a jail to access hardware. That restriction is one of the key points of a jail. By default, you cannot directly access most devices. It was about ten days ago that I first asked this question in the FreeBSD Forums. The answer was devfs.rules(5).

Last night, I started reading that man page. It made a bit of sense, but I didn’t see how it related to jails. Then I looked at /etc/defaults/devfs.rules and at the end of it I found this:

# Devices usually found in a jail.
#
[devfsrules_jail=4]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path zfs unhide

Ahh, so there’s something..

I started reading jail(8) and I found this:

devfs_ruleset
	     The number of the devfs ruleset that is enforced for mounting
	     devfs in this jail.  A value of zero (default) means no ruleset
	     is enforced.  Descendant jails inherit the parent jail's devfs
	     ruleset enforcement.  Mounting devfs inside a jail is possible
	     only if the allow.mount and allow.mount.devfs permissions are
	     effective and enforce_statfs is set to a value lower than 2.
	     Devfs rules and rulesets cannot be viewed or modified from inside
	     a jail.

Ahh, this is just what I need. Each jail can have its own set of rules! This is exactly what I need.

The devices

These are the devices which I need to access from within the jail:

ch0 at sym0 bus 0 scbus7 target 6 lun 0
ch0: <OVERLAND LXB 0524> Removable Changer SCSI-2 device 
ch0: 20.000MB/s transfers (10.000MHz, offset 15, 16bit)
ch0: 15 slots, 1 drive, 1 picker, 0 portals
sa0 at sym0 bus 0 scbus7 target 4 lun 0
sa0: <QUANTUM DLT8000 0250> Removable Sequential Access SCSI-2 device 
sa0: 20.000MB/s transfers (10.000MHz, offset 15, 16bit)

Or, as output by camcontrol devlist:

<QUANTUM DLT8000 0250>             at scbus7 target 4 lun 0 (sa0,pass10)
<OVERLAND LXB 0524>                at scbus7 target 6 lun 0 (pass11,ch0)

To summarize, I may need access to four devices:

  1. sa0
  2. pass10
  3. pass11
  4. ch0

For now, I will start with sa0 and ch0.

What’s in the jail now?

Let’s see what the jail has now. This is before I made any changes to the system:

$ ls -l /dev
total 1
dr-xr-xr-x  2 root  wheel          512 Aug  5 21:55 fd
lrwxr-xr-x  1 root  wheel           14 Aug  6 14:54 log -> ../var/run/log
crw-rw-rw-  1 root  wheel       0,  19 Aug  6 14:54 null
crw-rw-rw-  1 root  wheel       0,  22 Aug  5 21:55 ptmx
dr-xr-xr-x  2 root  wheel          512 Aug  6 14:54 pts
crw-rw-rw-  1 root  wheel       0,  23 Aug  5 21:56 random
lrwxr-xr-x  1 root  wheel            4 Aug  6 14:54 stderr -> fd/2
lrwxr-xr-x  1 root  wheel            4 Aug  6 14:54 stdin -> fd/0
lrwxr-xr-x  1 root  wheel            4 Aug  6 14:54 stdout -> fd/1
lrwxr-xr-x  1 root  wheel            6 Aug  6 14:54 urandom -> random
crw-rw-rw-  1 root  wheel       0,  20 Aug  5 21:55 zero
crw-rw-rw-  1 root  operator    0,  72 Aug  5 21:55 zfs
$ 

Now, let’s make some changes.

The rules

Let’s look at the devices in the host system. Although the tape device is sa0, most backup software will use the non-automatic-rewinding version of the device. So, we need to include nsa0 as well.

$ ls -l /dev/pass11 /dev/ch0 /dev/pass10  /dev/sa0 /dev/nsa0
crw-------  1 root  operator    0,  98 Aug  5 21:55 /dev/ch0
lrwxr-xr-x  1 root  wheel            6 Aug  5 21:55 /dev/nsa0 -> nsa0.0
crw-------  1 root  operator    0, 109 Aug  5 21:55 /dev/pass10
crw-rw----  1 root  operator    0, 110 Aug  5 21:55 /dev/pass11
lrwxr-xr-x  1 root  wheel            5 Aug  5 21:55 /dev/sa0 -> sa0.0

We need to also include nsa0.0 and sa0.0 as shown in the symlinks above. I will be running Bacula as a member of the operator group. Which means pass11 needs to be writable by the group.

Let’s try theses rules in /etc/devfs.rules on the host system:

[devfsrules_jail_unhide_tapes=5]
add path nsa0   unhide
add path nsa0.0 unhide
add path sa0    unhide
add path sa0.0  unhide
add path pass10 unhide
add path pass11 unhide mode 0660
add path ch0    unhide


[devfsrules_jail_bacula=6]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path zfs unhide
add include $devfsrules_jail_unhide_tapes

For this, I got help from Installing Asterisk In A FreeBSD Jail. The examples there were just what I needed.

In the above, line 1 defines a new rule set. Lines 2-7 will unhide the devices I want. Line 6 also sets the permissions on that device.

Lines 11-14 duplicate the efforts from /etc/defaults/devfs.rules (as shown in a previous section) and then invokes the first ruleset I created just above.

Specifying the ruleset for the jail

I am using ezjail. Each jail has its own configuration file in /usr/local/etc/ezjail. Without ezjail, these parameters go in /etc/rc.conf (I think). This is the line I changed in bacula_example_org (the jail in question):

export jail_crey_unixathome_org_devfs_ruleset="devfsrules_jail_bacula"

Restarting

Now let’s restart devfs and the jail:

# /etc/rc.d/devfs restart
# ezjail-admin restart bacula.example.org
Stopping jails: bacula.example.org.
Configuring jails:.
Starting jails: bacula.example.org.
#

After ssh‘ing into the jail, I found this:

$ ls -l /dev
total 1
crw-------  1 root  operator    0,  98 Aug  5 21:55 ch0
dr-xr-xr-x  2 root  wheel          512 Aug  5 21:55 fd
lrwxr-xr-x  1 root  wheel           14 Aug  6 19:21 log -> ../var/run/log
lrwxr-xr-x  1 root  wheel            6 Aug  6 19:21 nsa0 -> nsa0.0
crw-rw----  1 root  operator    0, 113 Aug  5 21:55 nsa0.0
crw-rw-rw-  1 root  wheel       0,  19 Aug  6 19:27 null
crw-------  1 root  operator    0, 109 Aug  5 21:55 pass10
crw-rw----  1 root  operator    0, 110 Aug  5 21:55 pass11
crw-rw-rw-  1 root  wheel       0,  22 Aug  5 21:55 ptmx
dr-xr-xr-x  2 root  wheel          512 Aug  6 19:21 pts
crw-rw-rw-  1 root  wheel       0,  23 Aug  5 21:56 random
lrwxr-xr-x  1 root  wheel            5 Aug  6 19:21 sa0 -> sa0.0
crw-rw----  1 root  operator    0, 112 Aug  5 21:55 sa0.0
lrwxr-xr-x  1 root  wheel            4 Aug  6 19:21 stderr -> fd/2
lrwxr-xr-x  1 root  wheel            4 Aug  6 19:21 stdin -> fd/0
lrwxr-xr-x  1 root  wheel            4 Aug  6 19:21 stdout -> fd/1
lrwxr-xr-x  1 root  wheel            6 Aug  6 19:21 urandom -> random
crw-rw-rw-  1 root  wheel       0,  20 Aug  5 21:55 zero
crw-rw-rw-  1 root  operator    0,  72 Aug  5 21:55 zfs
$ 

You will note that the jail has access to both sa0 and nsa0 and the device to which they are symlinked, sa0.0. Similarly, the jail also has access to pass11, which is what mtx will use to access ch0.

OK, but can you work the tape library?

Yes, I sure can. Look at this:

[root@crey ~]# /usr/local/sbin/mtx-changer /dev/pass11 slots 
15
[root@crey ~]# /usr/local/sbin/mtx-changer /dev/pass11 list
1:ETU002
2:ETU004
3:ETU008
4:ETU016
5:ETU025
6:ETU026
7:ETU028
8:ETU030
9:ETU043
10:ETU045
11:ETU049
12:ETU054
13:ETU095
14:ETU171
15:ETU233
[root@crey ~]# 

Success!

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive