Upgrading without overloading the CPU
There are a few different ways to keep a FreeBSD system up to date.
Portupgrade is my favorite way, but building ports from source can be slow on slower systems, possibly making the system laggy for days at a time. I know of two solutions to this problem.
1. Force portupgrade to use packages where available.
To go this route, just run portupgrade with the -P switch:
#portupgrade -aRrP
This will allow portupgrade to use packages instead of having to do all that compiling — good on slow machines, but you do lose control over compile time options. Note that you still have to keep the ports tree up to date (using for example portsnap) when using this option.
2. “Renice” portupgrade’s process group to make all the portupgrade processes run at lower priority.
Two ways to do this, depending on whether portupgrade is already running:
A. If portupgrade is already running:
-Find out what the process id (pid) of the currently running portupgrade is:
#ps -a |grep portupgrade 8814 p2 S+ 0:00.15 /usr/bin/script -qa /tmp/portupgrade20091007-37088-d7pur8-0 env UPGRADE_TOOL=portupgrade UPGRADE_PORT=wxgtk2-2.8. 37088 p2 I+ 8:30.59 ruby18: portupgrade: [50/167] wxgtk2-2.8.10 (ruby18)
note that using grep gets rid of the header, so it can be a bit confusing. That first column is the PID. Now, let’s find the process group (PGID) for 37088
#ps 37088 -ao pid,pgid,command ~
PID PGID COMMAND 37088 37088 ruby18: portupgrade: [50/167] wxgtk2-2.8.10 (ruby18)
Note that in this case, the PID and PGID are the same number. I’m not sure if that’s always true with Portupgrade, but you definitely want to renice the process group, not just the currently running process. Otherwise, the “niceness” will wear off once our currently upgrading port is finished building.
-Now, we want to “renice” that process group (lower its priority):
#renice 10 -g 37088 37088: old priority 0, new priority 10
This command lowers the priority of process group 37088. You can experiment with different levels of “niceness” (I used 10) depending on what you want to do.
B. If portupgrade isn’t running yet:
This should be far easier, and more straightforward. I would go this route all the time if only I could remember to do so.
#nice -n 10 portupgrade -aRr
Tips and tricks:
- Tip #1: Portupgrade status:
Did you know you can check the status of a large portupgrade job (like portupgrade -a) by just checking the process? Remember how earlier we ran
#ps -a |grep portupgrade
and it returned:
37088 p2 I+ 8:30.59 ruby18: portupgrade: [50/167] wxgtk2-2.8.10 (ruby18)
Well, check out that part of the line that says [50/167]. That gives us an idea of how far along we are. On that particular system, it’s been a while since I’ve run portupgrade, so it has 167 total ports to upgrade, and it’s on port #50 of 167. Someday, I’d sure like to see a utility that will convert this to a curses-style graph or something like that. Perl has p5-progress, maybe that’d work.
-Tip #2 Batch upgrades.
If you’re doing a whole ton of unattended upgrading, you may want to set the BATCH=YES option in /etc/make.conf. This will keep your portupgrade from being interrupted by all those options screens that pop up. But I guess if you do that, you may as well use packages, because it’ll use the options you selected earlier. Someday, it’d be nice to make the running system beep when it needs user input (as in those config screens). I think there’s also a way to run all the configurations then to build, maybe with portmaster.
That’s all for now!
Scott

June 8th, 2010 at 9:21 AM
Thanks for a great post. I had one issue with your command:
#nice -n 10 portupgrade -aRr.
you will get “nice: Badly formed number” if you’re using tcsh. It’s worth noting that if using tcsh, you can issue the command like this:
# /usr/bin/nice -n 10 portupgrade -aRr
or
# nice +10 portupgrade -aRr
June 8th, 2010 at 10:35 AM
[...] to: http://scottspare.com/bsdfun/?p=75 for pointing me in the right direction. Compiling port updates can take a while and slow down your [...]