Andrew Rutz's blog

Thursday Mar 22, 2007

Where I learned to drown, er, swim...

Here's the pool at UC Irvine where I learned how to swim the front crawl ("freestyle") and breaststroke. To be more precise, third lane from the right in the picture is where I "propulsed" myself in a swimmming-like-form from one end of the pool to the other... all without stopping. :-) ...but not without requiring the aid of several liters of pure oxygen after touching the far wall. ;-)

.

2007 South Central Zones meet

Well, my three failed attempts in the '60's (at learning how to swim) and my two recent years of "personal swimming" and my three more years of swimming on the UT Masters team have all led up to my first chance to swim in public.

I'll be swimming 3/23/07 at the 2007 South Central Zone Short Course Masters Championships, in Houston, Tx. I'll be swimming the 100yd IM (individual medley), 50 yd breaststroke, and 200yd breaststroke. If you find the "psych sheet" on the previous link, you can find my name and see that based on my seeding I'm not exactly going to "go home with all the hardware". :-) ..but... as they say... sometimes the key in Life is to make it to the Starting Line... not just the Finish Line.

A "Masters swim team" is a local chapter of the national swim club, United States Masters Swimming, which was started in the 1970's. The United States is partitioned into several zones, and Austin, TX is in the South Central Zone. Austin has several Masters swim teams, and my team swims at what people in the "swimming world" refer to as "Yankee Stadium". The Texas Swim Center is on the campus of UT-Austin, and is reknowned to be one of the five fastest pools in the United States; needless to say, I'm sure I help bring down the average ;-)

Wednesday Dec 06, 2006

One way to exit an infinite-reboot-loop

If you're in a situation where the system is panic'ing during boot, you can use

# boot net -s
to regain control of your system.

In my case, I'd added some diagnostic code to a (PCI) driver (that is used to boot the root filesystem). There was a bug in the driver, and each time during boot, the bug occurred, and so caused the system to panic:

...
000000000180b950 genunix:vfs_mountroot+60 (800, 200, 0, 185d400, 1883000, 18aec00)
  %l0-3: 0000000000001770 0000000000000640 0000000001814000 00000000000008fc
  %l4-7: 0000000001833c00 00000000018b1000 0000000000000600 0000000000000200
000000000180ba10 genunix:main+98 (18141a0, 1013800, 18362c0, 18ab800, 180e000, 1814000)
  %l0-3: 0000000070002000 0000000000000001 000000000180c000 000000000180e000
  %l4-7: 0000000000000001 0000000001074800 0000000000000060 0000000000000000

skipping system dump - no dump device configured
rebooting...

If you're logged in via the console, you can send a BREAK sequence in order to gain control of the firmware's (OBP's) prompt. Enter Ctrl-Shift-[ in order to get the "telnet>" prompt. Once telnet has control, enter this:

telnet> send brk

You'll be presented with OBP's "OK prompt":

ok

You then enter the following in order to boot into single-user mode via the network:

ok boot net -s

Note that booting from the network under Solaris will implicitly cause the system to be INSTALLED with whatever software had last been configured to be installed. However, we are using boot net -s as a "handle" with which to get at the Solaris prompt. Once at that prompt, we can perform actions as root that will let us back out our buggy driver (ok... MY buggy driver :-)) ...and replace it with the original, non-buggy driver.

Entering the boot command caused the following output, as well as left us at the Solaris prompt (in single-user-mode):

Sun Blade 1500, No Keyboard
Copyright 1998-2004 Sun Microsystems, Inc.  All rights reserved.
OpenBoot 4.16.4, 1024 MB memory installed, Serial #53463393.
Ethernet address 0:3:ba:2f:c9:61, Host ID: 832fc961.

Rebooting with command: boot net -s
Boot device: /pci@1f,700000/network@2  File and args: -s
1000 Mbps FDX Link up
Timeout waiting for ARP/RARP packet
Timeout waiting for ARP/RARP packet
4000 1000 Mbps FDX Link up

