![]()
|
SysAdmin Topics
|
IntroductionThe page How to change the output of the uname command in the Solaris OS shows how to add a new device driver to change the output of the uname command. More correctly, it changes the results of the uname system call. This tip is an example of how to deal with a common class of problem: the need to change static strings within the kernel. Rather than add a special driver, we can use the adb or mdb command to modify the running kernel. Note that we use mdb. In the Solaris 7 OS and earlier Solaris versions, mdb should be replaced by adb. PurposeMany kernel returned variables are static once the kernel has finished initializing. These are usually stored as strings in the kernel and are returned by various system calls. These strings include the utsname array, returned by uname, but also include the hostid. There are times during testing or disaster recovery that these strings may need to be set to values other than their default. ScriptThe provided script is a wrapper that formats its arguments into a form suitable for use by the mdb command. #!/bin/sh # # Change the static strings in the kernel. # We can change: flag base offset # sysname -s utsname 0 # nodename -n utsname 0x101 # release -r utsname 0x202 # version -v utsname 0x303 # machine -m utsname 0x404 # hostid -h hw_serial 0 # do_mdb() { /bin/echo "$VALUE"'\000\c' | od -v -t x1 | while read addr val do if [ X"$val" != "X" ] then echo "$BASE"'+'"$OFFSET"'+0o'"$addr"'/v '"$val" | mdb -kw fi done } # # while getopts s:n:r:v:m:h: name do BASE='utsname' VALUE="$OPTARG" case $name in s) OFFSET=0x000;; n) OFFSET=0x101;; r) OFFSET=0x202;; v) OFFSET=0x303;; m) OFFSET=0x404;; h) OFFSET=0x000 VALUE=`echo "$VALUE" | /usr/xpg4/bin/tr '[:lower:]' '[:upper:]'` VALUE=`echo "16i${VALUE}pq" | /bin/dc` BASE='hw_serial' ;; ?) echo usage: $0 '-s sysname|-n nodename|-r release|-v version|-m machine|-h hostid' exit 2;; esac do_mdb done The program works in two parts. The do_mdb function takes BASE OFFSET and VALUE and will insert the string VALUE into the kernel location specified by BASE + OFFSET. It converts the string into a hexadecimal representation of each byte using od and then reads each line and inserts as appropriate. The od command always returns an extra line which the if command checks for. The while loop processes the arguments using the getopts shell builtin. For the UTSNAME strings we preset the BASE value, and manipulate the OFFSET for each string. For the hostid we reset the base address. RebootingThe changes are only current for the running instance of the kernel. When the kernel is restarted the changes are lost. To have the changes persist across reboots, a startup script would need to be added to /etc/rc2.d in the Solaris 9 OS or earlier versions or to the SMF in the Solaris 10 OS. ConclusionThe mdb (or adb) command is a simple, effective method for changing static information in the running kernel. This works on all releases of Solaris 2.X and on Solaris 7 or later versions. |