This document contains notes on installing and using FreeNAS/NAS4Free to run a ZFS-based Network Attached Storage system.
By "FreeNAS" we mean versions of the product 7.x and less, not the currently-available product called FreeNAS. Originally, FreeNAS was all there was. Then, the name got sold and the company buying the name diverged the product to fit more in line with their business needs. Since the name was no longer available to them, the supporters of the original FreeNAS picked a new name when they opted to continue development on FreeNAS in the same vein as before. The new name is NAS4Free.
If you were using FreeNAS 7.x or 6.x and you wish to upgrade to something that looks and feels the same (but is just better), you will want to switch to NAS4Free. If you are planning a new installation, you can use these notes to instll either FreeNAS 7.x or NAS4Free 9.x (there is no NAS4Free 8.x). If you are undecided and are planning a new installation, there are copious opinions on the Internet about which is better (FreeNAS or NAS4Free). Obviously, we prefer NAS4Free but the choice is yours. You'll need a different set of install notes if you are going to install FreeNAS 8.x or greater.
To avoid confusion, we shall henceforth refer to the product as NAS4Free with the understanding that these notes may be used to install an earlier version of FreeNAS such as 7.x
Before you begin provisioning or installing NAS4Free, you may want to read the ZFS best practices guide at the Solaris Internals Wiki:
http://www.solarisinternals.com/wiki/index.php/ZFS_Best_Practices_Guide
Admittedly, this best practices guide is pitched more towards someone who is setting up a ZFS repository with 50 disks, etc., but it may provide you with some insights that will be helpful. It certainly gives you a good idea about what is possible.
One thing we do learn is that ZFS is potentially a memory hog. It uses a lot of memory to do caching and buffering while it is computing checksums so at least a couple of gigabytes is a good thing. Fortunately, this amount of memory will set you back less than twenty-five bucks, at today's prices.
And speaking of checksums, the processor needs to be relatively snappy to be able to constantly compute checksums, which is a key operation in ZFS. However, computing checksums ain't the same thing as compressing an hour of video data so you can safely consider one of the low-power, moderateperformance single or dual core processors (e.g. a 2.4 GHz Celeron, also cheap at today's prices). Probably the most important consideration is that the processor be a 64-bit processor, since ZFS runs best under the 64-bit version of NAS4Free.
NAS4Free itself can run from the installation CD or a USB stick or, presumably, anything else you can write to (a big enough floppy disk?). It has even been optimzed to not write anything back to the source media, once it has installed itself into memory at boot up, to ensure the longevity of flash memory-based devices such as USB sticks.
Call us traditionalists, but we like to use a small hard disk or SSD for the NAS4Free system itself. This allows us to make changes to the system, add scripts to do various tasks such as backups, etc. A small hard disk or 64GB SSD is cheap and should be reliable enough to run your system for a long time. If the hard disk does crash or something goes wrong with the SSD, the system can be easily reconstructed from backups, since no critical data (except for configuration information) is held on it.
One or two further thoughs on the concept of a separate, small system disk. Installing NAS4Free on one of the disks that will be used for the ZFS pool or trying to use the system disk for data storage is too complicated and is not really recommended. Thus, a separate, possibly low-power, green hard disk or SSD for your system is a good idea. If you wish to preserve all of the SATA ports on an older motherboard (many have four) for the ZFS disks, you should use an IDE drive for the system disk, since most older motherboards still have a single IDE connection which can be employed for a single hard disk as well as a DVD ROM drive for installation, or possibly a DVD R/W drive for installation and backup.
Depending on how you wish to configure the ZFS disk pool, you will probably want to add two or more big disks for data storage. In a mirrored configuration a pair of 1TB or 2TB disks work well. In this configuration, a third disk might be added as a hot spare. If you are going to be using one of the mirrored + striping RAID configurations, you will probably have three or more large disks.
Large SATA drives such as 1TB and 2TB green drives are ideal for the ZFS pool. One disk manufacturer even has a special line of disks designed particularly for NAS use that are low power but which have TLER to allow effective error reporting to ZFS. ZFS knows how to handle advanced format disks which is the format used by many 1TB and 2TB drives. Unless you are going to be pounding the ZFS pool with I/Os, the green drives are more than zippy enough for backing up other systems, supplying realtime video feeds, etc. Their big pluses are that they are easy on the power supply and they run very cool. If you care, most are extremely quiet too. Just be sure that you buy drives that are all exactly the same or nearly the same size, since RAID configurations do not appreciate differently-sized disks.
We now come, in a roundabout way, to the motherboard that you procure to build your NAS4Free system. We could have all sorts of discussions about server-class boards, how many PCI slots and what kind are needed, etc., etc.
Suffice to say that, in a simple NAS4Free system, any motherboard that supports your choice of processor, as much memory as you want to install and that has built-in video should work. If you want to run a lot of disks in your ZFS pool, you might look for one that has a lot of SATA ports or one that will allow you to add one or more SATA controller cards with JBOD arrays.
Probably the most important feature is one or more built-in gigabit ethernet ports. These will allow you to connect the NAS4Free system to your network and handle large volumes of data into and out of it. Incidentally, built-in gigabit ethernet is definitely better than adding gigabit ethernet via a PCI bus adapter, since most built-in gigabit ethernet adapters funnel data directly into and out of the system through its main bus, rather than through the much slower PCI bus. And, fortunately, the later versions of FreeNAS (e.g. 0.7.2) or NAS4Free (e.g. 9.x) now support even the dreaded RTL8111C chipset which seems to be the favorite chipset of many motherboard manufacturers.
If, before or during the course your NAS4Free installation, you wish to consult the NAS4Free documentation, you can find it at:
http://wiki.nas4free.org/doku.php?id=documentation:setup_and_user_guide
ZFS runs best on the 64-bit version of NAS4Free. On earlier versions of FreeNAS (e.g. 0.7.2) one would install the latest AMD64 release of FreeNAS because, despite the name AMD64, this version ran on 64-bit processors that were not from AMD. Now, the two versions are simply called x86 and x64 so the x64 version is the one to get. Out of the three x64 choices, the LiveCD or LiveUSB versions allow you to install NAS4Free on a hard drive, etc., so it is probably either of these two versions that you want. You can find the latest release at:
http://sourceforge.net/projects/nas4free/files/
When you boot the installation CD or USB stick, the initial boot process has a couple of distinct parts:
After the system goes through the POST and loads the OS from the boot device the NAS4Free boot menu will appear. This menu is visible for a few seconds (long enough to allow you to choose one of the other boot options, if you are awake and on the ball). At this step, you need do nothing. Just let the system take the default and boot normally. The system will continue booting as a NAS4Free server and, when it is complete, the system menu will appear. It is at this point that you can commence your installation by choosing the install option.
The install menu gives you a number of choices about how you'd like to install NAS4Free. Basically, the two choices are "full" or "embedded". If you choose the "embedded" version, NAS4Free installs itself so that any changes that are made to the system are wiped out whenever the system is rebooted. This refreshing of the system means that it is protected against inadvertent updates, software failures, malicious hacks, etc. If anything goes wrong, you simply reboot the system.
On the other hand, if you'll be wanting to make any system changes (e.g. adding device drivers), storing programs or scripts on the system partition, etc., you should choose the "full" version.
Other than that, you need to decide whether you want to provide swap space for the system (we always add at a minimum the same amount as main memory, and up to a maximum of double the amount as main memory, in swap space, so that the system keeps limping along even when it runs out of main memory -- although you may prefer a kernel panic in this situation). Especially if your system disk is an SSD, adding swap space from such a device provides low cost, extra pages with only a minor impact in performance.
You also need to decide how much disk space you want to allow for the system (just by way of example, a typical NAS4Free installation on an 16GB hard disk partition uses about 270MB or about 2% of the partition). Thus, unless you are planning on installing a boat load of your own software on the system, we wouldn't recommend anything more than a 16GB partition.
Given these considerations (and given that you've chosen to install NAS4Free on a smallish hard disk or SSD), you should install either the "'full' OS on HDD + DATA + SWAP partiton" or the "'embedded' OS on HDD/Flash/USB + DATA + SWAP partition". As we said above, if you plan on modifying the OS, choose the "full" installation, otherwise choose the "embedded" installation.
After you've decided which installation type you'll do, you'll be asked to select the partition sizes. Since there's probably plenty of space on your system disk, you can allow a large partition for the OS. We like to use 8GB or 16GB. As we said above, we like to provide at least one or two times the amount of swap space as there is main memory. With 2GB of main memory, this implies 4GB of swap space, while with 8GB of main memory this implies 16GB of swap space (once again, there's probably pleny of disk space). The installaion process will take care of assigning the remaining disk space to the data partition. The UFS file system is fine for this partition.
Let the install rip. Make a note of the data and swap partition names when install tells you what they are (you'll need them later). Then reboot the system without the installation disk. The NAS4Free system console should come up.
The immediate goal is now to get the network up and running because all of the ensuing NAS4Free configuration is done from the Web UI.
If your system has multiple NICs, you may need to select the "Assign Interaces" menu item. Usually, the system will "do the right thing" but, if you have a preference for which NIC should be the main one, etc., you can check what it has done and, if necessary, move the NICs around.
What about if your network card isn't found at all? Other than the obvious, the card isn't plugged in correctly, this means that your network card is not supported by NAS4Free or more specifically, by the underlying FreeBSD.
You have two choices. You can replace the network card with one supported by FreeBSD. A quick check of the NAS4Free hardware compatibility list page will (hopefully) show your version of NAS4Free in the hardware support table, from which you can follow the link to the appropriate FreeBSD compatibility list page:
http://wiki.nas4free.org/doku.php?id=nas4free_users_hardware
If you don't wish to replace the NIC, particularly if it is built-in to the motherboard, you can add a device driver if one is available (thankfully, the much-favored-by-motherboard-manufacturers 8111C chipset is now supported by the latest NAS4Free). Since it is likely that your NIC's driver will be found in NAS4Free, we won't dwell on this topic. But, if you do need to add a driver, Hani Ibrahim's blog may prove helpful:
http://blog.hani-ibrahim.de/en/netzwerktreiber-auf-freenas-installieren.html
The default IPv4 address for NAS4Free is 192.168.1.250, which will be assigned to the first or only network adapter. If this works out for your network, you can just leave it unchanged. Note, however, that when we tried this option under NAS4Free 9.1.0.1.636, no DNS servers were filled in. Not that this is a problem, per se, but when the Web UI was brought up later on, an error message saying "No DNS setting found" appeared. At this point, it would seem that there is a bug in the Web UI because as long as the error message was present, the complete UI did not get produced by index.php and it was not possible to do anything from the UI since all of the menu dropdown items were missing.
This being the case, the next step is probably to select the "Set LAN IP Address" menu item. The dialog that follows will allow you select whether the system will use DHCP or be assigned a static IP address. If don't choose DHCP, you should supply the desired IP address and the subnet mask, the default gateway, and at least one DNS sever's address. In a local network, there's no real need for IPv6 so turn it off.
That's about it. You should now be able to get to the NAS4Free Web UI by aiming a Web browser, on another system, at the IP address that you assigned (or that was assigned). You will see the NAS4Free login screen. Logon using the default userid which is "admin". Its password is "nas4free". If you have problems logging in (e.g. the login screen just keeps getting replayed, reguardless of what you type), you should check that cookies are enabled for the IP address of the NAS4Free server. If you are using any kind of Web blocking or filtering software that disables or blocks cookies, you will not be able to log in.
Initial setup consists of moving through all of the menu choices and tabs, and filling in the fields presented on each of the selected pages. The following paragraphs simply begin by showing the menu selections as a path, separated by slashes (e.g. "System/General/General" means choose the "System" menu item, followed by the "General" menu item, followed by the "General" tab). The choices that should be made are listed next. Notes are interspersed as full paragraphs or in parenthesis on the individual field lines. When you see the setup pages, you'll figure it out.
System/General/General (Setup)
Hostname: (you probably want something different than "nas4free") Domain: (the default is "local") IPV4 DNS servers: (if you set the NIC up from the console, you only need to add your second DNS server, if you need one) Time zone: (Eastern Time is GMT+4 or maybe GMT+5, in the winter) Enable NTP: checked (if you have a local or networked NTP server) NTP time server: (local or networked NTP server -- the default works OK)
System/General/Password
Set new password (default password is "freenas")
System/Advanced/Advanced
Console screensaver: checked (if you wish) Blank time: 300 seconds (5 minutes) seems about right. Enable Zeroconf/Bonjour to advertise services of this device: another bad idea whose time has come. You may want to turn it off. MOTD: (may want to include the machine name in the welcome message)
System/Advanced/Email
From email: temporarily start out by entering your to email address (that's intuitive) Outgoing mail server: your SMTP server (probably, an IP address is best) Once you've tested the connection to your SMTP server by clicking the "Send test email" button, you should then set the "From email" field to the address you want to use henceforth as the sender's address for delivering mail (e.g. "NAS4Free.NASBox"), so that all email messages will be sent with this from address. Note that, as of NAS4Free 9.1.0.1.636, clicking the "Send test email" button sends an inscrutable test message with a bogus UTF subject (hey, what's wrong with ANSI for the test message), the sender's address the same as the recipient's and a body that reads, "This email has been sent to validate your email configuration." If you see an email that looks like this in your in-box, you're in business.
System/Advanced/Swap
If you installed NAS4Free using one of the options that create a swap file, you must enable it first before it can be used by the system. The install should have given you instructions about how to do it. In case you didn't write them down, begin by checking the "Enable" box. Type: Device Device: /dev/ada2s3 (or whatever device name you were given by install) If you really didn't write down the swap device name when install told you what it was, you can go to the system console, open up a shell and enter the following command: ls -1 /dev/ada* Note that the flag, above, is a one, not the usual el. You should see all of the hard drives listed. The system drive will be the one that looks like this: /dev/ada2 /dev/ada2s1 /dev/ada2s1a /dev/ada2s2 /dev/ada2s2a /dev/ada2s3 The swap partition is the third partition listed (e.g. /dev/ada2s3 in this example).
Disks/Management/Management
If you installed the system with one or more UFS DATA partitions on the system disk, you can enable it or them now. Begin by clicking the "Plus" button at the right. Disk: ada2 (or other appropriate disk -- read the description of the disk until you see your system drive or SSD) Description: (you should provide a description -- we like to use something like "Data partition on System disk") S.M.A.R.T.: checked Preformatted file system: UFS Click the "Add" button at the bottom of the page. The disk will show up as "Initializing". Click the "Apply changes" button to make the disk available. The disk will show as "ONLINE".
Disks/Management/S.M.A.R.T.
Begin by checking the "Enable" box. Power mode: Standby Informal: 50 (most disks run in the 35-45 degree range) Critical: 60 (now, we're cookin') Email Report: check Activate To email: (put your to email address here) Click "Apply Changes" If you want to run any additional SMART tests (we like to do the Long Self Test once a week at 5AM for each disk, picking a different day for each disk), click the "Plus" button at the right of the "Scheduled self-tests" section. Click "Save and Restart" when you are all done.
Disks/Mount Point/Management
If you installed the system with one or more UFS DATA partitions on the system disk, you can mount it or them now. Begin by clicking the "Plus" button at the right. Type: Disk Disk: ada2 (or other appropriate disk) Partition type: MBR partition Partition number: 2 (or other appropriate partition number) File system: UFS Mount point name: System (or some other descriptive name). This name will appear under /mnt in the file system tree, e.g. /mnt/System. Description: (a description would be good -- we like "Data partition on System disk") File system check: checked If you really didn't write down the data device name when install told you what it was, see the notes in the System/Advanced/Swap section above about how to list the disk partitions. The data partition is the second partition listed (e.g. /dev/ada2s2 in this example). Click the "Add" button at the bottom of the page. The partition will show up as "Initializing". Click the "Apply changes" button to make the partition available. The partition will show as "OK". [You just never know where Martin Van Buren is going to turn up.]
Disks/Management/Management
Begin setting up ZFS by adding all of the disks that will be included in the storage pool (here, we're assuming two). Start by clicking the "Plus" button at the right. Disk: ada0 (or other appropriate disk) Description: ZFS Pool Disk 1 (you should provide a description) S.M.A.R.T.: checked Preformatted file system: Unformatted Click the "Add" button at the bottom of the page. The disk will show up as "Initializing". Continue clicking the "Plus" button and adding disks as needed. Disk: ada1 (or other appropriate disk) Description: ZFS Pool Disk 2 (you should provide a description) S.M.A.R.T.: checked Preformatted file system: Unformatted Again, click the "Add" button at the bottom of the page. Click the "Apply changes" button to make the disk or disks available. The disk will show as "ONLINE".
Disks/Format
Format each of the disks that were added in the previous section. Disk: ada0 (or other appropriate disk) File system: ZFS storage pool device Click the "Format disk" button to format the disk. Disk: ada1 (or other appropriate disk) File system: ZFS storage pool device Click the "Format disk" button to format the disk.
Disks/ZFS/Pools/Virtual device
Each of the disks that were added and formatted must configured as part of a virtual device before they can be added to a ZFS pool. Essentially, this step creates the equivalent of a RAID array that you can then assign to a ZFS pool. Start by clicking the "Plus" button at the right. Name: RAID1 (use a descriptive name for the virtual device) Type: Mirror (or choose one of the other types like RAID 5) Devices: ada0 ada1 (use the Ctrl+Click feature to pick multiple devices) Advanced Format: checked (especially if one or more drive is AF) Description: (a nice description of this virtual device) Click the "Add" button at the bottom of the page. The virtual device will show up on the Virtual Device listing. Click the "Apply changes" button to make the virutal device available.
Disks/ZFS/Pools/Management
Now, the virtual device can be added to the ZFS pool. Do that by clicking the "Plus" button at the right. Name: Pool1 (use a descriptive name for the ZFS pool) Virtual devices: RAID1 (use the Ctrl+Click feature to pick multiple virtual devices) Description: (a nice description of this pool) Click the "Add" button at the bottom of the page. The pool will show up with no information available. Click the "Apply changes" button to build the storage pool. The size and capacity information will become visible and the pool should show as "ONLINE".
Disks/ZFS/Datasets/Dataset
Finally, a dataset can be created on the ZFS pool. Do that by clicking the "Plus" button at the right. Name: Datastore1 (use a descriptive name for the dataset) Pool: Pool1 (select the ZFS pool name from the previous step) Compression: Off Canmount: checked Extended attributes: checked Description: (a nice description of this dataset) Click the "Add" button at the bottom of the page. Click the "Apply changes" button to assign the dataset to the storage pool.
Services/CIFS SMB/Settings
To share the volumes and datasets defined on the NAS4Free system with Windoze users, CIFS/SMB must be enabled. Begin by checking the "Enable" box. Authentication: Anonymous Max Protocol: NT1 NetBIOSname: (your system's name) Workgroup: WORKGROUP Description: (may want to add machine name to default description) Local Master Browser: No (you probably already have one on your network) Time server: No (same goes for this) Large read/write: checked Use sendfile: checked Null passwords: checked (if you so desire) Asynchronous I/O (AIO): checked Click "Save and Restart" to save the changes. Incidentally, here is a little note about setting the "Max Protocol" value. There is a bug in Samba (https://bugzilla.samba.org/show_bug.cgi?id=8726) having to do with the SMB2 protocol which causes random crashes when large files are transfered from/to NAS4Free using SMB/CIFS. Until this bug is fixed and rolled into the NAS4Free build, it is probably a good idea to stick with "NT1" and not use "SMB2". Admittedly, this will force CIFS/SMB to run slower (due to the chattiness of the original SMB protocol) but it will work. After the bug is fixed, you should be able to turn SMB2 on and Samba will negotiate with its clients to use either SMB2 or NT1, depending on what they can hack.
Services/CIFS SMB/Shares
Each volume or dataset that is to be shared must be configured by clicking the "Plus" button. Name: Datastore1 (use a descriptive name for the share) Comment: (a nice description of this share) Path: /mnt/Pool1/Datastore1 (select the path from the dialog box) Read only: unchecked Browseable: checked Guest: unchecked Recycle bin: unchecked Hide dot files: unchecked Shadow Copy: unchecked ZFS ACL: unchecked Click the "Add" button at the bottom of the page. Name: System (use a descriptive name for the share) Comment: (a nice description of this share) Path: /mnt/System (select the path from the dialog box) Read only: unchecked Browseable: checked Guest: unchecked Recycle bin: unchecked Hide dot files: unchecked Click the "Add" button at the bottom of the page. Click the "Apply changes" button to make the shares visible.
There's no need to use the console for tasks that can't be done through the Web UI. Instead, you can establish an SSH connection and then do all of your work through the login shell. To use SSH, the service must be enabled via the Web UI Services configuration page.
Services/SSH
Begin by checking the "Enable" box. Permit root login: checked (unless you don't want to allow this) Click the "Save and Restart" button.
Once you've save the configuration changes, you should be able to login to NAS4Free using a terminal client that supports SSH. The userid is "root" (not "admin") and the password is whatever password you set for the "admin" user under the Web UI.
If you wish to use local host names, that cannot to be found via DNS lookup, you can add those names to the /etc/hosts file through the NAS4Free Web UI.
Network/Hosts
Click the "Plus" button to add a new host name. Hostname: (the name of the host) IP address: (the host's IP address) Click the "Add" button at the bottom of the page. Click the "Apply changes" button to make the host names usable. Click "Save and Restart" because you can never have too many buttons to click.
If you wish to automatically back up files from one or more Windoze systems, the way to do it is definitely via rsync. Rsync uses a sophisticated checksum algorithm to only copy the actually changed portions of the files it copies so it works perfectly for maintaining backup copies. Furthermore, it can be set up to delete previously-copied files that are deleted from the source directory so that the backup directory becomes a true mirror of the source directory that it backs up.
An rsync client on the NAS4Free system requests copies of files from an rsync server on the Windoze system that is to be backed up. This being the case, the rsync server must be installed on each Windoze box. The easiest way to do this is get the latest copy of DeltaCopy from:
http://www.aboutmyip.com/AboutMyXApp/DeltaCopy.jsp
Download the "With Installer" version of DeltaCopy, unzip it and run the installer. Follow the instructions for each install step. You might want to change the install directory to "\Program Files\DeltaCopy" instead of the default directory (in the top-level of the directory tree).
Once you've installed DeltaCopy, you need to register the server as a service with Windoze. Registration will take place the first time you run the DeltaCopy server. It will cause Windoze to start up DeltaCopy when the system boots and ensure that the service stays up and running. Note that, when you register the service, you should check the log on as "Local System account" button and eschew supplying a username and password. This will allow the service to run as a system service (its a good thing).
Next, you should create aliases for all of the directories on each of the Windows systems that you want to back up. This is done by clicking on the "Virtual Directories" tab of the DeltaCopy Server Console. Under that tab, you can click on "<Add New Directory>" to add one or more directory aliases to be shared via rsync. Unfortunately, you can't include more than one directory under an rsync alias so you'll have to define as many aliases as the directories that you want to back up (making the top level directory an alias is not recommended). You should check the "Read only" box to ensure that rsync on the NAS4Free system does not monkey with any of the local files. You may want to delete the default "Backup" directory that appears automagically, when DeltaCopy is set up. It serves no purpose for us.
That's about it for Windoze. You can check that the rsync server is working, from the NAS4Free system, with this command:
/usr/local/bin/rsync rsync://mysys
Where "mysys" is the name of the system that is running the DeltaCopy server. You should see a list of modules (share points).
To set up an rsync server on Linux, you can either use the version of rsync that is supplied with your system and installed via the system's software installation interface. We prefer to get the latest version of the source from:
http://samba.anu.edu.au/rsync/
Download then unpack the tar file:
tar xzvf rsync-3.0.7.tar.gz
Change to the source directory, run configure and make the source:
cd rsync-3.0.7 ./configure make
Install rsync as root:
su make install
Many installation guides suggest that the rsync server be run, on demand, by xinetd. This is OK for the occasionaly rsync file transfer but we think that running rsync as a daemon is a better idea. To do this, you'll need a start/stop script for init.d. Here is our script:
/etc/init.d/rsync:
#!/bin/sh # # rsync - Script to start/stop the rsync daemon. # # Revision History: # ewilde 2011Mar26 Initial coding. # # chkconfig: 2345 18 92 # description: Rsync remote file/directory synchronization daemon # # pidfile: /var/lock/subsys/rsyncd.pid # # # Define the install path for the rsync binary, etc. # INSTALL_PATH="/usr/local/bin" CONFIG_FILE="/etc/rsync/rsyncd.conf" PID_RSYNCDAEMON="/var/run/rsyncd.pid" # # Load the RedHat functions. # if [ -f /etc/redhat-release ]; then . /etc/rc.d/init.d/functions fi # # Check that rsync has been installed (sometimes not the case). # [ -f $INSTALL_PATH/rsync ] || exit 0 # # Upon startup, we start rsync as a daemon. # start() { action "Starting rsync daemon: " \ $INSTALL_PATH/rsync --daemon --config=$CONFIG_FILE return $? } # # Upon shutdown, we stop the rsync daemon. # stop() { echo -n "Stopping rsync daemon: " killproc -p $PID_RSYNCDAEMON rsync >/dev/null 2>&1 StopVal=$? if [ $StopVal = 0 ] ; then echo_success else echo_failure fi echo return $StopVal }
#
# See how we were called.
#
case "$1" in
# # Start. # start) start RETVAL=$? ;; # # Stop. # stop) stop RETVAL=$? ;; # # Restart or reload (whatever). # restart|reload) stop start RETVAL=$? ;; # # Conditional restart. # condrestart) if [ -f $PID_RSYNCDAEMON ]; then stop start RETVAL=$? fi ;; # # Give the status of the rsync daemon. # status) if [ ! -f $PID_RSYNCDAEMON ]; then echo The rsync daemon is down exit 1 fi echo The rsync daemon is running RETVAL=0 ;; # # Help text. # *) echo $"Usage: $0 {start|stop|restart|condrestart|status}" exit 1
esac
exit $RETVAL
After you install this script into /etc/init.d, you need to set its ownership and permissions:
su chown root:root /etc/init.d/rsync chmod u=rwx,go=rx /etc/init.d/rsync
You will also need to add this script to the startup sequence, for example like this:
su /sbin/chkconfig --add rsync /sbin/chkconfig rsync on
You can check that it did get added to the startup sequence like this:
/sbin/chkconfig --list rsync
The next thing to do is create a configuration file that tells the rsync daemon how to run and which directories it should expose as modules (share points). We choose to create an rsync directory under /etc, to hold the config files:
su mkdir /etc/rsync chown root:root /etc/rsync chmod u=rwx,go=rx /etc/rsync
This sample config file should give you an idea of what your config file can look like. You can add as many modules (share points) as you wish. The rsync docs describe how to assign permissions to them, etc. We have chosen not to set any permissions (not always a wise idea), but you may want to have your remote backup login before it can copy secure directories.
/etc/rsync/rsyncd.conf:
# # Rsync daemon configuration file. # # # Global options. These apply to all connections unless specificaly # overridden. # # Note that the pid file path should match the path set in the rsync daemon # startup script (/etc/init.d/rsync). # pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock read only = yes list = yes uid = nobody gid = nobody # # Modules (share points). # [mail] path = /var/spool/mail uid = root gid = mail [mysql] path = /var/mysql uid = mysql gid = mysql [home-jsmith] path = /home/jsmith uid = jsmith gid = jsmith [home-jblow] path = /home/jblow uid = jblow gid = jblow
Note that, if you want to specifically exclude subdirectories from under a module, you can use the "exclude" directive, like this:
[www] path = /var/www uid = apache gid = apache exclude = Bugzilla/ manual/
Also note that the action of the gid parameter may violate the principal of least astonishment in that it doesn't mean what you think it does. If you specify a groupname via the gid parameter, it is only that exact group which is used to obtain permission to access the files found under the module's path. To access files under several groups, you must specify them all in a list following the gid parameter.
If, instead, you wish to have rsync access the files in the module with all of the groups that the user, specified by the gid parameter, is a member of, you should specify the group as '*'. This would look like:
[packages] path = /packages uid = jblow gid = *
You'll probably want to set the ownership and permissions for your new config file, like this:
su chown root:root /etc/rsync/rsyncd.conf chmod u=rw,go=r /etc/rsync/rsyncd.conf
Now that you've completed your config file, you can start the rsync service (it should start automatically, the next time the system boots):
su /etc/init.d/rsync start
From the local system, you can check that the rsync service is running by entering:
/etc/init.d/rsync status
You can check that the rsync service is running properly, from the NAS4Free system, with this command:
/usr/local/bin/rsync rsync://mysys
Where "mysys" is the name of the system that is running the rsync server. You should see a list of modules (share points).
If you should happen to get an error that says this:
rsync: read error: Connection reset by peer (54) rsync error: error in rsync protocol data stream (12) ...
It is most likely due to a preexisting inetd or xinetd grabbing the packets being sent to port 873 (rsync). You can look in /var/log/messages on the remote system to see what's going on. If inetd or xinetd is involved, you need to get rid of the rsync configuration in /etc/inetd.conf, /etc/xinetd.conf or /etc/xinetd.d/* (probably rsync). If the rsync package was installed by an RPM, you should remove it with yum, the package manager, apt or whatever.
Also, you'll need to restart inetd or xinetd to get it to give up on the rsync port. But, be advised that xinetd in particular is quite persistent and you may have to cancel it by hand. Try (if you're running inetd, substitute its name instead):
su /etc/init.d/xinetd restart
If this fails, try:
ps x | grep xinetd
kill -9 pidnum (where pidnum was returned by ps) /etc/init.d/xinetd restart
If you get an error that says:
rsync: failed to connect to mysys: Connection refused (61) rsync error: error in socket IO (code 10) ...
It is due to a the rsync daemon not listening on port 873 (rsync). Try restarting (or starting) the daemon, especially if you've just fixed the inetd/xinetd problem described above:
su /etc/init.d/rsync restart
Finally, we should say a few things about security. You'll note that we specified "uid = nobody" and "gid = nobody" in the global options and then overrode these options for each of the modules (share points). For example, the "mail" module uses "uid = root" and "gid = mail". These settings are necessary to allow rsync to have proper access to the subdirectories and files under the specified directories.
However, since we didn't specify any of the "auth users", "secrets file", "hosts allow" or "hosts deny" parameters, this essentially leaves these modules (share points) wide open to any rsync client on your system. You might want to consider at the very least a "hosts allow" parameter in the global options section of /etc/rsync/rsyncd.conf, to allow only the NAS4Free server access to the modules:
.
uid = nobody
gid = nobody
hosts allow = 192.168.1.nnn
. . .
Use the actual IP address of the NAS4Free server instead of 192.168.1.nnn.
Before you try any backups from the NAS4Free system, you may wish to see what files and directories will actually be backed up from each system on your network. After you've installed DeltaCopy on Windoze, or rsyncd on your Linux boxes, you can use this command from the console on the NAS4Free system or a logged-in terminal to see what rsync modules are available for backup:
/usr/local/bin/rsync rsync://mysys
For each of the modules listed, you can verify what files and directories will be backed up by passing the individual module names to rsync, one at a time, like this:
/usr/local/bin/rsync --recursive --list-only rsync://mysys/modname
Once everything looks good, the following script can be used to back up files from Windoze or Linux remote systems using rsync. Copy it to your System share and then, using a copy command from the console or a logged-in terminal, move it to the OS volume, where nobody will monkey with it:
su mkdir /etc/rsync cp /mnt/System/backup /etc/rsync chown root:wheel /etc/rsync/backup chmod u=rwx,go=rx /etc/rsync/backup
Here is the backup script. You should change the email variables, FromAddr and ToAddr, before you install the script. You may also wish to change the defalut ZFS pool, if you don't plan on setting it via the command line. And, the default backup file ownership and permissions should be set to something other than "root:wheel", etc., if you don't like those settings and don't wish to set them for each backed up directory, in the config file.
/etc/rsync/backup:
#!/bin/bash # # Shell script to back up files from remote systems, using rsync, to the # ZFS pool on NAS4Free. # # This script should be run at regular intervals (typically hourly), by # cron, under the root userid. It can be run whenever backups should be # done with the times set in the config file determining when the backups # are actually done. The command line looks like this: # # backup [-d|--debug] [-h|--help] [-n|--noemail] [-v|--verbose] # configfile [zfspool] # # The parameters are: # # -d|--debug Set this debug flag to test the config file, # etc. Doesn't actually run rsync. # # -h|--help Setting this flag displays help information. # # -n|--noemail If this flag is set, don't send an e-mail with # the results. Normally, if the email variables # are set (below), email is sent to the specified # address, giving the results of the backup. # # -v|--verbose If this flag is present, output status # information to stdout, as the backup # progresses. # # configfile The configuration file that drives the backups # to be done (see below). # # zfspool Optional ZFS pool name, if you wish to # override the internal value (set below). # # The configuration file that is read by this backup script is used to # decide which Rsync modules (share points) on one or more remote systems # should be backed up. # # Note that the configuration file must not contain any of the evil, # MS-generated carriage returns. If it does, this script will undoubtedly # function incorrectly. This ain't f**king Windoze, Sparky. # # The config file contains one or more source systems, specified by the # "Source" keyword, followed by an equal sign and the system's name or IP # address. If a machine name is given, it must be able to be resolved via # DNS or the hostname must be added to the /etc/hosts file via the # Network/Hosts tab on the NAS4Free Web page. # # After that, you may supply one or more destination directories (in the # ZFS pool) and one or more time strings. These are specified by the "Dest" # and "Time" keywords respectively, followed by an equal sign and the # destination directory or time string. # # The destination directory is given as a relative subdirectory underneath # the ZFS pool that is either implied or specified on the command line. # If the directory doesn't exist in the ZFS pool, it will be created. # # The time string is given as one or more hours, separated by spaces, in a # simple list. The hour numbers use the 24-hour clock. If this backup # script is run at an hour that matches one of those in the list, the # backup will be done. A time string of "" will match all backup times. # # The ownership and permissions of the backed up directories and files will # be set to the default values set within this script. If you don't like # this arrangement (e.g. if you are trying to adhere to a more diverse # security scheme), you may set the permissions on an individual backup # directory basis using the BackupOwner, DirPerms and FilePerms parameters, # which must occur before the module list for the directory that they are to # apply to. # # The values for these parameters must comply with the rules for the chown # and chmod commands. The ownership parameter will be applied to both the # directories and files that are backed up. The DirPerms parameter will # give the permissions only for directories. The FilePerms parameter will # give the permissions only for files. Sample values might be: "root:wheel"; # "u=rwx,go=rx" for directories; and "u=rw,go=r" for files. # # Following the keywords, lists of Rsync modules to be backed up to the # backup directory are given to direct the actual backups. The list can # consist of the string "", in which case all of the Rsync modules found # on the remote system will be backed up. If the list begins with a minus # sign, followed by a space, all of the Rsync modules found on the remote # system will be backed up, except for those modules listed. Otherwise, # only those modules listed will be backed up. The list of modules should # be separated by blanks. # Blank lines and lines that begin with "" can be liberally interspersed # throughout the config file. Comments may not be applied to the parameter or list lines, even if they do start with "". Note that the keywords # accumulate and the current value for all three is used whenever a backup # list is found. # # Here is a sample config file: # # # Backup the Profiles directory on Audrey. # Source = audrey # # Dest = Backup_Audrey # Time = 0 # Profiles # # # Backup all of the directories on Gabriella. # Source = gabriella # # Dest = Backup_Gabby # Time = 0 # BackupOwner = root:gabby # DirPerms = ug=rwx,o= # FilePerms = ug=rw,o= # * # # # Backup all of the directories on Video-Game (at diffent times). # Source = video-game # # Dest = Backup_Windoze # Time = 2,10,14,18 # - Profiles # # Dest = Backup_Video-Game # Time = 0 # Profiles # # Note that this script creates a lock file for each destination directory # to prevent multiple backups from running at the same time. If the system # crashes while the lock is held or you need to break the lock for any other # reason, simply delete the file "/var/run/rsync_client_running_backupdir", # replacing the string "backupdir" with the actual name of the top level # backup directory. # ############################################################################ # # Default ZFS pool where all backup files are to be stored. You can modify # this parameter to reflect your NAS4Free configuration, if you don't use the # zfspool positional on the command line. # DefZFSPool="/mnt/Pool1/Datastore1" # # File ownership. Rsync has its own ideas about who should own what. We # may have different ideas. # DefBackupOwner="root:wheel" DefDirPerms="u=rwx,go=rx" DefFilePerms="u=rw,go=r" # # Email variables. Set these up, if you want to have the script email you # backup status. # FromAddr=NAS4Free.Alexandria@gntrains.com ToAddr=ewilde@gntrains.com # # Email commands. # Printf=/usr/bin/printf MailerSMTP=/usr/local/bin/msmtp MailerSMTPConf=/var/etc/msmtp.conf # # Arguments. # Debug=0 WantMail=1 Verbose=0 # # Work areas. # Body="" Backups=0 Errors=0 LineNum=0 DestDir="" SourceSys="" TimeStr="" ############################################################################ # # Function to do an rsync backup from the source system to the destination # directory. # function BackupSource { # # Make sure that the user has indicated the source system whose files # are to be backed up. # if [ x"$SourceSys" = x ]; then if [ $Debug = 1 ]; then echo " No source host specified for backup" else let Errors=Errors+1 LogMsg "No source host specified for backup at config file \ line $LineNum" fi return fi # # Make sure that the user has specified the destination # directory where backups are to be put. # if [ x"$DestDir" = x ]; then if [ $Debug = 1 ]; then echo " No destination specified for backup" else let Errors=Errors+1 LogMsg "No destination specified for backup at config file \ line $LineNum" fi return fi # # If we aren't debugging the config file, we should check that the # time we were given is now, before we do any work. Otherwise, there's # nothing to do. # if [ x"$TimeStr" != x ] && [ "$TimeStr" != "*" ] && [ $Debug != 1 ]; then # # See if the current hour is in the run time string. # CurrHour=$CurrentHour for RunTime in $TimeStr; do if [ $RunTime = $CurrHour ]; then CurrHour="" break fi done # # If the current hour wasn't found in the list, we're done. # if [ x"$CurrHour" != x ]; then return fi fi # # If the module list that we were given is one that requires the full # list of modules (share points) from the remote system, or one that # operates on the full list, let's get it from the remote system now. # if [ "$1" = "" ] || [ "$1" = "-" ]; then SourceModules=`/usr/local/bin/rsync rsync://${SourceSys}` # # If the list isn't the full list, but one that we modify, let's # do that now. # if [ "$1" = "-" ]; then shift 1 IncludedModules="" # # Compare the list from the source against the exclude list. # for Module in $SourceModules; do for Exclude in "$"; do if [ "$Module" = "$Exclude" ]; then Module="" break fi done # # This particular module isn't excluded so add it to the # list. # if [ x"$Module" != x ]; then if [ x"$IncludedModules" = x ]; then IncludedModules=$Module else IncludedModules="${IncludedModules} ${Module}" fi fi done SourceModules=$IncludedModules fi else SourceModules="$*" fi # # If we're debugging the config file, we now have the list of modules # to be backed up so we can dump that list and get out. # if [ $Debug = 1 ]; then echo "Backing up \"$SourceModules\"" return fi let Backups=Backups+1 # # If the destination directory doesn't exist, create it now. # if [ ! -d ${ZFSPool}/${DestDir} ]; then mkdir ${ZFSPool}/${DestDir} chown $BackupOwner ${ZFSPool}/${DestDir} chmod $DirPerms ${ZFSPool}/${DestDir} fi # # Log the beginning of our work. # LogMsg "Starting rsync backup from ${SourceSys} to ${DestDir}" # # Check if we're already backing up the selected modules. # if [ -r /var/run/rsync_client_running_${DestDir} ]; then LogMsg " Previous backup still running, skipping this one" return fi # # Set the lock file. # /usr/bin/touch /var/run/rsync_client_running_${DestDir} # # Copy all of the modules on the remote system. # for Module in $SourceModules; do LogMsg " Backing up module ${Module}" /usr/local/bin/rsync --log-file=/var/log/rsync_client.log \ --recursive --times --compress --archive \ --delete --delete-delay --quiet --perms \ "rsync://${SourceSys}/${Module}" \ "${ZFSPool}/${DestDir}/${Module}" RetCode=$? if [ $RetCode != 0 ]; then let Errors=Errors+1 LogMsg " Backup failed with return code: $RetCode" fi # # Set the ownership and permissions. # # We start by setting the file permissions on everything. This is # pretty fast, since we use the "-R" option on chmod. Then, we # come back and set the directory permissions using find, which is # also pretty fast, since it only works on the directories. Note # that this works, even if the file permissions take away the # execute (i.e. list) permission of the directory because the # recursive find will add the execute permission back to the # directory before it dives into it. # chown -R $BackupOwner ${ZFSPool}/${DestDir}/ chmod -R $FilePerms ${ZFSPool}/${DestDir}/ find ${ZFSPool}/${DestDir} -type d -exec chmod $DirPerms \{\} \; done # # Clear the lock file. # /bin/rm -f /var/run/rsync_client_running_${DestDir} # # Log the end of our work. # LogMsg "Completed backup from ${SourceSys} to ${DestDir}" } ############################################################################ # # Function to add a message to the email body and/or log it to stdout. # function LogMsg { # # Add the message to the email body. # if [ $WantMail = 1 ]; then Body="${Body}${1}\n" fi # # Output the message to stdout, if in verbose mode. # if [ $Verbose = 1 ]; then echo $1 fi } ############################################################################ # # Function to send an email status message, if the user has requested it. # function SendMail { if [ $WantMail = 1 ]; then # # Create a subject. # Subject="NAS4Free rsync backup - `date +"%Y %b %d %H:%M:%S"`" if [ $1 -gt 0 ]; then Subject="${Subject}: Error Detected" fi # # Send the message. # $Printf "From:$FromAddr\nTo:$ToAddr\nSubject:$Subject\n\n$Body" | \ $MailerSMTP --file=$MailerSMTPConf -t fi } ############################################################################ # # Process all of the arguments (flags and positionals). # Args=("$*") for Arg in $Args; do case $Arg in # # Flags. # "-d" | "--debug") Debug=1 ;; "-n" | "--noemail") WantMail=0 ;; "-v" | "--verbose") Verbose=1 ;; "-h" | "--help") echo <<-ENDHELP usage: $0 [-d|--debug] [-h|--help] [-n|--noemail] [-v|--verbose] configfile [zfspool] -d|--debug Debug the config file but don't run rsync. -h|--help Display this help. -n|--noemail Don't send an e-mail with the results. -v|--verbose Output status information to stdout. configfile Config file with backup tasks defined therein. zfspool ZFS pool name, if iternal name is not acceptable. ENDHELP exit ;; # # Positionals. # *) if [ x"$ConfigFile" = x ]; then ConfigFile=$Arg else if [ x"$ZFSPool" = x ]; then ZFSPool=$Arg fi fi ;; esac
done
#
# If there are no email addresses, we'll turn off email.
#
if [ x"$FromAddr" = x ] || [ x"$ToAddr" = x ]; then
WantMail=0
fi
#
# Make sure that the user has indicated where the config file is.
#
if [ x"$ConfigFile" = x ]; then
Verbose=1 LogMsg "No config file specified listing the backup tasks" SendMail 1 exit 1
fi
#
# See if the user has specified the ZFS pool where backups are to be put.
#
if [ x"$ZFSPool" = x ]; then
ZFSPool=$DefZFSPool
fi
#
# Set the default ownership and permissions.
#
BackupOwner=$DefBackupOwner
DirPerms=$DefDirPerms
FilePerms=$DefFilePerms
#
# Get the current hour. Used to compare against the time string parameter
# in the config file.
#
CurrentHour=`date +%k`
#
# Read the config file and process all of the backups therein.
#
while read Line; do
# # Count lines for error reportage. # let LineNum=LineNum+1 if [ $Debug = 1 ]; then echo Line $LineNum: $Line fi # # If the line is not a comment, process it. if [ "`echo $Line | grep '^[^]'`"x != x ]; then # # If the line is a parameter and its value, process it. The # parameter will be turned into a shell variable. Here's what we # are looking for: # # BackupOwner The ownership string to apply to the backed up # directories and files (e.g. root:wheel). # # DestDir The name of the top level directory in the # ZFS pool where the remote system's files are # to be backed up. # # DirPerms The directory permission string (e.g. # u=rwx,go=rx). Only applies to backed up # directories. # # FilePerms The file permission string (e.g. u=rw,go=r). # Only applies to backed up files. # # SourceSys The source remote system whose files are to # be backed up. This is given as either an IP # address or a machine name. # # TimeStr The time string, containing a list of all # times when the backup should be done. Only # the hours are given, in 24-hour format, and # separated from one another by spaces. # # Note that you are supposed to be able to turn values read into # variables into actual shell variables like this: # # eval ${ParmName}=`echo -ne \""$ParmVal"\"` # # This doesn't work on the NAS4Free version of bash. Furthermore, # the shell variable name that is set depends on what name the # user uses in the config file. # # Instead, we look for what we want and set it. This lets us # control what we get and give error feedback if it ain't what we # want. # if [ "`echo $Line | grep -E '^[^=]+=[^=]+$'`"x != x ]; then # # Pick up the parameter name and value. Note that the two # values in the square brackets of the sed lines (below) are # <space> and <tab>. You cannot use "\t", "\\t", "\\\\t", # "\\\\\\t" or any other combination of backslashes and the # letter "t" that you might think of. Too baddie! You need # to use a real, hard tab. # ParmName=`echo "$Line" | awk -F"=" '{print $1}' | sed "s/[ ]\$//"` ParmVal=`echo "$Line" | awk -F"=" '{print $2}' | sed "s/^[ ]//"` if [ $Debug = 1 ]; then echo " Parm $ParmName = \"$ParmVal\"" fi # # Look for all of our variables. # case "$ParmName" in # # Backup owner. # backupowner|owner|BackUpOwner|Owner) BackupOwner=$ParmVal ;; # # Destination. # dest|destination|Dest|Destination) DestDir=$ParmVal ;; # # Directory permissions. # dirperms|DirPerms) DirPerms=$ParmVal ;; # # File permissions. # fileperms|FilePerms) FilePerms=$ParmVal ;; # # Source. Note that this parameter resets all of the # other parameters so that stuff left over from the # previous source isn't used with this source. # source|Source) SourceSys=$ParmVal BackupOwner=$DefBackupOwner DestDir="" DirPerms=$DefDirPerms FilePerms=$DefFilePerms TimeStr="" ;; # # Time string. # time|timestr|Time|Timestr|TimeStr) TimeStr="$ParmVal" ;; # # Unknown parameter. # ) if [ $Debug = 1 ]; then echo " Invalid parameter $ParmName" else let Errors=Errors+1 LogMsg "Invalid parameter $ParmName in config file \ at line $LineNum" fi esac # # Otherwise, the line is treated is a list, unless it is blank. # else if [ "`echo $Line | grep -c '^\\s$'`" = 0 ]; then if [ $Debug = 1 ]; then echo " List = \"$Line\"" fi # # Looks like we're good to go. # if [ "$Line" = "" ]; then BackupSource "" else BackupSource $Line fi fi fi fi
done < $ConfigFile
#
# Give a report of the number of errors.
#
if [ $Errors -gt 0 ]; then
LogMsg "$Errors error(s) occurred during backup"
fi
#
# Send email, if required.
#
if [ $Errors -gt 0 ] || [ $Backups -gt 0 ] ; then
SendMail $Errors
fi
Before you run this script, you'll need to create a config file to tell it which sources and modules (share points) are to be backed up and where the backups are to be stored. The script itself has quite a bit of documentation about how to do this so we'll just show a sample config file here. We put it in the System share and then, using a copy command from the console or a logged-in terminal, move it to the OS volume, where nobody will monkey with it:
su cp /mnt/System/backup.cfg /etc/rsync chown root:wheel /etc/rsync/backup.cfg chmod u=rwx,go=rx /etc/rsync/backup.cfg
/etc/rsync/backup.cfg:
# This configuration file is read by the NAS4Free backup script to decide # which Rsync modules (share points) on one or more remote systems should # be backed up. # # Note that this file must not contain any of the evil, MS-generated # carriage returns. This ain't f**king Windoze, Sparky. # Backup all of the directories on Audrey. Source = audrey Dest = Backup_Audrey Time = 0 * # Backup all of the directories on Video-Game. Source = video-game Dest = Backup_Windoze Time = 2 10 14 18 - Profiles Dest = Backup_Video-Game Time = 0 Profiles # Backup the global directories on the gateway server. Source = gateway Dest = Backup_Gateway Time = 0 mail mysql # Backup user directories on the gateway server. Source = gateway Dest = Backup_HomeDirs Time = 2 10 14 18 home-jsmith home-jblow
Before you do any actual damage, you can test your config file by running the script with the debug flag:
/etc/rsync/backup -d /etc/rsync/backup.cfg
Once you're happy with how your config file is being handled, you can test the operation of the script like this:
su /etc/rsync/backup -n -v /etc/rsync/backup.cfg
If any of the backups specified in the config file occur at the current time (i.e. the current hour), you should see the results of the backup on your terminal. If the time isn't correct, you can come back later or just modify the config file to use the current times. And, if you want to test that the backup job's status message is being delivered properly, you can test it like this:
su /etc/rsync/backup /etc/rsync/backup.cfg
When you are happy with the script and the config file, you should add a cron table entry to run the backup script at hourly intervals (the config file will decide which backups actually run during each hour).
System/Advanced/Cron
Begin by clicking the "Plus" button to add a new entry. Command: /etc/rsync/backup /etc/rsync/backup.cfg Who: root Description: Back up source_host on a regular basis. Schedule time: Minutes - 0, Hours - All, Days - All, Months - All, Weekdays - All If you want to test the script, you can click the "Run now" button. This is probably a good idea because the cron job may fail silently later on. Click the "Add" button to save the crontab entry and then click to "Apply Changes" button to actually save the crontab entry.
>>>>>>
<<<<<<
There should be no need to rotate the usual system logfiles because these are set up by default to be self-limiting in size. However, the logfile that is created by the rsync backup script (above) can grow quite large. This being the case you might wish to install logrotate and set it up to rotate certain logfiles.
The FreeBSD pkg_add command can be used to add the logrotate package to the NAS4Free system. For pkg_add to simply work, you must have a connection to the Internet. If you have a connection set up, you can try:
su pkg_add -v -r logrotate
If all goes according to plan, this will install logrotate and all of its prerequisites on your NAS4Free system.
Sometimes, the repository for your system's installed OS version will not be found. For example, the AMD64 repository for FreeBSD version 7.3 does not exist. In this case, you can try installing logrotate from the base repository but you will have to specify the repository file directly. For example:
su pkg_add -v -r ftp://ftp.freebsd.org/pub/FreeBSD/ports/amd64/\ packages-7-stable/sysutils/logrotate-3.7.9.tbz
You can figure out which repository file to use by surfing through the FreeBSD directory tree starting with:
ftp://ftp.freebsd.org/pub/FreeBSD/ports
Depending on which version of NAS4Free you installed, you'll probably want to look in the i386 or amd64 subdirectories.
If you don't have a direct network connection, you can download the package files from the FreeBSD FTP site and install them with pkg_add once you've copied them to the FreeBSD system. However, you may need to download and install the prerequisites manually first. You can find out what they are with pkg_info like this:
su pkg_info -r /local/pkgs/logrotate-3.7.9.tbz
By way of example, for the above version of logrotate, you can install its prerequisites like this:
su pkg_add -v /local/pkgs/libiconv-1.13.1_1.tbz pkg_add -v /local/pkgs/gettext-0.18.1.1.tbz pkg_add -v /local/pkgs/popt-1.16.tbz
Once you've downloaded and installed all of the prerequisites the actual pkg_add command for logrotate will look something like this:
su pkg_add -v /local/pkgs/logrotate-3.7.9.tbz
You can copy the logrotate.conf.sample file to create a logrotate config file that provides a set of default values:
su cp /usr/local/etc/logrotate.conf.sample /etc/logrotate.conf
However, we prefer a logrotate.conf that looks like this:
/etc/logrotate.conf:
# Rotate log files weekly. weekly # Keep 4 weeks worth of logfiles. rotate 4 # Create new (empty) log files after rotating old ones. create # Uncomment this if you want your log files compressed. #compress # Individual packages can place log rotation files into this directory. include /etc/logrotate.d
We must now create the logrotate.d directory, where the individual package rotation files can be placed:
su mkdir /etc/logrotate.d chown root:wheel /etc/logrotate.d
Next, we can add individual package rotation files in the logrotate.d directory for each of the packages whose logfiles we wish to rotate. For the rsync backup script above, for example, we might add:
/etc/logrotate.d/rsync-backup:
/var/log/rsync_client.log { missingok notifempty }
You can check that logrotate is working and rotating files properly by forcing a rotation:
su /usr/local/sbin/logrotate -f -v /etc/logrotate.conf
When you are happy that logrotate is working as you wish, you should add a cron table entry to run logrotate at daily intervals. This is done from the NAS4Free Web UI, which you may recall, is accessed by aiming a Web browser, on another system, at the IP address that you assigned (or that was assigned). You will see the NAS4Free login screen whereupon you should logon using the userid "admin".
System/Advanced/Cron
Begin by clicking the "Plus" button to add a new entry. Command: /usr/local/sbin/logrotate /etc/logrotate.conf Who: root Description: Rotate logfiles on a daily basis. Schedule time: Minutes - 0, Hours - 4, Days - All, Months - All, Weekdays - All If you want to test the script, you can click the "Run now" button. This is probably a good idea because the cron job may fail silently later on. Click the "Add" button to save the crontab entry and then click to "Apply Changes" button to actually save the crontab entry.
One of the benefits of using ZFS is the ability to scrub the data, that is regularly check it to see that its integrity is intact by comparing mirrored copies and checksums. If an error that is caused by bit-rot is found, the scrub can correct it before it becomes permanent.
For commercial-grade disk drives, monthly scrubbing is recommended. For consumer-grade disk drives, weekly scrubbing is recommended. Since scrubbing is an expensive operation (all data on the ZFS pools must be checked), one must consider how often to schedule the scrub. Personally, we prefer to do it once a week, regardless of the type of storage. Sometime in the wee hours on an off day is preferred.
The following script, taken from gimpe, with a couple of small corrections, will perform scrubs in the background. Copy it to your System share and then, using a copy command from the console or a logged-in terminal, move it to the OS volume, where nobody will monkey with it:
su cp /mnt/System/scrub /etc/zfs chown root:wheel /etc/zfs/scrub chmod u=rwx,go=rx /etc/zfs/scrub
You can test it like this:
su /etc/zfs/scrub -n -v
You should see the results of the scrub on your terminal. If you want to test that the status message is being delivered properly, you can test it like this:
/etc/zfs/scrub
Here is the scrub script. You should change the email variables, FROM, TO, and possibly SUBJECT, before you install the script:
/etc/zfs/scrub:
#!/bin/bash #VERSION: 0.2 #AUTHOR: gimpe #EMAIL: gimpe [at] hype-o-thetic.com #WEBSITE: http://hype-o-thetic.com #DESCRIPTION: Created on FreeNAS 0.7RC1 (Sardaukar) # This script will start a scrub on each ZFS pool (one at a time) and # will send an e-mail or display the result when everyting is completed. #CHANGELOG # 0.2: 2009-08-27 Code clean up # 0.1: 2009-08-25 Make it work #SOURCES: # http://aspiringsysadmin.com/blog/2007/06/07/ # scrub-your-zfs-file-systems-regularly/ # http://www.sun.com/bigadmin/scripts/sunScripts/zfs_completion.bash.txt # http://www.packetwatch.net/documents/guides/2009073001.php # e-mail variables FROM=from@devnull.com TO=to@devnull.com SUBJECT="Scrub of Pools on NAS4Free" BODY="" # arguments VERBOSE=0 SENDEMAIL=1 args=("$*") for arg in $args; do case $arg in "-v" | "--verbose") VERBOSE=1 ;; "-n" | "--noemail") SENDEMAIL=0 ;; "-a" | "--author") echo "by gimpe at hype-o-thetic.com" exit ;; "-h" | "--help" | *) echo " usage: $0 [-v --verbose|-n --noemail] -v --verbose output display -n --noemail don't send an e-mail with result -a --author display author info (by gimpe at hype-o-thetic.com) -h --help display this help " exit ;; esac done # work variables ERROR=0 SEP=" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " RUNNING=1 # commands & configuration ZPOOL=/sbin/zpool PRINTF=/usr/bin/printf MSMTP=/usr/local/bin/msmtp MSMTPCONF=/var/etc/msmtp.conf # print a message function _log { DATE="`date +"%Y-%m-%d %H:%M:%S"`" # add message to e-mail body BODY="${BODY}$DATE: $1\n" # output to console if verbose mode if [ $VERBOSE = 1 ]; then echo "$DATE: $1" fi
}
# find all pools pools=$($ZPOOL list -H -o name) # for each pool for pool in $pools; do # start scrub for $pool _log "starting scrub on $pool" zpool scrub $pool RUNNING=1 # wait until scrub for $pool has finished running while [ $RUNNING = 1 ]; do # still running? if $ZPOOL status -v $pool | grep -q "scrub in progress"; then sleep 60 # not running else # finished with this pool, exit _log "scrub ended on $pool" _log "`$ZPOOL status -v $pool`" _log "$SEP" RUNNING=0 # check for errors if ! $ZPOOL status -v $pool | grep -q "No known data errors"; then _log "data errors detected on $pool" ERROR=1 fi fi done done # change e-mail subject if there was error if [ $ERROR = 1 ]; then SUBJECT="${SUBJECT}: Error(s) Detected" fi # send e-mail if [ $SENDEMAIL = 1 ]; then $PRINTF "From:$FROM\nTo:$TO\nSubject:$SUBJECT\n\n$BODY" | \ $MSMTP --file=$MSMTPCONF -t fi
Add a cron table entry to run the scrub script at regular intervals by adding an entry on the Cron page.
System/Advanced/Cron
Begin by clicking the "Plus" button to add a new entry. Command: /etc/zfs/scrub Who: root Description: Scrub the ZFS pools on a regular basis. Schedule time: Minutes - 0, Hours - 1, Days - All, Months - All, Weekdays - Sunday If you want to test the script, you can click the "Run now" button. This is probably a good idea because the cron job may fail silently later on. Click the "Add" button to save the crontab entry and then click to "Apply Changes" button to actually save the crontab entry.