Requesting Internet address for 0:3:ba:2f:c9:61
SunOS Release 5.10 Version Generic_118833-17 64-bit
Copyright 1983-2005 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Booting to milestone "milestone/single-user:default".
Configuring devices.
Using RPC Bootparams for network configuration information.
Attempting to configure interface bge0...
Configured interface bge0
Requesting System Maintenance Mode
SINGLE USER MODE
#

Our goal is to now move to the directory containing the buggy driver and replace it with the original driver (that we had saved away before ever loading our buggy driver! :-)

However, since we booted from the network, the root filesystem ("/") is NOT mounted on one of our local disks. It is mounted on an NFS filesystem exported by our install server. To verify this, enter the following command:

# mount | head -1
/ on my-server:/export/install/media/s10u2/solarisdvd.s10s_u2dvd/latest/Solaris_10/Tools/Boot remote/read/write/setuid/devices/dev=4ac0001 on Wed Dec 31 16:00:00 1969

As a result, we have to create a temporary mount point and then mount the local disk onto that mount point:

# mkdir /tmp/mnt
# mount /dev/dsk/c0t0d0s0 /tmp/mnt

Note that your system will not necessarily have had its root filesystem on "c0t0d0s0". This is something that you should also have recorded before you ever loaded your.. er... "my" buggy driver! :-)

One can find the local disk mounted under the root filesystem by entering:

# df -k /
Filesystem            kbytes    used   avail capacity  Mounted on
/dev/dsk/c0t0d0s0    76703839 4035535 71901266     6%    /

To continue with our example, we can now move to the directory of buggy-driver in order to replace it with the original driver. Note that /tmp/mnt is prefixed to the path of where we'd "normally" find the driver:

# cd /tmp/mnt/platform/sun4u/kernel/drv/sparcv9
# ls -l pci*
-rw-r--r--   1 root     root      288504 Dec  6 15:38 pcisch
-rw-r--r--   1 root     root      288504 Dec  6 15:38 pcisch.aar
-rwxr-xr-x   1 root     sys       211616 Jun  8  2006 pcisch.orig
# cp -p pcisch.orig pcisch

We can now synchronize any in-memory filesystem data structures with those on disk... and then reboot. The system will then boot correctly... as expected:

# sync;sync
# reboot
syncing file systems... done
Sun Blade 1500, No Keyboard
Copyright 1998-2004 Sun Microsystems, Inc.  All rights reserved.
OpenBoot 4.16.4, 1024 MB memory installed, Serial #xxxxxxxx.
Ethernet address 0:3:ba:2f:c9:61, Host ID: yyyyyyyy.

Rebooting with command: boot
Boot device: /pci@1e,600000/ide@d/disk@0,0:a  File and args:
SunOS Release 5.10 Version Generic_118833-17 64-bit
Copyright 1983-2005 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Hostname: my-host
NIS domain name is my-campus.Central.Sun.COM

my-host console login:

...so that's how it's done! Of course, the easier way is to never write a buggy-driver... but.. then.. we all "have an eraser on the end of each of our pencils"... don't we ? :-)

"...thank you... and good night..."

Friday Nov 18, 2005

Using JumpStart to directly install from a CD/DVD

The following tutorial will save you time when installing Solaris via a CD or DVD. The default method is to do an Interactive Install, where one has to answer queries that the installer poses. This becomes tedious and error-prone if one has to install a large number of either machines or software versions. The solution is to use JumpStart.

However, I could not find any documentation describing how to use JumpStart when installing directly from a CD or DVD. In comparison, there are several places where "installing from a CD/DVD" is described, but they do not describe the desired solution (eg, they describe how to setup an install server using the CD/DVDs so that "network installs" can then be performed via the install server.

Note that there are two wonderful descriptions of how to create bootable CDs and DVDs ("Building a Bootable JumpStart Installation CD-ROM" and "Building a Bootable DVD to Deploy a Solaris Flash Archive" at this link) but they cater to the most general case: they provide an algorithm to modify a copy of the bootable image (and then write it to a CD/DVD).

However, for the cases where the bootable image does not need to be modified, the following describes how to use JumpStart so that its normal files (sysidcfg, profile, begin scripts, and finish scripts) can be referenced when directly booting from a CD/DVD. This capability allows one to do an unattended install.

Setting up the install server - Yes, I know I said one will be directly installing from the CD/DVD, but one has to get the JumpStart files from somewhere! =:-). The install server is actually an rpc.bootparamd(1M)-server, as we simply need a system other than the install client (eg, "target") that will provide the JumpStart configuration information via /etc/bootparams. This server must be on the same subnet as the target.

