Upgrading FreeBSD 7.2 to 8.0

Recently updated one of my production boxes to FreeBSD 7.2 Release machine to 8.0 Release. Thanks to freebsd-update and portsnap (both in base system now) from Colin Percival (part or security team for FreeBSD) , I was able to get the upgrade done with two downtime of just a minute each.

While updating the os and software, I relied heavily on a post by Colin at  http://www.daemonology.net/blog/2009-07-11-freebsd-update-to-8.0-beta1.html . I modified the instructions a little bit, as I needed to upgrade to 8.0 Release .  Also, instead of using portupgrade, I prefer using portmaster for upgrading my ports. It has no extra dependencies, and works pretty nicely. You can read more about portmaster here. I almost alwys use the ports to install any software on FreeBSD, so the methods and tools work fine for me. If you are using any custom ports or software, you will have to watch out for any nuances involved with those ports/software.  I will list out the steps that I followed while upgrading my system. If you follow Colins page, you will find this post closely following his advice, apart from the few changes in the tools being used:

Step 1: Update your ports to the latest

# portsnap fetch update
# portmaster -aD

If there are any config options available during port upgrade, you will be asked for the same at the start itself.

Step 2: Download the 8.0 Release binary diff/patches

# freebsd-update -r 8.0-RELEASE upgrade

You will start receving messages about your installed system. Once you have confirmed  the list presented, press y.

Looking up update.FreeBSD.org mirrors... 3 mirrors found.
...
The following components of FreeBSD seem to be installed:
...
The following components of FreeBSD do not seem to be installed:
...
Does this look reasonable (y/n)? y

If you have made any changes to the default config files of the OS, it will ask you to merge the changes by opening up your default editor with the changes

Fetching metadata signature for 8.0-RELEASE from update4.FreeBSD.org... done.
...
Inspecting system... done.
Preparing to download files... done.
...
Attempting to automatically merge changes in files... done.

If there any changes that are to be done, you would be notified of the same.

The following changes, which occurred between FreeBSD 7.2-RELEASE and
FreeBSD 8.0-RELEASE have been merged into /etc/hosts:
...

Now you will be shown three lists of files which it wants to remove, add or modify. Press q for each list if you are not too much concerned with the file listings.

The following files will be removed as part of updating to 8.0-RELEASE:
...
The following files will be added as part of updating to 8.0-RELEASE:
...
The following files will be updated as part of updating to 8.0-RELEASE:
...

Step 3: Install the 8.0-RELEASE kernel and make sure you reboot for the new kernel to be used:

# freebsd-update install
Installing updates...
Kernel updates have been installed. Please reboot and run
"freebsd-update install" again to finish installing updates.
# shutdown -r now

Step 4: Install the rest of the 8.0-RELEASE:

# freebsd-update install
Installing updates... done.
Completing this upgrade requires removing old shared object files.
Please rebuild all installed 3rd party software (e.g., programs
installed from the ports tree) and then run "freebsd-update install"
again to finish installing updates.

At this point, you will have the new os installed (kernel and userland), but  some ports  might still be linking to old libraries.  You need to force rebuild all ports to make sure that os and ports are at the same level.

Step 5: Rebuild all installed ports

# portmaster -aDf

Once this is completed, run freebsd-update once again to remove stale libraries and reboot your system to complete the process.

Step 9: Remove old shared libraries and reboot

# freebsd-update install
Installing updates... done.
# shutdown -r now

That’s it. You should have a working 8.0 RELEASE by now. I haven’t tested it out myself yet, but I believe that you can use the same procedure starting from 6.3 RELEASE.

As usual, before starting of the process, make sure you have safe backup of your system. Though the process is pretty safe and tested, you still have no guarantee of not hosing your entire system to the point of no recovery ;) .

Amitabh Kant

Installing MRTG graphs for monitoring network utilisation of multiple servers on FreeBSD

Recently, I had to monitor network transfer for multiple servers across various geographical locations. There are numerous tools available which can provide a pretty comprehensive reporting for network and other parameters, but I wanted something fairly simple to install and operate. The simplest solution that I came across was MRTG/SNMP combination, which provides me with a fairly accurate idea about my network utilisation.

For the post below, I am assuming three servers, srv1 with ip 1.1.1.1, srv2 with ip 2.2.2.2 and srv3 with ip address 3.3.3.3 are to be monitored from a single location i.e. srv1.

