The FreeBSD Handbook is one of the better examples of good documentation, especially for Unix and Linux systems. However, judging from frequent questions on the mailing lists, updating may have been made a bit more complex than it has to be. This is the way I update on a non-production box. There are some shortcuts that could cause problems--I will point them out as we come across them. Note that there's not too much explanation of why I'm doing things, just how to do them. For further explanations of why you can check the Handbook
Note: The first part of this article is about upgrading STABLE, which is version 4.x at time of writing. For upgrading 5.x or upgrading to 5.x see the section on updating to CURRENT
| which cvsup |
If you get an answer, then you can skip to step 3. Otherwise, continue with step 2.
| cd /usr/ports/net/cvsup-without-gui make install |
A nice additional package is /usr/ports/sysutils/fastest_cvsup. You might want to install that as well. Now we continue to step 3.
I am assuming you have sudo installed (for we try to do nothing as root). My /etc/sudoers allows members of the wheel group to execute commands. If not, here is the crash course on sudo.
cd /usr/ports/security/sudo make install clean visudo -f /usr/local/etc/sudoers |
In FreeBSD 5.x's /etc/sudoers (as well as many versions of Linux) it's line 21 that you want.
# %wheel ALL=(ALL) ALL |
Remove the # from that line and now if you're in the wheel group, you can perform the rest of these commands. If you're not in the wheel group, then as root or with root privilege, add yourself. Let's say your username is john and you are not in any gorups save the john group created when you added the account.
pw groupmod wheel -m john |
Now that sudo is installed, here is how I do it. As user john, I go into my home directory and
cp /usr/share/examples/cvsup/stable-supfile . |
I now edit both of them. The standard-supfile only needs the line about the default host to be changed. Note the * in front of the lines that the file actually uses. Lines beginning with # are comments and can be ignored, but the lines like *default base need that * in front of them. Change the line that reads
*default host=CHANGE_THIS.FreeBSD.org
to one of the default cvsup servers. The example supfile will give the most current url of a list of servers. If for example, you decided to use cvsup1 you would change the line to read
| *default host=cvsup1.FreeBSD.org |
Next, you will do the same for the ports supfile. (Updating ports is not actually a part of updating the base install, but while we're covering it, it's quite similar. Again you would change that CHANGE_THIS line. If there are ports you don't want (for example, I don't need any of the foreign language ones save Japanese, which I use) you can create a file named refuse that goes into /usr/sup. (You may have to create the sup directory). The file simply lists the ports you don't need. For example part of my /usr/sup/refuse reads
ports/arabic ports/astro ports/biology ports/chinese |
NOTE: Many people feel the refuse file is a bad idea. If you want to, for example, run make clean for all ports while in /usr/ports, the fact that the refused ports are not up to date will cause problems.
Now that your supfiles are configured, we're almost ready to use cvsup. There's one (also a bit dangerous) timesaver that I use that I'll put here--USE IT AT YOUR OWN RISK!
| cd /usr/src/sys/i386/conf cp GENERIC GENERIC.bak cp LINT LINT.bak |
Although the handbook recommends that after doing make world you first try the GENERIC kernel to see if it works, I've found that this step is often unnecessary. Downloading sources will give you a new GENERIC and new LINT kernel. So, I've made copies of them, that I will use to see if there are major differences. More on this in the further steps, but I mention it because if you are going to do it, it should be done before the next step.
One more thing to do in preparation. We're going to clean out /usr/obj which is where a lot of things get put when the system is being updated. (It's actually, if you're conscientious, a good thing to do after every update--however, I usually put it off till I'm ready to update again.)
| cd /usr/obj chflags -R noschg * rm -rf * |
We're now ready for the next step, that of actually downloading the new source (and ports if you wish) Earlier, I changed the CHANGE_THIS line. For an example, I used cvsup1. This is where we can make use of the fastest_cvsup port that we installed. Before doing the actual cvsup itself, first we see which server has the best connection at the moment. Note that I use -c us because I'm in the United States. You would change the -c option accordingly, depending upon your location.
| fastest_cvsup -c us |
This will query the US cvsup servers and at the end you'll get something like
>> Speed Daemons:
- 1st: cvsup11.freebsd.org
- 2nd: cvsup2.freebsd.org
- 3rd: cvsup3.freebsd.org
|
You can then edit your supfiles accordingly, or use the easy way, cvsup with an -h flag which will override the host in the supfile. For example
| sudo cvsup -h cvsup11.freedbsd.org -g -L 2 stable-supfile |
| sudo cvsup -g -L 2 stable-supfile && cvsup -g -L 2 ports-supfile |
I've named it cvsupx, so while in the directory I just type
| sh cvsupx |
It will now connect to the cvsup mirror site and download the latest source and ports. If you just wanted to update one or the other, (for this example, we'll use the source code as opposed to the ports) then the command is
| sudo cvsup -g -L 2 stable-supfile |
| shutdown now |
This drops you into single user mode--you'll be told to hit return for a sh prompt. Do so.
First, we'll look at /usr/src/UPDATING. As it's the only file that beings with U in that directory, I'm lazy as always and just do
| cat /usr/src/UP* | less |
Look through it. There's always a period where there's some sort of change and 100 people will post to FreeBSD-questions saying, "I went to update and got this error". For instance, at one point (and I still do this, though I don't know if it's still necessary--have to test that one day) you had to go into /usr/src/sys/modules/linux and do
| make cleandir |
If you didn't, you would run into a stop error. Another one was that there were changes in sendmail--whereas one used to be able to keep sendmail from running at startup by putting in /etc/rc.conf
| sendmail_enable="NO" |
you had to change it to
| sendmail_enable="NONE" |
So, take a quick look through it and see if there's anything that will affect you.
I mentioned copying GENERIC and LINT before downloading. This is the shortcut I take that goes against recommended procedure. The recommended procedure is to, after doing make buildworld, then compile and install the GENERIC kernel to make sure it will boot. However, often the changes are minimal, such as a change of date in the first few commented lines. So, now I do the following
| cd /usr/src/sys/i386/conf diff GENERIC GENERIC.bak diff LINT LINT.bak |
If the differences are minor, or lines that are commented, or something, for example, to do with devices that I don't have, then I know I can leave my custom MYKERN alone and skip the step of testing the new build with GENERIC. There's a risk of course, but I haven't been caught yet. Actually, if you include no options from LINT (I do, however, for my sound card, firewalling, etc) you could skip the diff LINT LINT.bak. For example, there was a change in syntax for /dev/pcm0 (the sound card) once. Had I just checked for changes in GENERIC, I would have missed it and possibly had problems
If there are major differences, you're probably better off taking the Handbook's advice and compiling and installing GENERIC. If you have a good idea of what you're doing, you might be able to simply make the necessary changes to your custom kernel. For this example, we'll assume there are no major changes, and you have a good shot of your custom kernel booting without problem after updating.
| cd /usr/src make buildworld && make buildkernel KERNCONF=MYKERN && make installkernel KERNCONF=MYKERN |
Unlike Linux the line beginning with make buildworld has to be on one line--you can't do && and then hit enter, you'll get an error message, at least while in single user mode. If your browser broke that line, then keep in mind--it has to be on one line. One could actually do make kernel KERNCONF=MYKERN but this way it gives me a better chance to see where the problem lies if one arises.
Also, note that I differ from the handbook which suggests using the -j4 option for make buildworld. Though theoretically, it should speed things up, subjectively at least (I've never done any benchmarking tests) it seems to make it go more slowly--others have posted similar observations on FreeBSD-questions, so I don't do it--you can do it if you want.
The process will take quite awhile (about an hour and a half on an Athlon 1 Gig processor with 256 megs of DDR) so go do something else. If, upon reboot, it fails, then you can get back in with, while it's counting down, hitting any key but the enter key. At the prompt type
| boot /boot/kernel.old |
which should get you back in. Then, curse yourself for taking my advice and redo the make buildkernel but this time change it to
| make buildkernel KERNCONF=GENERIC && make installkernel KERNCONF=GENERIC |
Again, on one line.
Some folks do make installworld at the same time--that is, instead of doing the make installkernel reboot, they'll do make installkernel && make install world, then reboot to run mergemaster. Others will do the entire five steps before rebooting. I like to see if the new kernel is going to boot without problems, so I do it as outlined above, rebooting after installing the new kernel. In my example, we're assuming that after make installkernel, you will then reboot.
Rebooting should be done in single user mode, as we want that for doing the next step, installing world. So as it's counting down, hit any key but the enter key and when you get to a prompt saying OK type
boot -s |
Again, you'll be told to hit return for the default /bin/sh. Then
fsck -p mount -u / mount -a cd /usr/src |
It's time to install the new sources. So,
| make installworld |
This proceeds relatively quickly.
The last step in the update is running mergemaster. It wouldn't hurt to look at the handbook and the mergemaster man page, but what is happening is this. There are now new files that haven't been installed in /etc, such as a new /etc/group, etc. If you just blithely overwrote your old files, you wouldn't be able to log in again. So, before running mergemaster, let's play it safe
| cp -Rp /etc /etc.old |
It's recommended that until you get used to using mergemaster you run it with the verbose and contextual diffs options. It's also been suggested that you add a width flag to enable you to see more things on one line. So
| mergemaster -cv -w 120 |
Others prefer the default sdiff. It's up to you. Try them both and see (you can run the whole program without making any changes, giving you a chance to try the various options)
The default is to leave everything alone. You can do this of course, and it's safe. You probably will want to install the latest MAKEDEV and such though. It'll name a file and then, if you press enter, show the differences, with the currently installed file preceded by a - and the temporary new one by a +. When you've figured out what to do, hit
| q |
for quit. Then you're given the option to install the new one, keep the old and throw out the new one, merge the two, or leave it for later (the default). If you choose to merge them you'll then see the files more or less side by side (a reason to use that -w 120 flag). You then choose either r for the right hand side one (the new one) or l (a lower case L, not the numeral one) to choose the lefthand one.
Some of them such as the new message of the day, (motd) can be installed or deleted without affecting your system. If you're not using sendmail or postfix (for instance, on my workstation, I use promcail as my MDA and nbsmtp to send mail, so it really doesn't affect anything) you can again just choose the old or the new without problem. I usually, in these cases, choose the new, since if, for example, I one day decided to make the box a mail server, I'll have the most current files.
Other files, such as /etc/group and /etc/passwd are important. You can either keep the old ones, or merge them--being careful to choose l for left when it comes to a line that has a current user, root, etc. What I do is this. I do all of this in console mode. I open up a second virtual console with alt+F2. Then, say I've merged /etc/passwd. I then go to the second console and make sure that I can still login as root and user. If there's a problem, I just replace /etc/passwd from the /etc.old backup that I made. This is a bit time-consuming, but, if you are going to merge one of these files (as opposed to just discarding the new one) it can be less time consuming than finding out, after discarding old files, that you made an error. I also check that I can log in from another machine with ssh after making any changes to /etc/ssh or sshd_config.
When finished, mergemaster will ask if you want to keep the temporary files or discard them. I usually pick discard. KEEP IN MIND THAT IS NOT THE SAFE WAY! It'll then ask should it run a new MAKEDEV script to which I pick yes. It then, depending upon what I've done, ask should it run a few other scripts updating the passwd and group files, again I choose yes. After it's done that, I once again check from the second virtual console, that I can log in as root and user. I've never run into a problem at that step, however (if I have problems from a mistype, it usually shows up earlier, right after I've installed the merged group or passwd files.) Again, I still have my /etc.old backup, so it's fixable. I would just copy the /etc.old/passwd or whatever back into /etc.
Congratulations, you're done. For further reading, there is the Handbook. (The section called "The Cutting Edge").
| *default release=cvs tag=RELENG_4 |
To get 5.x change it to
| *default release=cvs tag=RELENG_5_2 |
(I'm deliberately not giving you the line if you want to get CURRENT--if you want CURRENT and don't read any further than this page, then you are almost certainly headed for problems.)
Upgrading to Current can be an adventure--it often dies in the middle. Before even attempting it, you should really look at the handbook, and if you're going to ignore their advice about subscribing to the current mailing list, at least look at the recent archives. When it goes smoothly it goes relatively smoothly, however, take the Handbook's warnings about it seriously. Up to downloading (using a slightly different supfile than the standard-supfile one) the steps are pretty much the same through doing make buildworld. Although some brave souls get away with it, the chances are that if you're reading this, you're not as skilled as they are, so, for the next step, that of building the kernel, I would definitely stick with GENERIC. (And it WILL have changed quite a bit from your last kernel).
There's another step as well (This one is covered in UPDATING but it doesn't hurt to repeat it.) One does the make buildworld make mbuildkernel as above, however, note the additional step below between make buildkernel and make installkernel. Also, note the additional step after make installkernel. After clearing out /usr/obj and doing cvsup as explained above, one would, hopefully, first read UPDATING (which should make the below explanation superfluous) :) and then
| make buildworld make buildkernel KERNCONF=GENERIC cp /usr/src/sys/i386/conf/GENERIC.hints /boot/device.hints make installkernel KERNCONF=GENERIC cd /usr/src/sys/boot make installkernel KERNCONF=GENERIC reboot |
If you don't copy over the GENERIC.hints the build won't succeed. Also, I put /sys/i386--obviously, if your architecture is different, that is, if you were on a sparc or alpha, use your system's architecture. If you don't do that cd to /sys/boot and make install, when you reboot, you'll find that uname -a is still showing the old kernel.
The reboot will be into single user mode. Somewhere on the FreeBSD website, it comments that one should not use some of the shortcuts that are commonly used. I've found this to be true. Don't do a shutdown now (that was mentioned above), do a reboot.
As it starts to boot and you're told to hit [Enter] to boot and any other key for a command prompt, hit any other key. I use the space bar, use what you like. You'll then see a prompt like
| OK |
At that point you can hit
| boot -s |
Then, when hit return it will boot into single user mode. Then
fsck -p mount -u / mount -a cd /usr/src |
There's another line adjkerntz -i if CMOS is wall time, again, this is covered in UPDATING.
Lastly, one can usually get by after that with
| rm -rf /usr/include/g++ mergemaster -p make installworld mergemaster |
READ UPDATING. If you do, and follow the instructions, your upgrade should be successful. Trying on a few sacrificial installs, I've found it to go pretty smoothly (although other things would happen, like OpenOffice no longer working, or having carelessly installed new pam files in etc so that I couldn't use sudo. Well, that's why I used test boxes to do it.)
UPDATING gives a few different suggestions, saying that if it breaks, try make -k installworld which will keep it going even if it runs into broken things. They also suggest doing mergemaster -p ( to just merge the essentials) before finishing.
Also read UPDATING about how to speed up the system if you wish,
but remember CURRENT is primarily for the developers and
testers.
NOTE: Some of the above, such as copying over hints might be
unecessary if you are upgrading from 5.x to CURRENT.
One minor problem is that if you do pkg_add and have changed from XFree86 to xorg, the install will stop, complaining about missing XFree86 libraries. If one does pkg_add -f, it will install, despite the complaints and work without problem.
As of July 2004 I have found one other minor problem. There is a script in /usr/local/OpenOffice-x.x/programs called freebsd-local.sh. OpenOffice apparently needs this script to start, so it has to be copied over into your home/OpenOffice-x.x/programs directory.
Also, as mentioned, sudo didn't work properly after upgrading. I fixed this by doing make deinstall make clean make install.
You'll note that there's no longer a LINT file by default in
/usr/src/sys/i386/conf. You can create it, by doing (as root or
with root privilege)
| cd /usr/src/sys/i386/conf make LINT |
If you have an LCD monitor once you make your custom kernel you should be sure that you have the following included. (I'm just throwing this in so that I don't have to look it up each time. I only started using an LCD with a box that has 5.0 on it, so I'm not sure what would or wouldn't be needed in 4.x.) For 5.x to get a reasonable resolution on an LCD monitor, your kernel should have the following two lines:
options VESA options SC_PIXEL_MODE |
(By the way, for those who miss hangman, it's in /usr/ports/games/freebsd-games)
Another little note--I found on one box, with an ASUS motherboard, that shutdown -p stopped working. Something to do with problems with ACPI. Adding the following line to /etc/sysctl.conf fixed it. (Thanks to Stefan on the FreeBSD-CURRENT mailing list for the answer).
| hw.acpi.disable_on_poweroff=0 |
(As of September, 2004, this is no longer an issue. It's one of those things I leave in for those who aren't up to date).
I should add that I tried on two occasions to update from 5.1 to 5.2. In both cases, the whole system got messed up, this has to do with some libexec things. At this point, it isn't thoroughly researched on my part, however, if you do update from 5.1 to 5.2 be careful. When I figure out the problem (need to make room on some test boxes) I will post the information here.
Since the above was written, I did a few more upgrades on test boxes without problems. I then tried on a more important, though not critical box, and once again ran into a stop error with installworld. (I should add that I do follow the suggested procedure in UPDATING). One solution I had seen on google was to boot from a 5.2 CD and choose upgrade. I tried this on one box, only mounting / and /usr when asked to choose what to mount, and the upgrade went successfully--I was then able to boot into the 5.2 install.
From there, everything was fine, doing the usual updating with makeworld worked without problems. So, I would say if you run into this, trying to do upgrade from the 5.2 CD is worth a try.
Because of some issues with libpthreads and gcc, many packages may have to be reinstalled. Fluxbox is one of them. I found that I had to deinstall fluxbox and boxtools and reinstall both of them.
In the end, one should really reinstall all ports. However, even if one does that, some ports won't work (as of early October, 2004). An example is the native FreeBSD version of opera.
What is happening here (thanks to phoenix on FreeBSD forums for the explanation and solution) is that although opera is a port, it's still built from binaries looking for the older libraries. The easiest (in my opinion) workaround (again given me by phoenix) is
cd /usr/src/lib/compat/compat4x.i386 make depend && make && make install |
In the kernel, the pcm device is no longer used, instead one uses the device sound. One can also compile the module for their particular sound card into the kernel.
Now, this is something I didn't research very heavily--it didn't work at first, I did a bit of searching, got it to work and stopped investigating. In my case, I have in my kernel
device sound device snd_cmi |
However, when I rebooted, I still didn't have sound. It turns out that /boot/defaults/loader.conf has it turned off by default. So, I added to /boot/loader.conf
snd_cmi_load="YES" |
After that, sound worked without problem.
(Note that for AC97 type onboard sound, snd_ich usually works, at least it did for me.) :)
The FreeBSD website has other pointers for those upgrading, and it is worthwhile to read them