The trick is to hand-craft an /etc/bootparams entry for the target. The entry must use only the sysid_config and install_config keywords. The former identifies the directory where the sysidcfg file is located. The latter identifies where the other JumpStart files reside (eg, rules.ok, begin scripts, etc.).

You can use the following Korn Shell script to generate an /etc/bootparams entry for a target named foo and a server named my_server. foo's JumpStart files reside at /export/jump/foo on my_server:

function bootpadd {
 f=/etc/bootparams

 cat >> $f <<EOF
$1  sysid_config=${2}:$(pwd) install_config=${2}:$(pwd)
EOF
}

# bootpadd foo my_server
# grep foo /etc/bootparams
foo  sysid_config=my_server:/export/jump/foo install_config=my_server:/export/jump/foo

All of the target's JumpStart files can be put in one directory on the server. You will need a sysidcfg file, a rules file, and any file referenced by the rules file. For example, for a target with the name my_target, one could have the following rules file. Accordingly, a directory on the server would have these files:

# cd .../jumpstart/my_target
# cat rules
any - - prof finish_script
# ls -l
total 3952
-rwxr-xr-x   1 root     other       2920 Sep 17  2003 finish_script
-rwxr-xr-x   1 root     other        250 May  9  2005 prof
-rwxr-xr-x   1 root     other         27 Sep 17  2003 rules
-rwxr-xr-x   1 root     other         53 Nov 18 11:55 rules.ok
-rwxr-xr-x   1 root     other        243 Nov 18 14:25 sysidcfg

Note that the rules.ok file is created by running check(1M) on the files in the above directory. check(1M) is located on the server in the filesystem containing the install images for the Solaris version you are installing (from CD/DVD):

# .../Solaris_10/Misc/jumpstart_sample/check
Validating rules...
Validating profile prof...
The custom JumpStart configuration is ok.

Note that there is nothing in the contents of the above files that changes due to directly installing via CD/DVD. Eg, as expected, these files simply have to pass the verifications done by check(1M). Also, note that the profile file (prof in our example) will be used when doing the JumpStart. Eg, there is a profile file on the CD/DVD, but it is not used if the install_config keyword is used in the /etc/bootparams file. Also, if that keyword is not present, an Interactive Install will be performed.

Booting from the CD/DVD - All that is needed to use the above configuration is to reach the SPARC OBP command line and enter this boot command:

# sync; sync
# eeprom | grep auto-boot
auto-boot?=false
# shutdown -i0 -y -g0
...
ok boot cdrom - install
...

Adding the "- install" suffix causes JumpStart to be used. JumpStart will query our server for the target's /etc/bootparams entry. When you are done installing, you can use this Korn Shell function to remove our target's /etc/bootparams entry (as rm_install_client(1M) will not know about it, because we never ran add_install_client(1M)):

function bootprm {
 eval sed '/^${v}/d' /etc/bootparams
}

For example, this will remove my_target's entry:

# bootprm my_target

Friday Nov 11, 2005

JumpStart and multiple root slices

Here's a nice two-step trick that lets one have multiple root slices on a medium that is installed using JumpStart. Having multiple root slices on a physical disk is a space- and time-saver. One uses the disk space more efficiently, and the turnaround time on switching between Solaris versions is determined by the time to shutdown(1M) the system and boot(1M) the desired slice.

This example assumes that one is familiar with JumpStart. As a result, it will focus on how to setup two profile files, as these are what enables the multi-root slice functionality. Our profile is named prof in our rules file:

# cd <my_jumpstart_dir>
# cat rules
any - - prof finish_script

Step One - This step is what "carves out" space for the desired number of root slices. In our example, there will be three root slices. As a result, Step One will be performed once, and Step Two will be performed twice (eg., one less than the total number of root slices being installed). If it's decided that a disk is to have more root slices in the future, then any installed root slices will be destroyed when Step One is repeated.

Our profile file for this step is named prof.step1. Create a file that has these contents:

# cat prof.step1
install_type    initial_install
system_type     standalone
partitioning    explicit

# 'rootdisk' will be set to value of root_device
#root_device     c0t0d0s0
#root_device     c0t0d0s6
root_device     c0t0d0s7

# root_device must match the filesys whose name is '/'
filesys         rootdisk.s0  16000
filesys         rootdisk.s1  free  swap
filesys         rootdisk.s6  16000
filesys         rootdisk.s7  16000 /

Points to note:

  • The slice referenced by root_device (e.g., s7) must match the filesys entry whose name is "/".
  • All slices specify an explicit size (eg, "16000" MB) in their filesys entry.
  • The two slices not being installed to (eg, s0 and s6) are not given a name in their filesys entry (eg, there is no identifier following their size argument)

Before running the normal JumpStart binaries ( check(1M) and add_install_client(1M)), create a symbolic link so that prof references our profile file:

# ln -s prof.step1 prof

After logging in to the install client and executing

ok boot net - install

you will have space carved out for three root slices and your Solaris version will be installed on s7.

Step Two For the two remaining slices, s0 and s6, perform the following. We'll use s0 in the example.

Create the following profile file:

# cat prof.step2
install_type    initial_install
system_type     standalone
partitioning    explicit
# 'rootdisk' will be set to this
root_device     c0t0d0s0
#root_device     c0t0d0s6
#root_device     c0t0d0s7

# '/' slice must match root_device; complementary devices
#  must be 'ignore'
filesys         rootdisk.s0  existing /
filesys         rootdisk.s1  free  swap
filesys         rootdisk.s6  existing ignore
filesys         rootdisk.s7  existing ignore

The differences between prof.step1 and prof.step2 are highlighted.

Points to note:

  • root_device references s0 and the filesys entry named "/" also references s0.
  • The two slices not being installed to have a name of ignore.
  • All three slices use a size of existing. (This has the meaning of: "use the size that was specified in Step One" (eg, "16000")).

To install your desired Solaris version onto s0, execute this permutation of commands on the install server (with the appropriate arguments):

# rm prof
# ln -s prof.step2 prof
# check ...
# add_install_client ...

On the install client, execute our favorite JumpStart command:

ok boot net - install

Repeat Step Two in order to install your desired Solaris version onto s6.

...now.......... get to WORK!!!! :-)

Thursday Aug 25, 2005

Thoughts...

"...only when it is dark enough can you see the stars." (MLK, Jr.)

"Where it rains, the grass is greener."

"No rain, no rainbows."

"It did not come to stay; it came to pass."

"A Lucky Man affords his Wants; a Rich Man affords his Needs." (Andrew Rutz)

"..the eagle does not bother with the crow; the eagle simply flies higher." (J. Osteen)

"no prophet is accepted in his own country"

"A board has two ends."

"It is always sunny; you just have to get above the clouds."

"Weeping may endure for the night, but Joy is coming in the morning."

"...we lay our garments down, beside our beds to rest, though Death may soon disrobe us all, of what we now possess." (Unknown)

Tuesday Aug 23, 2005

Solaris boot-time and time-complexity

The only problem with algorithms reified as software programs is that they have to run on a real computer. Wall Street and Main Street are not interested in the theoretical world of Turing machines . As experienced in the real world, an algorithm must have a "running time" that is "practical". As taught in computer science classes, "practicality" is represented as time-complexity, which is represented using "O notation" , as in kO(n) (for an algorithm whose execution time is linearly proportional to a number of inputs, n). It's that darn little k, though, that makes this blog more interesting.