First, either get the latest port files, or update it to latest version on all three servers

portsnap fetch extract

or

portsnap fetch update

Now on all three servers, we need to install the SNMP port

cd /usr/ports/net-mgmt/net-snmp
make all install clean

The following data needs to be put into the file “/usr/local/share/snmp/snmpd.conf” on all three server with relevant changes

###########################################################################
#
# /usr/local/share/snmp/snmpd.conf
#
###########################################################################
#
# snmpd.conf
#
#   - created by the snmpconf configuration program
#
###########################################################################
# SECTION: System Information Setup
#
#   This section defines some of the information reported in
#   the "system" mib group in the mibII tree.

# syslocation: The [typically physical] location of the system.
#   Note that setting this value here means that when trying to
#   perform an snmp SET operation to the sysLocation.0 variable will make
#   the agent return the "notWritable" error code.  IE, including
#   this token in the snmpd.conf file will disable write access to
#   the variable.
#   arguments:  location_string

syslocation  server_location 

# syscontact: The contact information for the administrator
#   Note that setting this value here means that when trying to
#   perform an snmp SET operation to the sysContact.0 variable will make
#   the agent return the "notWritable" error code.  IE, including
#   this token in the snmpd.conf file will disable write access to
#   the variable.
#   arguments:  contact_string

syscontact  Name - email@domain.com

###########################################################################
# SECTION: Access Control Setup
#
#   This section defines who is allowed to talk to your running
#   snmp agent.

# rocommunity: a SNMPv1/SNMPv2c read-only access community name
#   arguments:  community [default|hostname|network/bits] [oid]

rocommunity  community_name 1.1.1.1

Three parameters need to be modified. syslocation can be changed to the actual location of the server. syscontact should be changed to the contact address of the server administrator.

The rocommunity string is the most important part. First parameter community_name should be set to something that is not easily identifiable to outside parties. I am assuming srv1_community, srv2_community and srv3_community for the three servers respectively. The second parameter is the ip address of remote server which will query the SNMP daemon for network statistics. In our case, our graphs are to be run on srv1, so we use its ip address. I would suggest creating a separate community_name for each server for better security. In case someone wants to encrypt the traffic between the SNMP daemon and the polling server, one can use SNMP v3. The links to the pages given below have a pretty good description on using SNMP v3.

Modify and save the contents to “/usr/local/share/snmp/snmpd.conf”

On all three servers, we need to add the following to the “/etc/rc.conf” file to make sure that SNMP daemon starts at boot process.

snmpd_enable="YES"

Now, run the SNMP daemon on all three servers:

/usr/local/etc/rc.d/snmpd start

Make sure that SNMP daemon is running on all three servers.

ps auwx |grep snmp

The above line should return the details of the running snmp daemon. If not, check for any errors.

We can now proceed to install mrtg on srv1. The code now needs to be executed only on srv1

cd /usr/ports/net-mgmt/mrtg
make all install clean

Configure mrtg config files for all three servers:

cfgmaker --global 'WorkDir: /usr/local/www/apache22/data/mrtg' --global 'Options[_]: growright,unknaszero' --output /usr/local/www/apache22/data/mrtg/srv1.cfg srv1_community@1.1.1.1
cfgmaker --global 'WorkDir: /usr/local/www/apache22/data/mrtg' --global 'Options[_]: growright,unknaszero' --output /usr/local/www/apache22/data/mrtg/srv2.cfg srv2_community@2.2.2.2
cfgmaker --global 'WorkDir: /usr/local/www/apache22/data/mrtg' --global 'Options[_]: growright,unknaszero' --output /usr/local/www/apache22/data/mrtg/srv3.cfg srv3_community@3.3.3.3

where “/usr/local/www/apache22/data/mrtg” is the location you want at your webserver for mrtg to display graphs
and “/usr/local/www/apache22/data/mrtg/srv1.cfg” etc. are the names of config files for each server.

Now generate the html files and other goodies through mrtg, thrice for each server.

/usr/local/bin/mrtg /usr/local/www/apache22/data/mrtg/srv1.cfg
/usr/local/bin/mrtg /usr/local/www/apache22/data/mrtg/srv2.cfg
/usr/local/bin/mrtg /usr/local/www/apache22/data/mrtg/srv3.cfg

