After installing a new OpenBSD image on my Soekris net4801, I needed to become root to perform some post installation configuration. When I ran the su command, it exited without switching me to the root user:
$ su
Password:
Sorry
This baffled me for a minute, since my user and group identifiers looked fine, and I was in the wheel group (OpenBSD allows you to use the group wheel to control which users can become uid 0):
$ id
uid=1000(matty) gid=1000(matty) groups=1000(matty), 0(wheel)
To see what was going on, I ran ktrace to view the call path for the su executable:
$ ktrace su
Password:
Sorry
After reviewing the complete dump, I noticed that the su executable couldn’t open the secure passwd database:
$ kdump | egrep '(NAM|open)'
< ..... >
28302 su NAMI "/etc/spwd.db"
28302 su RET open -1 errno 13 Permission denied
< ..... >
It then dawned on me that I shouldn’t be able to ktrace a setuid executable as an unprivileged user, so I decided to check the permissions of the su utility to see why the kdump worked:
$ ls -la /usr/bin/su-to-root /usr/bin/sudo /usr/bin/sudoedit /usr/bin/sudoreplay /usr/bin/sum
-r-xr-xr-x 1 root wheel 14948 Mar 2 2006 /usr/bin/su
Well I’ll be. When I extracted the files tonight to create my archive, I either extracted then as an unprivileged user (which is why the setuid / setgid bits weren’t preserved), or I forgot to use tar’s “-p” option to preserve the file modes (I no longer have the history file, so I can’t see where I made my mistake). I think the tryptophan from the turkey is setting in. :)
I run OpenBSD on a few soekris net4801s, which don’t have a whole lot of memory. To ensure that I am efficiently using the hardware, I build custom kernels that contain just the devices needed to load and run the OpenBSD kernel on the soekris. This minizes the kernel memory footprint, and allows me to eeek out a few extra pages of spare memory. To build a custom kernel with just the devices I need, I usually start by running the dmassage utility to identify the devices on my system:
$ dmassage -t
root
-mainbus0
|-bios0
| -pcibios0
|-cpu0
-pci0
|-auich0
| -audio0
|-ichpcib0
| -isa0
| |-fdc0
| | -fd0
| |-isadma0
| |-npx0
| |-pckbc0
| | |-pckbd0
| | | -wskbd0
| | -pmsi0
| | -wsmouse0
| -pcppi0
| |-midi0
| -spkr0
|-ne3
|-pchb0
|-pciide0
| |-atapiscsi0
| | -scsibus0
| | -cd0
| -wd0
|-uhci0
| -usb0
| -uhub0
-vga1
-wsdisplay0
Once I have the devices, I use my OpenBSD kernel build procedure, but trim the devices that aren’t displayed by dmassage. This works pretty well, and allows me to maximize the hardware in my Soekris.
Over the past few years, I have come across some super useful investing resources. To ensure that I can find these when I need them, I thought I would post them here:
Bill Cara on the markets: Great overview of the market.
Compound interest calculator: Great place to see the impacts of interest rates over time.
Fund Alarm Data Table: Great place to view the risks associated with a fund.
Investopedia: Great place to look up terminology and market conditions.
Money Guy Podcast: Weekly podcast about restoring financial chaos.
Morningstar: Great place to review funds and expense ratios.
Morningstar Instant Xray: Portfolio breakdown by asset class.
Random Roger’s Big Picture: Great overview of the market and ETFs.
Seeking Alpha: Great overview of where the market is heading.
Tax guide for investors: Great place to review tax information.
Vanguard diehard forums: Great place to get free advice on index funds.
I also enjoy listening to the pro money talk, Kiplinger, Vanguard, Fidelity and Merriman capitol podcasts, which are all available throught he iTunes music store.
Last year I wrote an article titled Veritas Volume Manager Recovery Features for SysAdmin magazine. In the article I described how to backup a Veritas configuration to a file with vxconfigbackup, and how to restore it with vxconfigrestore. One thing I didn’t touch on was selectively restoring individual volume configurations. This is easy to do, and I wrote the vxvmconfigbackup shell script to simplify capturing the data needed to restore a single Veritas Volume Manager volume. To illustrate just how easy this is, I added three disk drives to a disk group, and then created three volumes (datavol01, datavol02, datavol03). Here is the layout:
$ vxprint -hft
Disk group: datadg
DG NAME NCONFIG NLOG MINORS GROUP-ID
ST NAME STATE DM_CNT SPARE_CNT APPVOL_CNT
DM NAME DEVICE TYPE PRIVLEN PUBLEN STATE
RV NAME RLINK_CNT KSTATE STATE PRIMARY DATAVOLS SRL
RL NAME RVG KSTATE STATE REM_HOST REM_DG REM_RLNK
CO NAME CACHEVOL KSTATE STATE
VT NAME NVOLUME KSTATE STATE
V NAME RVG/VSET/CO KSTATE STATE LENGTH READPOL PREFPLEX UTYPE
PL NAME VOLUME KSTATE STATE LENGTH LAYOUT NCOL/WID MODE
SD NAME PLEX DISK DISKOFFS LENGTH [COL/]OFF DEVICE MODE
SV NAME PLEX VOLNAME NVOLLAYR LENGTH [COL/]OFF AM/NM MODE
SC NAME PLEX CACHE DISKOFFS LENGTH [COL/]OFF DEVICE MODE
DC NAME PARENTVOL LOGVOL
SP NAME SNAPVOL DCO
dg datadg default default 0 1158701822.18.snappy
dm hdb hdb auto 2074 8384848 -
dm hdc hdc auto 2074 8384848 -
dm hdd hdd auto 2074 8384848 -
v datavol01 - ENABLED ACTIVE 2097152 SELECT - fsgen
pl datavol01-01 datavol01 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdb-01 datavol01-01 hdb 0 2097152 0 hdb ENA
pl datavol01-02 datavol01 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdc-01 datavol01-02 hdc 0 2097152 0 hdc ENA
pl datavol01-03 datavol01 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdd-01 datavol01-03 hdd 0 2097152 0 hdd ENA
v datavol02 - ENABLED ACTIVE 2097152 RAID - raid5
pl datavol02-01 datavol02 ENABLED ACTIVE 2097152 RAID 3/32 RW
sd hdb-02 datavol02-01 hdb 2097152 1048576 0/0 hdb ENA
sd hdc-02 datavol02-01 hdc 2097152 1048576 1/0 hdc ENA
sd hdd-02 datavol02-01 hdd 2097152 1048576 2/0 hdd ENA
v datavol03 - ENABLED ACTIVE 2097152 SELECT - fsgen
pl datavol03-01 datavol03 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdb-03 datavol03-01 hdb 3145728 2097152 0 hdb ENA
The vxvmconfigbackup shell script can be used to backup the configuration data for all disk groups, a single disk group, or a volume inside a disk group. To backup the configuration needed to recreate the volume datavol01, the volume and disk group names can be passed to the “-v” and “-g” options:
$ vxvmconfigbackup -g datadg -v datavol01 -d /tmp
Backing up volume datavol01 to /tmp/datadg.datavol01.09-19-2006-2658
Now that the configuration of datavol01 is backed up, let’s create a hypothetical problem. Let’s assume that it is 4am, you have been up debugging a problem for 48-hours straight, and you accidentally remove the volume datavol01 instead of datavol03 (I helped an admin recover from a similar situation a few years back, so I know it happens):
$ vxedit -rf rm datavol01
$ vxprint -hft
Disk group: datadg
DG NAME NCONFIG NLOG MINORS GROUP-ID
ST NAME STATE DM_CNT SPARE_CNT APPVOL_CNT
DM NAME DEVICE TYPE PRIVLEN PUBLEN STATE
RV NAME RLINK_CNT KSTATE STATE PRIMARY DATAVOLS SRL
RL NAME RVG KSTATE STATE REM_HOST REM_DG REM_RLNK
CO NAME CACHEVOL KSTATE STATE
VT NAME NVOLUME KSTATE STATE
V NAME RVG/VSET/CO KSTATE STATE LENGTH READPOL PREFPLEX UTYPE
PL NAME VOLUME KSTATE STATE LENGTH LAYOUT NCOL/WID MODE
SD NAME PLEX DISK DISKOFFS LENGTH [COL/]OFF DEVICE MODE
SV NAME PLEX VOLNAME NVOLLAYR LENGTH [COL/]OFF AM/NM MODE
SC NAME PLEX CACHE DISKOFFS LENGTH [COL/]OFF DEVICE MODE
DC NAME PARENTVOL LOGVOL
SP NAME SNAPVOL DCO
dg datadg default default 0 1158701822.18.snappy
dm hdb hdb auto 2074 8384848 -
dm hdc hdc auto 2074 8384848 -
dm hdd hdd auto 2074 8384848 -
v datavol02 - ENABLED ACTIVE 2097152 RAID - raid5
pl datavol02-01 datavol02 ENABLED ACTIVE 2097152 RAID 3/32 RW
sd hdb-02 datavol02-01 hdb 2097152 1048576 0/0 hdb ENA
sd hdc-02 datavol02-01 hdc 2097152 1048576 1/0 hdc ENA
sd hdd-02 datavol02-01 hdd 2097152 1048576 2/0 hdd ENA
v datavol03 - ENABLED ACTIVE 2097152 SELECT - fsgen
pl datavol03-01 datavol03 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdb-03 datavol03-01 hdb 3145728 2097152 0 hdb ENA
If you weren’t prepared for this problem, you might respond by screaming a bunch of profanities, and yacking in the nearest garbage can. If you are backing up your configuration, you will most likely take a minute to laugh at yourself, and then you will run vxmake with the “-d” option and the configuration to restore:
$ vxmake -d /tmp/datadg.datavol01.09-19-2006-2658
Once the configuration is restored, the volume will be available for general purpose use:
$ vxprint -hft
Disk group: datadg
DG NAME NCONFIG NLOG MINORS GROUP-ID
ST NAME STATE DM_CNT SPARE_CNT APPVOL_CNT
DM NAME DEVICE TYPE PRIVLEN PUBLEN STATE
RV NAME RLINK_CNT KSTATE STATE PRIMARY DATAVOLS SRL
RL NAME RVG KSTATE STATE REM_HOST REM_DG REM_RLNK
CO NAME CACHEVOL KSTATE STATE
VT NAME NVOLUME KSTATE STATE
V NAME RVG/VSET/CO KSTATE STATE LENGTH READPOL PREFPLEX UTYPE
PL NAME VOLUME KSTATE STATE LENGTH LAYOUT NCOL/WID MODE
SD NAME PLEX DISK DISKOFFS LENGTH [COL/]OFF DEVICE MODE
SV NAME PLEX VOLNAME NVOLLAYR LENGTH [COL/]OFF AM/NM MODE
SC NAME PLEX CACHE DISKOFFS LENGTH [COL/]OFF DEVICE MODE
DC NAME PARENTVOL LOGVOL
SP NAME SNAPVOL DCO
dg datadg default default 0 1158701822.18.snappy
dm hdb hdb auto 2074 8384848 -
dm hdc hdc auto 2074 8384848 -
dm hdd hdd auto 2074 8384848 -
v datavol01 - ENABLED ACTIVE 2097152 SELECT - fsgen
pl datavol01-01 datavol01 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdb-01 datavol01-01 hdb 0 2097152 0 hdb ENA
pl datavol01-02 datavol01 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdc-01 datavol01-02 hdc 0 2097152 0 hdc ENA
pl datavol01-03 datavol01 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdd-01 datavol01-03 hdd 0 2097152 0 hdd ENA
v datavol02 - ENABLED ACTIVE 2097152 RAID - raid5
pl datavol02-01 datavol02 ENABLED ACTIVE 2097152 RAID 3/32 RW
sd hdb-02 datavol02-01 hdb 2097152 1048576 0/0 hdb ENA
sd hdc-02 datavol02-01 hdc 2097152 1048576 1/0 hdc ENA
sd hdd-02 datavol02-01 hdd 2097152 1048576 2/0 hdd ENA
v datavol03 - ENABLED ACTIVE 2097152 SELECT - fsgen
pl datavol03-01 datavol03 ENABLED ACTIVE 2097152 CONCAT - RW
sd hdb-03 datavol03-01 hdb 3145728 2097152 0 hdb ENA
$ mount -t vxfs /dev/vx/dsk/datadg/datavol01 /a
$ cd /a
$ ls -l
total 1536
-rw-r--r-- 1 root root 524288 Sep 19 18:32 data01.dbf
-rw-r--r-- 1 root root 524288 Sep 19 18:32 data02.dbf
-rw-r--r-- 1 root root 524288 Sep 19 18:32 data03.dbf
drwxr-xr-x 2 root root 96 Sep 19 18:32 lost+found
In addition to be being able to restore the configuration with vxmake’s “-d” option, you can also piece each object back together manually. This is a tedious and error prone process (especially at 4am), so I tend to create configuration backups on all my servers just to be safe. As with all recovery scenarios, you should validate recovery procedures in a test environment prior to using them on a production system.
Wordpress has become one of the most popular blogging engines on the Internet, and has numerous features that make blogging simple and easy. While there are numerous upsides to using wordpress, there is also one major drawback. Wordpress generates each blog entry dynamically from a database, which can cause a considerable drain on computing resources. To get a better idea of just many resources wordpress would consume on a 2GHZ/1GB AMD Athlon server, I decided to run a few tests with the siege web benchmarking utility. The first test I ran was a 50-user simulation:
$ siege -c 50 http://prefetch.net/blog
Availability: 100.00 %
Elapsed time: 50.04 secs
Data transferred: 4.28 MB
Response time: 10.05 secs
Transaction rate: 4.00 trans/sec
Throughput: 0.09 MB/sec
Concurrency: 40.17
Successful transactions: 250
Failed transactions: 0
Longest transaction: 31.60
Shortest transaction: 0.09
Ouch! The results reported by siege were nothing like I expected. When 50 simultaneous users were accessing my website, it took over 10-seconds to render the main page of my blog. In addition, the server run queue was over 30, and the box was nearly unusable during the test (luckily I was using the Solaris fair share scheduler to limit how much CPU time Apache could consume). Since these results were unacceptable, I decided to start profiling and tuning Wordpress to serve up content quicker. After spending a bit of time reviewing the MySQL performance data, I adjusted several buffer cache values that were sized too low, and enabled the Wordpress post-query accelerator to allow the SQL queries to be served from the MySQL query cache. Once these changes were made, I ran siege again, and the results were not much better:
$ siege -c 50 http://prefetch.net/blog
Transactions: 268 hits
Availability: 100.00 %
Elapsed time: 62.02 secs
Data transferred: 6.25 MB
Response time: 9.84 secs
Transaction rate: 4.32 trans/sec
Throughput: 0.10 MB/sec
Concurrency: 42.50
Successful transactions: 317
Failed transactions: 0
Longest transaction: 32.78
Shortest transaction: 0.08
Since the machine was limited by CPU, I decided to fire up DTrace to see where the httpd processes were spending their time. The DTrace results indicated that Apache was spending a considerable amount of time compiling PHP pages, and issuing queries to the back-end database. Since I only update my blog a few times each week, I started to wonder if there was a way to turn the pages I created in Wordpress into static content. After reading through a variety of wordpress resources, I came across the wordpress cache #2 plugin. This super useful plugin will create a static represetnation of each dynamically generated page, and serve that file instead of the page that wordpress would dynamically generate. Once I got wp-cache2 installed, the results were right on par with what I orginally thought they should be (since I don’t typically serve 50 simultaneous user sessions, 2.76 seconds was sufficient):
$ siege -c50 http://prefetch.net/blog/
Lifting the server siege... done.
Transactions: 592 hits
Availability: 100.00 %
Elapsed time: 45.44 secs
Data transferred: 30.93 MB
Response time: 2.76 secs
Transaction rate: 13.03 trans/sec
Throughput: 0.68 MB/sec
Concurrency: 35.99
Successful transactions: 592
Failed transactions: 0
Longest transaction: 33.67
Shortest transaction: 0.24
Since the load was low processing 50 simultaneous users, I decided to see what 100 simultaneous sessions would look like:
$ siege -c100 http://prefetch.net/blog
Availability: 100.00 %
Elapsed time: 54.91 secs
Data transferred: 35.59 MB
Response time: 2.15 secs
Transaction rate: 24.15 trans/sec
Throughput: 0.65 MB/sec
Concurrency: 51.93
Successful transactions: 1423
Failed transactions: 0
Longest transaction: 34.29
Shortest transaction: 0.06
The results with 100 sessions were just as good (actually better) than the 50-session output, and I was able to get the results even lower by enabling the PHP cache accelerator. So in summary, if you are looking to handle large volumes of connections with wordpress, you might investigate the following:
Viva la blizog!