Until Solaris supported platforms with very many resources (CPUs, main memory, IO devices), its boot algorithm, in general, was "conveniently agnostic" towards resource-dense systems. Until the last half of the 1990's, user and engineering focus had been given to measurements that flattered the system's steady-state capabilities (e.g., Dhrystones, Whetstones, MIPs , and bandwidth). However, a fairly recent industry focus on RAS (Reliability, Availability, and Serviceability) accordingly swayed the system's internal and external customers to the degree that the system's non-steady-state lifecycle events (boot time, crash time, low-power-cycle time) were equally important. Mission-critical systems are anything if not practical, and their return-on-investment and effectiveness were begrudgingly admitted to also be a function of the "punctuations" within a system's lifetime.

So, along comes Solaris 10 and its internal attack on significantly reducing boot time. Optimization of one function within the boot algorithm reduced boot time about 30% (on systems with a sparse IO device tree). cached_va_to_pa() is the optimized form of va_to_pa(). cached_va_to_pa() caches the last virtual- to physical-address translation so as to significantly decrease the translation cost.

va_to_pa() translates a kernel virtual address ("VA") into a physical address ("PA"). After Solaris has booted, the kernel uses its virtual memory (VM) metadata to quickly translate a VA to a PA. Early during boot, however, "the firmware" (OBP) is (still) responsible for this translation.

As any optimization in good-standing would be expected to do, cached_va_to_pa() leverages empirically-derived edge-cases to specialize a general purpose algorithm. Even though va_to_pa() is still one of the most popular dynamic call sites in Solaris, its generality during steady-state execution is its liability during boot-time.

cached_va_to_pa()'s lone static call site has this call-graph:

 _start
   main
    startup
      startup_modules
        sfmmu_init_nucleus_hblks
          cached_va_to_pa

However, this lone static call-site is (dynamically) called millions of times during boot. It initializes one field within a key data structure used within Solaris's virtual memory implementation. At this point during boot, cached_va_to_pa() is able to leverage these facts:

  • the kernel is single-threaded
  • a physical page has a statically-known and fixed size (8KB)
  • the caller is initializing a static array of small data structures whose virtual addresses are contiguous

These facts allow cached_va_to_pa() to quickly translate a VA to a PA. cached_va_to_pa() caches the last (starting) PA that was computed. If the next translation maps to that same physical page, then the PA is reused. If not, a call to va_to_pa() is made (and the computed (starting) PA is saved). Trivially, since the kernel is single-threaded when cached_va_to_pa() is called, one is guaranteed that the previous and current calls are from the same kernel thread. As a result, the hit ratio of this one-element lookup cache is optimal: only one in twenty five calls (per 8KB physical page) requires a call to the "heavyweight" va_to_pa() implementation.

So, even though the time-complexity of this part of Solaris's boot algorithm is still linear (k * O(n)), the constant number of instructions used per physical page, k, is significantly smaller.

The large reduction is due to not having to call OBP. OBP's binary interface requires its client (e.g., Solaris) to implement a call that is consistent with OBP's stack-based machine. As a result, a call occurs by having Solaris translate its "C" language implementation values into FORTH language tokens, pushing the token(s), executing the tokens, popping the tokens, and translating the tokens back into "C" from FORTH.

Tuesday Aug 02, 2005

Compulsive reading...

When I was asked as a kid what I liked to do, I'd say "read"... but I wasn't convinced. My passion was athletics, but I think I felt I wasn't supposed to have such an answer... that I was supposed to have a "real hobby" ... a productive one...

Well, times certainly did change, and not only can I read ;-), but I enjoy it. There's a Twilight Zone episode where a librarian who never has enough time to read... finally gets that time... when Earth is hit, I believe, by a meteor... and he is the only human left standing... yet he mistakenly knocks his "spectacles" off his ears... and they shatter on the ground... along with his hopes of reading all those books he's had on "his list".

My greatest fear would be to lose my sight... and probably why I have so much respect and awe of those who are not capable ... and it's probably why I volunteer at Reading for the Blind & Dyslexic. It allows me to share my sight ... to let it live on after I'm gone...