Make sure that you repeat each line thrice. Although not necessary, this will remove any warning messages being displayed by mrtg.

Each server will now have it’s own graph page. If you are like me, you would rather have all of them on a single page. For that to happen, you need to run the indexmaker command with all the mrtg config files

indexmaker --output=/usr/local/www/apache22/data/mrtg/index.html /usr/local/www/apache22/data/mrtg/srv1.cfg /usr/local/www/apache22/data/mrtg/srv2.cfg /usr/local/www/apache22/data/mrtg/srv3.cfg

Pointing your browser to http://your_server_name/mrtg should now bring up a single page with 5 minute interval graphs for all your servers. Clicking on those graphs will take you to the individual pages for those servers with further data and graphs.

We now need to add polling every 5 minutes for all the servers. Add the following line to “/etc/crontab” file:

*/5     *       *       *       *       root    /usr/bin/env LANG=C /usr/local/bin/mrtg /usr/local/www/apache22/data/mrtg/srv1.cfg --logging /usr/local/www/apache22/data/mrtg/srv1.log
*/5     *       *       *       *       root    /usr/bin/env LANG=C /usr/local/bin/mrtg /usr/local/www/apache22/data/mrtg/srv2.cfg --logging /usr/local/www/apache22/data/mrtg/srv2.log
*/5     *       *       *       *       root    /usr/bin/env LANG=C /usr/local/bin/mrtg /usr/local/www/apache22/data/mrtg/srv3.cfg --logging /usr/local/www/apache22/data/mrtg/srv3.log

You can scale this for as many servers you like as long as you generate individual config files for each server, and create the mrtg and index files accordingly.

Amitabh

While writing the post above, I have taken extensive help from the following two pages:

http://forums.freebsd.org/showthread.php?t=248

and

http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch22_:_Monitoring_Server_Performance

Lighttpd not running on FreeBSD with no errors shown

The data center on which my servers are hosted had a sudden electrical failure which let to a downtime of around 5 hours for my servers (I know it sucks, but then it happens).  The machine was later rebooted manually by the technician, and it went into a background fsck mode as it happens in BSD’s.

Now for some unknown reason, the lighttpd server would not start. It would not give any errors. I checked both the lighttpd logs and the syslog files for any erros being thrown, but the server would simply not give out any errors, but still would not run. I tried updating the ports, manually de-installing and reinstalling the lighttpd port, but I would still be getting the same results.

Then it hit upon me to reset the permissions of my webroot folders. I simply ran a recursive chown command ( chown -R www:www /path/to/webroot/directory ) .  This solved the problem immediately. Now I know this is a very simple problem, I was amazed by a simple fact that it would throw any errors and simply exit. It wasted my 5 hours, so I hope this can be of help to somebody.

Changing time zones on FreeBSD

I recently needed to change the timezone on my FreeBSD servers form the default to GMT. This was required as the servers were to be used for GPS based vehicle tracking system which always send date/time in GMT. After a little bit of searching on Google, I was able to come with the following method. Nothing great, just that this blog post would help me in remembering it later on:

First, copy the GMT time zone file to make it the default timezone of the server. The same can be done for any timezone you wish for.

cp /usr/share/zoneinfo/GMT /etc/localtime

Update your server with teh correct date/time using the ntp command

ntpdate -v -b pool.ntp.org

Check the server time using date command

#date

Now, to make sure that computer syncs itself everytime it boots, add these two lines to your /etc/rc.conf

ntpdate_enable="YES"
ntpdate_hosts="asia.pool.ntp.org"

[Updated: FreeBSD already comes in with  a ntpd and ntpdate binary. No need to install separate ports for just syncing the time.]

Initializing Postgresql 8.x on FreeBSD

I was recently creating a system with FreeBSD 7.x with Postgresql 8.x . The installation was done through ports and it went through smoothly. Instructions at the end of installation process were of no help.

For some reason, it would not initialize the database, nor would it give out any errors. Just to make sure, I ran this command both as root and as postgres user, but the result was same. It would neither log any message to the system log file.

A simple search through the Postgresql docs ( http://www.postgresql.org/docs/8.2/interactive/creating-cluster.html )gave an alternate way which worked for me:

# su - pgsql
$ initdb -D /usr/local/pgsql/data

Amitabh