So, after some background on me and reading, here's one of the "100 Best Novels lists" that are "out there". I have read the books that are highlighted.

Modern Library Top 100 English Novels of the 20th Century
  1. ULYSSES by James Joyce
  2. THE GREAT GATSBY by F. Scott Fitzgerald
  3. PORTRAIT OF THE ARTIST AS A YOUNG MAN by James Joyce
  4. LOLITA by Vladimir Nabokov
  5. BRAVE NEW WORLD by Aldous Huxley
  6. THE SOUND AND THE FURY by William Faulkner
  7. CATCH-22 by Joseph Heller
  8. DARKNESS AT NOON by Arthur Koestler
  9. SONS AND LOVERS by D.H. Lawrence
  10. THE GRAPES OF WRATH by John Steinbeck
  11. UNDER THE VOLCANO by Malcolm Lowry
  12. THE WAY OF ALL FLESH by Samuel Butler
  13. 1984 by George Orwell
  14. I, CLAUDIUS by Robert Graves
  15. TO THE LIGHTHOUSE by Virginia Woolf
  16. AN AMERICAN TRAGEDY by Theodore Dreiser
  17. THE HEART IS A LONELY HUNTER by Carson McCullers
  18. SLAUGHTERHOUSE-FIVE by Kurt Vonnegut
  19. INVISIBLE MAN by Ralph Ellison
  20. NATIVE SON by Richard Wright
  21. HENDERSON THE RAIN KING by Saul Bellow
  22. APPOINTMENT IN SAMARRA by John O'Hara
  23. U.S.A. (trilogy) by John Dos Passos
  24. WINESBURG, OHIO by Sherwood Anderson
  25. A PASSAGE TO INDIA by E.M. Forster
  26. THE WINGS OF THE DOVE by Henry James
  27. THE AMBASSADORS by Henry James
  28. TENDER IS THE NIGHT by F. Scott Fitzgerald
  29. THE STUDS LONIGAN TRILOGY by James T. Farrell
  30. THE GOOD SOLDIER by Ford Madox Ford
  31. ANIMAL FARM by George Orwell
  32. THE GOLDEN BOWL by Henry James
  33. SISTER CARRIE by Theodore Dreiser
  34. A HANDFUL OF DUST by Evelyn Waugh
  35. AS I LAY DYING by William Faulkner
  36. ALL THE KING'S MEN by Robert Penn Warren
  37. THE BRIDGE OF SAN LUIS REY by Thornton Wilder
  38. HOWARDS END by E.M. Forster
  39. GO TELL IT ON THE MOUNTAIN by James Baldwin
  40. THE HEART OF THE MATTER by Graham Greene
  41. LORD OF THE FLIES by William Golding
  42. DELIVERANCE by James Dickey
  43. A DANCE TO THE MUSIC OF TIME (series) by Anthony Powell
  44. POINT COUNTER POINT by Aldous Huxley
  45. THE SUN ALSO RISES by Ernest Hemingway
  46. THE SECRET AGENT by Joseph Conrad
  47. NOSTROMO by Joseph Conrad
  48. THE RAINBOW by D.H. Lawrence
  49. WOMEN IN LOVE by D.H. Lawrence
  50. TROPIC OF CANCER by Henry Miller
  51. THE NAKED AND THE DEAD by Norman Mailer
  52. PORTNOY'S COMPLAINT by Philip Roth
  53. PALE FIRE by Vladimir Nabokov
  54. LIGHT IN AUGUST by William Faulkner
  55. ON THE ROAD by Jack Kerouac
  56. THE MALTESE FALCON by Dashiell Hammett
  57. PARADE'S END by Ford Madox Ford
  58. THE AGE OF INNOCENCE by Edith Wharton
  59. ZULEIKA DOBSON by Max Beerbohm
  60. THE MOVIEGOER by Walker Percy
  61. DEATH COMES FOR THE ARCHBISHOP by Willa Cather
  62. FROM HERE TO ETERNITY by James Jones
  63. THE WAPSHOT CHRONICLES by John Cheever
  64. THE CATCHER IN THE RYE by J.D. Salinger
  65. A CLOCKWORK ORANGE by Anthony Burgess
  66. OF HUMAN BONDAGE by W. Somerset Maugham
  67. HEART OF DARKNESS by Joseph Conrad
  68. MAIN STREET by Sinclair Lewis
  69. THE HOUSE OF MIRTH by Edith Wharton
  70. THE ALEXANDRIA QUARTET by Lawrence Durell
  71. A HIGH WIND IN JAMAICA by Richard Hughes
  72. A HOUSE FOR MR BISWAS by V.S. Naipaul
  73. THE DAY OF THE LOCUST by Nathanael West
  74. A FAREWELL TO ARMS by Ernest Hemingway
  75. SCOOP by Evelyn Waugh
  76. THE PRIME OF MISS JEAN BRODIE by Muriel Spark
  77. FINNEGANS WAKE by James Joyce
  78. KIM by Rudyard Kipling
  79. A ROOM WITH A VIEW by E.M. Forster
  80. BRIDESHEAD REVISITED by Evelyn Waugh
  81. THE ADVENTURES OF AUGIE MARCH by Saul Bellow
  82. ANGLE OF REPOSE by Wallace Stegner
  83. A BEND IN THE RIVER by V.S. Naipaul
  84. THE DEATH OF THE HEART by Elizabeth Bowen
  85. LORD JIM by Joseph Conrad
  86. RAGTIME by E.L. Doctorow
  87. THE OLD WIVES' TALE by Arnold Bennett
  88. THE CALL OF THE WILD by Jack London
  89. LOVING by Henry Green
  90. MIDNIGHT'S CHILDREN by Salman Rushdie
  91. TOBACCO ROAD by Erskine Caldwell
  92. IRONWEED by William Kennedy
  93. THE MAGUS by John Fowles
  94. WIDE SARGASSO SEA by Jean Rhys
  95. UNDER THE NET by Iris Murdoch
  96. SOPHIE'S CHOICE by William Styron
  97. THE SHELTERING SKY by Paul Bowles
  98. THE POSTMAN ALWAYS RINGS TWICE by James M. Cain
  99. THE GINGER MAN by J.P. Donleavy
  100. THE MAGNIFICENT AMBERSONS by Booth Tarkington

Tuesday Jul 26, 2005

Hello Blog-o-mundo

Hello public-blog-o-sphere ! My first name is Andrew, and my last name should be pronounced "roots", but Los Angelenos in the early 1960's were incapable of such lingual contortions, so my family name came out sounding like "ruts".

I went to UC Irvine for this degree, which qualified me to work in the Exercise/Pulmonary Physiology lab at the UC Irvine Medical Center. After hearing a PDP-8 minicompuer humming in my ears for 2.5 years, I transitioned to the world of computers and obtained this degree. I worked at Xerox Corporation in Southern California for several years, writing embedded software for their 120 page-per-minute laser printers.

Some type of "mid-life thing" happened, and I found myself at this school, riding my bicycle 6.5 nights a week to the computer lab, in mad search of "educational satisfacton" which came in the form of a Master's Degree in Computer Science. I had the extreme privilege to have Dr. Urs Hölzle as my research advisor.

Affordable Housing was the next priority, so I relocated to Austin, TX and worked in the AIX kernel group at IBM. I developed a solution so that dbx could identify pthread-level deadlocks in an arbitrary process. My solution would also compute whether there was a "deadlock" with any of a process's read-write locks (I operated on the identities of the set of lock owners. If the more recent set is a (set-theoretic) superset of the previous set, then the number of lock owners is either not changing or increasing. Either case could assist a developer in understanding their program's behavior).

I then moseyed on over (...well... it is Texas!) to Sun Microsystem, Inc.'s Austin site. I work on the Solaris operating system. Initially, I worked on improving boot time, and now I work on device drivers.

When my doctor clears my arteries for a new load of lipids, I go here for some real Texas vittles

Calendar

Search my blog

Links

Navigation